From fb29b66fcf029342959d9403964f5e3b3be89a23 Mon Sep 17 00:00:00 2001
From: Ptolemy <ptolemy@lindenlab.com>
Date: Thu, 21 Jul 2022 19:55:11 -0700
Subject: [PATCH] SL-17762: PBR: Cleanup code, add clipProjectedLightVars()

---
 .../shaders/class1/deferred/deferredUtil.glsl | 34 +++++++++++++++++++
 .../class3/deferred/multiSpotLightF.glsl      | 20 +++--------
 .../shaders/class3/deferred/spotLightF.glsl   | 19 +++--------
 3 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 4df74b762a8..721bd933cca 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -26,6 +26,13 @@
 uniform sampler2DRect   normalMap;
 uniform sampler2DRect   depthMap;
 
+// projected lighted params
+uniform mat4 proj_mat; //screen space to light space projector
+uniform vec3 proj_n; // projector normal
+
+// light params
+uniform float size; // light_size
+
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
 
@@ -52,6 +59,33 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v,
     lightDist = length(lv);
 }
 
+// In:
+//   light_center
+//   pos
+// Out:
+//   dist
+//   l_dist
+//   lv
+//   proj_tc  Projector Textue Coordinates
+bool clipProjectedLightVars(vec3 light_center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc )
+{
+    lv = light_center - pos.xyz;
+    dist = length(lv);
+    bool clipped = (dist >= size);
+    if ( !clipped )
+    {
+        dist /= size;
+
+        l_dist = -dot(lv, proj_n);
+        vec4 projected_point = (proj_mat * vec4(pos.xyz, 1.0));
+        clipped = (projected_point.z < 0.0);
+        projected_point.xyz /= projected_point.w;
+        proj_tc = projected_point;
+    }
+
+    return clipped;
+}
+
 vec2 getScreenCoordinate(vec2 screenpos)
 {
     vec2 sc = screenpos.xy * 2.0;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
index 332cf28fb8e..31544cf212b 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -78,6 +78,7 @@ uniform mat4 inv_proj;
 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);
+bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
 vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
 vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
 vec2 getScreenXY(vec4 clip);
@@ -146,14 +147,13 @@ void main()
     vec2 tc          = getScreenXY(vary_fragcoord);
     vec3 pos         = getPosition(tc).xyz;
 
-    vec3 lv = center.xyz-pos.xyz;
-    float dist = length(lv);
-
-    if (dist >= size)
+    vec3 lv;
+    vec4 proj_tc;
+    float dist, l_dist;
+    if (clipProjectedLightVars(center, pos, dist, l_dist, lv, proj_tc))
     {
         discard;
     }
-    dist /= size;
 
     float shadow = 1.0;
     
@@ -169,16 +169,6 @@ void main()
     vec3 n;
     vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity);
 
-    float l_dist = -dot(lv, proj_n);
-
-    vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
-    if (proj_tc.z < 0.0)
-    {
-        discard;
-    }
-
-    proj_tc.xyz /= proj_tc.w;
-
     float fa = falloff+1.0;
     float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
     dist_atten *= dist_atten;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
index b94db1b4cbb..7a2cb84f6ee 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -77,6 +77,7 @@ uniform mat4 inv_proj;
 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);
+bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
 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);
@@ -135,13 +136,13 @@ void main()
     vec2 tc          = getScreenXY(vary_fragcoord);
     vec3 pos         = getPosition(tc).xyz;
 
-    vec3 lv = trans_center.xyz-pos.xyz;
-    float dist = length(lv);
-    if (dist >= size)
+    vec3 lv;
+    vec4 proj_tc;
+    float dist, l_dist;
+    if (clipProjectedLightVars(trans_center, pos, dist, l_dist, lv, proj_tc))
     {
         discard;
     }
-    dist /= size;
 
     float shadow = 1.0;
 
@@ -157,16 +158,6 @@ void main()
     vec3 n;
     vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
 
-    float l_dist = -dot(lv, proj_n);
-
-    vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
-    if (proj_tc.z < 0.0)
-    {
-        discard;
-    }
-
-    proj_tc.xyz /= proj_tc.w;
-
     float fa = falloff+1.0;
     float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
     dist_atten *= dist_atten;
-- 
GitLab