From 07ada65df1c72adff6e356011840ca262beb4be0 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@lindenlab.com>
Date: Wed, 16 Nov 2022 07:11:13 -0800
Subject: [PATCH] A few tweaks to SSR while I'm in the neighborhood.

Mostly just making it actually kind of work.  Still needs a lot more tweaking - but can revisit later.
SL-18332
---
 .../class3/deferred/screenSpaceReflPostF.glsl | 58 +++++++++++++------
 .../class3/deferred/screenSpaceReflUtil.glsl  | 28 ++++-----
 indra/newview/pipeline.cpp                    |  5 +-
 3 files changed, 56 insertions(+), 35 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
index 9172789b38d..d48aeb98b6b 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
@@ -44,8 +44,10 @@ VARYING vec3 camera_ray;
 
 uniform sampler2D depthMap;
 uniform sampler2D normalMap;
+uniform sampler2D specularRect;
 uniform sampler2D sceneMap;
 uniform sampler2D diffuseRect;
+uniform sampler2D diffuseMap;
 
 vec3 getNorm(vec2 screenpos);
 float getDepth(vec2 pos_screen);
@@ -54,45 +56,63 @@ float linearDepth01(float d, float znear, float zfar);
 
 vec4 getPositionWithDepth(vec2 pos_screen, float depth);
 vec4 getPosition(vec2 pos_screen);
-
-bool traceScreenRay(vec3 position, vec3 reflection, out vec3 hitColor, out float hitDepth, float depth, sampler2D textureFrame);
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float hitDepth, float depth, sampler2D textureFrame);
 float random (vec2 uv);
 void main() {
     vec2  tc = vary_fragcoord.xy;
     float depth = linearDepth01(getDepth(tc), zNear, zFar);
+    vec3 n = vec3(0, 0, 1);
+    float envIntensity;
+    vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
     vec3 pos = getPositionWithDepth(tc, getDepth(tc)).xyz;
+    vec4 spec    = texture2D(specularRect, tc);
     vec3 viewPos = camera_ray * depth;
-    vec3 rayDirection = normalize(reflect(normalize(viewPos), getNorm(tc))) * -viewPos.z;
+    vec3 rayDirection = normalize(reflect(normalize(viewPos), n)) * -viewPos.z;
     vec2 hitpixel;
-    vec3 hitpoint;
+    vec4 hitpoint;
+    vec4 diffuse = texture2D(diffuseRect, tc);
+    vec3 specCol = spec.rgb;
+
+    if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) {
+        vec3 orm = specCol.rgb;
+        float perceptualRoughness = orm.g;
+        float metallic = orm.b;
+        vec3 f0 = vec3(0.04);
+        vec3 baseColor = diffuse.rgb;
+        
+        vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+
+        specCol = mix(f0, baseColor.rgb, metallic);
+    }
 
 	vec2 uv2 = tc * screen_res;
 	float c = (uv2.x + uv2.y) * 0.125;
 	float jitter = mod( c, 1.0);
 
-    vec3 firstBasis = normalize(cross(vec3(0.f, 0.f, 1.f), rayDirection));
+    vec3 firstBasis = normalize(cross(vec3(1.f, 1.f, 1.f), rayDirection));
 	vec3 secondBasis = normalize(cross(rayDirection, firstBasis));
     
-    frag_color.rgb = texture(diffuseRect, tc).rgb;
+    frag_color = texture(diffuseMap, tc);
     vec4 collectedColor;
