diff options
author | Dave Parks <davep@lindenlab.com> | 2023-03-29 13:24:07 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2023-03-29 13:24:07 -0500 |
commit | b130831106d058f0be5414a9a3bcaa99636c7bc0 (patch) | |
tree | f83e82760c4b3a3eeb7186439c8b45d21120ef6e /indra | |
parent | 4f651bceabc721c9c05e58c74583373ec5d9bcba (diff) |
DRTVWR-559 Dynamic exposure followup -- stochastic sampling, weight based on luminance and distance to center of screen, rebalance night, don't rely on blending not clamping R16F.
Diffstat (limited to 'indra')
6 files changed, 82 insertions, 54 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl index d0269735fd..689929fe38 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl @@ -31,12 +31,22 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D emissiveRect; +uniform sampler2D exposureMap; + uniform float dt; +uniform vec2 noiseVec; + +// calculate luminance the same way LLColor4::calcHSL does +float lum(vec3 col) +{ + float mx = max(max(col.r, col.g), col.b); + float mn = min(min(col.r, col.g), col.b); + return (mx + mn) * 0.5; +} void main() { - int samples = 16; - float step = 1.0/(samples-4); + float step = 1.0/32.0; float start = step; float end = 1.0-step; @@ -45,23 +55,38 @@ void main() vec3 col; + vec2 nz = noiseVec * step * 0.5; + 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 + texture(emissiveRect, tc).rgb; + vec2 tc = vec2(x,y) + nz; + vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb; + float L = max(lum(c), 0.25); + + float d = length(vec2(0.5)-tc); + d = 1.0-d; + d *= d; + d *= d; + d *= d; + L *= d; + + w += L; + + col += c * L; } } 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; + float L = lum(col); + + float s = clamp(0.1/L, 0.5, 4.0); + + float prev = texture(exposureMap, vec2(0.5,0.5)).r; + s = mix(prev, s, min(dt*2.0, 0.04)); - frag_color = vec4(lum, lum, lum, dt); + frag_color = vec4(s, s, s, dt); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 834cf9dc43..4ac1ff9368 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -108,9 +108,8 @@ uniform float gamma; vec3 toneMap(vec3 color) { - float exp_sample = texture(exposureMap, vec2(0.5,0.5)).r; + float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - float exp_scale = clamp(0.1/exp_sample, 0.5, 8.0); color *= exposure * exp_scale; #ifdef TONEMAP_ACES_NARKOWICZ diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 08fbc4bce8..fc6291d438 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -91,7 +91,7 @@ void main() vary_LightNormPosDot = rel_pos_lightnorm_dot; // Initialize temp variables - vec3 sunlight = (sun_up_factor == 1) ? sunlight_color*2.0 : moonlight_color*0.5; + vec3 sunlight = (sun_up_factor == 1) ? sunlight_color*2.0 : moonlight_color*0.75; // Sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl index 7129718ff8..0d3dbf85e2 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl @@ -63,7 +63,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou vec3 rel_pos_norm = normalize(rel_pos); float rel_pos_len = length(rel_pos); float scale = 2.0; - vec3 sunlight = (sun_up_factor == 1) ? sunlight_color * scale: moonlight_color/scale; + vec3 sunlight = (sun_up_factor == 1) ? sunlight_color * scale: moonlight_color*0.75; // sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index da8c46de83..eaec698f84 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -116,27 +116,7 @@ #include "llenvironment.h" #include "llsettingsvo.h" -#ifdef _DEBUG -// Debug indices is disabled for now for debug performance - djs 4/24/02 -//#define DEBUG_INDICES -#else -//#define DEBUG_INDICES -#endif - -// Expensive and currently broken -// -#define MATERIALS_IN_REFLECTIONS 0 - -// NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml -// NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables. -// const S32 WATER_REFLECT_NONE_WATER_OPAQUE = -2; - //const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1; - //const S32 WATER_REFLECT_MINIMAL = 0; -// const S32 WATER_REFLECT_TERRAIN = 1; - //const S32 WATER_REFLECT_STATIC_OBJECTS = 2; - //const S32 WATER_REFLECT_AVATARS = 3; - //const S32 WATER_REFLECT_EVERYTHING = 4; - +extern BOOL gSnapshot; bool gShiftFrame = false; //cached settings @@ -851,11 +831,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) 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")) { @@ -1086,8 +1061,6 @@ void LLPipeline::releaseGLBuffers() mSceneMap.release(); - mExposureMap.release(); - mPostMap.release(); for (U32 i = 0; i < 3; i++) @@ -1110,6 +1083,10 @@ void LLPipeline::releaseLUTBuffers() } mPbrBrdfLut.release(); + + mExposureMap.release(); + mLastExposure.release(); + } void LLPipeline::releaseShadowBuffers() @@ -1286,6 +1263,13 @@ void LLPipeline::createLUTBuffers() gDeferredGenBrdfLutProgram.unbind(); mPbrBrdfLut.flush(); + + mExposureMap.allocate(1, 1, GL_R16F); + mExposureMap.bindTarget(); + mExposureMap.clear(); + mExposureMap.flush(); + + mLastExposure.allocate(1, 1, GL_R16F); } @@ -7407,30 +7391,50 @@ void LLPipeline::renderFinalize() // exposure sample { LL_PROFILE_GPU_ZONE("exposure sample"); + + { + // copy last frame's exposure into mLastExposure + mLastExposure.bindTarget(); + gCopyProgram.bind(); + gGL.getTexUnit(0)->bind(&mExposureMap); + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + mLastExposure.flush(); + } + + 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()); + channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); if (channel > -1) { screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT); } - channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, screenTarget()->getUsage()); + channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); if (channel > -1) { - mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + mGlow[1].bindTexture(0, channel); + } + + channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP); + if (channel > -1) + { + mLastExposure.bindTexture(0, channel); } static LLStaticHashedString dt("dt"); + static LLStaticHashedString noiseVec("noiseVec"); gExposureProgram.uniform1f(dt, gFrameIntervalSeconds); - + gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0); + mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -7562,9 +7566,8 @@ void LLPipeline::renderFinalize() 2.f / width * scale_x, 2.f / height * scale_y); { - // at this point we should pointed at the backbuffer - llassert(LLRenderTarget::sCurFBO == 0); - + // at this point we should pointed at the backbuffer (or a snapshot render target) + llassert(gSnapshot || LLRenderTarget::sCurFBO == 0); 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); @@ -7577,8 +7580,8 @@ void LLPipeline::renderFinalize() } else { - // at this point we should pointed at the backbuffer - llassert(LLRenderTarget::sCurFBO == 0); + // at this point we should pointed at the backbuffer (or a snapshot render target) + llassert(gSnapshot || LLRenderTarget::sCurFBO == 0); LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 19d511c2c4..eb30c85993 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -679,6 +679,7 @@ public: // exposure map for getting average color in scene LLRenderTarget mExposureMap; + LLRenderTarget mLastExposure; // tonemapped and gamma corrected render ready for post LLRenderTarget mPostMap; |