summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
diff options
context:
space:
mode:
authorRye Mutt <rye@alchemyviewer.org>2024-08-27 22:47:32 -0400
committerRye Mutt <rye@alchemyviewer.org>2024-08-29 17:24:50 -0400
commit958afaa7a7bfb1217bbffee3fe562f21901277ac (patch)
tree64a878d5c747ce9d848ad3b993b0eb24298ef65c /indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
parent3a7374892945a233a9eaa3a88c94a984873373d3 (diff)
Integrate SMAA and rework post process chain for better visual quality
Add SMAA buffer generation passes Add quality levels for both FXAA and SMAA Separate gamma correction and tonemapping for effects that require linear-but-tonemapped inputs Move application of noise to final render pass to screen to avoid damaging other post process effects
Diffstat (limited to 'indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl150
1 files changed, 150 insertions, 0 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
new file mode 100644
index 0000000000..c16ab2f9c4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
@@ -0,0 +1,150 @@
+/**
+ * @file postDeferredTonemap.glsl
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+uniform sampler2D diffuseRect;
+uniform sampler2D exposureMap;
+
+uniform vec2 screen_res;
+in vec2 vary_fragcoord;
+
+vec3 linear_to_srgb(vec3 cl);
+
+//===============================================================
+// tone mapping taken from Khronos sample implementation
+//===============================================================
+
+// 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
+);
+
+// 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;
+}
+
+uniform float exposure;
+uniform float gamma;
+uniform float aces_mix;
+
+vec3 toneMap(vec3 color)
+{
+#ifndef NO_POST
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+
+ color *= exposure * exp_scale;
+
+ // mix ACES and Linear here as a compromise to avoid over-darkening legacy content
+ color = mix(toneMapACES_Hill(color), color, aces_mix);
+#endif
+
+ return color;
+}
+
+//===============================================================
+
+void debugExposure(inout vec3 color)
+{
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+ exp_scale *= 0.5;
+ if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1)
+ {
+ color = vec3(1,0,0);
+ }
+}
+
+vec3 legacyGamma(vec3 color)
+{
+ vec3 c = 1. - clamp(color, vec3(0.), vec3(1.));
+ c = 1. - pow(c, vec3(gamma)); // s/b inverted already CPU-side
+
+ return c;
+}
+
+void main()
+{
+ //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
+ vec4 diff = texture(diffuseRect, vary_fragcoord);
+
+#ifndef NO_POST
+ diff.rgb = toneMap(diff.rgb);
+#else
+ diff.rgb = clamp(diff.rgb, vec3(0.0), vec3(1.0));
+#endif
+
+ //debugExposure(diff.rgb);
+ frag_color = max(diff, vec4(0));
+}
+