diff options
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl | 1 | ||||
| -rw-r--r-- | indra/newview/featuretable.txt | 10 | ||||
| -rw-r--r-- | indra/newview/featuretable_mac.txt | 10 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 112 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.h | 49 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml | 17 | 
7 files changed, 141 insertions, 69 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 594f40e5a1..0c83355a81 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9076,6 +9076,17 @@      <key>Value</key>      <integer>1</integer>    </map> +    <key>RenderReflectionProbeCount</key> +    <map> +        <key>Comment</key> +        <string>Number of probes to render.  Maximum of 256.  Clamps to the nearest power of 2.</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>U32</string> +        <key>Value</key> +        <integer>256</integer> +    </map>    <key>RenderReflectionProbeResolution</key>    <map>      <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 0283104a76..dba9c46332 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -87,6 +87,7 @@ vec3 clampHDRRange(vec3 color)      // This is a safety measure to prevent that.      // As to the specific number there - allegedly some HDR displays expect values to be in the 0-11.2 range. Citation needed.      // -Geenz 2025-03-05 +    color = mix(color, vec3(1), isinf(color));      color = mix(color, vec3(0.0), isnan(color));      return clamp(color, vec3(0.0), vec3(11.2));  } diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index cb79410d72..883963d558 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -86,6 +86,7 @@ RenderTonemapType			1   1  RenderTonemapMix			1   1  RenderDisableVintageMode           1   1  RenderMaxTextureResolution         1   2048 +RenderReflectionProbeCount  1   256  //  // Low Graphics Settings @@ -128,6 +129,7 @@ RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0  RenderMaxTextureResolution         1   512 +RenderReflectionProbeCount  1   1  //  // Medium Low Graphics Settings @@ -170,6 +172,7 @@ RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0  RenderMaxTextureResolution         1   1024 +RenderReflectionProbeCount  1   16  //  // Medium Graphics Settings (standard) @@ -211,6 +214,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   32  //  // Medium High Graphics Settings @@ -252,6 +256,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   64  //  // High Graphics Settings (SSAO + sun shadows) @@ -293,6 +298,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   128  //  // High Ultra Graphics Settings (deferred + SSAO + all shadows) @@ -334,6 +340,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   256  //  // Ultra graphics (REALLY PURTY!) @@ -375,6 +382,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   256  //  // Class Unknown Hardware (unknown) @@ -408,6 +416,7 @@ RenderReflectionProbeDetail	0	-1  RenderMirrors				0	0  RenderDisableVintageMode           1   0  RenderMaxTextureResolution         1   2048 +RenderReflectionProbeCount  0   0  list Intel  RenderAnisotropic			1	0 @@ -429,6 +438,7 @@ RenderMirrors				0	0  RenderGLMultiThreadedTextures 0 0  RenderGLMultiThreadedMedia 0 0  RenderDisableVintageMode           1   0 +RenderReflectionProbeCount  0   0  list TexUnit16orLess  RenderTerrainPBRDetail      1   -1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index dc9473b042..103d24a26d 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -86,6 +86,7 @@ RenderTonemapMix			1   1  RenderDisableVintageMode           1   1  RenderDownScaleMethod       1   0  RenderMaxTextureResolution         1   2048 +RenderReflectionProbeCount  1   256  //  // Low Graphics Settings @@ -128,6 +129,7 @@ RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0  RenderMaxTextureResolution         1   512 +RenderReflectionProbeCount  1   1  //  // Medium Low Graphics Settings @@ -170,6 +172,7 @@ RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0  RenderMaxTextureResolution         1   1024 +RenderReflectionProbeCount  1   16  //  // Medium Graphics Settings (standard) @@ -211,6 +214,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   32  //  // Medium High Graphics Settings @@ -252,6 +256,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   64  //  // High Graphics Settings (SSAO + sun shadows) @@ -293,6 +298,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   128  //  // High Ultra Graphics Settings (SSAO + all shadows) @@ -334,6 +340,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   256  //  // Ultra graphics (REALLY PURTY!) @@ -375,6 +382,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 +RenderReflectionProbeCount  1   256  //  // Class Unknown Hardware (unknown) @@ -407,6 +415,7 @@ RenderShadowDetail			0	0  RenderMirrors				0	0  RenderDisableVintageMode           1   0  RenderMaxTextureResolution         1   2048 +RenderReflectionProbeCount  0   0  list TexUnit8orLess  RenderDeferredSSAO			0	0 @@ -447,6 +456,7 @@ RenderReflectionProbeDetail	0	0  RenderReflectionsEnabled    0   0  RenderMirrors				0	0  RenderDisableVintageMode           1   0 +RenderReflectionProbeCount  0   0  list VaryingVectors16orLess  RenderTerrainPBRPlanarSampleCount 1   1 diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 9a20977652..48b73531ea 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -221,6 +221,14 @@ void LLReflectionMapManager::update()          resume();      } +    static LLCachedControl<U32> probe_count(gSavedSettings, "RenderReflectionProbeCount", 256U); +    bool countReset = mReflectionProbeCount != probe_count; + +    if (countReset) +    { +        mResetFade = -0.5f; +    } +      initReflectionMaps();      static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); @@ -335,6 +343,13 @@ void LLReflectionMapManager::update()          }      } +    if (countReset) +    { +        mResetFade = -0.5f; +    } + +    mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds), 1.f); +      for (unsigned int i = 0; i < mProbes.size(); ++i)      {          LLReflectionMap* probe = mProbes[i]; @@ -1012,60 +1027,18 @@ void LLReflectionMapManager::updateUniforms()      LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; -    // structure for packing uniform buffer object -    // see class3/deferred/reflectionProbeF.glsl -    struct ReflectionProbeData -    { -        // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of -        // 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]; - -        // extra parameters -        //  x - irradiance scale -        //  y - radiance scale -        //  z - fade in -        //  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 -        //  [i][2] - number of probes  that intersect this probe, or -1 for no neighbors -        //  [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes) -        GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; - -        // list of neighbor indices -        GLint refNeighbor[4096]; - -        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);      getReflectionMaps(mReflectionMaps); -    ReflectionProbeData rpd; -      F32 minDepth[256];      for (int i = 0; i < 256; ++i)      { -        rpd.refBucket[i][0] = mReflectionProbeCount; -        rpd.refBucket[i][1] = mReflectionProbeCount; -        rpd.refBucket[i][2] = mReflectionProbeCount; -        rpd.refBucket[i][3] = mReflectionProbeCount; +        mProbeData.refBucket[i][0] = mReflectionProbeCount; +        mProbeData.refBucket[i][1] = mReflectionProbeCount; +        mProbeData.refBucket[i][2] = mReflectionProbeCount; +        mProbeData.refBucket[i][3] = mReflectionProbeCount;          minDepth[i] = FLT_MAX;      } @@ -1111,7 +1084,7 @@ void LLReflectionMapManager::updateUniforms()                  if (refmap->mMinDepth < minDepth[i])                  {                      minDepth[i] = refmap->mMinDepth; -                    rpd.refBucket[i][0] = refmap->mProbeIndex; +                    mProbeData.refBucket[i][0] = refmap->mProbeIndex;                  }              }          } @@ -1139,25 +1112,25 @@ void LLReflectionMapManager::updateUniforms()                  }              }              modelview.affineTransform(refmap->mOrigin, oa); -            rpd.refSphere[count].set(oa.getF32ptr()); -            rpd.refSphere[count].mV[3] = refmap->mRadius; +            mProbeData.refSphere[count].set(oa.getF32ptr()); +            mProbeData.refSphere[count].mV[3] = refmap->mRadius;          } -        rpd.refIndex[count][0] = refmap->mCubeIndex; +        mProbeData.refIndex[count][0] = refmap->mCubeIndex;          llassert(nc % 4 == 0); -        rpd.refIndex[count][1] = nc / 4; -        rpd.refIndex[count][3] = refmap->mPriority; +        mProbeData.refIndex[count][1] = nc / 4; +        mProbeData.refIndex[count][3] = refmap->mPriority;          // for objects that are reflection probes, use the volume as the influence volume of the probe          // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres -        if (refmap->getBox(rpd.refBox[count])) +        if (refmap->getBox(mProbeData.refBox[count]))          { // negate priority to indicate this probe has a box influence volume -            rpd.refIndex[count][3] = -rpd.refIndex[count][3]; +            mProbeData.refIndex[count][3] = -mProbeData.refIndex[count][3];          } -        rpd.refParams[count].set( -            llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale -            radscale, // radiance scale +        mProbeData.refParams[count].set( +            llmax(minimum_ambiance, refmap->getAmbiance())*ambscale * llmax(mResetFade, 0.f), // ambiance scale +            radscale * llmax(mResetFade, 0.f), // radiance scale              refmap->mFadeIn, // fade in weight              oa.getF32ptr()[2] - refmap->mRadius); // z near @@ -1182,7 +1155,7 @@ void LLReflectionMapManager::updateUniforms()                  }                  // this neighbor may be sampled -                rpd.refNeighbor[ni++] = idx; +                mProbeData.refNeighbor[ni++] = idx;                  neighbor_count++;                  if (neighbor_count >= max_neighbors) @@ -1195,11 +1168,11 @@ void LLReflectionMapManager::updateUniforms()          if (nc == ni)          {              //no neighbors, tag as empty -            rpd.refIndex[count][1] = -1; +            mProbeData.refIndex[count][1] = -1;          }          else          { -            rpd.refIndex[count][2] = ni - nc; +            mProbeData.refIndex[count][2] = ni - nc;              // move the cursor forward              nc = ni; @@ -1237,19 +1210,19 @@ void LLReflectionMapManager::updateUniforms()      }  #endif -    rpd.refmapCount = count; +    mProbeData.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; +    mProbeData.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox; +    mProbeData.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere; +    mProbeData.heroShape  = gPipeline.mHeroProbeManager.mHeroData.heroShape; +    mProbeData.heroMipCount   = gPipeline.mHeroProbeManager.mHeroData.heroMipCount; +    mProbeData.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount; -    //copy rpd into uniform buffer object +    //copy mProbeData into uniform buffer object      if (mUBO == 0)      {          glGenBuffers(1, &mUBO); @@ -1258,7 +1231,7 @@ void LLReflectionMapManager::updateUniforms()      {          LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer");          glBindBuffer(GL_UNIFORM_BUFFER, mUBO); -        glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); +        glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &mProbeData, GL_STREAM_DRAW);          glBindBuffer(GL_UNIFORM_BUFFER, 0);      } @@ -1392,7 +1365,8 @@ void LLReflectionMapManager::renderDebug()  void LLReflectionMapManager::initReflectionMaps()  { -    U32 count = LL_MAX_REFLECTION_PROBE_COUNT; +    static LLCachedControl<U32> probe_count(gSavedSettings, "RenderReflectionProbeCount", 256U); +    U32 count = probe_count();      static LLCachedControl<U32> ref_probe_res(gSavedSettings, "RenderReflectionProbeResolution", 128U);      U32 probe_resolution = nhpo2(llclamp(ref_probe_res(), (U32)64, (U32)512)); diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index f81fb30738..9f88776ac2 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -56,6 +56,51 @@ public:          REALTIME = 2      }; +    // General guidance for UBOs is to statically allocate all of these fields to make your life ever so slightly easier. +    // Then set a "max" value for the number of probes you'll ever have, and use that to index into the arrays. +    // We do this with refmapCount.  The shaders will just pick up on it there. +    // This data structure should _always_ match what's in class3/deferred/reflectionProbeF.glsl. +    // The shader can and will break otherwise. +    // -Geenz 2025-03-10 +    struct ReflectionProbeData +    { +        // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of +        // 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]; + +        // extra parameters +        //  x - irradiance scale +        //  y - radiance scale +        //  z - fade in +        //  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 +        //  [i][2] - number of probes  that intersect this probe, or -1 for no neighbors +        //  [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes) +        GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; + +        // list of neighbor indices +        GLint refNeighbor[4096]; + +        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; +    }; +      // allocate an environment map of the given resolution      LLReflectionMapManager(); @@ -207,8 +252,12 @@ private:      // if true, reset all probe render state on the next update (for teleports and sky changes)      bool mReset = false; +    float mResetFade = 1.f; +      // if true, only update the default probe      bool mPaused = false;      F32 mResumeTime = 0.f; + +    ReflectionProbeData mProbeData;  }; diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 96de9e61cb..f1c7ab78d0 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -859,6 +859,23 @@    </combo_box>    <slider +    control_name="RenderReflectionProbeCount" +    decimal_digits="0" +    follows="left|top" +    height="16" +    increment="1" +    initial_value="256" +    label="Max. Reflection Probes:" +    label_width="145" +    layout="topleft" +    left="420" +    min_val="1" +    max_val="256" +    name="MaxProbes" +    top_delta="24" +    width="260" /> + +  <slider      control_name="RenderExposure"      decimal_digits="1"      follows="left|top" | 
