diff options
Diffstat (limited to 'indra/newview')
22 files changed, 657 insertions, 535 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b599358aa3..6d852e47f8 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1686,6 +1686,7 @@ set(viewer_APPSETTINGS_FILES packages-info.txt featuretable.txt featuretable_mac.txt + featuretable_linux.txt ) source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES}) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 049ec3ad34..129f593454 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10080,6 +10080,17 @@ <key>Value</key> <string>00000000-0000-0000-0000-000000000000</string> </map> + <key>RenderCAS</key> + <map> + <key>Comment</key> + <string>Use Contrast Adaptive Sharpening post process effect</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>RenderCASSharpness</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl b/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl index e80c59b39f..abab71e5ce 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl @@ -38,6 +38,7 @@ uniform sampler2D diffuseRect; uniform vec2 out_screen_res; uniform uvec4 cas_param_0; uniform uvec4 cas_param_1; +uniform float gamma; vec3 srgb_to_linear(vec3 cs); vec3 linear_to_srgb(vec3 cl); @@ -2545,11 +2546,69 @@ A_STATIC void CasSetup( #endif #ifdef A_GPU + +//================================= +// borrowed noise from: +// <https://www.shadertoy.com/view/4dS3Wd> +// By Morgan McGuire @morgan3d, http://graphicscodex.com +// +float hash(float n) { return fract(sin(n) * 1e4); } +float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } + +float noise(float x) { + float i = floor(x); + float f = fract(x); + float u = f * f * (3.0 - 2.0 * f); + return mix(hash(i), hash(i + 1.0), u); +} + +float noise(vec2 x) { + vec2 i = floor(x); + vec2 f = fract(x); + + // Four corners in 2D of a tile + float a = hash(i); + float b = hash(i + vec2(1.0, 0.0)); + float c = hash(i + vec2(0.0, 1.0)); + float d = hash(i + vec2(1.0, 1.0)); + + // Simple 2D lerp using smoothstep envelope between the values. + // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)), + // mix(c, d, smoothstep(0.0, 1.0, f.x)), + // smoothstep(0.0, 1.0, f.y))); + + // Same code, with the clamps in smoothstep and common subexpressions + // optimized away. + vec2 u = f * f * (3.0 - 2.0 * f); + return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; +} + +//=============================================================== + +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() { vec4 diff = vec4(0.f); uvec2 point = uvec2(vary_fragcoord * out_screen_res.xy); CasFilter(diff.r, diff.g, diff.b, point, cas_param_0, cas_param_1, true); + diff.rgb = linear_to_srgb(diff.rgb); + +#ifdef LEGACY_GAMMA + diff.rgb = legacyGamma(diff.rgb); +#endif + + vec2 tc = vary_fragcoord.xy*out_screen_res.xy*4.0; + vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y); + vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); + diff.rgb += nz*0.003; + diff.a = texture(diffuseRect, vary_fragcoord).a; frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/SMAANeighborhoodBlendF.glsl b/indra/newview/app_settings/shaders/class1/deferred/SMAANeighborhoodBlendF.glsl index 3276405447..08052a9ddf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/SMAANeighborhoodBlendF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/SMAANeighborhoodBlendF.glsl @@ -31,10 +31,12 @@ in vec2 vary_texcoord0; in vec4 vary_offset; uniform sampler2D diffuseRect; +uniform sampler2D emissiveRect; uniform sampler2D blendTex; #if SMAA_REPROJECTION uniform sampler2D velocityTex; #endif +uniform sampler2D depthMap; #define float4 vec4 #define float2 vec2 @@ -51,7 +53,7 @@ float4 SMAANeighborhoodBlendingPS(float2 texcoord, void main() { - frag_color = SMAANeighborhoodBlendingPS(vary_texcoord0, + vec4 diff = SMAANeighborhoodBlendingPS(vary_texcoord0, vary_offset, diffuseRect, blendTex @@ -59,5 +61,11 @@ void main() , velocityTex #endif ); +#ifndef NO_GLOW + diff.rgb += texture2D(emissiveRect, vary_texcoord0).rgb; +#endif + frag_color = diff; + + gl_FragDepth = texture(depthMap, vary_texcoord0.xy).r; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl index 4a26b8924a..36611db2fb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl @@ -29,6 +29,7 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D depthMap; +uniform sampler2D emissiveRect; uniform float focal_distance; uniform float blur_constant; @@ -66,12 +67,13 @@ void main() vec4 p = inv_proj*ndc; float depth = p.z/p.w; - vec4 diff = texture(diffuseRect, vary_fragcoord.xy); + vec4 diff = texture(diffuseRect, tc); float sc = calc_cof(depth); sc = min(sc, max_cof); sc = max(sc, -max_cof); - frag_color.rgb = diff.rgb; + vec4 bloom = texture2D(emissiveRect, tc); + frag_color.rgb = diff.rgb + bloom.rgb; frag_color.a = sc/max_cof*0.5+0.5; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl deleted file mode 100644 index befd2ae6da..0000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file postDeferredGammaCorrect.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, 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 float gamma; -uniform vec2 screen_res; -in vec2 vary_fragcoord; - -vec3 linear_to_srgb(vec3 cl); - -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); - diff.rgb = linear_to_srgb(diff.rgb); - -#ifdef LEGACY_GAMMA - diff.rgb = legacyGamma(diff.rgb); -#endif - - frag_color = max(diff, vec4(0)); -} - diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index 32b0a1ac8e..cb0a6edea9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -30,60 +30,12 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D depthMap; -uniform vec2 screen_res; in vec2 vary_fragcoord; -//================================= -// borrowed noise from: -// <https://www.shadertoy.com/view/4dS3Wd> -// By Morgan McGuire @morgan3d, http://graphicscodex.com -// -float hash(float n) { return fract(sin(n) * 1e4); } -float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } - -float noise(float x) { - float i = floor(x); - float f = fract(x); - float u = f * f * (3.0 - 2.0 * f); - return mix(hash(i), hash(i + 1.0), u); -} - -float noise(vec2 x) { - vec2 i = floor(x); - vec2 f = fract(x); - - // Four corners in 2D of a tile - float a = hash(i); - float b = hash(i + vec2(1.0, 0.0)); - float c = hash(i + vec2(0.0, 1.0)); - float d = hash(i + vec2(1.0, 1.0)); - - // Simple 2D lerp using smoothstep envelope between the values. - // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)), - // mix(c, d, smoothstep(0.0, 1.0, f.x)), - // smoothstep(0.0, 1.0, f.y))); - - // Same code, with the clamps in smoothstep and common subexpressions - // optimized away. - vec2 u = f * f * (3.0 - 2.0 * f); - return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; -} - -//============================= - - - void main() { vec4 diff = texture(diffuseRect, vary_fragcoord.xy); -#ifdef HAS_NOISE - vec2 tc = vary_fragcoord.xy*screen_res*4.0; - vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y); - vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); - diff.rgb += nz*0.003; -#endif - 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..9d449a5ae2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl @@ -30,6 +30,7 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D exposureMap; +uniform float gamma; uniform vec2 screen_res; in vec2 vary_fragcoord; @@ -149,6 +150,42 @@ vec3 toneMap(vec3 color) return color; } +//================================= +// borrowed noise from: +// <https://www.shadertoy.com/view/4dS3Wd> +// By Morgan McGuire @morgan3d, http://graphicscodex.com +// +float hash(float n) { return fract(sin(n) * 1e4); } +float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } + +float noise(float x) { + float i = floor(x); + float f = fract(x); + float u = f * f * (3.0 - 2.0 * f); + return mix(hash(i), hash(i + 1.0), u); +} + +float noise(vec2 x) { + vec2 i = floor(x); + vec2 f = fract(x); + + // Four corners in 2D of a tile + float a = hash(i); + float b = hash(i + vec2(1.0, 0.0)); + float c = hash(i + vec2(0.0, 1.0)); + float d = hash(i + vec2(1.0, 1.0)); + + // Simple 2D lerp using smoothstep envelope between the values. + // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)), + // mix(c, d, smoothstep(0.0, 1.0, f.x)), + // smoothstep(0.0, 1.0, f.y))); + + // Same code, with the clamps in smoothstep and common subexpressions + // optimized away. + vec2 u = f * f * (3.0 - 2.0 * f); + return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; +} + //=============================================================== void debugExposure(inout vec3 color) @@ -161,16 +198,40 @@ void debugExposure(inout vec3 color) } } +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); +#ifdef TONEMAP #ifndef NO_POST diff.rgb = toneMap(diff.rgb); -#else +#endif +#ifndef GAMMA_CORRECT diff.rgb = clamp(diff.rgb, vec3(0.0), vec3(1.0)); #endif +#endif + +#ifdef GAMMA_CORRECT + diff.rgb = linear_to_srgb(diff.rgb); + +#ifdef LEGACY_GAMMA + diff.rgb = legacyGamma(diff.rgb); +#endif + + vec2 tc = vary_fragcoord.xy*screen_res*4.0; + vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y); + vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); + diff.rgb += nz*0.003; +#endif //debugExposure(diff.rgb); frag_color = max(diff, vec4(0)); diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl index ca000dcb23..0e7858743c 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl @@ -29,10 +29,12 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D emissiveRect; +uniform sampler2D depthMap; in vec2 tc; void main() { frag_color = texture(diffuseRect, tc) + texture(emissiveRect, tc); + gl_FragDepth = texture(depthMap, tc.xy).r; } diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl index 6d34c8aefa..8a8de88182 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl @@ -28,6 +28,7 @@ out vec4 frag_color; uniform sampler2D diffuseRect; +uniform sampler2D emissiveRect; uniform vec2 screen_res; @@ -36,6 +37,8 @@ in vec2 vary_tc; void main() { vec3 col = texture(diffuseRect, vary_tc).rgb; - - frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144))); +#ifndef NO_GLOW + col += texture2D(emissiveRect, vary_tc).rgb; +#endif + frag_color = vec4(col, dot(col, vec3(0.299, 0.587, 0.144))); } diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 6390e43b7a..ce9fc853c8 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 64 +version 65 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -80,6 +80,7 @@ RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 RenderDownScaleMethod 1 1 +RenderCAS 1 1 RenderCASSharpness 1 1 RenderExposure 1 4 RenderTonemapType 1 1 @@ -120,6 +121,7 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 4 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -160,6 +162,7 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -200,6 +203,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -240,6 +244,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -280,6 +285,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 1 RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 @@ -320,6 +326,7 @@ RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 @@ -360,6 +367,7 @@ RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 9465acae6b..e8004bc1db 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,10 +1,10 @@ -version 30 +version 31 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended // defaults. This should be as rare an event as we can manage. -// NOTE: This is mostly identical to featuretable_mac.txt with a few differences +// NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table // @@ -77,9 +77,10 @@ RenderScreenSpaceReflections 1 1 RenderMirrors 1 1 RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 -RenderHeroProbeUpdateRate 1 4 +RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 RenderDownScaleMethod 1 1 +RenderCAS 1 1 RenderCASSharpness 1 1 RenderExposure 1 4 RenderTonemapType 1 1 @@ -120,6 +121,7 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 4 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -160,6 +162,7 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -200,6 +203,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -240,6 +244,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -280,6 +285,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 1 RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 @@ -320,6 +326,7 @@ RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 @@ -360,6 +367,7 @@ RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 9ba922c3ce..26ccb17f27 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 62 +version 63 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -79,6 +79,7 @@ RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 1 RenderCASSharpness 1 1 RenderExposure 1 1 RenderTonemapType 1 1 @@ -119,6 +120,7 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 4 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -159,6 +161,7 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -199,6 +202,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -239,6 +243,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -279,6 +284,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 0 RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 @@ -319,6 +325,7 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 @@ -359,6 +366,7 @@ RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index cf6b08797d..5ca841f9f1 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -523,31 +523,19 @@ bool LLGLTFPreviewTexture::render() gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap); gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap); gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap, /*use_history = */ false); - gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap); - LLVertexBuffer::unbind(); - gPipeline.generateGlow(&gPipeline.mPostMap); - gPipeline.combineGlow(&gPipeline.mPostMap, &screen); - gPipeline.renderDoF(&screen, &gPipeline.mPostMap); - gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); - // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame) - gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); + LLRenderTarget* src = &gPipeline.mPostPingMap; + LLRenderTarget* dst = &gPipeline.mPostPongMap; + gPipeline.tonemap(&screen, dst); + std::swap(src, dst); // Final render + LLVertexBuffer::unbind(); + gPipeline.generateGlow(src); + gPipeline.combineGlow(src, nullptr); - gDeferredPostNoDoFProgram.bind(); - - // From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems." - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &screen); - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true); - - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - gPipeline.mScreenTriangleVB->setBuffer(); - gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - gDeferredPostNoDoFProgram.unbind(); + // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame) + gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); // Clean up gPipeline.setupHWLights(); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 184c0e7d8b..e9e231db59 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -770,6 +770,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); + setting_setup_signal_listener(gSavedSettings, "RenderCAS", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderFSAAType", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index c219b0575e..4d248af5d5 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -87,6 +87,7 @@ LLGLSLShader gRadianceGenProgram; LLGLSLShader gHeroRadianceGenProgram; LLGLSLShader gIrradianceGenProgram; LLGLSLShader gGlowCombineFXAAProgram; +LLGLSLShader gFXAALumaGenProgram; LLGLSLShader gTwoTextureCompareProgram; LLGLSLShader gOneTextureFilterProgram; LLGLSLShader gDebugProgram; @@ -198,6 +199,7 @@ LLGLSLShader gDeferredPostTonemapProgram; LLGLSLShader gNoPostTonemapProgram; LLGLSLShader gDeferredPostGammaCorrectProgram; LLGLSLShader gLegacyPostGammaCorrectProgram; +LLGLSLShader gNoPostGammaCorrectProgram; LLGLSLShader gExposureProgram; LLGLSLShader gExposureProgramNoFade; LLGLSLShader gLuminanceProgram; @@ -205,7 +207,9 @@ LLGLSLShader gFXAAProgram[4]; LLGLSLShader gSMAAEdgeDetectProgram[4]; LLGLSLShader gSMAABlendWeightsProgram[4]; LLGLSLShader gSMAANeighborhoodBlendProgram[4]; +LLGLSLShader gSMAANeighborhoodBlendGlowCombineProgram[4]; LLGLSLShader gCASProgram; +LLGLSLShader gCASLegacyGammaProgram; LLGLSLShader gDeferredPostNoDoFProgram; LLGLSLShader gDeferredPostNoDoFNoiseProgram; LLGLSLShader gDeferredWLSkyProgram; @@ -434,8 +438,8 @@ void LLViewerShaderMgr::finalizeShaderList() mShaderList.push_back(&gHUDPBRAlphaProgram); mShaderList.push_back(&gDeferredPostTonemapProgram); mShaderList.push_back(&gNoPostTonemapProgram); - mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma - mShaderList.push_back(&gLegacyPostGammaCorrectProgram); + mShaderList.push_back(&gLegacyPostGammaCorrectProgram); // for gamma + mShaderList.push_back(&gCASLegacyGammaProgram); // for gamma mShaderList.push_back(&gDeferredDiffuseProgram); mShaderList.push_back(&gDeferredBumpProgram); mShaderList.push_back(&gDeferredPBROpaqueProgram); @@ -2326,8 +2330,10 @@ bool LLViewerShaderMgr::loadShadersDeferred() gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true; gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); gDeferredPostGammaCorrectProgram.clearPermutations(); + gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP", "1"); + gDeferredPostGammaCorrectProgram.addPermutation("GAMMA_CORRECT", "1"); gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER)); + gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredPostGammaCorrectProgram.createShader(); llassert(success); @@ -2340,9 +2346,10 @@ bool LLViewerShaderMgr::loadShadersDeferred() gLegacyPostGammaCorrectProgram.mFeatures.isDeferred = true; gLegacyPostGammaCorrectProgram.mShaderFiles.clear(); gLegacyPostGammaCorrectProgram.clearPermutations(); + gLegacyPostGammaCorrectProgram.addPermutation("GAMMA_CORRECT", "1"); gLegacyPostGammaCorrectProgram.addPermutation("LEGACY_GAMMA", "1"); gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER)); + gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); gLegacyPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gLegacyPostGammaCorrectProgram.createShader(); llassert(success); @@ -2350,11 +2357,27 @@ bool LLViewerShaderMgr::loadShadersDeferred() if (success) { + gNoPostGammaCorrectProgram.mName = "No Post Gamma Correction Post Process"; + gNoPostGammaCorrectProgram.mFeatures.hasSrgb = true; + gNoPostGammaCorrectProgram.mFeatures.isDeferred = true; + gNoPostGammaCorrectProgram.mShaderFiles.clear(); + gNoPostGammaCorrectProgram.clearPermutations(); + gNoPostGammaCorrectProgram.addPermutation("GAMMA_CORRECT", "1"); + gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); + gNoPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gNoPostGammaCorrectProgram.createShader(); + llassert(success); + } + + if (success) + { gDeferredPostTonemapProgram.mName = "Deferred Tonemap Post Process"; gDeferredPostTonemapProgram.mFeatures.hasSrgb = true; gDeferredPostTonemapProgram.mFeatures.isDeferred = true; gDeferredPostTonemapProgram.mShaderFiles.clear(); gDeferredPostTonemapProgram.clearPermutations(); + gDeferredPostTonemapProgram.addPermutation("TONEMAP", "1"); gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); gDeferredPostTonemapProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; @@ -2369,6 +2392,7 @@ bool LLViewerShaderMgr::loadShadersDeferred() gNoPostTonemapProgram.mFeatures.isDeferred = true; gNoPostTonemapProgram.mShaderFiles.clear(); gNoPostTonemapProgram.clearPermutations(); + gNoPostTonemapProgram.addPermutation("TONEMAP", "1"); gNoPostTonemapProgram.addPermutation("NO_POST", "1"); gNoPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); gNoPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); @@ -2474,6 +2498,7 @@ bool LLViewerShaderMgr::loadShadersDeferred() gSMAANeighborhoodBlendProgram[i].clearPermutations(); gSMAANeighborhoodBlendProgram[i].addPermutations(defines); + gSMAANeighborhoodBlendProgram[i].addPermutation("NO_GLOW", "1"); gSMAANeighborhoodBlendProgram[i].mShaderFiles.clear(); gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -2481,8 +2506,27 @@ bool LLViewerShaderMgr::loadShadersDeferred() gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB)); gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB)); gSMAANeighborhoodBlendProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gSMAANeighborhoodBlendProgram[i].createShader(); } + + if (success) + { + gSMAANeighborhoodBlendGlowCombineProgram[i].mName = llformat("SMAA Neighborhood Blending Glow Combine (%s)", smaa_pair.second.c_str()); + gSMAANeighborhoodBlendGlowCombineProgram[i].mFeatures.isDeferred = true; + + gSMAANeighborhoodBlendGlowCombineProgram[i].clearPermutations(); + gSMAANeighborhoodBlendGlowCombineProgram[i].addPermutations(defines); + + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.clear(); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendV.glsl", GL_VERTEX_SHADER_ARB)); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB)); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB)); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + + success = gSMAANeighborhoodBlendGlowCombineProgram[i].createShader(); + } ++i; } } @@ -2500,6 +2544,19 @@ bool LLViewerShaderMgr::loadShadersDeferred() if (success) { + gCASLegacyGammaProgram.mName = "Contrast Adaptive Sharpening Legacy Gamma Shader"; + gCASLegacyGammaProgram.mFeatures.hasSrgb = true; + gCASLegacyGammaProgram.clearPermutations(); + gCASLegacyGammaProgram.addPermutation("LEGACY_GAMMA", "1"); + gCASLegacyGammaProgram.mShaderFiles.clear(); + gCASLegacyGammaProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gCASLegacyGammaProgram.mShaderFiles.push_back(make_pair("deferred/CASF.glsl", GL_FRAGMENT_SHADER)); + gCASLegacyGammaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gCASLegacyGammaProgram.createShader(); + } + + if (success) + { gDeferredPostProgram.mName = "Deferred Post Shader"; gDeferredPostProgram.mFeatures.isDeferred = true; gDeferredPostProgram.mShaderFiles.clear(); @@ -2548,22 +2605,6 @@ bool LLViewerShaderMgr::loadShadersDeferred() if (success) { - gDeferredPostNoDoFNoiseProgram.mName = "Deferred Post NoDoF Noise Shader"; - gDeferredPostNoDoFNoiseProgram.mFeatures.isDeferred = true; - gDeferredPostNoDoFNoiseProgram.mShaderFiles.clear(); - gDeferredPostNoDoFNoiseProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredPostNoDoFNoiseProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER)); - - gDeferredPostNoDoFNoiseProgram.clearPermutations(); - gDeferredPostNoDoFNoiseProgram.addPermutation("HAS_NOISE", "1"); - - gDeferredPostNoDoFNoiseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostNoDoFNoiseProgram.createShader(); - llassert(success); - } - - if (success) - { gEnvironmentMapProgram.mName = "Environment Map Program"; gEnvironmentMapProgram.mShaderFiles.clear(); gEnvironmentMapProgram.mFeatures.calculatesAtmospherics = true; @@ -2951,7 +2992,7 @@ bool LLViewerShaderMgr::loadShadersInterface() if (success) { - gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader"; + gGlowCombineFXAAProgram.mName = "Glow Combine FXAA Luma Gen Shader"; gGlowCombineFXAAProgram.mShaderFiles.clear(); gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER)); gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER)); @@ -2966,6 +3007,25 @@ bool LLViewerShaderMgr::loadShadersInterface() } } + if (success) + { + gFXAALumaGenProgram.mName = "FXAA Luma Gen Shader"; + gFXAALumaGenProgram.mShaderFiles.clear(); + gFXAALumaGenProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER)); + gFXAALumaGenProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER)); + gFXAALumaGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + gFXAALumaGenProgram.clearPermutations(); + gFXAALumaGenProgram.addPermutation("NO_GLOW", "1"); + success = gFXAALumaGenProgram.createShader(); + if (success) + { + gFXAALumaGenProgram.bind(); + gFXAALumaGenProgram.uniform1i(sGlowMap, 0); + gFXAALumaGenProgram.uniform1i(sScreenMap, 1); + gFXAALumaGenProgram.unbind(); + } + } + #ifdef LL_WINDOWS if (success) { diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e654967c46..60b880c161 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -160,6 +160,7 @@ extern LLGLSLShader gRadianceGenProgram; extern LLGLSLShader gHeroRadianceGenProgram; extern LLGLSLShader gIrradianceGenProgram; extern LLGLSLShader gGlowCombineFXAAProgram; +extern LLGLSLShader gFXAALumaGenProgram; extern LLGLSLShader gDebugProgram; enum NormalDebugShaderVariant : S32 { @@ -250,11 +251,13 @@ extern LLGLSLShader gFXAAProgram[4]; extern LLGLSLShader gSMAAEdgeDetectProgram[4]; extern LLGLSLShader gSMAABlendWeightsProgram[4]; extern LLGLSLShader gSMAANeighborhoodBlendProgram[4]; +extern LLGLSLShader gSMAANeighborhoodBlendGlowCombineProgram[4]; extern LLGLSLShader gCASProgram; +extern LLGLSLShader gCASLegacyGammaProgram; extern LLGLSLShader gDeferredPostNoDoFProgram; -extern LLGLSLShader gDeferredPostNoDoFNoiseProgram; extern LLGLSLShader gDeferredPostGammaCorrectProgram; extern LLGLSLShader gLegacyPostGammaCorrectProgram; +extern LLGLSLShader gNoPostGammaCorrectProgram; extern LLGLSLShader gDeferredPostTonemapProgram; extern LLGLSLShader gNoPostTonemapProgram; extern LLGLSLShader gExposureProgram; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0b4b98d674..a88756452e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -828,8 +828,9 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY) mRT->deferredScreen.shareDepthBuffer(mRT->screen); - if (shadow_detail > 0 || ssao || RenderDepthOfField) - { //only need mRT->deferredLight for shadows OR ssao OR dof + static LLCachedControl<bool> render_cas(gSavedSettings, "RenderCAS", true); + if (shadow_detail > 0 || ssao || render_cas) + { //only need mRT->deferredLight for shadows OR ssao if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false; } else @@ -849,13 +850,18 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY) } } - if (RenderFSAAType > 0) + if (RenderFSAAType > 0 || RenderDepthOfField) { if (!mFXAAMap.allocate(resX, resY, GL_RGBA)) return false; if (RenderFSAAType == 2) { if (!mSMAABlendBuffer.allocate(resX, resY, GL_RGBA, false)) return false; } + else + { + mSMAABlendBuffer.release(); + } + } else { @@ -875,7 +881,8 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY) mSceneMap.release(); } - mPostMap.allocate(resX, resY, GL_RGBA16F); + mPostPingMap.allocate(resX, resY, GL_RGBA); + mPostPongMap.allocate(resX, resY, GL_RGBA); // used to scale down textures // See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown @@ -1133,7 +1140,8 @@ void LLPipeline::releaseGLBuffers() mSceneMap.release(); - mPostMap.release(); + mPostPingMap.release(); + mPostPongMap.release(); mFXAAMap.release(); @@ -6895,7 +6903,10 @@ static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex) { - dst->bindTarget(); + if (dst) + { + dst->bindTarget(); + } gDeferredBufferVisualProgram.bind(); gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex); @@ -6908,7 +6919,10 @@ void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); gDeferredBufferVisualProgram.unbind(); - dst->flush(); + if (dst) + { + dst->flush(); + } } void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) @@ -7047,7 +7061,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool extern LLPointer<LLImageGL> gEXRImage; -void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) +void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst, bool gamma_correct/* = true*/) { dst->bindTarget(); // gamma correct lighting @@ -7064,18 +7078,26 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools->isAvailable()); - LLGLSLShader& shader = no_post ? gNoPostTonemapProgram : gDeferredPostTonemapProgram; + bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable()); + LLGLSLShader* shader = nullptr; + if (gamma_correct) + { + shader = no_post ? &gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping) + psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? &gLegacyPostGammaCorrectProgram : + &gDeferredPostGammaCorrectProgram; + } + else + { + shader = (psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || no_post) ? &gNoPostTonemapProgram : &gDeferredPostTonemapProgram; + } - shader.bind(); + shader->bind(); S32 channel = 0; - shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT); - - shader.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap); - - shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); + shader->bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT); + shader->bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f); @@ -7085,47 +7107,19 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) static LLStaticHashedString tonemap_mix("tonemap_mix"); static LLStaticHashedString tonemap_type("tonemap_type"); - shader.uniform1f(s_exposure, e); + shader->uniform1f(s_exposure, e); static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U); - shader.uniform1i(tonemap_type, tonemap_type_setting); + shader->uniform1i(tonemap_type, tonemap_type_setting); static LLCachedControl<F32> tonemap_mix_setting(gSavedSettings, "RenderTonemapMix", 1.f); - shader.uniform1f(tonemap_mix, tonemap_mix_setting); + shader->uniform1f(tonemap_mix, tonemap_mix_setting); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); gGL.getTexUnit(channel)->unbind(src->getUsage()); - shader.unbind(); - } - dst->flush(); -} - -void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) -{ - dst->bindTarget(); - // gamma correct lighting - { - LL_PROFILE_GPU_ZONE("gamma correct"); - - LLGLDepthTest depth(GL_FALSE, GL_FALSE); - - static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false); - static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); - - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLGLSLShader& shader = psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram : - gDeferredPostGammaCorrectProgram; - - shader.bind(); - shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT); - shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - - shader.unbind(); + shader->unbind(); } dst->flush(); } @@ -7270,13 +7264,10 @@ void LLPipeline::generateGlow(LLRenderTarget* src) void LLPipeline::applyCAS(LLRenderTarget* src, LLRenderTarget* dst) { static LLCachedControl<F32> cas_sharpness(gSavedSettings, "RenderCASSharpness", 0.4f); - if (cas_sharpness == 0.0f || !gCASProgram.isComplete()) - { - gPipeline.copyRenderTarget(src, dst); - return; - } + static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); - LLGLSLShader* sharpen_shader = &gCASProgram; + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + LLGLSLShader* sharpen_shader = psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? &gCASLegacyGammaProgram : &gCASProgram; // Bind setup: dst->bindTarget(); @@ -7312,89 +7303,85 @@ void LLPipeline::applyCAS(LLRenderTarget* src, LLRenderTarget* dst) dst->flush(); } -void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) +void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst, bool combine_glow) { - { - llassert(!gCubeSnapshot); - bool multisample = RenderFSAAType == 1 && mFXAAMap.isComplete(); - LLGLSLShader* shader = &gGlowCombineProgram; + llassert(!gCubeSnapshot); + LLGLSLShader* shader = &gGlowCombineProgram; - // Present everything. - if (multisample) - { - LL_PROFILE_GPU_ZONE("aa"); - S32 width = dst->getWidth(); - S32 height = dst->getHeight(); + LL_PROFILE_GPU_ZONE("aa"); + S32 width = src->getWidth(); + S32 height = src->getHeight(); - // bake out texture2D with RGBL for FXAA shader - mFXAAMap.bindTarget(); - mFXAAMap.invalidate(GL_COLOR_BUFFER_BIT); + // bake out texture2D with RGBL for FXAA shader + mFXAAMap.bindTarget(); + mFXAAMap.invalidate(GL_COLOR_BUFFER_BIT); - shader = &gGlowCombineFXAAProgram; - shader->bind(); + shader = combine_glow ? &gGlowCombineFXAAProgram : &gFXAALumaGenProgram; + shader->bind(); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); - if (channel > -1) - { - src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); + if (channel > -1) + { + src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } + shader->bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); - shader->unbind(); + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); + shader->unbind(); - mFXAAMap.flush(); + mFXAAMap.flush(); - dst->bindTarget(); + if (dst) + { + dst->bindTarget(); + } - static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); - U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); + static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); + U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); - shader = &gFXAAProgram[fsaa_quality]; - shader->bind(); + shader = &gFXAAProgram[fsaa_quality]; + shader->bind(); - channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAAMap.getUsage()); - if (channel > -1) - { - mFXAAMap.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAAMap.getUsage()); + if (channel > -1) + { + mFXAAMap.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - F32 scale_x = (F32)width / mFXAAMap.getWidth(); - F32 scale_y = (F32)height / mFXAAMap.getHeight(); - shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); - shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, - 0.5f / width * scale_x, 0.5f / height * scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, - 2.f / width * scale_x, 2.f / height * scale_y); + F32 scale_x = (F32)width / mFXAAMap.getWidth(); + F32 scale_y = (F32)height / mFXAAMap.getHeight(); + shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); + shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, + 0.5f / width * scale_x, 0.5f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, + 2.f / width * scale_x, 2.f / height * scale_y); - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); - gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true); + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + shader->bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - shader->unbind(); - dst->flush(); - } - else { - copyRenderTarget(src, dst); - } + shader->unbind(); + if (dst) + { + dst->flush(); } } @@ -7517,67 +7504,69 @@ void LLPipeline::generateSMAABuffers(LLRenderTarget* src) } } -void LLPipeline::applySMAA(LLRenderTarget* src, LLRenderTarget* dst) +void LLPipeline::applySMAA(LLRenderTarget* src, LLRenderTarget* dst, bool combine_glow) { llassert(!gCubeSnapshot); - bool multisample = RenderFSAAType == 2 && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); - // Present everything. - if (multisample) - { - LL_PROFILE_GPU_ZONE("aa"); - static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); - U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); + LL_PROFILE_GPU_ZONE("aa"); + static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); + U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); - S32 width = src->getWidth(); - S32 height = src->getHeight(); + S32 width = src->getWidth(); + S32 height = src->getHeight(); - float rt_metrics[] = { 1.f / width, 1.f / height, (float)width, (float)height }; + float rt_metrics[] = { 1.f / width, 1.f / height, (float)width, (float)height }; - LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); - static LLCachedControl<bool> use_sample(gSavedSettings, "RenderSMAAUseSample", false); - //static LLCachedControl<bool> use_stencil(gSavedSettings, "RenderSMAAUseStencil", true); + static LLCachedControl<bool> use_sample(gSavedSettings, "RenderSMAAUseSample", false); + //static LLCachedControl<bool> use_stencil(gSavedSettings, "RenderSMAAUseStencil", true); + + { + //LLGLDisable stencil(GL_STENCIL_TEST); + // Bind setup: + LLGLSLShader& blend_shader = combine_glow ? gSMAANeighborhoodBlendGlowCombineProgram[fsaa_quality] + : gSMAANeighborhoodBlendProgram[fsaa_quality]; + + if(dst) { - //LLGLDisable stencil(GL_STENCIL_TEST); + dst->bindTarget(); + dst->invalidate(GL_COLOR_BUFFER_BIT); + } - // Bind setup: - LLRenderTarget* bound_target = dst; - LLGLSLShader& blend_shader = gSMAANeighborhoodBlendProgram[fsaa_quality]; + blend_shader.bind(); + blend_shader.uniform4fv(sSmaaRTMetrics, 1, rt_metrics); + + S32 diffuse_channel = blend_shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); + if(diffuse_channel > -1) + { + src->bindTexture(0, diffuse_channel, LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + } - bound_target->bindTarget(); - bound_target->invalidate(GL_COLOR_BUFFER_BIT); + S32 blend_channel = blend_shader.enableTexture(LLShaderMgr::SMAA_BLEND_TEX); + if (blend_channel > -1) + { + mSMAABlendBuffer.bindTexture(0, blend_channel, LLTexUnit::TFO_BILINEAR); + } - blend_shader.bind(); - blend_shader.uniform4fv(sSmaaRTMetrics, 1, rt_metrics); + blend_shader.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); - S32 diffuse_channel = blend_shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); - if(diffuse_channel > -1) - { - src->bindTexture(0, diffuse_channel, LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - } + blend_shader.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - S32 blend_channel = blend_shader.enableTexture(LLShaderMgr::SMAA_BLEND_TEX); - if (blend_channel > -1) - { - mSMAABlendBuffer.bindTexture(0, blend_channel, LLTexUnit::TFO_BILINEAR); - } + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + blend_shader.unbind(); + gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(blend_channel)->unbindFast(LLTexUnit::TT_TEXTURE); - bound_target->flush(); - blend_shader.unbind(); - gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(blend_channel)->unbindFast(LLTexUnit::TT_TEXTURE); + if (dst) + { + dst->flush(); } } - else - { - copyRenderTarget(src, dst); - } } void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) @@ -7605,216 +7594,217 @@ void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) { // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer. - dst->bindTarget(); - + if (dst) { + dst->bindTarget(); + } + { gGlowCombineProgram.bind(); gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src); gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); + gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } - - dst->flush(); + if (dst) + { + dst->flush(); + } } void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) { - { - bool dof_enabled = - (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && - RenderDepthOfField && - !gCubeSnapshot; - - gViewerWindow->setup3DViewport(); + gViewerWindow->setup3DViewport(); - if (dof_enabled) - { - LL_PROFILE_GPU_ZONE("dof"); - LLGLDisable blend(GL_BLEND); + LL_PROFILE_GPU_ZONE("dof"); + LLGLDisable blend(GL_BLEND); - // depth of field focal plane calculations - static F32 current_distance = 16.f; - static F32 start_distance = 16.f; - static F32 transition_time = 1.f; + // depth of field focal plane calculations + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; - LLVector3 focus_point; + LLVector3 focus_point; - LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); - if (obj && obj->mDrawable && obj->isSelected()) - { // focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) - { - LLFace* face = obj->mDrawable->getFace(face_idx); - if (face) - { - focus_point = face->getPositionAgent(); - } - } + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { // focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); } + } + } - if (focus_point.isExactlyZero()) - { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { // focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { // focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { // focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { // focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); - gViewerWindow->cursorIntersect(-1, -1, 512.f, nullptr, -1, false, false, true, true, nullptr, nullptr, nullptr, &result); + gViewerWindow->cursorIntersect(-1, -1, 512.f, nullptr, -1, false, false, true, true, nullptr, nullptr, nullptr, &result); - focus_point.set(result.getF32ptr()); - } - else - { - // focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); - } - } - } - - LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); - F32 target_distance = 16.f; - if (!focus_point.isExactlyZero()) + focus_point.set(result.getF32ptr()); + } + else + { + // focus on alt-zoom target + LLViewerRegion* region = gAgent.getRegion(); + if (region) { - target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); + focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); } + } + } - if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) - { // large shift happened, interpolate smoothly to new target distance - transition_time = 0.f; - start_distance = current_distance; - } - else if (transition_time < 1.f) - { // currently in a transition, continue interpolating - transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); - transition_time = llmin(transition_time, 1.f); + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); + } - F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; - current_distance = start_distance + (target_distance - start_distance) * t; - } - else - { // small or no change, just snap to target distance - current_distance = target_distance; - } + if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) + { // large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { // currently in a transition, continue interpolating + transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); + transition_time = llmin(transition_time, 1.f); - // convert to mm - F32 subject_distance = current_distance * 1000.f; - F32 fnumber = CameraFNumber; - F32 default_focal_length = CameraFocalLength; + F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; + current_distance = start_distance + (target_distance - start_distance) * t; + } + else + { // small or no change, just snap to target distance + current_distance = target_distance; + } - F32 fov = LLViewerCamera::getInstance()->getView(); + // convert to mm + F32 subject_distance = current_distance * 1000.f; + F32 fnumber = CameraFNumber; + F32 default_focal_length = CameraFocalLength; - const F32 default_fov = CameraFieldOfView * F_PI / 180.f; + F32 fov = LLViewerCamera::getInstance()->getView(); - // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); + const F32 default_fov = CameraFieldOfView * F_PI / 180.f; - F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); + // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); - F32 focal_length = dv / (2 * tanf(fov / 2.f)); + F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); - // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); + F32 focal_length = dv / (2 * tanf(fov / 2.f)); - // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) - // where N = fnumber - // s2 = dot distance - // s1 = subject distance - // f = focal length - // + // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); - F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); - blur_constant /= 1000.f; // convert to meters for shader - F32 magnification = focal_length / (subject_distance - focal_length); + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // - { // build diffuse+bloom+CoF - mRT->deferredLight.bindTarget(); + F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); + blur_constant /= 1000.f; // convert to meters for shader + F32 magnification = focal_length / (subject_distance - focal_length); - gDeferredCoFProgram.bind(); + { // build diffuse+bloom+CoF + mFXAAMap.bindTarget(); - gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); - gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); + gDeferredCoFProgram.bind(); - gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)dst->getWidth(), (GLfloat)dst->getHeight()); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); + gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - gDeferredCoFProgram.unbind(); - mRT->deferredLight.flush(); - } + gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)mFXAAMap.getWidth(), (GLfloat)mFXAAMap.getHeight()); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); - U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); - U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gDeferredCoFProgram.unbind(); + mFXAAMap.flush(); + } - { // perform DoF sampling at half-res (preserve alpha channel) - src->bindTarget(); - glViewport(0, 0, dof_width, dof_height); + U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); + U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); - gGL.setColorMask(true, false); + { // perform DoF sampling at half-res (preserve alpha channel) + src->bindTarget(); + glViewport(0, 0, dof_width, dof_height); - gDeferredPostProgram.bind(); - gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT); + gGL.setColorMask(true, false); - gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)dst->getWidth(), (GLfloat)dst->getHeight()); - gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredPostProgram.bind(); + gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mFXAAMap, LLTexUnit::TFO_POINT); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); + gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - gDeferredPostProgram.unbind(); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - src->flush(); - gGL.setColorMask(true, true); - } + gDeferredPostProgram.unbind(); - { // combine result based on alpha + src->flush(); + gGL.setColorMask(true, true); + } - dst->bindTarget(); - glViewport(0, 0, dst->getWidth(), dst->getHeight()); + { // combine result based on alpha - gDeferredDoFCombineProgram.bind(); - gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); - gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT); + if(dst) + { + dst->bindTarget(); + } + glViewport(0, 0, mFXAAMap.getWidth(), mFXAAMap.getHeight()); - gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)dst->getWidth(), (GLfloat)dst->getHeight()); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth()); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight()); + gDeferredDoFCombineProgram.bind(); + gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); + gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mFXAAMap, LLTexUnit::TFO_POINT); + gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth()); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight()); - gDeferredDoFCombineProgram.unbind(); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - dst->flush(); - } - } - else + gDeferredDoFCombineProgram.unbind(); + + if (dst) { - copyRenderTarget(src, dst); + dst->flush(); } } } void LLPipeline::renderFinalize() { + // Ensure changes here are propogated to relevant portions of LLGLTFPreviewTexture::render() + llassert(!gCubeSnapshot); LLVertexBuffer::unbind(); LLGLState::checkStates(); @@ -7840,21 +7830,26 @@ void LLPipeline::renderFinalize() generateExposure(&mLuminanceMap, &mExposureMap); - tonemap(&mRT->screen, &mPostMap); + LLRenderTarget* src = &mPostPingMap; + LLRenderTarget* dest = &mPostPongMap; - applyCAS(&mPostMap, &mRT->screen); - - generateSMAABuffers(&mRT->screen); + static LLCachedControl<bool> render_cas(gSavedSettings, "RenderCAS", true); + if (render_cas && gCASProgram.isComplete()) + { + tonemap(&mRT->screen, &mRT->deferredLight, false); // Must output to 16F buffer when passing to CAS or banding occurs - gammaCorrect(&mRT->screen, &mPostMap); + applyCAS(&mRT->deferredLight, dest); // Gamma corrects after sharpening + std::swap(src, dest); + } + else + { + tonemap(&mRT->screen, dest); + std::swap(src, dest); + } LLVertexBuffer::unbind(); - applySMAA(&mPostMap, &mRT->screen); - - generateGlow(&mRT->screen); - - combineGlow(&mRT->screen, &mPostMap); + generateGlow(src); gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; @@ -7862,13 +7857,30 @@ void LLPipeline::renderFinalize() gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - renderDoF(&mPostMap, &mRT->screen); + bool smaa_enabled = RenderFSAAType == 2 && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); + bool fxaa_enabled = RenderFSAAType == 1 && mFXAAMap.isComplete(); + bool dof_enabled = RenderDepthOfField && + (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()); + if(dof_enabled) // DoF Combines Glow + { + LLRenderTarget* dof_dest = (smaa_enabled || fxaa_enabled) ? dest : nullptr; // render to screen if no AA enabled + renderDoF(src, dof_dest); + std::swap(src, dof_dest); + } - LLRenderTarget* finalBuffer = &mRT->screen; - if (RenderFSAAType == 1) + // Render to screen + if (smaa_enabled) { - applyFXAA(&mRT->screen, &mPostMap); - finalBuffer = &mPostMap; + generateSMAABuffers(src); + applySMAA(src, nullptr, !dof_enabled); + } + else if (fxaa_enabled) + { + applyFXAA(src, nullptr, !dof_enabled); + } + else if (!dof_enabled) + { + combineGlow(src, nullptr); } if (RenderBufferVisualization > -1) @@ -7879,16 +7891,16 @@ void LLPipeline::renderFinalize() case 1: case 2: case 3: - visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization); + visualizeBuffers(&mRT->deferredScreen, nullptr, RenderBufferVisualization); break; case 4: - visualizeBuffers(&mLuminanceMap, finalBuffer, 0); + visualizeBuffers(&mLuminanceMap, nullptr, 0); break; case 5: { if (RenderFSAAType > 0) { - visualizeBuffers(&mFXAAMap, finalBuffer, 0); + visualizeBuffers(&mFXAAMap, nullptr, 0); } break; } @@ -7896,7 +7908,7 @@ void LLPipeline::renderFinalize() { if (RenderFSAAType == 2) { - visualizeBuffers(&mSMAABlendBuffer, finalBuffer, 0); + visualizeBuffers(&mSMAABlendBuffer, nullptr, 0); } break; } @@ -7905,24 +7917,6 @@ void LLPipeline::renderFinalize() } } - // Present the screen target. - - gDeferredPostNoDoFNoiseProgram.bind(); // Add noise as part of final render to screen pass to avoid damaging other post effects - - // Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems. - gDeferredPostNoDoFNoiseProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer); - gDeferredPostNoDoFNoiseProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - - gDeferredPostNoDoFNoiseProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)finalBuffer->getWidth(), (GLfloat)finalBuffer->getHeight()); - - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - gDeferredPostNoDoFNoiseProgram.unbind(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c69ca863e7..309665f80a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -155,13 +155,12 @@ public: void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst); void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst); void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true); - void tonemap(LLRenderTarget* src, LLRenderTarget* dst); - void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst); + void tonemap(LLRenderTarget* src, LLRenderTarget* dst, bool gamma_correct = true); void generateGlow(LLRenderTarget* src); void applyCAS(LLRenderTarget* src, LLRenderTarget* dst); - void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst); + void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst, bool combine_glow); void generateSMAABuffers(LLRenderTarget* src); - void applySMAA(LLRenderTarget* src, LLRenderTarget* dst); + void applySMAA(LLRenderTarget* src, LLRenderTarget* dst, bool combine_glow); void renderDoF(LLRenderTarget* src, LLRenderTarget* dst); void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst); void combineGlow(LLRenderTarget* src, LLRenderTarget* dst); @@ -337,8 +336,6 @@ public: // should be called just before rendering pre-water alpha objects void doWaterHaze(); - void postDeferredGammaCorrect(LLRenderTarget* screen_target); - void generateSunShadow(LLCamera& camera); LLRenderTarget* getSunShadowTarget(U32 i); LLRenderTarget* getSpotShadowTarget(U32 i); @@ -725,7 +722,8 @@ public: LLRenderTarget mLastExposure; // tonemapped and gamma corrected render ready for post - LLRenderTarget mPostMap; + LLRenderTarget mPostPingMap; + LLRenderTarget mPostPongMap; // FXAA helper target LLRenderTarget mFXAAMap; diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index e39328fdd6..0deb59cad0 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -32,24 +32,24 @@ // // Defining these makes it easier if we ever need to change our tag -#define RLV_WARNS LL_WARNS("RLV") -#define RLV_INFOS LL_INFOS("RLV") -#define RLV_DEBUGS LL_DEBUGS("RLV") -#define RLV_ENDL LL_ENDL -#define RLV_VERIFY(f) (f) +#define RLV_WARNS LL_WARNS("RLV") +#define RLV_INFOS LL_INFOS("RLV") +#define RLV_DEBUGS LL_DEBUGS("RLV") +#define RLV_ENDL LL_ENDL +#define RLV_VERIFY(f) (f) #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG // Make sure we halt execution on errors - #define RLV_ERRS LL_ERRS("RLV") + #define RLV_ERRS LL_ERRS("RLV") // Keep our asserts separate from LL's - #define RLV_ASSERT(f) if (!(f)) { RLV_ERRS << "ASSERT (" << #f << ")" << RLV_ENDL; } - #define RLV_ASSERT_DBG(f) RLV_ASSERT(f) + #define RLV_ASSERT(f) if (!(f)) { RLV_ERRS << "ASSERT (" << #f << ")" << RLV_ENDL; } + #define RLV_ASSERT_DBG(f) RLV_ASSERT(f) #else // Don't halt execution on errors in release - #define RLV_ERRS LL_WARNS("RLV") + #define RLV_ERRS LL_WARNS("RLV") // We don't want to check assertions in release builds #ifdef RLV_DEBUG - #define RLV_ASSERT(f) RLV_VERIFY(f) + #define RLV_ASSERT(f) RLV_VERIFY(f) #define RLV_ASSERT_DBG(f) #else #define RLV_ASSERT(f) @@ -142,9 +142,9 @@ namespace Rlv enum class EExceptionCheck { - Permissive, // Exception can be set by any object - Strict, // Exception must be set by all objects holding the restriction - Default, // Permissive or strict will be determined by currently enforced restrictions + Permissive, // Exception can be set by any object + Strict, // Exception must be set by all objects holding the restriction + Default, // Permissive or strict will be determined by currently enforced restrictions }; // Replace&remove in c++23 diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index f241332594..f0ce35b816 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -49,12 +49,12 @@ namespace Rlv enum EBehaviourFlags : uint32_t { // General behaviour flags - Strict = 0x0001, // Behaviour has a "_sec" version - Synonym = 0x0002, // Behaviour is a synonym of another - Extended = 0x0004, // Behaviour is part of the RLVa extended command set - Experimental = 0x0008, // Behaviour is part of the RLVa experimental command set - Blocked = 0x0010, // Behaviour is blocked - Deprecated = 0x0020, // Behaviour is deprecated + Strict = 0x0001, // Behaviour has a "_sec" version + Synonym = 0x0002, // Behaviour is a synonym of another + Extended = 0x0004, // Behaviour is part of the RLVa extended command set + Experimental = 0x0008, // Behaviour is part of the RLVa experimental command set + Blocked = 0x0010, // Behaviour is blocked + Deprecated = 0x0020, // Behaviour is deprecated MaskGeneral = 0x0FFF, // Force-wear specific flags @@ -175,7 +175,7 @@ namespace Rlv template<EBehaviour templBhvr> using ReplyHandler = CommandHandler<EParamType::Reply, templBhvr>; // List of shared handlers - using VersionReplyHandler = ReplyHandler<EBehaviour::Version>; // Shared between @version and @versionnew + using VersionReplyHandler = ReplyHandler<EBehaviour::Version>; // Shared between @version and @versionnew // // CommandProcessor - Templated glue class that brings BehaviourInfo, CommandHandlerBaseImpl and CommandHandler together diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index e81ff7f343..610cffb84a 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -924,6 +924,19 @@ </combo_box> <!-- End of mirror settings --> <!-- Sharpening Settings --> + <check_box + control_name="RenderCAS" + height="16" + initial_value="false" + label="Sharpening" + layout="topleft" + left="420" + name="Sharpening" + top_delta="24" + width="240"> + <check_box.commit_callback + function="Pref.RenderOptionUpdate" /> + </check_box> <slider control_name="RenderCASSharpness" decimal_digits="1" @@ -931,7 +944,7 @@ height="16" increment="0.1" initial_value="160" - label="Sharpening:" + label="Sharpening Strength:" label_width="145" layout="topleft" left="420" |