summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class1/deferred
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/app_settings/shaders/class1/deferred')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/globalF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl130
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl180
10 files changed, 217 insertions, 157 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
index ce018623a8..1a065daf89 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
@@ -78,10 +78,10 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen)
{
float ret = 1.0;
vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture(noiseMap, pos_screen.xy * (screen_res / 128)).xy;
+ vec2 noise_reflect = texture(noiseMap, pos_screen.xy * (screen_res / 128.0)).xy;
float angle_hidden = 0.0;
- float points = 0;
+ float points = 0.0;
float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 94711be473..63ab0b9b38 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -80,6 +80,18 @@ vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
vec4 decodeNormal(vec4 norm);
+vec3 clampHDRRange(vec3 color)
+{
+ // Why do this?
+ // There are situations where the color range will go to something insane - potentially producing infs and NaNs even.
+ // This is a safety measure to prevent that.
+ // As to the specific number there - allegedly some HDR displays expect values to be in the 0-11.2 range. Citation needed.
+ // -Geenz 2025-03-05
+ color = mix(color, vec3(1), isinf(color));
+ color = mix(color, vec3(0.0), isnan(color));
+ return clamp(color, vec3(0.0), vec3(11.2));
+}
+
float calcLegacyDistanceAttenuation(float distance, float falloff)
{
float dist_atten = 1.0 - clamp((distance + falloff)/(1.0 + falloff), 0.0, 1.0);
@@ -253,7 +265,7 @@ vec4 texture2DLodSpecular(vec2 tc, float lod)
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
float d = min(dist.x, dist.y);
- d *= min(1, d * (proj_lod - lod)); // BUG? extra factor compared to diffuse causes N repeats
+ d *= min(1.0, d * (proj_lod - lod)); // BUG? extra factor compared to diffuse causes N repeats
float edge = 0.25*det;
ret *= clamp(d/edge, 0.0, 1.0);
@@ -371,7 +383,7 @@ void pbrIbl(vec3 diffuseColor,
out vec3 specularOut)
{
// retrieve a scale and bias to F0. See [1], Figure 3
- vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
+ vec2 brdf = BRDF(clamp(nv, 0.0, 1.0), 1.0-perceptualRough);
vec3 diffuseLight = irradiance;
vec3 specularLight = radiance;
@@ -426,9 +438,10 @@ float geometricOcclusion(PBRInfo pbrInputs)
float NdotL = pbrInputs.NdotL;
float NdotV = pbrInputs.NdotV;
float r = pbrInputs.alphaRoughness;
+ float r2 = r * r;
- float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
- float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
+ float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r2 + (1.0 - r2) * (NdotL * NdotL)));
+ float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r2 + (1.0 - r2) * (NdotV * NdotV)));
return attenuationL * attenuationV;
}
@@ -613,24 +626,11 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v,
uniform vec4 waterPlane;
uniform float waterSign;
-// discard if given position in eye space is on the wrong side of the waterPlane according to waterSign
void waterClip(vec3 pos)
{
- // TODO: make this less branchy
- if (waterSign > 0)
+ if (((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) * waterSign) < 0.0)
{
- if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < 0.0)
- {
- discard;
- }
+ discard;
}
- else
- {
- if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > 0.0)
- {
- discard;
- }
- }
-
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl
index 2ed4ba3163..9060d358cf 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl
@@ -34,7 +34,7 @@ uniform float clipSign;
void mirrorClip(vec3 pos)
{
- if (mirror_flag > 0)
+ if (mirror_flag > 0.0)
{
if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
index 4acab159cb..4331418b33 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
@@ -37,14 +37,10 @@ uniform sampler2D emissiveRect;
uniform sampler2D normalMap;
uniform float diffuse_luminance_scale;
-float lum(vec3 col)
-{
- vec3 l = vec3(0.2126, 0.7152, 0.0722);
- return dot(l, col);
-}
void main()
{
+ const vec3 l = vec3(0.2126, 0.7152, 0.0722);
vec2 tc = vary_fragcoord*0.6+0.2;
tc.y -= 0.1; // HACK - nudge exposure sample down a little bit to favor ground over sky
vec3 c = texture(diffuseRect, tc).rgb;
@@ -62,7 +58,7 @@ void main()
c += texture(emissiveRect, tc).rgb;
- float L = lum(c);
+ float L = dot(l, c);
frag_color = vec4(max(L, 0.0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
index dc43007dca..fb4b139662 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
@@ -297,7 +297,7 @@ vec3 _t_normal_post_1(vec3 vNt0, float sign_or_zero)
sign = (2.0*sign) + 1.0;
sign /= abs(sign);
// If the sign is negative, rotate normal by 180 degrees
- vNt1.xy = (min(0, sign) * vNt1.xy) + (min(0, -sign) * -vNt1.xy);
+ vNt1.xy = (min(0.0, sign) * vNt1.xy) + (min(0.0, -sign) * -vNt1.xy);
return vNt1;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
index 9797bcd2ce..4e737492a7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
@@ -69,6 +69,8 @@ void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc)
w += wg;
}
+vec3 clampHDRRange(vec3 color);
+
void main()
{
vec2 tc = vary_fragcoord.xy;
@@ -120,5 +122,6 @@ void main()
diff /= w;
}
+ diff.rgb = clampHDRRange(diff.rgb);
frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index befd2ae6da..4ccc6f54a8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -43,6 +43,8 @@ vec3 legacyGamma(vec3 color)
return c;
}
+vec3 clampHDRRange(vec3 color);
+
void main()
{
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
@@ -53,6 +55,7 @@ void main()
diff.rgb = legacyGamma(diff.rgb);
#endif
- frag_color = max(diff, vec4(0));
+ diff.rgb = clampHDRRange(diff.rgb);
+ frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
index 32b0a1ac8e..c05b4eed7a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
@@ -71,6 +71,7 @@ float noise(vec2 x) {
//=============================
+vec3 clampHDRRange(vec3 color);
void main()
@@ -84,6 +85,7 @@ void main()
diff.rgb += nz*0.003;
#endif
+ diff.rgb = clampHDRRange(diff.rgb);
frag_color = diff;
gl_FragDepth = texture(depthMap, vary_fragcoord.xy).r;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
index fc6d4d7727..1f01c7f16a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
@@ -28,138 +28,13 @@
out vec4 frag_color;
uniform sampler2D diffuseRect;
-uniform sampler2D exposureMap;
-uniform vec2 screen_res;
in vec2 vary_fragcoord;
vec3 linear_to_srgb(vec3 cl);
+vec3 toneMap(vec3 color);
-//===============================================================
-// 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;
-}
-
-// Khronos Neutral tonemapping
-// https://github.com/KhronosGroup/ToneMapping/tree/main
-// Input color is non-negative and resides in the Linear Rec. 709 color space.
-// Output color is also Linear Rec. 709, but in the [0, 1] range.
-vec3 PBRNeutralToneMapping( vec3 color )
-{
- const float startCompression = 0.8 - 0.04;
- const float desaturation = 0.15;
-
- float x = min(color.r, min(color.g, color.b));
- float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
- color -= offset;
-
- float peak = max(color.r, max(color.g, color.b));
- if (peak < startCompression) return color;
-
- const float d = 1. - startCompression;
- float newPeak = 1. - d * d / (peak + d - startCompression);
- color *= newPeak / peak;
-
- float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
- return mix(color, newPeak * vec3(1, 1, 1), g);
-}
-
-uniform float exposure;
-uniform float tonemap_mix;
-uniform int tonemap_type;
-
-vec3 toneMap(vec3 color)
-{
-#ifndef NO_POST
- float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
-
- color *= exposure * exp_scale;
-
- vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
-
- switch(tonemap_type)
- {
- case 0:
- color = PBRNeutralToneMapping(color);
- break;
- case 1:
- color = toneMapACES_Hill(color);
- break;
- }
-
- // mix tonemapped and linear here to provide adjustment
- color = mix(clamped_color, color, tonemap_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 clampHDRRange(vec3 color);
void main()
{
@@ -172,6 +47,7 @@ void main()
diff.rgb = clamp(diff.rgb, vec3(0.0), vec3(1.0));
#endif
+ diff.rgb = clampHDRRange(diff.rgb);
//debugExposure(diff.rgb);
frag_color = max(diff, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl
new file mode 100644
index 0000000000..a63b8d7c2b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl
@@ -0,0 +1,180 @@
+/**
+ * @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]*/
+
+uniform sampler2D exposureMap;
+uniform vec2 screen_res;
+in vec2 vary_fragcoord;
+
+//===============================================================
+// 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;
+}
+
+// Khronos Neutral tonemapping
+// https://github.com/KhronosGroup/ToneMapping/tree/main
+// Input color is non-negative and resides in the Linear Rec. 709 color space.
+// Output color is also Linear Rec. 709, but in the [0, 1] range.
+vec3 PBRNeutralToneMapping( vec3 color )
+{
+ const float startCompression = 0.8 - 0.04;
+ const float desaturation = 0.15;
+
+ float x = min(color.r, min(color.g, color.b));
+ float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
+ color -= offset;
+
+ float peak = max(color.r, max(color.g, color.b));
+ if (peak < startCompression) return color;
+
+ const float d = 1. - startCompression;
+ float newPeak = 1. - d * d / (peak + d - startCompression);
+ color *= newPeak / peak;
+
+ float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
+ return mix(color, newPeak * vec3(1, 1, 1), g);
+}
+
+uniform float exposure;
+uniform float tonemap_mix;
+uniform int tonemap_type;
+
+vec3 toneMap(vec3 color)
+{
+#ifndef NO_POST
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+
+ color *= exposure * exp_scale;
+
+ vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
+
+ switch(tonemap_type)
+ {
+ case 0:
+ color = PBRNeutralToneMapping(color);
+ break;
+ case 1:
+ color = toneMapACES_Hill(color);
+ break;
+ }
+
+ // mix tonemapped and linear here to provide adjustment
+ color = mix(clamped_color, color, tonemap_mix);
+#endif
+
+ return color;
+}
+
+
+vec3 toneMapNoExposure(vec3 color)
+{
+#ifndef NO_POST
+ vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
+
+ switch(tonemap_type)
+ {
+ case 0:
+ color = PBRNeutralToneMapping(color);
+ break;
+ case 1:
+ color = toneMapACES_Hill(color);
+ break;
+ }
+
+ // mix tonemapped and linear here to provide adjustment
+ color = mix(clamped_color, color, tonemap_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);
+ }
+}