From 314f27d1b1701e0fdc4bb983d0f9fd4d4ed6573a Mon Sep 17 00:00:00 2001
From: Ptolemy <ptolemy@lindenlab.com>
Date: Fri, 15 Jul 2022 17:29:39 -0700
Subject: [PATCH] SL-17702: PBR: Cleanup light shaders to use calcHalfVectors,
 remove da alias, and unused sa

---
 .../shaders/class1/deferred/deferredUtil.glsl | 20 +++++--
 .../class3/deferred/multiPointLightF.glsl     | 43 ++++++++-------
 .../class3/deferred/multiSpotLightF.glsl      | 34 ++++++------
 .../shaders/class3/deferred/pointLightF.glsl  | 53 ++++++++-----------
 .../shaders/class3/deferred/spotLightF.glsl   | 36 ++++++-------
 5 files changed, 96 insertions(+), 90 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 3427f373d22..4df74b762a8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -31,13 +31,25 @@ uniform vec2 screen_res;
 
 const float M_PI = 3.14159265;
 
-void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh)
-{
-//  l  = normalize(lv);
-//  h  = normalize(l + v);
+// In:
+//   lv  unnormalized surface to light vector
+//   n   normal of the surface
+//   pos unnormalized camera to surface vector
+// Out:
+//   l   normalized surace to light vector
+//   nl  diffuse angle
+//   nh  specular angle
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v,
+    out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist)
+{
+    l  = normalize(lv);
+    h  = normalize(l + v);
     nh = clamp(dot(n, h), 0.0, 1.0);
+    nl = clamp(dot(n, l), 0.0, 1.0);
     nv = clamp(dot(n, v), 0.0, 1.0);
     vh = clamp(dot(v, h), 0.0, 1.0);
+
+    lightDist = length(lv);
 }
 
 vec2 getScreenCoordinate(vec2 screenpos)
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
index fa553cf341f..d4e82cebf38 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -52,10 +52,14 @@ uniform mat4  inv_proj;
 
 VARYING vec4 vary_fragcoord;
 
-void calcHalfVectors(vec3 h, vec3 n, vec3 npos, out float nh, out float nv, out float vh);
+vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
+vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance);
 vec4 getPosition(vec2 pos_screen);
 vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
 vec2 getScreenXY(vec4 clip);
+void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
 vec3 srgb_to_linear(vec3 c);
 
 void main()
@@ -66,10 +70,6 @@ void main()
     vec3 final_color = vec3(0, 0, 0);
     vec2 tc          = getScreenXY(vary_fragcoord);
     vec3 pos         = getPosition(tc).xyz;
-    if (pos.z < far_z)
-    {
-        discard;
-    }
 
     float envIntensity; // not used for this shader
     vec3 n;
@@ -78,8 +78,8 @@ void main()
     vec4 spec    = texture2DRect(specularRect, tc);
     vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
 
-    float noise = texture2D(noiseMap, tc/128.0).b;
-    vec3  v     = -normalize(pos);
+    vec3  h, l, v = -normalize(pos);
+    float nh, nl, nv, vh, lightDist;
 
     if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
     {
@@ -92,6 +92,13 @@ void main()
     }
     else
     {
+        if (pos.z < far_z)
+        {
+            discard;
+        }
+
+        float noise = texture2D(noiseMap, tc/128.0).b;
+
         // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
         for (int i = 0; i < LIGHT_COUNT; ++i)
         {
@@ -100,11 +107,11 @@ void main()
             dist /= light[i].w;
             if (dist <= 1.0)
             {
-                float da = dot(n, lv);
-                if (da > 0.0)
+                float nl = dot(n, lv);
+                if (nl > 0.0)
                 {
-                    lv = normalize(lv);
-                    da = dot(n, lv);
+                    float lightDist;
+                    calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
 
                     float fa         = light_col[i].a + 1.0;
                     float dist_atten = clamp(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 0.0, 1.0);
@@ -116,25 +123,21 @@ void main()
 
                     dist_atten *= noise;
 
-                    float lit = da * dist_atten;
+                    float lit = nl * dist_atten;
 
                     vec3 col = light_col[i].rgb * lit * diffuse;
 
                     if (spec.a > 0.0)
                     {
-                        lit        = min(da * 6.0, 1.0) * dist_atten;
-                        vec3  h    = normalize(lv + v);
-                        float nh, nv, vh;
-                        calcHalfVectors(h, n, v, nh, nv, vh);
-                        float sa   = nh;
-                        float fres = pow(1 - dot(h, v), 5) * 0.4 + 0.5;
+                        lit        = min(nl * 6.0, 1.0) * dist_atten;
+                        float fres = pow(1 - vh, 5) * 0.4 + 0.5;
 
                         float gtdenom = 2 * nh;
-                        float gt      = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+                        float gt      = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
 
                         if (nh > 0.0)
                         {
-                            float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * da);
+                            float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * nl);
                             col += lit * scol * light_col[i].rgb * spec.rgb;
                         }
                     }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
index d36ff995dd7..b86402b0315 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -62,6 +62,7 @@ uniform float sun_wash;
 uniform int proj_shadow_idx;
 uniform float shadow_fade;
 
+// Light params
 uniform vec3 center;
 uniform float size;
 uniform vec3 color;
@@ -72,9 +73,13 @@ uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
 
-void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh);
+vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
+vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
 vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
 vec2 getScreenXY(vec4 clip);
+void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
 vec3 srgb_to_linear(vec3 cs);
 
 vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
@@ -182,8 +187,9 @@ void main()
     }
 
     lv = proj_origin-pos.xyz;
