diff options
author | Kevin Ottens <kevin.ottens@kdab.com> | 2017-08-02 10:25:02 +0200 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-09-22 11:21:08 +0000 |
commit | e67119b71d1b63c5710100349fa634113e93ada2 (patch) | |
tree | 4ada3a09ddfb38152c20ed7d16b062bc910ec234 /src/extras/shaders/es2 | |
parent | 11b804f9cd70d0abe4ca6168c6fc7aaddf14b82c (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.inc | 85 | ||||
-rw-r--r-- | src/extras/shaders/es2/light.inc.frag | 72 | ||||
-rw-r--r-- | src/extras/shaders/es2/light.inc.frag100 | 75 | ||||
-rw-r--r-- | src/extras/shaders/es2/normaldiffusemap.frag | 13 | ||||
-rw-r--r-- | src/extras/shaders/es2/normaldiffusemap.vert | 8 | ||||
-rw-r--r-- | src/extras/shaders/es2/normaldiffusemapalpha.frag | 13 | ||||
-rw-r--r-- | src/extras/shaders/es2/normaldiffusespecularmap.frag | 13 |
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 ); |