summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2023-12-11 15:28:25 -0600
committerDave Parks <davep@lindenlab.com>2023-12-11 15:28:25 -0600
commitf3b87145775d3803306036d1e31fa39177f2600e (patch)
tree3002aba971e65a144da09344dd325f634c24cd1b
parent4024a4df3b36b55ce2f05e02218251e15a4a2286 (diff)
SL-20611 Followup -- fix for artifacts on water surface from GPUs that don't like to read from a depth buffer that is bound for writing
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl6
-rw-r--r--indra/newview/lldrawpoolwater.cpp9
-rw-r--r--indra/newview/pipeline.cpp45
-rw-r--r--indra/newview/pipeline.h2
6 files changed, 60 insertions, 19 deletions
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
index 025bcdaf3e..13619a82d3 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -35,10 +35,26 @@ float getDepth(vec2 pos_screen);
vec4 getWaterFogView(vec3 pos);
+uniform int above_water;
+
void main()
{
vec2 tc = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;
float depth = getDepth(tc.xy);
+
+ if (above_water > 0)
+ {
+ // we want to depth test when the camera is above water, but some GPUs have a hard time
+ // with depth testing against render targets that are bound for sampling in the same shader
+ // so we do it manually here
+
+ float cur_depth = vary_fragcoord.z/vary_fragcoord.w*0.5+0.5;
+ if (cur_depth > depth)
+ {
+ discard;
+ }
+ }
+
vec4 pos = getPositionWithDepth(tc, depth);
vec4 norm = texture(normalMap, tc);
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index ddb1b79681..223e55eb69 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -30,7 +30,6 @@ uniform sampler2D bumpMap;
#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
-uniform sampler2D screenDepth;
#endif
uniform vec4 fogCol;
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index f53bc2e13e..b364e454e8 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -76,7 +76,7 @@ uniform sampler2D bumpMap2;
uniform float blend_factor;
#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
-uniform sampler2D screenDepth;
+uniform sampler2D depthMap;
#endif
uniform sampler2D refTex;
@@ -210,7 +210,7 @@ void main()
#ifdef TRANSPARENT_WATER
vec4 fb = texture(screenTex, distort2);
- float depth = texture(screenDepth, distort2).r;
+ float depth = texture(depthMap, distort2).r;
vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
if (refPos.z > pos.z-0.05)
@@ -218,7 +218,7 @@ void main()
//we sampled an above water sample, don't distort
distort2 = distort;
fb = texture(screenTex, distort2);
- depth = texture(screenDepth, distort2).r;
+ depth = texture(depthMap, distort2).r;
refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
}
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 14f3142e1b..ca93815de7 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -206,7 +206,7 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
}
}
- gPipeline.bindDeferredShader(*shader);
+ gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
//bind normal map
S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
@@ -238,7 +238,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
// bind reflection texture from RenderTarget
S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
- S32 screenDepth = shader->enableTexture(LLShaderMgr::WATER_SCREENDEPTH);
F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
@@ -255,11 +254,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
}
- if (screenDepth > -1)
- {
- gGL.getTexUnit(screenDepth)->bind(&gPipeline.mWaterDis, true);
- }
-
if (mShaderLevel == 1)
{
fog_color.mV[VW] = log(fog_density) / log(2);
@@ -342,7 +336,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
shader->disableTexture(LLShaderMgr::BUMP_MAP);
shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
shader->disableTexture(LLShaderMgr::WATER_REFTEX);
- shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
// clean up
gPipeline.unbindDeferredShader(*shader);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2e55b65c82..b24a8106cc 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7476,7 +7476,7 @@ void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader)
}
}
-void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
+void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target, LLRenderTarget* depth_target)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LLRenderTarget* deferred_target = &mRT->deferredScreen;
@@ -7515,7 +7515,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
if (channel > -1)
{
- gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+ if (depth_target)
+ {
+ gGL.getTexUnit(channel)->bind(depth_target, TRUE);
+ }
+ else
+ {
+ gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+ }
stop_glerror();
}
@@ -8232,16 +8239,42 @@ void LLPipeline::doAtmospherics()
if (RenderDeferredAtmospheric)
{
+ if (!sUnderWaterRender)
+ {
+ // copy depth buffer for use in haze shader (use water displacement map as temp storage)
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+ LLRenderTarget& src = gPipeline.mRT->screen;
+ LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen;
+ LLRenderTarget& dst = gPipeline.mWaterDis;
+
+ mRT->screen.flush();
+ dst.bindTarget();
+ gCopyDepthProgram.bind();
+
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+
+ gGL.getTexUnit(diff_map)->bind(&src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+
+ gGL.setColorMask(false, false);
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ dst.flush();
+ mRT->screen.bindTarget();
+ }
+
LLGLEnable blend(GL_BLEND);
gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA);
-
gGL.setColorMask(true, true);
// apply haze
LLGLSLShader& haze_shader = gHazeProgram;
LL_PROFILE_GPU_ZONE("haze");
- bindDeferredShader(haze_shader);
+ bindDeferredShader(haze_shader, nullptr, sUnderWaterRender ? nullptr : &mWaterDis);
LLEnvironment& environment = LLEnvironment::instance();
haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
@@ -8294,7 +8327,7 @@ void LLPipeline::doWaterHaze()
else
{
//render water patches like LLDrawPoolWater does
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
+ /*LLGLDepthTest depth(GL_FALSE);
LLGLDisable cull(GL_CULL_FACE);
gGLLastMatrix = NULL;
@@ -8303,7 +8336,7 @@ void LLPipeline::doWaterHaze()
if (mWaterPool)
{
mWaterPool->pushFaceGeometry();
- }
+ }*/
}
unbindDeferredShader(haze_shader);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index bbed7cad92..88a7eab813 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -306,7 +306,7 @@ public:
// if setup is true, wil lset texture compare mode function and filtering options
void bindShadowMaps(LLGLSLShader& shader);
void bindDeferredShaderFast(LLGLSLShader& shader);
- void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
+ void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr, LLRenderTarget* depth_target = nullptr);
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
void unbindDeferredShader(LLGLSLShader& shader);