summaryrefslogtreecommitdiff
path: root/indra/newview/llreflectionmapmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llreflectionmapmanager.cpp')
-rw-r--r--indra/newview/llreflectionmapmanager.cpp166
1 files changed, 90 insertions, 76 deletions
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 2708d5edf0..9c95dc8e4b 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -144,13 +144,14 @@ static void touch_default_probe(LLReflectionMap* probe)
LLReflectionMapManager::LLReflectionMapManager()
{
+ mDynamicProbeCount = LL_MAX_REFLECTION_PROBE_COUNT;
initCubeFree();
}
void LLReflectionMapManager::initCubeFree()
{
// start at 1 because index 0 is reserved for mDefaultProbe
- for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i)
+ for (U32 i = 1; i < mDynamicProbeCount; ++i)
{
mCubeFree.push_back(i);
}
@@ -221,7 +222,50 @@ void LLReflectionMapManager::update()
resume();
}
- initReflectionMaps();
+ static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
+ static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
+
+ // Once every 20 frames, update the dynamic probe count.
+ if (gFrameCount % 20)
+ {
+ U32 probe_count_temp = mDynamicProbeCount;
+ if (sLevel == 0)
+ {
+ mDynamicProbeCount = 1;
+ }
+ else if (sLevel == 1)
+ {
+ mDynamicProbeCount = (U32)mProbes.size();
+
+ }
+ else if (sLevel == 2)
+ {
+ mDynamicProbeCount = llmax((U32)mProbes.size(), 128);
+ }
+ else
+ {
+ mDynamicProbeCount = 256;
+ }
+
+ // Round mDynamicProbeCount to the nearest increment of 32
+ mDynamicProbeCount = ((mDynamicProbeCount + 16) / 32) * 32;
+ mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, LL_MAX_REFLECTION_PROBE_COUNT);
+
+ if (mDynamicProbeCount < probe_count_temp * 1.1 && mDynamicProbeCount > probe_count_temp * 0.9)
+ mDynamicProbeCount = probe_count_temp;
+ else
+ mGlobalFadeTarget = 0.f;
+ }
+
+ if (mGlobalFadeTarget < mResetFade)
+ mResetFade = llmax(mGlobalFadeTarget, mResetFade - (F32)gFrameIntervalSeconds * 2);
+ else
+ mResetFade = llmin(mGlobalFadeTarget, mResetFade + (F32)gFrameIntervalSeconds * 2);
+
+ if (mResetFade == mGlobalFadeTarget)
+ {
+ initReflectionMaps();
+ }
static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
@@ -278,9 +322,6 @@ void LLReflectionMapManager::update()
bool did_update = false;
- static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
- static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
-
bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME;
LLReflectionMap* closestDynamic = nullptr;
@@ -335,6 +376,8 @@ void LLReflectionMapManager::update()
}
}
+ mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f);
+
for (unsigned int i = 0; i < mProbes.size(); ++i)
{
LLReflectionMap* probe = mProbes[i];
@@ -505,6 +548,16 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
return probe;
}
+U32 LLReflectionMapManager::probeCount()
+{
+ return mDynamicProbeCount;
+}
+
+U32 LLReflectionMapManager::probeMemory()
+{
+ return (mDynamicProbeCount * 6 * (mProbeResolution * mProbeResolution) * 4) / 1024 / 1024 + (mDynamicProbeCount * 6 * (LL_IRRADIANCE_MAP_RESOLUTION * LL_IRRADIANCE_MAP_RESOLUTION) * 4) / 1024 / 1024;
+}
+
struct CompareProbeDepth
{
bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs)
@@ -1022,60 +1075,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;
}
@@ -1095,7 +1106,11 @@ void LLReflectionMapManager::updateUniforms()
bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass();
F32 ambscale = is_ambiance_pass ? 0.f : 1.f;
+ ambscale *= mResetFade;
+ ambscale = llmax(0, ambscale);
F32 radscale = is_ambiance_pass ? 0.5f : 1.f;
+ radscale *= mResetFade;
+ radscale = llmax(0, radscale);
for (auto* refmap : mReflectionMaps)
{
@@ -1121,7 +1136,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;
}
}
}
@@ -1149,23 +1164,23 @@ 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(
+ mProbeData.refParams[count].set(
llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale
radscale, // radiance scale
refmap->mFadeIn, // fade in weight
@@ -1192,7 +1207,7 @@ void LLReflectionMapManager::updateUniforms()
}
// this neighbor may be sampled
- rpd.refNeighbor[ni++] = idx;
+ mProbeData.refNeighbor[ni++] = idx;
neighbor_count++;
if (neighbor_count >= max_neighbors)
@@ -1205,11 +1220,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;
@@ -1247,19 +1262,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);
@@ -1268,7 +1283,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);
}
@@ -1402,11 +1417,9 @@ void LLReflectionMapManager::renderDebug()
void LLReflectionMapManager::initReflectionMaps()
{
- U32 count = LL_MAX_REFLECTION_PROBE_COUNT;
-
static LLCachedControl<U32> ref_probe_res(gSavedSettings, "RenderReflectionProbeResolution", 128U);
U32 probe_resolution = nhpo2(llclamp(ref_probe_res(), (U32)64, (U32)512));
- if (mTexture.isNull() || mReflectionProbeCount != count || mProbeResolution != probe_resolution || mReset)
+ if (mTexture.isNull() || mReflectionProbeCount != mDynamicProbeCount || mProbeResolution != probe_resolution || mReset)
{
if(mProbeResolution != probe_resolution)
{
@@ -1415,9 +1428,10 @@ void LLReflectionMapManager::initReflectionMaps()
}
gEXRImage = nullptr;
-
+ mGlobalFadeTarget = 1.f;
+ mResetFade = -0.125f;
mReset = false;
- mReflectionProbeCount = count;
+ mReflectionProbeCount = mDynamicProbeCount;
mProbeResolution = probe_resolution;
mMaxProbeLOD = log2f((F32)mProbeResolution) - 1.f; // number of mips - 1