-    lv = normalize(lv);
-    float da = dot(n, lv);
+    vec3  h, l, v = -normalize(pos);
+    float nh, nl, nv, vh, lightDist;
+    calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
 
     vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
     vec4 spec    = texture2DRect(specularRect, tc);
@@ -210,9 +216,9 @@ void main()
             float amb_da = proj_ambiance;
             float lit = 0.0;
 
-            if (da > 0.0)
+            if (nl > 0.0)
             {
-                lit = da * dist_atten * noise;
+                lit = nl * dist_atten * noise;
 
                 float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
                 float lod = diff * proj_lod;
@@ -224,14 +230,14 @@ void main()
                 final_color = dlit*lit*diffuse*shadow;
 
                 // unshadowed for consistency between forward and deferred?
-                amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+                amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
             }
         
             //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
             vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
 
             // use unshadowed for consistency between forward and deferred?
-            amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+            amb_da += (nl*nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
             amb_da *= dist_atten * noise;
             amb_da = min(amb_da, 1.0-lit);
 
@@ -241,22 +247,16 @@ void main()
 
         if (spec.a > 0.0)
         {
-            vec3 v = -normalize(pos);
-            dlit *= min(da*6.0, 1.0) * dist_atten;
+            dlit *= min(nl*6.0, 1.0) * dist_atten;
 
-            //vec3 ref = dot(pos+lv, n);
-            vec3 h = normalize(lv + v);
-            float nh, nv, vh;
-            calcHalfVectors(h, n, v, nh, nv, vh);
-            float sa = nh;
-            float fres = pow(1 - dot(h, v), 5)*0.4+0.5;
+            float fres = pow(1 - vh, 5)*0.4+0.5;
 
             float gtdenom = 2 * nh;
-            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+            float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
                                 
             if (nh > 0.0)
             {
-                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
                 vec3 speccol = dlit*scol*spec.rgb*shadow;
                 speccol = clamp(speccol, vec3(0), vec3(1));
                 final_color += speccol;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
index 46de34e49a3..ddfbafd7393 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -59,7 +59,8 @@ uniform vec4 viewport;
 
 vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
 vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
-void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh);
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance);
 vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
 vec4 getPosition(vec2 pos_screen);
 vec2 getScreenXY(vec4 clip);
@@ -72,35 +73,18 @@ void main()
     vec2 tc          = getScreenXY(vary_fragcoord);
     vec3 pos         = getPosition(tc).xyz;
 
-    vec3 lv = trans_center.xyz-pos;
-    float dist = length(lv);
-    if (dist >= size)
-    {
-        discard;
-    }
-    dist /= size;
-
     float envIntensity;
     vec3 n;
     vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
 
-    float da = dot(n, lv);
-    if (da < 0.0)
-    {
-        discard;
-    }
-
-    lv = normalize(lv);
-    da = dot(n, lv); // alias for: nl
-
     vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
     vec4 spec    = texture2DRect(specularRect, tc);
 
     // Common half vectors calcs
-    vec3  v = -normalize(pos);
-    vec3  h = normalize(lv + v);
-    float nh, nv, vh;
-    calcHalfVectors(h, n, v, nh, nv, vh);
+    vec3  lv = trans_center.xyz-pos;
+    vec3  h, l, v = -normalize(pos);
+    float nh, nl, nv, vh, lightDist;
+    calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
 
     if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
     {
@@ -113,9 +97,6 @@ void main()
         float alphaRough, specWeight;
         initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
 
-        vec3  l    = lv; // already normalized
-        float nl   = clamp(dot(n, l), 0.0, 1.0);
-
         if (nl > 0.0 || nv > 0.0)
         {
             vec3 intensity = size * color;
@@ -127,28 +108,40 @@ void main()
     }
     else
     {
+        float dist = lightDist;
+        if (dist >= size)
+        {
+            discard;
+        }
+        dist /= size;
+
+        if (nl < 0.0)
+        {
+            discard;
+        }
+
         float fa = falloff+1.0;
         float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
         dist_atten *= dist_atten;
         dist_atten *= 2.0;
 
         float noise = texture2D(noiseMap, tc/128.0).b;
-        float lit = da * dist_atten * noise;
+        float lit = nl * dist_atten * noise;
 
         final_color = color.rgb*lit*diffuse;
 
         if (spec.a > 0.0)
         {
-            lit = min(da*6.0, 1.0) * dist_atten;
+            lit = min(nl*6.0, 1.0) * dist_atten;
 
             float sa = nh;
-            float fres = pow(1 - dot(h, v), 5) * 0.4+0.5;
+            float fres = pow(1 - vh, 5) * 0.4+0.5;
             float gtdenom = 2 * nh;
-            float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
+            float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh)));
 
             if (nh > 0.0)
             {
-                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
                 final_color += lit*scol*color.rgb*spec.rgb;
             }
         }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
