From 6540b4c480d1d4b4c8342a0d093d09f525485659 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 22 Jun 2022 19:56:26 -0500
Subject: SL-17600 Cubemap filter tuning.

---
 .../shaders/class1/interface/irradianceGenF.glsl   |  9 ++--
 .../shaders/class1/interface/radianceGenF.glsl     |  6 ++-
 indra/newview/llreflectionmapmanager.cpp           | 54 ++++++++++++----------
 3 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
index 2028509775..4d91395a1b 100644
--- a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
@@ -70,11 +70,12 @@ SOFTWARE.
 
 #define PI 3.1415926535897932384626433832795
 
-float deltaPhi = PI/16.0;
-float deltaTheta = deltaPhi*0.25;
-
 void main()
 {
+    float deltaPhi = (2.0 * PI) / 11.25;
+	float deltaTheta = (0.5 * PI) / 4.0;
+    float mipLevel = 2;
+
 	vec3 N = normalize(vary_dir);
 	vec3 up = vec3(0.0, 1.0, 0.0);
 	vec3 right = normalize(cross(up, N));
@@ -89,7 +90,7 @@ void main()
 		for (float theta = 0.0; theta < HALF_PI; theta += deltaTheta) {
 			vec3 tempVec = cos(phi) * right + sin(phi) * up;
 			vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec;
-			color += textureLod(reflectionProbes, vec4(sampleVector, sourceIdx), 3).rgb * cos(theta) * sin(theta);
+			color += textureLod(reflectionProbes, vec4(sampleVector, sourceIdx), mipLevel).rgb * cos(theta) * sin(theta);
 			sampleCount++;
 		}
 	}
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
index 3fc227eae7..94fedce243 100644
--- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -68,7 +68,7 @@ SOFTWARE.
 
 uniform float roughness;
 
-uniform int numSamples;
+uniform float mipLevel;
 
 const float PI = 3.1415926536;
 
@@ -130,6 +130,8 @@ vec3 prefilterEnvMap(vec3 R, float roughness)
 	vec3 color = vec3(0.0);
 	float totalWeight = 0.0;
 	float envMapDim = 256.0;
+    int numSamples = 32/max(int(mipLevel), 1);
+
 	for(uint i = 0u; i < numSamples; i++) {
 		vec2 Xi = hammersley2d(i, numSamples);
 		vec3 H = importanceSample_GGX(Xi, roughness, N);
@@ -148,7 +150,7 @@ vec3 prefilterEnvMap(vec3 R, float roughness)
 			// Solid angle of 1 pixel across all cube faces
 			float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
 			// Biased (+1.0) mip level for better result
-			float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
+			//float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
 			color += textureLod(reflectionProbes, vec4(L,sourceIdx), mipLevel).rgb * dotNL;
 			totalWeight += dotNL;
 
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index dfd0d1b9a9..bde8c0c51c 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -425,7 +425,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
 
         S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f;
 
-        for (int i = 0; i < mMipChain.size(); ++i)
+        //for (int i = 0; i < mMipChain.size(); ++i)
+        for (int i = 0; i < 1; ++i)
         {
             LL_PROFILE_GPU_ZONE("probe mip");
             mMipChain[i].bindTarget();
@@ -464,6 +465,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
                 mTexture->bind(0);
                 //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
                 glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res);
+                glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
                 mTexture->unbind();
             }
             mMipChain[i].flush();
@@ -485,24 +487,28 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
         static LLStaticHashedString sSourceIdx("sourceIdx");
         gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx);
 
-        for (int cf = 0; cf < 6; ++cf)
-        { // for each cube face
-            LLCoordFrame frame;
-            frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+        static LLStaticHashedString sMipLevel("mipLevel");
 
-            F32 mat[16];
-            frame.getOpenGLRotation(mat);
-            gGL.loadMatrix(mat);
+        for (int i = 1; i < mMipChain.size(); ++i)
+        {
+            for (int cf = 0; cf < 6; ++cf)
+            { // for each cube face
+                LLCoordFrame frame;
+                frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+                F32 mat[16];
+                frame.getOpenGLRotation(mat);
+                gGL.loadMatrix(mat);
 
-            for (int i = 0; i < mMipChain.size(); ++i)
-            {
                 mMipChain[i].bindTarget();
                 static LLStaticHashedString sRoughness("roughness");
-                static LLStaticHashedString sNumSamples("numSamples");
 
-                gRadianceGenProgram.uniform1i(sNumSamples, 32);
                 gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));
-
+                gRadianceGenProgram.uniform1f(sMipLevel, llmax((F32)(i - 1), 0.f));
+                if (i > 0)
+                {
+                    gRadianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex);
+                }
                 gGL.begin(gGL.QUADS);
                 gGL.vertex3f(-1, -1, -1);
                 gGL.vertex3f(1, -1, -1);
@@ -523,7 +529,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
         channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
         mTexture->bind(channel);
 
-        gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx);
+        gIrradianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex);
 
         int start_mip = 0;
         // find the mip target to start with based on irradiance map resolution
@@ -535,17 +541,17 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
             }
         }
 
-        for (int cf = 0; cf < 6; ++cf)
-        { // for each cube face
-            LLCoordFrame frame;
-            frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+        for (int i = start_mip; i < mMipChain.size(); ++i)
+        {
+            for (int cf = 0; cf < 6; ++cf)
+            { // for each cube face
+                LLCoordFrame frame;
+                frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
 
-            F32 mat[16];
-            frame.getOpenGLRotation(mat);
-            gGL.loadMatrix(mat);
+                F32 mat[16];
+                frame.getOpenGLRotation(mat);
+                gGL.loadMatrix(mat);
 
-            for (int i = start_mip; i < mMipChain.size(); ++i)
-            {
                 mMipChain[i].bindTarget();
 
                 gGL.begin(gGL.QUADS);
@@ -558,7 +564,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
 
                 S32 res = mMipChain[i].getWidth();
                 mIrradianceMaps->bind(channel);
-                glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i-start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+                glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
                 mTexture->bind(channel);
                 mMipChain[i].flush();
             }
-- 
cgit v1.2.3