summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2023-02-21 15:40:20 -0600
committerDave Parks <davep@lindenlab.com>2023-02-21 15:40:20 -0600
commit131d116ffd21ef1e726e21c8fe2e6b7068c6c3d9 (patch)
tree48f32f650c520e9322ecb70cd414ced5d5bd2f3e
parentcd0944caa692e6440f85d21fa706636fc5e46e27 (diff)
SL-19239 Day after three day quality pass - add ACES tone mapping to address "haziness" (and also fix banding in emissive materials)
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl118
-rw-r--r--indra/newview/pipeline.cpp2
2 files changed, 118 insertions, 2 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index 987b2d1fe8..e0e975faf0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -41,6 +41,122 @@ uniform float display_gamma;
vec3 linear_to_srgb(vec3 cl);
+//===============================================================
+// tone mapping taken from Khronos sample implementation
+//===============================================================
+const float GAMMA = 2.2;
+const float INV_GAMMA = 1.0 / GAMMA;
+
+
+// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
+const mat3 ACESInputMat = mat3
+(
+ 0.59719, 0.07600, 0.02840,
+ 0.35458, 0.90834, 0.13383,
+ 0.04823, 0.01566, 0.83777
+);
+
+
+// ODT_SAT => XYZ => D60_2_D65 => sRGB
+const mat3 ACESOutputMat = mat3
+(
+ 1.60475, -0.10208, -0.00327,
+ -0.53108, 1.10813, -0.07276,
+ -0.07367, -0.00605, 1.07602
+);
+
+
+// linear to sRGB approximation
+// see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html
+vec3 linearTosRGB(vec3 color)
+{
+ return pow(color, vec3(INV_GAMMA));
+}
+
+
+// sRGB to linear approximation
+// see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html
+vec3 sRGBToLinear(vec3 srgbIn)
+{
+ return vec3(pow(srgbIn.xyz, vec3(GAMMA)));
+}
+
+
+vec4 sRGBToLinear(vec4 srgbIn)
+{
+ return vec4(sRGBToLinear(srgbIn.xyz), srgbIn.w);
+}
+
+
+// ACES tone map (faster approximation)
+// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
+vec3 toneMapACES_Narkowicz(vec3 color)
+{
+ const float A = 2.51;
+ const float B = 0.03;
+ const float C = 2.43;
+ const float D = 0.59;
+ const float E = 0.14;
+ return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0);
+}
+
+
+// ACES filmic tone map approximation
+// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
+vec3 RRTAndODTFit(vec3 color)
+{
+ vec3 a = color * (color + 0.0245786) - 0.000090537;
+ vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081;
+ return a / b;
+}
+
+
+// tone mapping
+vec3 toneMapACES_Hill(vec3 color)
+{
+ color = ACESInputMat * color;
+
+ // Apply RRT and ODT
+ color = RRTAndODTFit(color);
+
+ color = ACESOutputMat * color;
+
+ // Clamp to [0, 1]
+ color = clamp(color, 0.0, 1.0);
+
+ return color;
+}
+
+
+#define TONEMAP_ACES_NARKOWICZ
+//#define TONEMAP_ACES_HILL_EXPOSURE_BOOST
+float u_Exposure = 1;
+
+vec3 toneMap(vec3 color)
+{
+ color *= u_Exposure;
+
+#ifdef TONEMAP_ACES_NARKOWICZ
+ color = toneMapACES_Narkowicz(color);
+#endif
+
+#ifdef TONEMAP_ACES_HILL
+ color = toneMapACES_Hill(color);
+#endif
+
+#ifdef TONEMAP_ACES_HILL_EXPOSURE_BOOST
+ // boost exposure as discussed in https://github.com/mrdoob/three.js/pull/19621
+ // this factor is based on the exposure correction of Krzysztof Narkowicz in his
+ // implemetation of ACES tone mapping
+ color /= 0.6;
+ color = toneMapACES_Hill(color);
+#endif
+
+ return linearTosRGB(color);
+}
+
+//===============================================================
+
//=================================
// borrowed noise from:
// <https://www.shadertoy.com/view/4dS3Wd>
@@ -83,7 +199,7 @@ void main()
{
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
vec4 diff = texture2D(diffuseRect, vary_fragcoord);
- diff.rgb = linear_to_srgb(diff.rgb);
+ diff.rgb = toneMap(diff.rgb);
vec2 tc = vary_fragcoord.xy*screen_res;
vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e814b77725..69b149f82d 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -354,7 +354,7 @@ bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
bool valid = true
&& target.addColorAttachment(GL_RGBA) // frag-data[1] specular OR PBR ORM
&& target.addColorAttachment(GL_RGBA16F) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight
- && target.addColorAttachment(GL_RGBA); // frag_data[3] PBR emissive
+ && target.addColorAttachment(GL_RGB16); // frag_data[3] PBR emissive
return valid;
}