diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 46ce7d66526e4a6e04211770aed7a7d97d1275e8..1dd697b43d6fc4331722f18e518770c0003b6af3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -144,26 +144,26 @@ vec2 getScreenCoordinate(vec2 screenpos) // Method #4: Spheremap Transform, Lambert Azimuthal Equal-Area projection vec3 getNorm(vec2 screenpos) { - vec2 enc = texture(normalMap, screenpos.xy).xy; - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; + vec2 f = texture(normalMap, screenpos.xy).xy; + f = f * 2.0 - 1.0; + + // https://twitter.com/Stubbesaurus/status/937994790553227264 + vec3 n = vec3( f.x, f.y, 1.0 - abs( f.x ) - abs( f.y ) ); + float t = clamp( -n.z , 0.0, 1.0); + n.xy += vec2(n.x >= 0.0 ? -t : t, n.y >= 0.0 ? -t : t); + return normalize( n ); } vec3 getNormalFromPacked(vec4 packedNormalEnvIntensityFlags) { - vec2 enc = packedNormalEnvIntensityFlags.xy; - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return normalize(n); // TODO: Is this normalize redundant? + vec2 f = packedNormalEnvIntensityFlags.xy; + f = f * 2.0 - 1.0; + + // https://twitter.com/Stubbesaurus/status/937994790553227264 + vec3 n = vec3( f.x, f.y, 1.0 - abs( f.x ) - abs( f.y ) ); + float t = clamp( -n.z , 0.0, 1.0); + n.xy += vec2(n.x >= 0.0 ? -t : t, n.y >= 0.0 ? -t : t); + return normalize( n ); } // return packedNormalEnvIntensityFlags since GBUFFER_FLAG_HAS_PBR needs .w @@ -392,7 +392,7 @@ vec3 pbrIbl(vec3 diffuseColor, out vec3 specContrib) { // retrieve a scale and bias to F0. See [1], Figure 3 - vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough); + vec2 brdf = BRDF(clamp(nv, 0, 1), perceptualRough); vec3 diffuseLight = irradiance; vec3 specularLight = radiance; diff --git a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl index 6cd24455228f402580f9e9d068400b4d935728c6..20e68fae2596df21b0be42ee51586ad25bd5e76d 100644 --- a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl @@ -23,12 +23,20 @@ * $/LicenseInfo$ */ -// Lambert Azimuthal Equal-Area projection -// See: https://aras-p.info/texts/CompactNormalStorage.html -// Also see: A_bit_more_deferred_-_CryEngine3.ppt + // Octahedron normal vector encoding + // https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/ + // + +vec2 OctWrap( vec2 v ) +{ + return ( 1.0 - abs( v.yx ) ) * vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0); +} + vec2 encode_normal(vec3 n) { - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; + n /= ( abs( n.x ) + abs( n.y ) + abs( n.z ) ); + n.xy = n.z >= 0.0 ? n.xy : OctWrap( n.xy ); + n.xy = n.xy * 0.5 + 0.5; + return n.xy; }