summaryrefslogtreecommitdiffstats
path: root/src/extras/shaders/es2
diff options
context:
space:
mode:
authorKevin Ottens <kevin.ottens@kdab.com>2017-08-02 10:25:02 +0200
committerSean Harmer <sean.harmer@kdab.com>2017-09-22 11:21:08 +0000
commite67119b71d1b63c5710100349fa634113e93ada2 (patch)
tree4ada3a09ddfb38152c20ed7d16b062bc910ec234 /src/extras/shaders/es2
parent11b804f9cd70d0abe4ca6168c6fc7aaddf14b82c (diff)
Get rid of adsModelNormalMapped
All materials and examples are ported away from it. It was really not related to normal mapping at all, somehow it was an implementation of adsModel working in tangent space instead of world space. Now we got it all in world space, just like for the metal/rough implementation. Change-Id: I3346277ce9b91328d70d914b319ac25f947fff0e Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/extras/shaders/es2')
-rw-r--r--src/extras/shaders/es2/coordinatesystems.inc85
-rw-r--r--src/extras/shaders/es2/light.inc.frag72
-rw-r--r--src/extras/shaders/es2/light.inc.frag10075
-rw-r--r--src/extras/shaders/es2/normaldiffusemap.frag13
-rw-r--r--src/extras/shaders/es2/normaldiffusemap.vert8
-rw-r--r--src/extras/shaders/es2/normaldiffusemapalpha.frag13
-rw-r--r--src/extras/shaders/es2/normaldiffusespecularmap.frag13
7 files changed, 122 insertions, 157 deletions
diff --git a/src/extras/shaders/es2/coordinatesystems.inc b/src/extras/shaders/es2/coordinatesystems.inc
new file mode 100644
index 000000000..fad0040c7
--- /dev/null
+++ b/src/extras/shaders/es2/coordinatesystems.inc
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+FP mat3 transpose(const in FP mat3 inputMatrix)
+{
+ FP vec3 i0 = inputMatrix[0];
+ FP vec3 i1 = inputMatrix[1];
+ FP vec3 i2 = inputMatrix[2];
+
+ FP mat3 outputMatrix = mat3(
+ vec3(i0.x, i1.x, i2.x),
+ vec3(i0.y, i1.y, i2.y),
+ vec3(i0.z, i1.z, i2.z)
+ );
+
+ return outputMatrix;
+}
+
+FP mat3 calcWorldSpaceToTangentSpaceMatrix(const in FP vec3 wNormal, const in FP vec4 wTangent)
+{
+ // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
+ // This allows to build the tangentMatrix below by simply transposing the
+ // tangent -> eyespace matrix (which would now be orthogonal)
+ FP vec3 wFixedTangent = normalize(wTangent.xyz - dot(wTangent.xyz, wNormal) * wNormal);
+
+ // Calculate binormal vector. No "real" need to renormalize it,
+ // as built by crossing two normal vectors.
+ // To orient the binormal correctly, use the fourth coordinate of the tangent,
+ // which is +1 for a right hand system, and -1 for a left hand system.
+ FP vec3 wBinormal = cross(wNormal, wFixedTangent.xyz) * wTangent.w;
+
+ // Construct matrix to transform from world space to tangent space
+ // This is the transpose of the tangentToWorld transformation matrix
+ FP mat3 tangentToWorldMatrix = mat3(wFixedTangent, wBinormal, wNormal);
+ FP mat3 worldToTangentMatrix = transpose(tangentToWorldMatrix);
+ return worldToTangentMatrix;
+}
+
diff --git a/src/extras/shaders/es2/light.inc.frag b/src/extras/shaders/es2/light.inc.frag
index 57a30036f..aec04139d 100644
--- a/src/extras/shaders/es2/light.inc.frag
+++ b/src/extras/shaders/es2/light.inc.frag
@@ -14,78 +14,6 @@ struct Light {
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
-void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- const in FP mat3 tangentMatrix,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) );
-
- FP vec3 n = normalize( vnormal );
-
- FP vec3 s, ts;
- Light light;
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- if (i >= lightCount) // Make brcm happy with the for loop
- break;
- if (i == 0)
- light = lights[0];
- else if (i == 1)
- light = lights[1];
- else if (i == 2)
- light = lights[2];
- else if (i == 3)
- light = lights[3];
- else if (i == 4)
- light = lights[4];
- else if (i == 5)
- light = lights[5];
- else if (i == 6)
- light = lights[6];
- else if (i == 7)
- light = lights[7];
-
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if ( dot(snormal, s) < 0.0 )
- att = 0.0;
- else {
- ts = normalize( tangentMatrix * s );
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
- }
- }
- } else {
- if ( dot(snormal, -light.direction) > 0.0 )
- s = normalize( tangentMatrix * -light.direction );
- else
- att = 0.0;
- }
-
- FP float diffuse = max( dot( ts, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -ts, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * light.intensity * diffuse * light.color;
- specularColor += att * light.intensity * specular * light.color;
- }
-}
-
void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
out FP vec3 diffuseColor, out FP vec3 specularColor)
{
diff --git a/src/extras/shaders/es2/light.inc.frag100 b/src/extras/shaders/es2/light.inc.frag100
index b4988ad82..6c6f6a259 100644
--- a/src/extras/shaders/es2/light.inc.frag100
+++ b/src/extras/shaders/es2/light.inc.frag100
@@ -14,81 +14,6 @@ struct Light {
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
-void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- const in FP mat3 tangentMatrix,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- // 0
- if (lightCount < 1)
- return;
- FP vec3 s;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = tangentMatrix * ( lights[0].position - vpos );
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[0].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( tangentMatrix * -lights[0].direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
- specularColor += att * specular;
-
- // 1
- if (lightCount < 2)
- return;
- att = 1.0;
- if ( lights[1].type != TYPE_DIRECTIONAL ) {
- s = tangentMatrix * ( lights[1].position - vpos );
- if (length( lights[1].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[1].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( tangentMatrix * -lights[1].direction );
- }
-
- diffuse = max( dot( s, n ), 0.0 );
-
- specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
- specularColor += att * specular;
-}
-
void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
out FP vec3 diffuseColor, out FP vec3 specularColor)
{
diff --git a/src/extras/shaders/es2/normaldiffusemap.frag b/src/extras/shaders/es2/normaldiffusemap.frag
index c69aa8b81..e1f19b81a 100644
--- a/src/extras/shaders/es2/normaldiffusemap.frag
+++ b/src/extras/shaders/es2/normaldiffusemap.frag
@@ -1,8 +1,9 @@
#define FP highp
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
@@ -15,16 +16,22 @@ uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
#pragma include light.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ FP vec3 tNormal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ FP mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ FP mat3 invertTangentMatrix = transpose(tangentMatrix);
+
+ FP vec3 wNormal = normalize(invertTangentMatrix * tNormal);
// Calculate the lighting model, keeping the specular component separate
FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ adsModel(worldPosition, wNormal, eyePosition, shininess, diffuseColor, specularColor);
// Combine spec with ambient+diffuse for final fragment color
gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, 1.0 );
diff --git a/src/extras/shaders/es2/normaldiffusemap.vert b/src/extras/shaders/es2/normaldiffusemap.vert
index ecc689f69..0681e370a 100644
--- a/src/extras/shaders/es2/normaldiffusemap.vert
+++ b/src/extras/shaders/es2/normaldiffusemap.vert
@@ -4,6 +4,8 @@ attribute vec2 vertexTexCoord;
attribute vec4 vertexTangent;
varying vec3 worldPosition;
+varying vec3 worldNormal;
+varying vec4 worldTangent;
varying vec2 texCoord;
varying mat3 tangentMatrix;
@@ -20,9 +22,13 @@ void main()
texCoord = vertexTexCoord * texCoordScale;
// Transform position, normal, and tangent to world coords
+ worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
+ worldNormal = normalize(modelNormalMatrix * vertexNormal);
+ worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
+ worldTangent.w = vertexTangent.w;
+
vec3 normal = normalize( modelNormalMatrix * vertexNormal );
vec3 tangent = normalize( modelNormalMatrix * vertexTangent.xyz );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
// Calculate binormal vector
vec3 binormal = normalize( cross( normal, tangent ) );
diff --git a/src/extras/shaders/es2/normaldiffusemapalpha.frag b/src/extras/shaders/es2/normaldiffusemapalpha.frag
index 98acbf01d..599445b9b 100644
--- a/src/extras/shaders/es2/normaldiffusemapalpha.frag
+++ b/src/extras/shaders/es2/normaldiffusemapalpha.frag
@@ -1,8 +1,9 @@
#define FP highp
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
@@ -15,16 +16,22 @@ uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
#pragma include light.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ FP vec3 tNormal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ FP mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ FP mat3 invertTangentMatrix = transpose(tangentMatrix);
+
+ FP vec3 wNormal = normalize(invertTangentMatrix * tNormal);
// Calculate the lighting model, keeping the specular component separate
FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ adsModel(worldPosition, wNormal, eyePosition, shininess, diffuseColor, specularColor);
// Combine spec with ambient+diffuse for final fragment color
// Use the alpha from the diffuse texture (for alpha to coverage)
diff --git a/src/extras/shaders/es2/normaldiffusespecularmap.frag b/src/extras/shaders/es2/normaldiffusespecularmap.frag
index b30c1bd5f..6dc2fba02 100644
--- a/src/extras/shaders/es2/normaldiffusespecularmap.frag
+++ b/src/extras/shaders/es2/normaldiffusespecularmap.frag
@@ -1,8 +1,9 @@
#define FP highp
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture;
@@ -15,17 +16,23 @@ uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
#pragma include light.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
FP vec4 specularTextureColor = texture2D( specularTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ FP vec3 tNormal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ FP mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ FP mat3 invertTangentMatrix = transpose(tangentMatrix);
+
+ FP vec3 wNormal = normalize(invertTangentMatrix * tNormal);
// Calculate the lighting model, keeping the specular component separate
FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ adsModel(worldPosition, wNormal, eyePosition, shininess, diffuseColor, specularColor);
// Combine spec with ambient+diffuse for final fragment color
gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + specularTextureColor.rgb * specularColor, 1.0 );