diff options
20 files changed, 400 insertions, 31 deletions
| diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 37697f8a15..25d8ccd4b3 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1392,6 +1392,7 @@ void LLShaderMgr::initAttribsAndUniforms()      mReservedUniforms.push_back("screenTex");      mReservedUniforms.push_back("screenDepth");      mReservedUniforms.push_back("refTex"); +    mReservedUniforms.push_back("exclusionTex");      mReservedUniforms.push_back("eyeVec");      mReservedUniforms.push_back("time");      mReservedUniforms.push_back("waveDir1"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 34bd73a42e..46788841a5 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -36,6 +36,8 @@ public:      LLShaderMgr();      virtual ~LLShaderMgr(); +    // Note: although you can use statically hashed strings to just bind a random uniform, it's generally preferably that you use this. +    // Always document what the actual shader uniform is next to the shader uniform in this struct.      // clang-format off      typedef enum      {                                       // Shader uniform name, set in LLShaderMgr::initAttribsAndUniforms() @@ -234,6 +236,7 @@ public:          WATER_SCREENTEX,                    //  "screenTex"          WATER_SCREENDEPTH,                  //  "screenDepth"          WATER_REFTEX,                       //  "refTex" +        WATER_EXCLUSIONTEX,                 //  "exclusionTex"          WATER_EYEVEC,                       //  "eyeVec"          WATER_TIME,                         //  "time"          WATER_WAVE_DIR1,                    //  "waveDir1" diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5bcfddfe25..d2736c7c12 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -156,6 +156,7 @@ set(viewer_SOURCE_FILES      lldrawpooltree.cpp      lldrawpoolwater.cpp      lldrawpoolwlsky.cpp +    lldrawpoolwaterexclusion.cpp      lldynamictexture.cpp      llemote.cpp      llenvironment.cpp @@ -823,6 +824,7 @@ set(viewer_HEADER_FILES      lldrawpooltree.h      lldrawpoolwater.h      lldrawpoolwlsky.h +    lldrawpoolwaterexclusion.h      lldynamictexture.h      llemote.h      llenvironment.h diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl new file mode 100644 index 0000000000..dea76da5a5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl @@ -0,0 +1,57 @@ +/** + * @file simpleColorF.glsl + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +out vec4 frag_color; + +in vec4 vertex_color; +in vec4 vertex_position; + +uniform vec4 waterPlane; +uniform float waterSign; + +void waterClip(vec3 pos) +{ +    // TODO: make this less branchy +    if (waterSign > 0) +    { +        if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < 0.0) +        { +            discard; +        } +    } +    else +    { +        if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > 0.0) +        { +            discard; +        } +    } +} + +void main() +{ + +    frag_color = vertex_color; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl new file mode 100644 index 0000000000..4564e56313 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl @@ -0,0 +1,43 @@ +/** + * @file simpleNoAtmosV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix; + +uniform vec4 color; + +in vec3 position; + +out vec4 vertex_color; +out vec4 vertex_position; + +void main() +{ +    //transform vertex +    vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); +    vertex_position = modelview_projection_matrix * vec4(position.xyz, 1.0); +    gl_Position = vertex_position; +    vertex_color = color; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl index ee49b4baae..091c25d15e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl @@ -35,13 +35,25 @@ vec4 getWaterFogView(vec3 pos);  uniform int above_water; +uniform sampler2D exclusionTex; +  void main()  {      vec2  tc           = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;      float depth        = getDepth(tc.xy); +    float mask = texture(exclusionTex, tc.xy).r;      if (above_water > 0)      { +        // Just discard if we're in the exclusion mask. +        // The previous invisiprim hack we're replacing would also crank up water fog desntiy. +        // But doing that makes exclusion surfaces very slow as we'd need to render even more into the mask. +        // - Geenz 2025-02-06 +        if (mask < 1) +        { +            discard; +        } +          // 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 @@ -51,12 +63,14 @@ void main()          {              discard;          } +      }      vec4  pos          = getPositionWithDepth(tc, depth);      vec4 fogged = getWaterFogView(pos.xyz);      fogged.a = max(pow(fogged.a, 1.7), 0); +      frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results  } diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl index 1c02dc764d..fa410e9f11 100644 --- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl @@ -26,6 +26,7 @@  out vec4 frag_color;  uniform sampler2D bumpMap; +uniform sampler2D exclusionTex;  #ifdef TRANSPARENT_WATER  uniform sampler2D screenTex; @@ -59,6 +60,9 @@ void mirrorClip(vec3 position);  void main()  {      mirrorClip(vary_position); +    vec2 screen_tc = (refCoord.xy/refCoord.z) * 0.5 + 0.5; +    float water_mask = texture(exclusionTex, screen_tc).r; +      vec4 color;      //get detail normals @@ -68,8 +72,8 @@ void main()      vec3 wavef = normalize(wave1+wave2+wave3);      //figure out distortion vector (ripply) -    vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; -    distort = distort+wavef.xy*refScale; +    vec2 distort = screen_tc; +    distort = mix(distort, distort+wavef.xy*refScale, water_mask);  #ifdef TRANSPARENT_WATER      vec4 fb = texture(screenTex, distort); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index f8aa684433..7027e3796e 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -88,7 +88,7 @@ uniform sampler2D screenTex;  uniform sampler2D depthMap;  #endif -uniform sampler2D refTex; +uniform sampler2D exclusionTex;  uniform float sunAngle;  uniform float sunAngle2; @@ -252,6 +252,8 @@ void main()      float shadow = 1.0f; +    float water_mask = texture(exclusionTex, distort).r; +  #ifdef HAS_SUN_SHADOW      shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, distort);  #endif @@ -266,9 +268,8 @@ void main()      vec3 refPos = getPositionWithNDC(vec3(distort*2.0-vec2(1.0), depth*2.0-1.0));      // Calculate some distance fade in the water to better assist with refraction blending and reducing the refraction texture's "disconnect". -    fade = max(0,min(1, (pos.z - refPos.z) / 10)); +    fade = max(0,min(1, (pos.z - refPos.z) / 10)) * water_mask;      distort2 = mix(distort, distort2, min(1, fade * 10)); -      depth = texture(depthMap, distort2).r;      refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0)); @@ -282,6 +283,9 @@ void main()  #else      vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0)); + +    if (water_mask < 1) +        discard;  #endif      float metallic = 1.0; @@ -333,6 +337,7 @@ void main()      color = mix(fb.rgb, color, fade);      float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05); -    frag_color = min(vec4(1),max(vec4(color.rgb, spec), vec4(0))); + +    frag_color = min(vec4(1),max(vec4(color.rgb, spec * water_mask), vec4(0)));  } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 7bd5206453..e60b3eb5dc 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -42,6 +42,7 @@  #include "lldrawpooltree.h"  #include "lldrawpoolterrain.h"  #include "lldrawpoolwater.h" +#include "lldrawpoolwaterexclusion.h"  #include "llface.h"  #include "llviewerobjectlist.h" // For debug listing.  #include "pipeline.h" @@ -119,6 +120,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)      case POOL_GLTF_PBR_ALPHA_MASK:          poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);          break; +    case POOL_WATEREXCLUSION: +        poolp = new LLDrawPoolWaterExclusion(); +        break;      default:          LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;          return NULL; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index bc412214c7..1c8864a9df 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -55,6 +55,7 @@ public:          // based on fill rate and likelihood to occlude future passes (faster, large occluders first).          //          POOL_SKY = 1, +        POOL_WATEREXCLUSION,          POOL_WL_SKY,          POOL_SIMPLE,          POOL_FULLBRIGHT, @@ -140,7 +141,7 @@ public:          PASS_GRASS,          PASS_FULLBRIGHT,          PASS_FULLBRIGHT_RIGGED, -        PASS_INVISIBLE, +        PASS_INVISIBLE,                         // Formerly, invisiprims.  Now, water exclusion surfaces.          PASS_INVISIBLE_RIGGED,          PASS_INVISI_SHINY,          PASS_INVISI_SHINY_RIGGED, diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 53d6e528b6..c27f5ef486 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -236,6 +236,8 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)              gGL.getTexUnit(bumpTex2)->bind(tex_b);          } +        shader->bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &gPipeline.mWaterExclusionMask); +          // bind reflection texture from RenderTarget          S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX); @@ -307,30 +309,11 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)          LLGLDisable cullface(GL_CULL_FACE); -        LLVOWater* water = nullptr; -        for (LLFace* const& face : mDrawFace) -        { -            if (!face) continue; -            water = static_cast<LLVOWater*>(face->getViewerObject()); -            if (!water) continue; - -            if ((bool)edge == (bool)water->getIsEdgePatch()) -            { -                face->renderIndexed(); - -                // Note non-void water being drawn, updates required -                if (!edge)  // SL-16461 remove !LLPipeline::sUseOcclusion check -                { -                    sNeedsReflectionUpdate = true; -                    sNeedsDistortionUpdate = true; -                } -            } -        } +        pushWaterPlanes(edge);          shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);          shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);          shader->disableTexture(LLShaderMgr::BUMP_MAP); -        shader->disableTexture(LLShaderMgr::WATER_REFTEX);          // clean up          gPipeline.unbindDeferredShader(*shader); @@ -345,6 +328,31 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)      gGL.setColorMask(true, false);  } +void LLDrawPoolWater::pushWaterPlanes(int pass) +{ +    LLVOWater* water = nullptr; +    for (LLFace* const& face : mDrawFace) +    { +        if (!face) +            continue; +        water = static_cast<LLVOWater*>(face->getViewerObject()); +        if (!water) +            continue; + +        if ((bool)pass == (bool)water->getIsEdgePatch()) +        { +            face->renderIndexed(); + +            // Note non-void water being drawn, updates required +            if (!pass) // SL-16461 remove !LLPipeline::sUseOcclusion check +            { +                sNeedsReflectionUpdate = true; +                sNeedsDistortionUpdate = true; +            } +        } +    } +} +  LLViewerTexture *LLDrawPoolWater::getDebugTexture()  {      return LLViewerTextureManager::getFetchedTexture(IMG_SMOKE); diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index f64477a059..7fc9b68bcf 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -74,6 +74,8 @@ public:      void setOpaqueTexture(const LLUUID& opaqueTextureId);      void setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId); +    void pushWaterPlanes(int pass); +  protected:      void renderOpaqueLegacyWater();  }; diff --git a/indra/newview/lldrawpoolwaterexclusion.cpp b/indra/newview/lldrawpoolwaterexclusion.cpp new file mode 100644 index 0000000000..d796bf39bf --- /dev/null +++ b/indra/newview/lldrawpoolwaterexclusion.cpp @@ -0,0 +1,79 @@ +/** + * @file lldrawpool.cpp + * @brief LLDrawPoolMaterials class implementation + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lldrawpoolwaterexclusion.h" +#include "llviewershadermgr.h" +#include "pipeline.h" +#include "llglcommonfunc.h" +#include "llvoavatar.h" +#include "lldrawpoolwater.h" + +LLDrawPoolWaterExclusion::LLDrawPoolWaterExclusion() : LLRenderPass(LLDrawPool::POOL_WATEREXCLUSION) +{ +    LL_INFOS("DPInvisible") << "Creating water exclusion draw pool" << LL_ENDL; +} + + +void LLDrawPoolWaterExclusion::render(S32 pass) +{                                             // render invisiprims +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; // LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE); + +    if (gPipeline.shadersLoaded()) +    { +        gDrawColorProgram.bind(); +    } + + +    LLGLDepthTest depth(GL_TRUE); +    gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 1, 1, 1, 1); + +    LLDrawPoolWater* pwaterpool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER); +    if (pwaterpool) +    { +        // Just treat our water planes as double sided for the purposes of generating the exclusion mask. +        LLGLDisable cullface(GL_CULL_FACE); +        pwaterpool->pushWaterPlanes(0); + +        // Take care of the edge water tiles. +        pwaterpool->pushWaterPlanes(1); +    } + +    gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 0, 0, 0, 1); + +    static LLStaticHashedString waterSign("waterSign"); +    gDrawColorProgram.uniform1f(waterSign, 1.f); + +    pushBatches(LLRenderPass::PASS_INVISIBLE, false, false); + + +    if (gPipeline.shadersLoaded()) +    { +        gDrawColorProgram.unbind(); +    } +} diff --git a/indra/newview/lldrawpoolwaterexclusion.h b/indra/newview/lldrawpoolwaterexclusion.h new file mode 100644 index 0000000000..e95721a443 --- /dev/null +++ b/indra/newview/lldrawpoolwaterexclusion.h @@ -0,0 +1,61 @@ +/** + * @file lldrawpoolwaterexclusion.h + * @brief LLDrawPoolWaterExclusion class definition + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLDRAWPOOLWATEREXCLUSION_H +#define LL_LLDRAWPOOLWATEREXCLUSION_H + +#include "v4coloru.h" +#include "v2math.h" +#include "v3math.h" +#include "llvertexbuffer.h" +#include "lldrawpool.h" + +class LLViewerTexture; +class LLDrawInfo; +class LLGLSLShader; + +class LLDrawPoolWaterExclusion : public LLRenderPass +{ +public: +    LLDrawPoolWaterExclusion(); + +    enum +    { +        VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX +    }; + +    virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + +    virtual void prerender() {} + +    virtual void render(S32 pass = 0); +    virtual void beginRenderPass(S32 pass) {} +    virtual void endRenderPass(S32 pass) {} +    virtual S32  getNumPasses() { return 1; } +}; + +#endif // LL_LLDRAWPOOLWATEREXCLUSION_H diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 2619bbbfcb..ac4519e593 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -101,6 +101,7 @@ LLGLSLShader    gReflectionProbeDisplayProgram;  LLGLSLShader    gCopyProgram;  LLGLSLShader    gCopyDepthProgram;  LLGLSLShader    gPBRTerrainBakeProgram; +LLGLSLShader    gDrawColorProgram;  //object shaders  LLGLSLShader        gObjectPreviewProgram; @@ -3355,6 +3356,17 @@ bool LLViewerShaderMgr::loadShadersInterface()          success = gCopyDepthProgram.createShader();      } +    if (success) +    { +        gDrawColorProgram.mName = "Draw Color Shader"; +        gDrawColorProgram.mShaderFiles.clear(); +        gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoAtmosV.glsl", GL_VERTEX_SHADER)); +        gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleColorF.glsl", GL_FRAGMENT_SHADER)); +        gDrawColorProgram.clearPermutations(); +        gDrawColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; +        success = gDrawColorProgram.createShader(); +    } +      if (gSavedSettings.getBOOL("LocalTerrainPaintEnabled"))      {          if (success) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index b08796025a..6326de9a6b 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -175,6 +175,7 @@ extern LLGLSLShader         gReflectionProbeDisplayProgram;  extern LLGLSLShader         gCopyProgram;  extern LLGLSLShader         gCopyDepthProgram;  extern LLGLSLShader         gPBRTerrainBakeProgram; +extern LLGLSLShader         gDrawColorProgram;  //output tex0[tc0] - tex1[tc1]  extern LLGLSLShader         gTwoTextureCompareProgram; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 7f38642623..0c186c0ed2 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -266,7 +266,7 @@ void LLViewerTextureList::doPrefetchImages()          S32 pixel_area = imagesd["area"];          S32 texture_type = imagesd["type"]; -        if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type) +        if((LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type))          {              LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);              if (image) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 4dba930ed5..4e8932f912 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -6732,8 +6732,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace              { //shiny                  if (tex->getPrimaryFormat() == GL_ALPHA)                  { //invisiprim+shiny -                    registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); -                    registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); +                    if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh()) +                    { +                        registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); +                        registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); +                    }                  }                  else if (!hud_group)                  { //deferred rendering @@ -6769,7 +6772,10 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace              { //not alpha and not shiny                  if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)                  { //invisiprim -                    registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); +                    if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh()) +                    { +                        registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); +                    }                  }                  else if (fullbright || bake_sunlight)                  { //fullbright diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f91b054dd7..18dd694246 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -431,6 +431,7 @@ void LLPipeline::init()      stop_glerror();      //create render pass pools +    getPool(LLDrawPool::POOL_WATEREXCLUSION);      getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);      getPool(LLDrawPool::POOL_ALPHA_POST_WATER);      getPool(LLDrawPool::POOL_SIMPLE); @@ -673,6 +674,8 @@ void LLPipeline::cleanup()      // don't delete wl sky pool it was handled above in the for loop      //delete mWLSkyPool;      mWLSkyPool = NULL; +    delete mWaterExclusionPool; +    mWaterExclusionPool = nullptr;      releaseGLBuffers(); @@ -907,6 +910,15 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)          mPostMap.allocate(resX, resY, screenFormat); +        // The water exclusion mask needs its own depth buffer so we can take care of the problem of multiple water planes. +        // Should we ever make water not just a plane, it also aids with that as well as the water planes will be rendered into the mask. +        // Why do we do this? Because it saves us some janky logic in the exclusion shader when we generate the mask. +        // Regardless, this should always only be an R8 texture unless we choose to start having multiple kinds of exclusion that 8 bits can't handle. +        // - Geenz 2025-02-06 +        bool success = mWaterExclusionMask.allocate(resX, resY, GL_R8, true); + +        assert(success); +          // used to scale down textures          // See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown          mDownResMap.allocate(1024, 1024, GL_RGBA); @@ -1166,6 +1178,8 @@ void LLPipeline::releaseGLBuffers()      mSceneMap.release(); +    mWaterExclusionMask.release(); +      mPostMap.release();      mFXAAMap.release(); @@ -1676,6 +1690,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)          poolp = mPBRAlphaMaskPool;          break; +    case LLDrawPool::POOL_WATEREXCLUSION: +        poolp = mWaterExclusionPool; +        break; +      default:          llassert(0);          LL_ERRS() << "Invalid Pool Type in  LLPipeline::findPool() type=" << type << LL_ENDL; @@ -4068,6 +4086,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)      }  } +// Render all of our geometry that's required after our deferred pass. +// This is gonna be stuff like alpha, water, etc.  void LLPipeline::renderGeomPostDeferred(LLCamera& camera)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; @@ -4084,6 +4104,10 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)      bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds      bool done_water_haze = done_atmospherics; +    bool done_water_exclusion = false; + +    // do water exclusion just before water pass. +    U32 water_exclusion_pass = LLDrawPool::POOL_WATEREXCLUSION;      // do atmospheric haze just before post water alpha      U32 atmospherics_pass = LLDrawPool::POOL_ALPHA_POST_WATER; @@ -4122,6 +4146,12 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)          cur_type = poolp->getType(); +        if (cur_type >= water_exclusion_pass && !done_water_exclusion) +        { // do water exclusion against depth buffer before rendering alpha +            doWaterExclusionMask(); +            done_water_exclusion = true; +        } +          if (cur_type >= atmospherics_pass && !done_atmospherics)          { // do atmospherics against depth buffer before rendering alpha              doAtmospherics(); @@ -5201,6 +5231,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )          }          break; +    case LLDrawPool::POOL_WATEREXCLUSION: +        if (mWaterExclusionPool) +        { +            llassert(0); +            LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water Exclusion Pool" << LL_ENDL; +        } +        else +        { +            mWaterExclusionPool = new_poolp; +        } +        break;      default:          llassert(0); @@ -5323,6 +5364,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )          mPBRAlphaMaskPool = NULL;          break; +    case LLDrawPool::POOL_WATEREXCLUSION: +        llassert(poolp == mWaterExclusionPool); +        mWaterExclusionPool = nullptr; +        break; +      default:          llassert(0);          LL_WARNS() << "Invalid Pool Type in  LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; @@ -8824,6 +8870,7 @@ void LLPipeline::renderDeferredLighting()                            LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,                            LLPipeline::RENDER_TYPE_TERRAIN,                            LLPipeline::RENDER_TYPE_WATER, +                          LLPipeline::RENDER_TYPE_WATEREXCLUSION,                            END_RENDER_TYPES);          renderGeomPostDeferred(*LLViewerCamera::getInstance()); @@ -8962,6 +9009,8 @@ void LLPipeline::doWaterHaze()          static LLStaticHashedString above_water_str("above_water");          haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1); +        haze_shader.bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &mWaterExclusionMask); +          if (LLPipeline::sUnderWaterRender)          {              LLGLDepthTest depth(GL_FALSE); @@ -8992,6 +9041,17 @@ void LLPipeline::doWaterHaze()      }  } +void LLPipeline::doWaterExclusionMask() +{ +    mWaterExclusionMask.bindTarget(); +    glClearColor(1, 1, 1, 1); +    mWaterExclusionMask.clear(); +    mWaterExclusionPool->render(); + +    mWaterExclusionMask.flush(); +    glClearColor(0, 0, 0, 0); +} +  void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  {      //construct frustum diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5c9b95ef4a..315e38ed8c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -337,6 +337,9 @@ public:      // should be called just before rendering pre-water alpha objects      void doWaterHaze(); +    // Generate the water exclusion surface mask. +    void doWaterExclusionMask(); +      void postDeferredGammaCorrect(LLRenderTarget* screen_target);      void generateSunShadow(LLCamera& camera); @@ -500,6 +503,7 @@ public:          RENDER_TYPE_AVATAR                      = LLDrawPool::POOL_AVATAR,          RENDER_TYPE_CONTROL_AV                  = LLDrawPool::POOL_CONTROL_AV, // Animesh          RENDER_TYPE_TREE                        = LLDrawPool::POOL_TREE, +        RENDER_TYPE_WATEREXCLUSION              = LLDrawPool::POOL_WATEREXCLUSION,          RENDER_TYPE_VOIDWATER                   = LLDrawPool::POOL_VOIDWATER,          RENDER_TYPE_WATER                       = LLDrawPool::POOL_WATER,          RENDER_TYPE_GLTF_PBR                    = LLDrawPool::POOL_GLTF_PBR, @@ -714,6 +718,7 @@ public:      LLRenderTarget          mSpotShadow[2];      LLRenderTarget          mPbrBrdfLut; +    LLRenderTarget          mWaterExclusionMask;      // copy of the color/depth buffer just before gamma correction      // for use by SSR @@ -953,6 +958,7 @@ protected:      LLDrawPool*                 mWLSkyPool = nullptr;      LLDrawPool*                 mPBROpaquePool = nullptr;      LLDrawPool*                 mPBRAlphaMaskPool = nullptr; +    LLDrawPool*                 mWaterExclusionPool      = nullptr;      // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar | 
