diff options
| author | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2024-03-06 17:56:16 -0800 | 
|---|---|---|
| committer | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2024-03-06 17:56:16 -0800 | 
| commit | 1fc45a50ff15e6f31a4554da83256b7f59b1af15 (patch) | |
| tree | b65f155530ebc130443582ca0fedda284833b02d /indra | |
| parent | 47cd3cb0ad03c91f118fd20fea8d8924759fd2b7 (diff) | |
#681 Add probe blending for mirrors.
Diffstat (limited to 'indra')
6 files changed, 69 insertions, 79 deletions
| diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index c83a6be85d..57c0a6024f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -133,6 +133,7 @@ uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlpha  #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3  in vec4[2] vary_coords;  #endif +in vec3 vary_position;  in vec3 vary_normal;  in vec3 vary_tangent;  flat in float vary_sign; @@ -140,11 +141,14 @@ in vec4 vary_texcoord0;  in vec4 vary_texcoord1;  vec2 encode_normal(vec3 n); +void mirrorClip(vec3 position);  float terrain_mix(TerrainMix tm, vec4 tms4);  void main()  { +    // Make sure we clip the terrain if we're in a mirror. +    mirrorClip(vary_position);  #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3      TerrainCoord terrain_texcoord = vary_coords; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index dbb9404219..489fc26e3f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -25,6 +25,7 @@  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; +uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix;  in vec3 position; @@ -42,6 +43,7 @@ out vec3 vary_tangent;  flat out float vary_sign;  out vec4 vary_texcoord0;  out vec4 vary_texcoord1; +out vec3 vary_position;  // *HACK: tangent_space_transform should use texture_normal_transform, or maybe  // we shouldn't use tangent_space_transform at all. See the call to @@ -55,6 +57,7 @@ void main()  {      //transform vertex  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);  +    vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;  	vec3 n = normal_matrix * normal;      vary_vertex_normal = normal; diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 257299258e..4f2475b101 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -48,6 +48,7 @@ layout (std140) uniform ReflectionProbes      /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation      //  box[3][0..2] - plane thickness      mat4 refBox[MAX_REFMAP_COUNT]; +    mat4 heroBox;      // list of bounding spheres for reflection probes sorted by distance to camera (closest first)      vec4 refSphere[MAX_REFMAP_COUNT];      // extra parameters  @@ -56,6 +57,7 @@ layout (std140) uniform ReflectionProbes      //  z - fade in      //  w - znear      vec4 refParams[MAX_REFMAP_COUNT]; +    vec4 heroSphere;      // index  of cube map in reflectionProbes for a corresponding reflection probe      // e.g. cube map channel of refSphere[2] is stored in refIndex[2]      // refIndex.x - cubemap channel in reflectionProbes @@ -71,6 +73,10 @@ layout (std140) uniform ReflectionProbes      // number of reflection probes present in refSphere      int refmapCount; + +    int heroShape; +    int heroMipCount; +    int heroProbeCount;  };  // Inputs @@ -682,48 +688,37 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)      return col[1]+col[0];  } -  #if defined(HERO_PROBES)  uniform vec4 clipPlane; -  uniform samplerCubeArray   heroProbes; -layout (std140) uniform HeroProbeData -{ -    mat4 heroBox[1]; -    vec4 heroSphere[1]; -    uint heroShape[1]; -    int heroMipCount; -    int heroProbeCount; -}; -  void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)  {      float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w;      float w = 0;      float dw = 0; -    if (heroShape[0] < 1) +    float falloffMult = 10; +    vec3 refnormpersp = reflect(pos.xyz, norm.xyz); +    if (heroShape < 1)      {          float d = 0; -        boxIntersect(pos, norm, heroBox[0], d, 1.0); +        boxIntersect(pos, norm, heroBox, d, 1.0); -        w = max(d, 0.001); +        w = max(d, 0);      }      else      { -        float r = heroSphere[0].w; +        float r = heroSphere.w; -        w = sphereWeight(pos, norm, heroSphere[0].xyz, r, vec4(1), dw); -    } -     -    { -        vec3 refnormpersp = reflect(pos.xyz, norm.xyz); -        if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) -        { -            glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w); -        } +        w = sphereWeight(pos, refnormpersp, heroSphere.xyz, r, vec4(1), dw);      } + +    clipDist = clipDist * 0.95 + 0.05; +    clipDist = clamp(clipDist * falloffMult, 0, 1); +    w = clamp(w * falloffMult * clipDist, 0, 1); + +    glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w);  }  #else diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index ee993c6ba1..8f1c1848cc 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -151,6 +151,7 @@ void LLHeroProbeManager::update()              // Collect the list of faces that need updating based upon the camera's rotation.              LLVector3 cam_direction = LLVector3(0, 0, 1) * LLViewerCamera::instance().getQuaternion(); +            cam_direction.normalize();              static LLVector3 cubeFaces[6] = {                   LLVector3(1, 0, 0),  @@ -163,7 +164,7 @@ void LLHeroProbeManager::update()              for (int i = 0; i < 6; i++)              { -                float shouldUpdate = cam_direction * cubeFaces[i] * 0.5 + 0.5; +                float shouldUpdate = fminf(1, (fmaxf(-1, cam_direction * cubeFaces[i]) * 0.5 + 0.5));                  int updateRate = ceilf((1 - shouldUpdate) * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); @@ -215,6 +216,9 @@ void LLHeroProbeManager::update()          mRenderingMirror = false;          gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass; + +        mProbes[0]->mViewerObject = mNearestHero; +        mProbes[0]->autoAdjustOrigin();      }      mCurrentProbeUpdateFrame++; @@ -424,26 +428,14 @@ void LLHeroProbeManager::updateUniforms()      LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; -    struct HeroProbeData -    { -        LLMatrix4 heroBox[1]; -        LLVector4 heroSphere[1]; -        GLint heroShape[1]; -        GLint heroMipCount; -        GLint heroProbeCount; -    }; -     -    HeroProbeData hpd; -          LLMatrix4a modelview;      modelview.loadu(gGLModelView);      LLVector4a oa; // scratch space for transformed origin      oa.set(0, 0, 0, 0); -    hpd.heroProbeCount = 1; +    mHeroData.heroProbeCount = 1;      if (mNearestHero != nullptr)      { -        mProbes[0]->mViewerObject = mNearestHero;          if (mNearestHero->getReflectionProbeIsBox())          {              LLVector3 s = mNearestHero->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f)); @@ -455,44 +447,17 @@ void LLHeroProbeManager::updateUniforms()          }          modelview.affineTransform(mProbes[0]->mOrigin, oa); -        hpd.heroShape[0] = 0; -        if (!mProbes[0]->getBox(hpd.heroBox[0])) +        mHeroData.heroShape = 0; +        if (!mProbes[0]->getBox(mHeroData.heroBox))          { -            hpd.heroShape[0] = 1; +            mHeroData.heroShape = 1;          } -        hpd.heroSphere[0].set(oa.getF32ptr()); -        hpd.heroSphere[0].mV[3] = mProbes[0]->mRadius; +        mHeroData.heroSphere.set(oa.getF32ptr()); +        mHeroData.heroSphere.mV[3] = mProbes[0]->mRadius;      } -    hpd.heroMipCount = mMipChain.size(); - -    //copy rpd into uniform buffer object -    if (mUBO == 0) -    { -        glGenBuffers(1, &mUBO); -    } - -    { -        LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); -        glBindBuffer(GL_UNIFORM_BUFFER, mUBO); -        glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW); -        glBindBuffer(GL_UNIFORM_BUFFER, 0); -    } -} - -void LLHeroProbeManager::setUniforms() -{ -    if (!LLPipeline::sReflectionProbesEnabled) -    { -        return; -    } - -    if (mUBO == 0) -    {  -        updateUniforms(); -    } -    glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); +    mHeroData.heroMipCount = mMipChain.size();  }  void LLHeroProbeManager::renderDebug() @@ -581,9 +546,6 @@ void LLHeroProbeManager::cleanup()      mDefaultProbe = nullptr;      mUpdatingProbe = nullptr; - -    glDeleteBuffers(1, &mUBO); -    mUBO = 0;      mHeroVOList.clear();      mNearestHero = nullptr; diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index e430cae203..04027cd57e 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -38,6 +38,15 @@ class LLViewerObject;  // number of reflection probes to keep in vram  #define LL_MAX_HERO_PROBE_COUNT 2 +struct HeroProbeData +{ +    LLMatrix4 heroBox; +    LLVector4 heroSphere; +    GLint     heroShape; +    GLint     heroMipCount; +    GLint     heroProbeCount; +}; +  class alignas(16) LLHeroProbeManager  {      LL_ALIGN_NEW @@ -74,16 +83,17 @@ public:      bool isMirrorPass() const { return mRenderingMirror; }      LLVector3 mMirrorPosition; -    LLVector3 mMirrorNormal; +    LLVector3     mMirrorNormal; +    HeroProbeData mHeroData;  private:      friend class LLPipeline; +    friend class LLReflectionMapManager;      // update UBO used for rendering (call only once per render pipe flush)      void updateUniforms();      // bind UBO used for rendering -    void setUniforms();      // render target for cube snapshots      // used to generate mipmaps without doing a copy-to-texture @@ -109,9 +119,6 @@ private:      // list of active reflection maps      std::vector<LLPointer<LLReflectionMap>> mProbes; -    // handle to UBO -    U32 mUBO = 0; -      // list of maps being used for rendering      std::vector<LLReflectionMap*> mReflectionMaps; @@ -141,5 +148,6 @@ private:      std::vector<LLVOVolume*>                       mHeroVOList;      LLVOVolume*                                 mNearestHero; +  }; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 3144260905..ce389a5cad 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -906,6 +906,8 @@ void LLReflectionMapManager::updateUniforms()          // the box probe          LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; +        LLMatrix4 heroBox; +          // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space          LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; @@ -916,6 +918,8 @@ void LLReflectionMapManager::updateUniforms()          //  w - znear          LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; +        LLVector4 heroSphere; +          // indices used by probe:          //  [i][0] - cubemap array index for this probe          //  [i][1] - index into "refNeighbor" for probes that intersect this probe @@ -929,6 +933,10 @@ void LLReflectionMapManager::updateUniforms()          GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth          // numbrer of active refmaps          GLint refmapCount; + +        GLint     heroShape; +        GLint     heroMipCount; +        GLint     heroProbeCount;      };      mReflectionMaps.resize(mReflectionProbeCount); @@ -1118,6 +1126,16 @@ void LLReflectionMapManager::updateUniforms()      rpd.refmapCount = count; +    gPipeline.mHeroProbeManager.updateUniforms(); + +    // Get the hero data. + +    rpd.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox; +    rpd.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere; +    rpd.heroShape  = gPipeline.mHeroProbeManager.mHeroData.heroShape; +    rpd.heroMipCount = gPipeline.mHeroProbeManager.mHeroData.heroMipCount; +    rpd.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount; +      //copy rpd into uniform buffer object      if (mUBO == 0)      { | 