index e70a545a7b3..680fcbfab3f 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -72,9 +72,13 @@ uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
 
-void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh);
-vec2 getScreenXY(vec4 clip_point);
+vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
+vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
 vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec2 getScreenXY(vec4 clip_point);
+void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
 vec3 srgb_to_linear(vec3 c);
 
 vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
@@ -144,7 +148,7 @@ void main()
         vec4 shd = texture2DRect(lightMap, tc);
         shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
         shadow += shadow_fade;
-        shadow = clamp(shadow, 0.0, 1.0);        
+        shadow = clamp(shadow, 0.0, 1.0);
     }
 
     float envIntensity;
@@ -172,8 +176,9 @@ void main()
     }
 
     lv = proj_origin-pos.xyz;
-    lv = normalize(lv);
-    float da = dot(n, lv);
+    vec3  h, l, v = -normalize(pos);
+    float nh, nl, nv, vh, lightDist;
+    calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
 
     vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
     vec4 spec    = texture2DRect(specularRect, tc);
@@ -200,9 +205,9 @@ void main()
             float amb_da = proj_ambiance;
             float lit = 0.0;
 
-            if (da > 0.0)
+            if (nl > 0.0)
             {
-                lit = da * dist_atten * noise;
+                lit = nl * dist_atten * noise;
 
                 float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
                 float lod = diff * proj_lod;
@@ -213,13 +218,13 @@ void main()
 
                 final_color = dlit*lit*diffuse*shadow;
 
-                amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+                amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
             }
 
             //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
             vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
 
-            amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+            amb_da += (nl*nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
             amb_da *= dist_atten * noise;
             amb_da = min(amb_da, 1.0-lit);
 
@@ -228,22 +233,15 @@ void main()
 
         if (spec.a > 0.0)
         {
-            dlit *= min(da*6.0, 1.0) * dist_atten;
-            vec3 v = -normalize(pos);
-
-            //vec3 ref = dot(pos+lv, n);
-            vec3 h = normalize(lv + v);
-            float nh, nv, vh;
-            calcHalfVectors(h, n, v, nh, nv, vh);
-            float sa = nh;
+            dlit *= min(nl*6.0, 1.0) * dist_atten;
             float fres = pow(1 - dot(h, v), 5)*0.4+0.5;
 
             float gtdenom = 2 * nh;
-            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+            float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
 
             if (nh > 0.0)
             {
-                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
                 vec3 speccol = dlit*scol*spec.rgb*shadow;
                 speccol = clamp(speccol, vec3(0), vec3(1));
                 final_color += speccol;
-- 
GitLab