-    for (int i = 0; i < 1; i++) {
-		vec2 coeffs = vec2(random(tc + vec2(0, i)) + random(tc + vec2(i, 0))) * 0.25;
+    
+    vec2 screenpos = 1 - abs(tc * 2 - 1);
+    float vignette = clamp((screenpos.x * screenpos.y) * 16,0, 1);
+    vignette *= clamp((dot(normalize(viewPos), n) * 0.5 + 0.5 - 0.2) * 8, 0, 1);
+    vignette *= min(linearDepth(getDepth(tc), zNear, zFar) / zFar, 1);
+    int totalSamples = 4;
+    for (int i = 0; i < totalSamples; i++) {
+		vec2 coeffs = vec2(random(tc + vec2(0, i)) + random(tc + vec2(i, 0)));
 		vec3 reflectionDirectionRandomized = rayDirection + firstBasis * coeffs.x + secondBasis * coeffs.y;
 
-        bool hit = traceScreenRay(pos, reflectionDirectionRandomized, hitpoint, depth, depth, diffuseRect);
+        bool hit = traceScreenRay(pos, reflectionDirectionRandomized, hitpoint, depth, depth, diffuseMap);
         if (hit) {
-            vec2 screenpos = tc * 2 - 1;
-            float vignette = 1;// clamp((1 - dot(screenpos, screenpos)) * 4,0, 1);
-            vignette *= dot(normalize(viewPos), getNorm(tc)) * 0.5 + 0.5;
-            vignette *= min(linearDepth(getDepth(tc), zNear, zFar) / (zFar * 0.0125), 1);
-            collectedColor.rgb = hitpoint * vignette * 0.25;
-            frag_color.rgb = hitpoint;
+            collectedColor += hitpoint;
+            collectedColor.rgb *= specCol.rgb;
         }
 	}
 
-    //frag_color.rgb = collectedColor.rgb;
-
-
+    collectedColor *= vignette;
 
-    frag_color.a = 1.0;
+    frag_color += collectedColor;
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl
index 5eefd99d001..f8c6e5701af 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl
@@ -52,28 +52,28 @@ vec2 generateProjectedPosition(vec3 pos){
 
 bool isBinarySearchEnabled = true;
 bool isAdaptiveStepEnabled = true;
-bool isExponentialStepEnabled = false;
+bool isExponentialStepEnabled = true;
 bool debugDraw = false;
-int iterationCount = 100;
-float rayStep = 0.2;
-float distanceBias = 0.05;
+int iterationCount = 40;
+float rayStep = 0.1;
+float distanceBias = 0.02;
 float depthRejectBias = 0.001;
 float epsilon = 0.1;
 
-bool traceScreenRay(vec3 position, vec3 reflection, out vec3 hitColor, out float hitDepth, float depth, sampler2D textureFrame) {
+bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float hitDepth, float depth, sampler2D textureFrame) {
 	vec3 step = rayStep * reflection;
 	vec3 marchingPosition = position + step;
 	float delta;
 	float depthFromScreen;
 	vec2 screenPosition;
     bool hit = false;
-    hitColor = vec3(0);
+    hitColor = vec4(0);
 	
 	int i = 0;
 	if (depth > depthRejectBias) {
 		for (; i < iterationCount && !hit; i++) {
 			screenPosition = generateProjectedPosition(marchingPosition);
-			depthFromScreen = abs(getPositionWithDepth(screenPosition, linearDepth(getDepth(screenPosition), zNear, zFar)).z);
+				depthFromScreen = linearDepth(getDepth(screenPosition), zNear, zFar);
 			delta = abs(marchingPosition.z) - depthFromScreen;
 			
 			if (depth < depthFromScreen + epsilon && depth > depthFromScreen - epsilon) {
@@ -81,10 +81,10 @@ bool traceScreenRay(vec3 position, vec3 reflection, out vec3 hitColor, out float
 			}
 
 			if (abs(delta) < distanceBias) {
-				vec3 color = vec3(1);
+				vec4 color = vec4(1);
 				if(debugDraw)
-					color = vec3( 0.5+ sign(delta)/2,0.3,0.5- sign(delta)/2);
-				hitColor = texture(textureFrame, screenPosition).xyz * color;
+					color = vec4( 0.5+ sign(delta)/2,0.3,0.5- sign(delta)/2, 0);
+				hitColor = texture(textureFrame, screenPosition) * color;
 				hitDepth = depthFromScreen;
 				hit = true;
 				break;
@@ -114,7 +114,7 @@ bool traceScreenRay(vec3 position, vec3 reflection, out vec3 hitColor, out float
 				marchingPosition = marchingPosition - step * sign(delta);
 				
 				screenPosition = generateProjectedPosition(marchingPosition);
-				depthFromScreen = abs(getPositionWithDepth(screenPosition, getDepth(screenPosition)).z);
+				depthFromScreen = linearDepth(getDepth(screenPosition), zNear, zFar);
 				delta = abs(marchingPosition.z) - depthFromScreen;
 
 				if (depth < depthFromScreen + epsilon && depth > depthFromScreen - epsilon) {
@@ -122,10 +122,10 @@ bool traceScreenRay(vec3 position, vec3 reflection, out vec3 hitColor, out float
 				}
 
 				if (abs(delta) < distanceBias && depthFromScreen != (depth - distanceBias)) {
-					vec3 color = vec3(1);
+					vec4 color = vec4(1);
 					if(debugDraw)
-						color = vec3( 0.5+ sign(delta)/2,0.3,0.5- sign(delta)/2);
-					hitColor = texture(textureFrame, screenPosition).xyz * color;
+						color = vec4( 0.5+ sign(delta)/2,0.3,0.5- sign(delta)/2, 0);
+					hitColor = texture(textureFrame, screenPosition) * color;
 					hitDepth = depthFromScreen;
 					hit = true;
 					break;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index dff84bda0e1..82194163b34 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7620,7 +7620,7 @@ void LLPipeline::renderFinalize()
             LLRenderTarget *screen_target = &mRT->screen;
 
             screen_target->bindTarget();
-            S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
+            S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screen_target->getUsage());
             if (channel > -1)
             {
                 screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
@@ -7628,8 +7628,9 @@ void LLPipeline::renderFinalize()
             }
 
             {
-                LLGLDisable   blend(GL_BLEND);
+                LLGLDisable blend(GL_BLEND);
                 LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+
                 stop_glerror();
                 mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
                 stop_glerror();
-- 
GitLab