diff options
author | Dave Parks <davep@lindenlab.com> | 2023-03-28 14:30:59 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2023-03-28 14:30:59 -0500 |
commit | 10f66c05190585e9de2e85831712323c297d81c4 (patch) | |
tree | 7ca97a8f67aea3714a88e4e5016be12a0d1f62e5 /indra/newview | |
parent | 9bf08f553aa59122a606487f1b28bd6083d9f966 (diff) |
DRTVWR-559 Dynamically adjust exposure.
Diffstat (limited to 'indra/newview')
9 files changed, 156 insertions, 16 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl new file mode 100644 index 0000000000..6994a20b79 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl @@ -0,0 +1,66 @@ +/** + * @file exposureF.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, 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$ + */ + +#extension GL_ARB_texture_rectangle : enable + +/*[EXTRA_CODE_HERE]*/ + +out vec4 frag_color; + +uniform sampler2D diffuseRect; +uniform float dt; + +void main() +{ + int samples = 16; + float step = 1.0/(samples-4); + + float start = step; + float end = 1.0-step; + + float w = 0.0; + + vec3 col; + + for (float x = start; x <= end; x += step) + { + for (float y = start; y <= end; y += step) + { + vec2 tc = vec2(x,y); + w += 1.0; + col += texture(diffuseRect, tc).rgb; + } + } + + col /= w; + + // calculate luminance the same way LLColor4::calcHSL does + float mx = max(max(col.r, col.g), col.b); + float mn = min(min(col.r, col.g), col.b); + float lum = (mx + mn) * 0.5; + + frag_color = vec4(lum, lum, lum, dt); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 87324bca7f..87725affe7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -35,6 +35,7 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D emissiveRect; +uniform sampler2D exposureMap; uniform vec2 screen_res; VARYING vec2 vary_fragcoord; @@ -107,7 +108,10 @@ uniform float gamma; vec3 toneMap(vec3 color) { - color *= exposure; + float exp_sample = texture(exposureMap, vec2(0.5,0.5)).r; + + float exp_scale = clamp(0.1/exp_sample, 0.4, 8.0); + color *= exposure * exp_scale; #ifdef TONEMAP_ACES_NARKOWICZ color = toneMapACES_Narkowicz(color); @@ -190,6 +194,9 @@ void main() vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); diff.rgb += nz*0.003; //diff.rgb = nz; + + //float exp_sample = texture(exposureMap, vec2(0.5,0.5)).r; + //diff.g = exp_sample; frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl index 4d24b4de9a..8b4cac3e64 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl @@ -33,6 +33,6 @@ void main() { //transform vertex vec4 pos = vec4(position.xyz, 1.0); - gl_Position = pos; + gl_Position = pos; vary_fragcoord = (pos.xy*0.5+0.5); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index f028b303f7..0090155e5c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -91,10 +91,8 @@ void main() vary_LightNormPosDot = rel_pos_lightnorm_dot; // Initialize temp variables - vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; - float scale = cube_snapshot*0.75+1; - sunlight *= scale; - + vec3 sunlight = (sun_up_factor == 1) ? sunlight_color*2.0 : moonlight_color; + // Sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl index 55e1411be2..f9a1f5e4d6 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl @@ -62,7 +62,9 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou vec3 rel_pos_norm = normalize(rel_pos); float rel_pos_len = length(rel_pos); - vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; + float scale = sun_up_factor + 1.0; + vec3 sunlight = (sun_up_factor == 1) ? sunlight_color: moonlight_color; + sunlight *= scale; // sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes @@ -140,7 +142,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou // fudge sunlit and amblit to get consistent lighting compared to legacy // midday before PBR was a thing - sunlit = sunlight.rgb * 0.7; + sunlit = sunlight.rgb / scale; amblit = tmpAmbient.rgb * 0.25; additive *= vec3(1.0 - combined_haze); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 7790013f01..93f4d22ff8 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -187,6 +187,7 @@ LLGLSLShader gDeferredPostProgram; LLGLSLShader gDeferredCoFProgram; LLGLSLShader gDeferredDoFCombineProgram; LLGLSLShader gDeferredPostGammaCorrectProgram; +LLGLSLShader gExposureProgram; LLGLSLShader gFXAAProgram; LLGLSLShader gDeferredPostNoDoFProgram; LLGLSLShader gDeferredWLSkyProgram; @@ -1000,6 +1001,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPostProgram.unload(); gDeferredCoFProgram.unload(); gDeferredDoFCombineProgram.unload(); + gExposureProgram.unload(); gDeferredPostGammaCorrectProgram.unload(); gFXAAProgram.unload(); gDeferredWLSkyProgram.unload(); @@ -2518,6 +2520,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; } + if (success) + { + gExposureProgram.mName = "Exposure"; + gExposureProgram.mFeatures.hasSrgb = true; + gExposureProgram.mFeatures.isDeferred = true; + gExposureProgram.mShaderFiles.clear(); + gExposureProgram.clearPermutations(); + gExposureProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gExposureProgram.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER)); + gExposureProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gExposureProgram.createShader(NULL, NULL); + llassert(success); + } + if (success) { gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 867413b6c9..6fb2bc3fec 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -235,6 +235,7 @@ extern LLGLSLShader gDeferredDoFCombineProgram; extern LLGLSLShader gFXAAProgram; extern LLGLSLShader gDeferredPostNoDoFProgram; extern LLGLSLShader gDeferredPostGammaCorrectProgram; +extern LLGLSLShader gExposureProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAvatarAlphaShadowProgram; extern LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7a5443825d..7b72d7f987 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -849,6 +849,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mSceneMap.allocate(resX, resY, GL_RGB, true); } + mPostMap.allocate(resX, resY, GL_RGBA); + + mExposureMap.allocate(1, 1, GL_R16F); + mExposureMap.bindTarget(); + mExposureMap.clear(); + mExposureMap.flush(); + //HACK make screenbuffer allocations start failing after 30 seconds if (gSavedSettings.getBOOL("SimulateFBOFailure")) { @@ -1079,6 +1086,10 @@ void LLPipeline::releaseGLBuffers() mSceneMap.release(); + mExposureMap.release(); + + mPostMap.release(); + for (U32 i = 0; i < 3; i++) { mGlow[i].release(); @@ -7393,7 +7404,36 @@ void LLPipeline::renderFinalize() dst.flush(); } - screenTarget()->bindTarget(); + // exposure sample + { + LL_PROFILE_GPU_ZONE("exposure sample"); + mExposureMap.bindTarget(); + + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + gExposureProgram.bind(); + + S32 channel = 0; + channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage()); + if (channel > -1) + { + screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT); + } + + static LLStaticHashedString dt("dt"); + gExposureProgram.uniform1f(dt, gFrameIntervalSeconds); + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage()); + gExposureProgram.unbind(); + mExposureMap.flush(); + } + + mPostMap.bindTarget(); // gamma correct lighting { @@ -7420,6 +7460,12 @@ void LLPipeline::renderFinalize() mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); } + channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP, mExposureMap.getUsage()); + if (channel > -1) + { + mExposureMap.bindTexture(0, channel); + } + gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight()); static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f); @@ -7437,7 +7483,7 @@ void LLPipeline::renderFinalize() gDeferredPostGammaCorrectProgram.unbind(); } - screenTarget()->flush(); + mPostMap.flush(); LLVertexBuffer::unbind(); } @@ -7466,10 +7512,10 @@ void LLPipeline::renderFinalize() shader->bind(); shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); - channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage()); + channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage()); if (channel > -1) { - screenTarget()->bindTexture(0, channel); + mPostMap.bindTexture(0, channel); } { @@ -7480,7 +7526,7 @@ void LLPipeline::renderFinalize() gGL.flush(); - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage()); + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage()); shader->unbind(); mRT->fxaaBuffer.flush(); @@ -7535,7 +7581,7 @@ void LLPipeline::renderFinalize() S32 screen_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DIFFUSE); S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); - gGL.getTexUnit(screen_channel)->bind(screenTarget()); + gGL.getTexUnit(screen_channel)->bind(&mPostMap); gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true); gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 4cefb719fd..19d511c2c4 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -300,8 +300,6 @@ public: void bindReflectionProbes(LLGLSLShader& shader); void unbindReflectionProbes(LLGLSLShader& shader); - - void renderDeferredLighting(); void postDeferredGammaCorrect(LLRenderTarget* screen_target); @@ -679,6 +677,12 @@ public: // for use by SSR LLRenderTarget mSceneMap; + // exposure map for getting average color in scene + LLRenderTarget mExposureMap; + + // tonemapped and gamma corrected render ready for post + LLRenderTarget mPostMap; + LLCullResult mSky; LLCullResult mReflectedObjects; LLCullResult mRefractedObjects; |