summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolalpha.cpp
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-10-10 18:53:43 -0500
committerDave Parks <davep@lindenlab.com>2022-10-10 18:53:43 -0500
commit07bca31e06e4219401f82ae04539418c65e22ea8 (patch)
treed5190e4cad4e3a70b7077e2fd3f56201dff79c5b /indra/newview/lldrawpoolalpha.cpp
parent5890f423b4ae0f372d72af413b2296e5291bfa67 (diff)
SL-18190 Fix alpha not playing nice with water surface by split LLDrawPoolAlpha into two passes, one above water, one below water, and clip against water plane. Currently brute forces two complete alpha passes, still need to cull against water plane and add support for fullbright shaders.
Diffstat (limited to 'indra/newview/lldrawpoolalpha.cpp')
-rw-r--r--indra/newview/lldrawpoolalpha.cpp36
1 files changed, 31 insertions, 5 deletions
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 8a912b00d9..0d9e83a976 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -56,6 +56,8 @@ BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
#define current_shader (LLGLSLShader::sCurBoundShaderPtr)
+LLVector4 LLDrawPoolAlpha::sWaterPlane;
+
static BOOL deferred_render = FALSE;
// minimum alpha before discarding a fragment
@@ -96,11 +98,13 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
}
// set some common parameters on the given shader to prepare for alpha rendering
-static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment)
+static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment, F32 water_sign)
{
static LLCachedControl<F32> displayGamma(gSavedSettings, "RenderDeferredDisplayGamma");
F32 gamma = displayGamma;
+ static LLStaticHashedString waterSign("waterSign");
+
// Does this deferred shader need environment uniforms set such as sun_dir, etc. ?
// NOTE: We don't actually need a gbuffer since we are doing forward rendering (for transparency) post deferred rendering
// TODO: bindDeferredShader() probably should have the updating of the environment uniforms factored out into updateShaderEnvironmentUniforms()
@@ -115,6 +119,8 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
}
shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+ shader->uniform1f(waterSign, water_sign);
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
if (LLPipeline::sImpostorRender)
{
@@ -132,7 +138,7 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
//also prepare rigged variant
if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
{
- prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment);
+ prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment, water_sign);
}
}
@@ -143,19 +149,39 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
deferred_render = TRUE;
+ F32 water_sign = 1.f;
+
+ if (getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ {
+ water_sign = -1.f;
+ }
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ water_sign *= -1.f;
+ }
+
// prepare shaders
emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
(LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
- prepare_alpha_shader(emissive_shader, true, false);
+ prepare_alpha_shader(emissive_shader, true, false, water_sign);
fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightAlphaMaskProgram;
- prepare_alpha_shader(fullbright_shader, true, true);
+ prepare_alpha_shader(fullbright_shader, true, true, water_sign);
simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
- prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
+ prepare_alpha_shader(simple_shader, false, true, water_sign); //prime simple shader (loads shadow relevant uniforms)
+
+
+ LLGLSLShader* materialShader = LLPipeline::sUnderWaterRender ? gDeferredMaterialWaterProgram : gDeferredMaterialProgram;
+ for (int i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ prepare_alpha_shader(&materialShader[i], false, false, water_sign);
+ }
+ prepare_alpha_shader(&gDeferredPBRAlphaProgram, false, false, water_sign);
// first pass, render rigged objects only and render to depth buffer
forwardRender(true);