diff options
| author | Dave Parks <davep@lindenlab.com> | 2023-12-11 15:28:25 -0600 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2023-12-11 15:28:25 -0600 | 
| commit | f3b87145775d3803306036d1e31fa39177f2600e (patch) | |
| tree | 3002aba971e65a144da09344dd325f634c24cd1b /indra | |
| parent | 4024a4df3b36b55ce2f05e02218251e15a4a2286 (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
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl | 16 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl | 1 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class3/environment/waterF.glsl | 6 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolwater.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 45 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 2 | 
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); | 
