diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 4ddccc06b0ca7547aab36921d57da90542b4756a..f923fc86d0e967baf7776910fe758f27f9c827ff 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1307,8 +1307,9 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("warmthAmount"); mReservedUniforms.push_back("glowStrength"); mReservedUniforms.push_back("glowDelta"); + mReservedUniforms.push_back("glowNoiseMap"); - llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_DELTA+1); + llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_NOISE_MAP+1); mReservedUniforms.push_back("minimum_alpha"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index ff8a795a1eb6276485458afd070734c7cc2b5b2d..8af82c64b152aafc8a6d7656a62588d5c70ca772 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -131,6 +131,7 @@ class LLShaderMgr GLOW_WARMTH_AMOUNT, // "warmthAmount" GLOW_STRENGTH, // "glowStrength" GLOW_DELTA, // "glowDelta" + GLOW_NOISE_MAP, // "glowNoiseMap" MINIMUM_ALPHA, // "minimum_alpha" EMISSIVE_BRIGHTNESS, // "emissive_brightness" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 68c67f33bc93373932fb5128ceb9a2b19e08b5d8..fb4dbc2cc0b413a8b4417bdad9a62f590805d450 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9839,6 +9839,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderPostProcessingHDR</key> + <map> + <key>Comment</key> + <string>Enable HDR for post processing buffer</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderMaxOpenGLVersion</key> <map> <key>Comment</key> @@ -10654,6 +10665,17 @@ <key>Value</key> <integer>9</integer> </map> + <key>RenderGlowHDR</key> + <map> + <key>Comment</key> + <string>Enable HDR for glow map</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderGlowStrength</key> <map> <key>Comment</key> @@ -10702,6 +10724,17 @@ <key>Value</key> <real>1.3</real> </map> + <key>RenderGlowNoise</key> + <map> + <key>Comment</key> + <string>Enables glow noise (dithering). Reduces banding from glow in certain cases.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <real>1</real> + </map> <key>DisableAllRenderTypes</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl index 7a5e14566bb7d09d6fdb89526d42ee2c747cf452..b5437d43d2869789e8bf23d469cc0b9a04580573 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -28,6 +28,10 @@ out vec4 frag_color; uniform sampler2D diffuseMap; +#if HAS_NOISE +uniform sampler2D glowNoiseMap; +uniform vec2 screen_res; +#endif uniform float minLuminance; uniform float maxExtractAlpha; uniform vec3 lumWeights; @@ -44,7 +48,16 @@ void main() float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) ); float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) ); - frag_color.rgb = col.rgb; +#if HAS_NOISE + float TRUE_NOISE_RES = 128; // See mTrueNoiseMap + // *NOTE: Usually this is vary_fragcoord not vary_texcoord0, but glow extraction is in screen space + vec3 glow_noise = texture(glowNoiseMap, vary_texcoord0.xy * (screen_res / TRUE_NOISE_RES)).xyz; + // Dithering. Reduces banding effects in the reduced precision glow buffer. + float NOISE_DEPTH = 64.0; + col.rgb += glow_noise / NOISE_DEPTH; + col.rgb = max(col.rgb, vec3(0)); +#endif + frag_color.rgb = col.rgb; frag_color.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 25f9ced41425de302b82c9b016a5bf1c6079667e..77678538ee0f5d389b560aadff3fc802824bb8be 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -720,6 +720,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderPostProcessingHDR", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); @@ -727,6 +728,8 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlowHDR", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlowNoise", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index d6022e0f24218d962f491a6684e3b1505b638333..182438c1c3027303061ea4e8e8639ac4d46c6a4a 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -910,11 +910,20 @@ BOOL LLViewerShaderMgr::loadShadersEffects() if (success) { - gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; + const bool use_glow_noise = gSavedSettings.getBOOL("RenderGlowNoise"); + const std::string glow_noise_label = use_glow_noise ? " (+Noise)" : ""; + + gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str()); gGlowExtractProgram.mShaderFiles.clear(); gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER)); gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER)); gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; + + if (use_glow_noise) + { + gGlowExtractProgram.addPermutation("HAS_NOISE", "1"); + } + success = gGlowExtractProgram.createShader(NULL, NULL); if (!success) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 16d6f08d5ac00b1b971045b1ca6af72bb270e7f7..175e559569b102c61990a82e947762811648d0ef 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -170,6 +170,7 @@ S32 LLPipeline::RenderGlowResolutionPow; S32 LLPipeline::RenderGlowIterations; F32 LLPipeline::RenderGlowWidth; F32 LLPipeline::RenderGlowStrength; +bool LLPipeline::RenderGlowNoise; bool LLPipeline::RenderDepthOfField; bool LLPipeline::RenderDepthOfFieldInEditMode; bool LLPipeline::RenderFocusPointLocked; @@ -543,6 +544,7 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderGlowIterations"); connectRefreshCachedSettingsSafe("RenderGlowWidth"); connectRefreshCachedSettingsSafe("RenderGlowStrength"); + connectRefreshCachedSettingsSafe("RenderGlowNoise"); connectRefreshCachedSettingsSafe("RenderDepthOfField"); connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode"); connectRefreshCachedSettingsSafe("CameraFocusTransitionTime"); @@ -1078,6 +1080,7 @@ void LLPipeline::refreshCachedSettings() RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations"); RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth"); RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength"); + RenderGlowNoise = gSavedSettings.getBOOL("RenderGlowNoise"); RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField"); RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode"); RenderFocusPointLocked = gSavedSettings.getBOOL("RenderFocusPointLocked"); @@ -1260,9 +1263,11 @@ void LLPipeline::createGLBuffers() // allocate screen space glow buffers const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); + const bool glow_hdr = gSavedSettings.getBOOL("RenderGlowHDR"); + const U32 glow_color_fmt = glow_hdr ? GL_RGBA16F : GL_RGBA; for (U32 i = 0; i < 3; i++) { - mGlow[i].allocate(512, glow_res, GL_RGBA); + mGlow[i].allocate(512, glow_res, glow_color_fmt); } allocateScreenBuffer(resX, resY); @@ -6989,6 +6994,19 @@ void LLPipeline::generateGlow(LLRenderTarget* src) warmthWeights.mV[2]); gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); + if (RenderGlowNoise) + { + S32 channel = gGlowExtractProgram.enableTexture(LLShaderMgr::GLOW_NOISE_MAP); + if (channel > -1) + { + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + gGlowExtractProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, + mGlow[2].getWidth(), + mGlow[2].getHeight()); + } + { LLGLEnable blend_on(GL_BLEND); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 39f8f29c57adf47d13ee182e94f0873e2e4d1b3b..ee6ab5c1757d21d73032a9d5d9a7f410b15e334a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -991,6 +991,7 @@ class LLPipeline static S32 RenderGlowIterations; static F32 RenderGlowWidth; static F32 RenderGlowStrength; + static bool RenderGlowNoise; static bool RenderDepthOfField; static bool RenderDepthOfFieldInEditMode; static bool RenderFocusPointLocked;