From 86de20e711dd077e18f5776de1bc4b26ebd62c3d Mon Sep 17 00:00:00 2001
From: Ptolemy <ptolemy@lindenlab.com>
Date: Tue, 26 Jul 2022 10:26:25 -0700
Subject: [PATCH] SL-17762L PBR: Move  texture2DLodDiffuse() to defferredUtil

---
 .../shaders/class1/deferred/deferredUtil.glsl | 82 +++++++++++++++++++
 .../class3/deferred/multiSpotLightF.glsl      | 31 ++-----
 .../shaders/class3/deferred/spotLightF.glsl   | 23 +-----
 3 files changed, 90 insertions(+), 46 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 721bd933cca..70a7f678642 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -25,12 +25,18 @@
 
 uniform sampler2DRect   normalMap;
 uniform sampler2DRect   depthMap;
+uniform sampler2D projectionMap; // rgba
 
 // projected lighted params
 uniform mat4 proj_mat; //screen space to light space projector
 uniform vec3 proj_n; // projector normal
+uniform vec3 proj_p; //plane projection is emitting from (in screen space)
+uniform float proj_focus; // distance from plane to begin blurring
+uniform float proj_lod  ; // (number of mips in proj map)
+uniform float proj_range; // range between near clip and far clip plane of projection
 
 // light params
+uniform vec3 color; // light_color
 uniform float size; // light_size
 
 uniform mat4 inv_proj;
@@ -38,6 +44,8 @@ uniform vec2 screen_res;
 
 const float M_PI = 3.14159265;
 
+vec3 srgb_to_linear(vec3 cs);
+
 // In:
 //   lv  unnormalized surface to light vector
 //   n   normal of the surface
@@ -138,6 +146,80 @@ float getDepth(vec2 pos_screen)
     return depth;
 }
 
+vec4 getTexture2DLodDiffuse(vec2 tc, float lod)
+{
+    vec4 ret = texture2DLod(projectionMap, tc, lod);
+    ret.rgb = srgb_to_linear(ret.rgb);
+
+    vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+    float det = min(lod/(proj_lod*0.5), 1.0);
+    float d = min(dist.x, dist.y);
+    float edge = 0.25*det;
+    ret *= clamp(d/edge, 0.0, 1.0);
+
+    return ret;
+}
+
+// Returns projected light in Linear
+// Uses:
+//  color
+// NOTE: projected.a will be pre-multiplied with projected.rgb
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv)
+{
+    float diff = clamp((light_distance - proj_focus)/proj_range, 0.0, 1.0);
+    float lod = diff * proj_lod;
+    vec4 plcol = getTexture2DLodDiffuse(projected_uv.xy, lod);
+
+    return color.rgb * plcol.rgb * plcol.a;
+}
+
+vec4 texture2DLodSpecular(vec2 tc, float lod)
+{
+    vec4 ret = texture2DLod(projectionMap, tc, lod);
+    ret.rgb = srgb_to_linear(ret.rgb);
+
+    vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+    float det = min(lod/(proj_lod*0.5), 1.0);
+    float d = min(dist.x, dist.y);
+    d *= min(1, d * (proj_lod - lod)); // BUG? extra factor compared to diffuse causes N repeats
+    float edge = 0.25*det;
+    ret *= clamp(d/edge, 0.0, 1.0);
+
+    return ret;
+}
+
+// See: clipProjectedLightVars()
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n )
+{
+    vec3 slit = vec3(0);
+    vec3 ref = reflect(normalize(pos), n);
+
+    //project from point pos in direction ref to plane proj_p, proj_n
+    vec3 pdelta = proj_p-pos;
+    float l_dist = length(pdelta);
+    float ds = dot(ref, proj_n);
+    if (ds < 0.0)
+    {
+        vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+        vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+        if (stc.z > 0.0)
+        {
+            stc /= stc.w;
+            slit = getProjectedLightDiffuseColor( l_dist, stc.xy ); // NOTE: Using diffuse due to texture2DLodSpecular() has extra: d *= min(1, d * (proj_lod - lod));
+        }
+    }
+    return slit; // specular light
+}
+
+vec3 getProjectedLightSpecularColor(float light_distance, vec2 projected_uv)
+{
+    float diff = clamp((light_distance - proj_focus)/proj_range, 0.0, 1.0);
+    float lod = diff * proj_lod;
+    vec4 plcol = getTexture2DLodDiffuse(projected_uv.xy, lod); // NOTE: Using diffuse due to texture2DLodSpecular() has extra: d *= min(1, d * (proj_lod - lod));
+
+    return color.rgb * plcol.rgb * plcol.a;
+}
+
 vec4 getPosition(vec2 pos_screen)
 {
     float depth = getDepth(pos_screen);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
index a6b09ad3ad0..90445cb0ef6 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -81,6 +81,8 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float
 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);
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
 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);
@@ -104,24 +106,6 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
     return ret;
 }
 
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
-    vec4 ret = texture2DLod(projectionMap, tc, lod);
-    ret.rgb = srgb_to_linear(ret.rgb);
-
-    vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
-    float det = min(lod/(proj_lod*0.5), 1.0);
-
-    float d = min(dist.x, dist.y);
-
-    float edge = 0.25*det;
-
-    ret *= clamp(d/edge, 0.0, 1.0);
-
-    return ret;
-}
-
 vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
 {
     vec4 ret = texture2DLod(projectionMap, tc, lod);
@@ -186,6 +170,7 @@ void main()
     vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
     vec4 spec    = texture2DRect(specularRect, tc);
     vec3 dlit    = vec3(0, 0, 0);
+    vec3 slit    = vec3(0, 0, 0);
 
     if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
     {
@@ -216,13 +201,8 @@ void main()
             {
                 lit = nl * dist_atten * noise;
 
-                float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
-                float lod = diff * proj_lod;
-            
-                vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-        
-                dlit = color.rgb * plcol.rgb * plcol.a;
-            
+                dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
+
                 final_color = dlit*lit*diffuse*shadow;
 
                 // unshadowed for consistency between forward and deferred?
@@ -240,7 +220,6 @@ void main()
             final_color += amb_da*color.rgb*diffuse.rgb*amb_plcol.rgb*amb_plcol.a;
         }
     
-
         if (spec.a > 0.0)
         {
             dlit *= min(nl*6.0, 1.0) * 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 e4996389912..c9e635ab3f9 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -80,6 +80,8 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float
 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);
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
 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);
@@ -99,20 +101,6 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
     return ret;
 }
 
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
-    vec4 ret = texture2DLod(projectionMap, tc, lod);
-    ret.rgb = srgb_to_linear(ret.rgb);
-
-    vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-    float det = min(lod/(proj_lod*0.5), 1.0);
-    float d = min(dist.x, dist.y);
-    float edge = 0.25*det;
-    ret *= clamp(d/edge, 0.0, 1.0);
-
-    return ret;
-}
-
 vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
 {
     vec4 ret = texture2DLod(projectionMap, tc, lod);
@@ -206,12 +194,7 @@ void main()
             {
                 lit = nl * dist_atten * noise;
 
-                float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
-                float lod = diff * proj_lod;
-
-                vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
-                dlit = color.rgb * plcol.rgb * plcol.a;
+                dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
 
                 final_color = dlit*lit*diffuse*shadow;
 
-- 
GitLab