From 5dcb84d1b52f14c3e907c1a3642ab87cbae161e6 Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Fri, 22 Sep 2023 22:15:07 -0400
Subject: [PATCH] Multiscatter IBL

---
 .../shaders/class1/deferred/deferredUtil.glsl | 24 +++++++++++++------
 .../shaders/class1/deferred/genbrdflutF.glsl  |  2 +-
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index c8eaba64182..46ce7d66526 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -375,6 +375,12 @@ vec2 BRDF(float NoV, float roughness)
     return texture(brdfLut, vec2(NoV, roughness)).rg;
 }
 
+// Lagarde and de Rousiers 2014, "Moving Frostbite to PBR"
+float computeSpecularAO(float NoV, float ao, float roughness) 
+{
+    return clamp(pow(NoV + ao, exp2(-16.0 * roughness - 1.0)) - 1.0 + ao, 0.0, 1.0);
+}
+
 // set colorDiffuse and colorSpec to the results of GLTF PBR style IBL
 vec3 pbrIbl(vec3 diffuseColor,
             vec3 specularColor,
@@ -386,16 +392,20 @@ vec3 pbrIbl(vec3 diffuseColor,
             out vec3 specContrib)
 {
     // retrieve a scale and bias to F0. See [1], Figure 3
-	vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
-	vec3 diffuseLight = irradiance;
-	vec3 specularLight = radiance;
+    vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
+    vec3 diffuseLight = irradiance;
+    vec3 specularLight = radiance;
     
-	vec3 diffuse = diffuseLight * diffuseColor;
-	vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
+    vec3 energy = mix(brdf.xxx, brdf.yyy, specularColor);
+
+    vec3 diffuse = diffuseLight * diffuseColor * (1.0 - energy);
+    vec3 specular = specularLight * energy;
+
+    specular *= computeSpecularAO(nv, ao, perceptualRough * perceptualRough) * (1.0 + specularColor * (1.0 / brdf.y - 1.0));
 
-    specContrib = specular * ao;
+    specContrib = specular;
 
-	return (diffuse + specular) * ao;
+    return (diffuse * ao) + specular;
 }
 
 vec3 pbrIbl(vec3 diffuseColor,
diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
index e40d070268e..df0d21b4323 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
@@ -129,7 +129,7 @@ vec2 BRDF(float NoV, float roughness)
 			float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
 			float G_Vis = (G * dotVH) / (dotNH * dotNV);
 			float Fc = pow(1.0 - dotVH, 5.0);
-			LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis);
+			LUT += vec2(Fc * G_Vis, G_Vis);
 		}
 	}
 	return LUT / float(NUM_SAMPLES);
-- 
GitLab