From a57d82b3a9337eb4ac00340e80749ac97392e03e Mon Sep 17 00:00:00 2001 From: Rye Date: Fri, 1 Nov 2024 03:30:23 -0400 Subject: Eliminate reduntant copies and full screen passes from post process effect chain --- indra/newview/CMakeLists.txt | 1 + indra/newview/app_settings/settings.xml | 11 + .../app_settings/shaders/class1/deferred/CASF.glsl | 59 ++ .../class1/deferred/postDeferredGammaCorrect.glsl | 58 -- .../class1/deferred/postDeferredNoDoFF.glsl | 47 -- .../class1/deferred/postDeferredTonemap.glsl | 63 +- indra/newview/featuretable.txt | 10 +- indra/newview/featuretable_linux.txt | 14 +- indra/newview/featuretable_mac.txt | 10 +- indra/newview/llgltfmaterialpreviewmgr.cpp | 18 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 59 +- indra/newview/llviewershadermgr.h | 3 +- indra/newview/pipeline.cpp | 637 ++++++++++----------- indra/newview/pipeline.h | 8 +- .../en/floater_preferences_graphics_advanced.xml | 15 +- 16 files changed, 539 insertions(+), 475 deletions(-) delete mode 100644 indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl 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 @@ Value 00000000-0000-0000-0000-000000000000 + RenderCAS + + Comment + Use Contrast Adaptive Sharpening post process effect + Persist + 0 + Type + Boolean + Value + 1 + RenderCASSharpness Comment 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: +// +// 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/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..07384ebe9b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -33,57 +33,10 @@ uniform sampler2D depthMap; uniform vec2 screen_res; in vec2 vary_fragcoord; -//================================= -// borrowed noise from: -// -// 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: +// +// 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/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..f473afb74c 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -523,12 +523,16 @@ 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); + + LLRenderTarget* src = &gPipeline.mPostPingMap; + LLRenderTarget* dst = &gPipeline.mPostPongMap; + gPipeline.tonemap(&screen, dst); + std::swap(src, dst); + LLVertexBuffer::unbind(); - gPipeline.generateGlow(&gPipeline.mPostMap); - gPipeline.combineGlow(&gPipeline.mPostMap, &screen); - gPipeline.renderDoF(&screen, &gPipeline.mPostMap); - gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); + gPipeline.generateGlow(src); + gPipeline.combineGlow(src, dst); + std::swap(src, dst); // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame) gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); @@ -538,9 +542,11 @@ bool LLGLTFPreviewTexture::render() 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_DIFFUSE, src); gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true); + gDeferredPostNoDoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); + { LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); gPipeline.mScreenTriangleVB->setBuffer(); 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..52fd75f672 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -198,6 +198,7 @@ LLGLSLShader gDeferredPostTonemapProgram; LLGLSLShader gNoPostTonemapProgram; LLGLSLShader gDeferredPostGammaCorrectProgram; LLGLSLShader gLegacyPostGammaCorrectProgram; +LLGLSLShader gNoPostGammaCorrectProgram; LLGLSLShader gExposureProgram; LLGLSLShader gExposureProgramNoFade; LLGLSLShader gLuminanceProgram; @@ -206,6 +207,7 @@ LLGLSLShader gSMAAEdgeDetectProgram[4]; LLGLSLShader gSMAABlendWeightsProgram[4]; LLGLSLShader gSMAANeighborhoodBlendProgram[4]; LLGLSLShader gCASProgram; +LLGLSLShader gCASLegacyGammaProgram; LLGLSLShader gDeferredPostNoDoFProgram; LLGLSLShader gDeferredPostNoDoFNoiseProgram; LLGLSLShader gDeferredWLSkyProgram; @@ -434,8 +436,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 +2328,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,14 +2344,30 @@ 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); } + 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"; @@ -2355,6 +2375,7 @@ bool LLViewerShaderMgr::loadShadersDeferred() 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 +2390,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)); @@ -2498,6 +2520,19 @@ bool LLViewerShaderMgr::loadShadersDeferred() gCASProgram.createShader(); } + 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"; @@ -2546,22 +2581,6 @@ bool LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - 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"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e654967c46..afc29e6fd2 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -251,10 +251,11 @@ extern LLGLSLShader gSMAAEdgeDetectProgram[4]; extern LLGLSLShader gSMAABlendWeightsProgram[4]; extern LLGLSLShader gSMAANeighborhoodBlendProgram[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..541208b133 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 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(); @@ -7047,7 +7055,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool extern LLPointer 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 +7072,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 exposure(gSavedSettings, "RenderExposure", 1.f); @@ -7085,47 +7101,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 tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U); - shader.uniform1i(tonemap_type, tonemap_type_setting); + shader->uniform1i(tonemap_type, tonemap_type_setting); static LLCachedControl 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 buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false); - static LLCachedControl 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 +7258,10 @@ void LLPipeline::generateGlow(LLRenderTarget* src) void LLPipeline::applyCAS(LLRenderTarget* src, LLRenderTarget* dst) { static LLCachedControl cas_sharpness(gSavedSettings, "RenderCASSharpness", 0.4f); - if (cas_sharpness == 0.0f || !gCASProgram.isComplete()) - { - gPipeline.copyRenderTarget(src, dst); - return; - } + static LLCachedControl 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(); @@ -7314,88 +7299,78 @@ void LLPipeline::applyCAS(LLRenderTarget* src, LLRenderTarget* dst) void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) { - { - llassert(!gCubeSnapshot); - bool multisample = RenderFSAAType == 1 && mFXAAMap.isComplete(); - LLGLSLShader* shader = &gGlowCombineProgram; - - // Present everything. - if (multisample) - { - LL_PROFILE_GPU_ZONE("aa"); - S32 width = dst->getWidth(); - S32 height = dst->getHeight(); + llassert(!gCubeSnapshot); + LLGLSLShader* shader = &gGlowCombineProgram; - // bake out texture2D with RGBL for FXAA shader - mFXAAMap.bindTarget(); - mFXAAMap.invalidate(GL_COLOR_BUFFER_BIT); + LL_PROFILE_GPU_ZONE("aa"); + S32 width = dst->getWidth(); + S32 height = dst->getHeight(); - shader = &gGlowCombineFXAAProgram; - shader->bind(); + // bake out texture2D with RGBL for FXAA shader + mFXAAMap.bindTarget(); + mFXAAMap.invalidate(GL_COLOR_BUFFER_BIT); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); - if (channel > -1) - { - src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } + shader = &gGlowCombineFXAAProgram; + shader->bind(); - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); + if (channel > -1) + { + src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); - shader->unbind(); + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - mFXAAMap.flush(); + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); + shader->unbind(); - dst->bindTarget(); + mFXAAMap.flush(); - static LLCachedControl aa_quality(gSavedSettings, "RenderFSAASamples", 0U); - U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); + dst->bindTarget(); - shader = &gFXAAProgram[fsaa_quality]; - shader->bind(); + static LLCachedControl aa_quality(gSavedSettings, "RenderFSAASamples", 0U); + U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); - channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAAMap.getUsage()); - if (channel > -1) - { - mFXAAMap.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } + shader = &gFXAAProgram[fsaa_quality]; + shader->bind(); - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAAMap.getUsage()); + if (channel > -1) + { + mFXAAMap.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - 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); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - { - 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); + 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); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + { + 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); - shader->unbind(); - dst->flush(); - } - else { - copyRenderTarget(src, dst); - } + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } + + shader->unbind(); + dst->flush(); } void LLPipeline::generateSMAABuffers(LLRenderTarget* src) @@ -7520,63 +7495,54 @@ void LLPipeline::generateSMAABuffers(LLRenderTarget* src) void LLPipeline::applySMAA(LLRenderTarget* src, LLRenderTarget* dst) { llassert(!gCubeSnapshot); - bool multisample = RenderFSAAType == 2 && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); - // Present everything. - if (multisample) - { - LL_PROFILE_GPU_ZONE("aa"); - static LLCachedControl aa_quality(gSavedSettings, "RenderFSAASamples", 0U); - U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); + LL_PROFILE_GPU_ZONE("aa"); + static LLCachedControl 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 use_sample(gSavedSettings, "RenderSMAAUseSample", false); - //static LLCachedControl use_stencil(gSavedSettings, "RenderSMAAUseStencil", true); + static LLCachedControl use_sample(gSavedSettings, "RenderSMAAUseSample", false); + //static LLCachedControl use_stencil(gSavedSettings, "RenderSMAAUseStencil", true); - { - //LLGLDisable stencil(GL_STENCIL_TEST); + { + //LLGLDisable stencil(GL_STENCIL_TEST); - // Bind setup: - LLRenderTarget* bound_target = dst; - LLGLSLShader& blend_shader = gSMAANeighborhoodBlendProgram[fsaa_quality]; + // Bind setup: + LLRenderTarget* bound_target = dst; + LLGLSLShader& blend_shader = gSMAANeighborhoodBlendProgram[fsaa_quality]; - bound_target->bindTarget(); - bound_target->invalidate(GL_COLOR_BUFFER_BIT); + bound_target->bindTarget(); + bound_target->invalidate(GL_COLOR_BUFFER_BIT); - blend_shader.bind(); - blend_shader.uniform4fv(sSmaaRTMetrics, 1, rt_metrics); + 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); - } + 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); + } - S32 blend_channel = blend_shader.enableTexture(LLShaderMgr::SMAA_BLEND_TEX); - if (blend_channel > -1) - { - mSMAABlendBuffer.bindTexture(0, blend_channel, LLTexUnit::TFO_BILINEAR); - } + 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); - bound_target->flush(); - blend_shader.unbind(); - gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(blend_channel)->unbindFast(LLTexUnit::TT_TEXTURE); - } - } - else - { - copyRenderTarget(src, dst); + bound_target->flush(); + blend_shader.unbind(); + gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(blend_channel)->unbindFast(LLTexUnit::TT_TEXTURE); } } @@ -7623,198 +7589,186 @@ void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) { - { - bool dof_enabled = - (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && - RenderDepthOfField && - !gCubeSnapshot; - - gViewerWindow->setup3DViewport(); - - if (dof_enabled) - { - LL_PROFILE_GPU_ZONE("dof"); - LLGLDisable blend(GL_BLEND); + gViewerWindow->setup3DViewport(); - // depth of field focal plane calculations - static F32 current_distance = 16.f; - static F32 start_distance = 16.f; - static F32 transition_time = 1.f; + LL_PROFILE_GPU_ZONE("dof"); + LLGLDisable blend(GL_BLEND); - LLVector3 focus_point; + // depth of field focal plane calculations + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; - 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(); - } - } - } + LLVector3 focus_point; - if (focus_point.isExactlyZero()) + 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) { - 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(); + focus_point = face->getPositionAgent(); + } + } + } - gViewerWindow->cursorIntersect(-1, -1, 512.f, nullptr, -1, false, false, true, true, nullptr, nullptr, nullptr, &result); + 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(); - focus_point.set(result.getF32ptr()); - } - else - { - // focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); - } - } - } + gViewerWindow->cursorIntersect(-1, -1, 512.f, nullptr, -1, false, false, true, true, nullptr, nullptr, nullptr, &result); - 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)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); - 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)dst->getWidth(), (GLfloat)dst->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); + dst->bindTarget(); + glViewport(0, 0, dst->getWidth(), dst->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); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + 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.unbind(); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - dst->flush(); - } - } - else - { - copyRenderTarget(src, dst); - } + gDeferredDoFCombineProgram.unbind(); + + dst->flush(); } } void LLPipeline::renderFinalize() { + // Ensure changes here are propogated to relevant portions of LLGLTFPreviewTexture::render() + llassert(!gCubeSnapshot); LLVertexBuffer::unbind(); LLGLState::checkStates(); @@ -7840,21 +7794,29 @@ void LLPipeline::renderFinalize() generateExposure(&mLuminanceMap, &mExposureMap); - tonemap(&mRT->screen, &mPostMap); - - applyCAS(&mPostMap, &mRT->screen); + LLRenderTarget* src = &mPostPingMap; + LLRenderTarget* dest = &mPostPongMap; - generateSMAABuffers(&mRT->screen); + static LLCachedControl 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); + generateGlow(src); - combineGlow(&mRT->screen, &mPostMap); + combineGlow(src, dest); + std::swap(src, dest); gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; @@ -7862,13 +7824,27 @@ void LLPipeline::renderFinalize() gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - renderDoF(&mPostMap, &mRT->screen); + bool dof_enabled = + (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && + RenderDepthOfField && + !gCubeSnapshot; + if(dof_enabled) + { + renderDoF(src, dest); + std::swap(src, dest); + } + + if (RenderFSAAType == 2 && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete()) + { + generateSMAABuffers(src); + applySMAA(src, dest); + std::swap(src, dest); + } - LLRenderTarget* finalBuffer = &mRT->screen; - if (RenderFSAAType == 1) + if (RenderFSAAType == 1 && mFXAAMap.isComplete()) { - applyFXAA(&mRT->screen, &mPostMap); - finalBuffer = &mPostMap; + applyFXAA(src, dest); + std::swap(src, dest); } if (RenderBufferVisualization > -1) @@ -7879,16 +7855,16 @@ void LLPipeline::renderFinalize() case 1: case 2: case 3: - visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization); + visualizeBuffers(&mRT->deferredScreen, src, RenderBufferVisualization); break; case 4: - visualizeBuffers(&mLuminanceMap, finalBuffer, 0); + visualizeBuffers(&mLuminanceMap, src, 0); break; case 5: { if (RenderFSAAType > 0) { - visualizeBuffers(&mFXAAMap, finalBuffer, 0); + visualizeBuffers(&mFXAAMap, src, 0); } break; } @@ -7896,7 +7872,7 @@ void LLPipeline::renderFinalize() { if (RenderFSAAType == 2) { - visualizeBuffers(&mSMAABlendBuffer, finalBuffer, 0); + visualizeBuffers(&mSMAABlendBuffer, src, 0); } break; } @@ -7906,14 +7882,13 @@ 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 + gDeferredPostNoDoFProgram.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); + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src); + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - gDeferredPostNoDoFNoiseProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)finalBuffer->getWidth(), (GLfloat)finalBuffer->getHeight()); + gDeferredPostNoDoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); { LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); @@ -7921,7 +7896,7 @@ void LLPipeline::renderFinalize() mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } - gDeferredPostNoDoFNoiseProgram.unbind(); + gDeferredPostNoDoFProgram.unbind(); gGL.setSceneBlendType(LLRender::BT_ALPHA); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c69ca863e7..b76d07704c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -155,8 +155,7 @@ 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); @@ -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/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 @@ + + +