DRTVWR-559 Optimization pass on probe allocation and search. Incidental decruft.
parent
741c815966
commit
5d862c994c
|
|
@ -47,7 +47,11 @@ layout (std140) uniform ReflectionProbes
|
|||
mat4 refBox[MAX_REFMAP_COUNT];
|
||||
// list of bounding spheres for reflection probes sorted by distance to camera (closest first)
|
||||
vec4 refSphere[MAX_REFMAP_COUNT];
|
||||
// extra parameters (currently only .x used for probe ambiance)
|
||||
// extra parameters
|
||||
// x - irradiance scale
|
||||
// y - radiance scale
|
||||
// z - fade in
|
||||
// w - znear
|
||||
vec4 refParams[MAX_REFMAP_COUNT];
|
||||
// index of cube map in reflectionProbes for a corresponding reflection probe
|
||||
// e.g. cube map channel of refSphere[2] is stored in refIndex[2]
|
||||
|
|
@ -60,6 +64,8 @@ layout (std140) uniform ReflectionProbes
|
|||
// neighbor list data (refSphere indices, not cubemap array layer)
|
||||
ivec4 refNeighbor[1024];
|
||||
|
||||
ivec4 refBucket[256];
|
||||
|
||||
// number of reflection probes present in refSphere
|
||||
int refmapCount;
|
||||
};
|
||||
|
|
@ -118,13 +124,26 @@ bool shouldSampleProbe(int i, vec3 pos)
|
|||
return true;
|
||||
}
|
||||
|
||||
int getStartIndex(vec3 pos)
|
||||
{
|
||||
#if 1
|
||||
int idx = clamp(int(floor(-pos.z)), 0, 255);
|
||||
return clamp(refBucket[idx].x, 1, refmapCount+1);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// call before sampleRef
|
||||
// populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT
|
||||
void preProbeSample(vec3 pos)
|
||||
{
|
||||
#if REFMAP_LEVEL > 0
|
||||
|
||||
int start = getStartIndex(pos);
|
||||
|
||||
// TODO: make some sort of structure that reduces the number of distance checks
|
||||
for (int i = 1; i < refmapCount; ++i)
|
||||
for (int i = start; i < refmapCount; ++i)
|
||||
{
|
||||
// found an influencing probe
|
||||
if (shouldSampleProbe(i, pos))
|
||||
|
|
@ -142,6 +161,7 @@ void preProbeSample(vec3 pos)
|
|||
{
|
||||
// check up to REF_SAMPLE_COUNT-1 neighbors (neighborIdx is ivec4 index)
|
||||
|
||||
// sample refNeighbor[neighborIdx].x
|
||||
int idx = refNeighbor[neighborIdx].x;
|
||||
if (shouldSampleProbe(idx, pos))
|
||||
{
|
||||
|
|
@ -157,6 +177,7 @@ void preProbeSample(vec3 pos)
|
|||
break;
|
||||
}
|
||||
|
||||
// sample refNeighbor[neighborIdx].y
|
||||
idx = refNeighbor[neighborIdx].y;
|
||||
if (shouldSampleProbe(idx, pos))
|
||||
{
|
||||
|
|
@ -172,6 +193,7 @@ void preProbeSample(vec3 pos)
|
|||
break;
|
||||
}
|
||||
|
||||
// sample refNeighbor[neighborIdx].z
|
||||
idx = refNeighbor[neighborIdx].z;
|
||||
if (shouldSampleProbe(idx, pos))
|
||||
{
|
||||
|
|
@ -187,6 +209,7 @@ void preProbeSample(vec3 pos)
|
|||
break;
|
||||
}
|
||||
|
||||
// sample refNeighbor[neighborIdx].w
|
||||
idx = refNeighbor[neighborIdx].w;
|
||||
if (shouldSampleProbe(idx, pos))
|
||||
{
|
||||
|
|
@ -197,11 +220,7 @@ void preProbeSample(vec3 pos)
|
|||
}
|
||||
}
|
||||
count++;
|
||||
if (count == neighborCount)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
++neighborIdx;
|
||||
}
|
||||
|
||||
|
|
@ -735,6 +754,14 @@ vec4 sampleReflectionProbesDebug(vec3 pos)
|
|||
debugTapRefMap(pos, dir, d, i, col);
|
||||
}
|
||||
|
||||
#if 0 //debug getStartIndex
|
||||
col.g = float(getStartIndex(pos));
|
||||
|
||||
col.g /= 255.0;
|
||||
col.rb = vec2(0);
|
||||
col.a = 1.0;
|
||||
#endif
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,8 +78,12 @@ public:
|
|||
// point at which environment map was last generated from (in agent space)
|
||||
LLVector4a mOrigin;
|
||||
|
||||
// distance from viewer camera
|
||||
F32 mDistance;
|
||||
// distance from main viewer camera
|
||||
F32 mDistance = -1.f;
|
||||
|
||||
// Minimum and maximum depth in current render camera
|
||||
F32 mMinDepth = -1.f;
|
||||
F32 mMaxDepth = -1.f;
|
||||
|
||||
// radius of this probe's affected area
|
||||
F32 mRadius = 16.f;
|
||||
|
|
|
|||
|
|
@ -45,10 +45,13 @@ extern U32 nhpo2(U32 v);
|
|||
|
||||
static void touch_default_probe(LLReflectionMap* probe)
|
||||
{
|
||||
LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
|
||||
origin.mV[2] += 64.f;
|
||||
if (LLViewerCamera::getInstance())
|
||||
{
|
||||
LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
|
||||
origin.mV[2] += 64.f;
|
||||
|
||||
probe->mOrigin.load3(origin.mV);
|
||||
probe->mOrigin.load3(origin.mV);
|
||||
}
|
||||
}
|
||||
|
||||
LLReflectionMapManager::LLReflectionMapManager()
|
||||
|
|
@ -58,17 +61,17 @@ LLReflectionMapManager::LLReflectionMapManager()
|
|||
|
||||
void LLReflectionMapManager::initCubeFree()
|
||||
{
|
||||
// start at 1 because index 0 is reserved for mDefaultProbe
|
||||
for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i)
|
||||
{
|
||||
mCubeFree[i] = true;
|
||||
mCubeFree.push_back(i);
|
||||
}
|
||||
|
||||
// cube index 0 is reserved for the fallback probe
|
||||
mCubeFree[0] = false;
|
||||
}
|
||||
|
||||
struct CompareProbeDistance
|
||||
{
|
||||
LLReflectionMap* mDefaultProbe;
|
||||
|
||||
bool operator()(const LLPointer<LLReflectionMap>& lhs, const LLPointer<LLReflectionMap>& rhs)
|
||||
{
|
||||
return lhs->mDistance < rhs->mDistance;
|
||||
|
|
@ -83,7 +86,15 @@ static F32 update_score(LLReflectionMap* p)
|
|||
// return true if a is higher priority for an update than b
|
||||
static bool check_priority(LLReflectionMap* a, LLReflectionMap* b)
|
||||
{
|
||||
if (!a->mComplete && !b->mComplete)
|
||||
if (a->mCubeIndex == -1)
|
||||
{ // not a candidate for updating
|
||||
return false;
|
||||
}
|
||||
else if (b->mCubeIndex == -1)
|
||||
{ // certainly higher priority than b
|
||||
return true;
|
||||
}
|
||||
else if (!a->mComplete && !b->mComplete)
|
||||
{ //neither probe is complete, use distance
|
||||
return a->mDistance < b->mDistance;
|
||||
}
|
||||
|
|
@ -133,14 +144,7 @@ void LLReflectionMapManager::update()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (mDefaultProbe.isNull())
|
||||
{
|
||||
mDefaultProbe = addProbe();
|
||||
mDefaultProbe->mDistance = -4096.f; // hack to make sure the default probe is always first in sort order
|
||||
mDefaultProbe->mRadius = 4096.f;
|
||||
touch_default_probe(mDefaultProbe);
|
||||
}
|
||||
llassert(mProbes[0] == mDefaultProbe);
|
||||
|
||||
LLVector4a camera_pos;
|
||||
camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
|
||||
|
|
@ -170,6 +174,7 @@ void LLReflectionMapManager::update()
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
bool did_update = false;
|
||||
|
||||
static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
|
||||
|
|
@ -188,7 +193,46 @@ void LLReflectionMapManager::update()
|
|||
doProbeUpdate();
|
||||
}
|
||||
|
||||
//LL_INFOS() << mProbes.size() << LL_ENDL;
|
||||
// update distance to camera for all probes
|
||||
std::sort(mProbes.begin()+1, mProbes.end(), CompareProbeDistance());
|
||||
llassert(mProbes[0] == mDefaultProbe);
|
||||
llassert(mProbes[0]->mCubeArray == mTexture);
|
||||
llassert(mProbes[0]->mCubeIndex == 0);
|
||||
|
||||
// make sure we're assigning cube slots to the closest probes
|
||||
|
||||
// first free any cube indices for distant probes
|
||||
for (U32 i = mReflectionProbeCount; i < mProbes.size(); ++i)
|
||||
{
|
||||
LLReflectionMap* probe = mProbes[i];
|
||||
llassert(probe != nullptr);
|
||||
|
||||
if (probe->mCubeIndex != -1 && mUpdatingProbe != probe)
|
||||
{ // free this index
|
||||
mCubeFree.push_back(probe->mCubeIndex);
|
||||
|
||||
probe->mCubeArray = nullptr;
|
||||
probe->mCubeIndex = -1;
|
||||
probe->mComplete = false;
|
||||
}
|
||||
}
|
||||
|
||||
// next distribute the free indices
|
||||
U32 count = llmin(mReflectionProbeCount, (U32)mProbes.size());
|
||||
|
||||
for (S32 i = 1; i < count && !mCubeFree.empty(); ++i)
|
||||
{
|
||||
// find the closest probe that needs a cube index
|
||||
LLReflectionMap* probe = mProbes[i];
|
||||
|
||||
if (probe->mCubeIndex == -1)
|
||||
{
|
||||
S32 idx = allocateCubeIndex();
|
||||
llassert(idx > 0); //if we're still in this loop, mCubeFree should not be empty and allocateCubeIndex should be returning good indices
|
||||
probe->mCubeArray = mTexture;
|
||||
probe->mCubeIndex = idx;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mProbes.size(); ++i)
|
||||
{
|
||||
|
|
@ -205,8 +249,6 @@ void LLReflectionMapManager::update()
|
|||
continue;
|
||||
}
|
||||
|
||||
probe->mProbeIndex = i;
|
||||
|
||||
LLVector4a d;
|
||||
|
||||
if (probe != mDefaultProbe)
|
||||
|
|
@ -219,6 +261,10 @@ void LLReflectionMapManager::update()
|
|||
// make default probe have a distance of 64m for the purposes of prioritization (if it's already been generated once)
|
||||
probe->mDistance = 64.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
probe->mDistance = -4096.f; //boost priority of default probe when it's not complete
|
||||
}
|
||||
|
||||
if (probe->mComplete)
|
||||
{
|
||||
|
|
@ -288,13 +334,8 @@ void LLReflectionMapManager::update()
|
|||
if (!did_update && oldestProbe != nullptr)
|
||||
{
|
||||
LLReflectionMap* probe = oldestProbe;
|
||||
if (probe->mCubeIndex == -1)
|
||||
{
|
||||
probe->mCubeArray = mTexture;
|
||||
|
||||
probe->mCubeIndex = probe == mDefaultProbe ? 0 : allocateCubeIndex();
|
||||
}
|
||||
|
||||
llassert(probe->mCubeIndex != -1);
|
||||
|
||||
probe->autoAdjustOrigin();
|
||||
|
||||
mUpdatingProbe = probe;
|
||||
|
|
@ -307,10 +348,6 @@ void LLReflectionMapManager::update()
|
|||
oldestOccluded->autoAdjustOrigin();
|
||||
oldestOccluded->mLastUpdateTime = gFrameTimeSeconds;
|
||||
}
|
||||
|
||||
// update distance to camera for all probes
|
||||
mDefaultProbe->mDistance = -4096.f; // make default probe always end up at index 0
|
||||
std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance());
|
||||
}
|
||||
|
||||
LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
|
||||
|
|
@ -318,6 +355,14 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
|
|||
LLReflectionMap* probe = new LLReflectionMap();
|
||||
probe->mGroup = group;
|
||||
|
||||
if (mDefaultProbe.isNull())
|
||||
{ //safety check to make sure default probe is always first probe added
|
||||
mDefaultProbe = new LLReflectionMap();
|
||||
mProbes.push_back(mDefaultProbe);
|
||||
}
|
||||
|
||||
llassert(mProbes[0] == mDefaultProbe);
|
||||
|
||||
if (group)
|
||||
{
|
||||
probe->mOrigin = group->getOctreeNode()->getCenter();
|
||||
|
|
@ -335,10 +380,22 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
|
|||
return probe;
|
||||
}
|
||||
|
||||
struct CompareProbeDepth
|
||||
{
|
||||
bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs)
|
||||
{
|
||||
return lhs->mMinDepth < rhs->mMinDepth;
|
||||
}
|
||||
};
|
||||
|
||||
void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& maps)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
|
||||
LLMatrix4a modelview;
|
||||
modelview.loadu(gGLModelView);
|
||||
LLVector4a oa; // scratch space for transformed origin
|
||||
|
||||
U32 count = 0;
|
||||
U32 lastIdx = 0;
|
||||
for (U32 i = 0; count < maps.size() && i < mProbes.size(); ++i)
|
||||
|
|
@ -348,8 +405,10 @@ void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& ma
|
|||
{
|
||||
if (!mProbes[i]->mOccluded && mProbes[i]->mComplete)
|
||||
{
|
||||
mProbes[i]->mProbeIndex = count;
|
||||
maps[count++] = mProbes[i];
|
||||
modelview.affineTransform(mProbes[i]->mOrigin, oa);
|
||||
mProbes[i]->mMinDepth = -oa.getF32ptr()[2] - mProbes[i]->mRadius;
|
||||
mProbes[i]->mMaxDepth = -oa.getF32ptr()[2] + mProbes[i]->mRadius;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -365,6 +424,16 @@ void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& ma
|
|||
mProbes[i]->mProbeIndex = -1;
|
||||
}
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
std::sort(maps.begin(), maps.begin() + count, CompareProbeDepth());
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < count; ++i)
|
||||
{
|
||||
maps[i]->mProbeIndex = i;
|
||||
}
|
||||
|
||||
// null terminate list
|
||||
if (count < maps.size())
|
||||
{
|
||||
|
|
@ -407,32 +476,15 @@ LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vo
|
|||
return probe;
|
||||
}
|
||||
|
||||
|
||||
S32 LLReflectionMapManager::allocateCubeIndex()
|
||||
{
|
||||
for (int i = 0; i < mReflectionProbeCount; ++i)
|
||||
if (!mCubeFree.empty())
|
||||
{
|
||||
if (mCubeFree[i])
|
||||
{
|
||||
mCubeFree[i] = false;
|
||||
return i;
|
||||
}
|
||||
S32 ret = mCubeFree.front();
|
||||
mCubeFree.pop_front();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// no cubemaps free, steal one from the back of the probe list
|
||||
for (int i = mProbes.size() - 1; i >= mReflectionProbeCount; --i)
|
||||
{
|
||||
if (mProbes[i]->mCubeIndex != -1)
|
||||
{
|
||||
S32 ret = mProbes[i]->mCubeIndex;
|
||||
mProbes[i]->mCubeIndex = -1;
|
||||
mProbes[i]->mCubeArray = nullptr;
|
||||
mProbes[i]->mComplete = false;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
llassert(false); // should never fail to allocate, something is probably wrong with mCubeFree
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -445,7 +497,7 @@ void LLReflectionMapManager::deleteProbe(U32 i)
|
|||
|
||||
if (probe->mCubeIndex != -1)
|
||||
{ // mark the cube index used by this probe as being free
|
||||
mCubeFree[probe->mCubeIndex] = true;
|
||||
mCubeFree.push_back(probe->mCubeIndex);
|
||||
}
|
||||
if (mUpdatingProbe == probe)
|
||||
{
|
||||
|
|
@ -776,13 +828,14 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe)
|
|||
}
|
||||
|
||||
// search for new neighbors
|
||||
if (probe->isRelevant())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search");
|
||||
for (auto& other : mProbes)
|
||||
{
|
||||
if (other != mDefaultProbe && other != probe)
|
||||
{
|
||||
if (probe->intersects(other))
|
||||
if (other->isRelevant() && probe->intersects(other))
|
||||
{
|
||||
probe->mNeighbors.push_back(other);
|
||||
other->mNeighbors.push_back(probe);
|
||||
|
|
@ -816,6 +869,7 @@ void LLReflectionMapManager::updateUniforms()
|
|||
// x - irradiance scale
|
||||
// y - radiance scale
|
||||
// z - fade in
|
||||
// w - znear
|
||||
LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT];
|
||||
|
||||
// indices used by probe:
|
||||
|
|
@ -828,6 +882,7 @@ void LLReflectionMapManager::updateUniforms()
|
|||
// 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;
|
||||
};
|
||||
|
|
@ -837,6 +892,17 @@ void LLReflectionMapManager::updateUniforms()
|
|||
|
||||
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;
|
||||
minDepth[i] = FLT_MAX;
|
||||
}
|
||||
|
||||
// load modelview matrix into matrix 4a
|
||||
LLMatrix4a modelview;
|
||||
modelview.loadu(gGLModelView);
|
||||
|
|
@ -861,6 +927,28 @@ void LLReflectionMapManager::updateUniforms()
|
|||
break;
|
||||
}
|
||||
|
||||
if (refmap != mDefaultProbe)
|
||||
{
|
||||
// bucket search data
|
||||
// theory of operation:
|
||||
// 1. Determine minimum and maximum depth of each influence volume and store in mDepth (done in getReflectionMaps)
|
||||
// 2. Sort by minimum depth
|
||||
// 3. Prepare a bucket for each 1m of depth out to 256m
|
||||
// 4. For each bucket, store the index of the nearest probe that might influence pixels in that bucket
|
||||
// 5. In the shader, lookup the bucket for the pixel depth to get the index of the first probe that could possibly influence
|
||||
// the current pixel.
|
||||
int depth_min = llclamp(llfloor(refmap->mMinDepth), 0, 255);
|
||||
int depth_max = llclamp(llfloor(refmap->mMaxDepth), 0, 255);
|
||||
for (U32 i = depth_min; i <= depth_max; ++i)
|
||||
{
|
||||
if (refmap->mMinDepth < minDepth[i])
|
||||
{
|
||||
minDepth[i] = refmap->mMinDepth;
|
||||
rpd.refBucket[i][0] = refmap->mProbeIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
llassert(refmap->mProbeIndex == count);
|
||||
llassert(mReflectionMaps[refmap->mProbeIndex] == refmap);
|
||||
|
||||
|
|
@ -890,7 +978,11 @@ void LLReflectionMapManager::updateUniforms()
|
|||
rpd.refIndex[count][3] = -rpd.refIndex[count][3];
|
||||
}
|
||||
|
||||
rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, refmap->mFadeIn, 0.f);
|
||||
rpd.refParams[count].set(
|
||||
llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale
|
||||
radscale, // radiance scale
|
||||
refmap->mFadeIn, // fade in weight
|
||||
oa.getF32ptr()[2] - refmap->mRadius); // z near
|
||||
|
||||
S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors
|
||||
{
|
||||
|
|
@ -907,7 +999,7 @@ void LLReflectionMapManager::updateUniforms()
|
|||
}
|
||||
|
||||
GLint idx = neighbor->mProbeIndex;
|
||||
if (idx == -1 || neighbor->mOccluded)
|
||||
if (idx == -1 || neighbor->mOccluded || neighbor->mCubeIndex == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -944,6 +1036,30 @@ void LLReflectionMapManager::updateUniforms()
|
|||
count++;
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
// fill in gaps in refBucket
|
||||
S32 probe_idx = mReflectionProbeCount;
|
||||
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
if (i < count)
|
||||
{ // for debugging, store depth of mReflectionsMaps[i]
|
||||
rpd.refBucket[i][1] = (S32) (mReflectionMaps[i]->mDepth * 10);
|
||||
}
|
||||
|
||||
if (rpd.refBucket[i][0] == mReflectionProbeCount)
|
||||
{
|
||||
rpd.refBucket[i][0] = probe_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
probe_idx = rpd.refBucket[i][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rpd.refmapCount = count;
|
||||
|
||||
//copy rpd into uniform buffer object
|
||||
|
|
@ -958,6 +1074,21 @@ void LLReflectionMapManager::updateUniforms()
|
|||
glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!gCubeSnapshot)
|
||||
{
|
||||
for (auto& probe : mProbes)
|
||||
{
|
||||
LLViewerObject* vobj = probe->mViewerObject;
|
||||
if (vobj)
|
||||
{
|
||||
F32 time = (F32)gFrameTimeSeconds - probe->mLastUpdateTime;
|
||||
vobj->setDebugText(llformat("%d/%d/%d/%.1f - %.1f/%.1f", probe->mCubeIndex, probe->mProbeIndex, (U32) probe->mNeighbors.size(), probe->mMinDepth, probe->mMaxDepth, time), time > 1.f ? LLColor4::white : LLColor4::green);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLReflectionMapManager::setUniforms()
|
||||
|
|
@ -977,37 +1108,40 @@ void LLReflectionMapManager::setUniforms()
|
|||
|
||||
void renderReflectionProbe(LLReflectionMap* probe)
|
||||
{
|
||||
F32* po = probe->mOrigin.getF32ptr();
|
||||
|
||||
//draw orange line from probe to neighbors
|
||||
gGL.flush();
|
||||
gGL.diffuseColor4f(1, 0.5f, 0, 1);
|
||||
gGL.begin(gGL.LINES);
|
||||
for (auto& neighbor : probe->mNeighbors)
|
||||
if (probe->isRelevant())
|
||||
{
|
||||
if (probe->mViewerObject && neighbor->mViewerObject)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gGL.vertex3fv(po);
|
||||
gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
F32* po = probe->mOrigin.getF32ptr();
|
||||
|
||||
gGL.diffuseColor4f(1, 1, 0, 1);
|
||||
gGL.begin(gGL.LINES);
|
||||
for (auto& neighbor : probe->mNeighbors)
|
||||
{
|
||||
if (probe->mViewerObject && neighbor->mViewerObject)
|
||||
//draw orange line from probe to neighbors
|
||||
gGL.flush();
|
||||
gGL.diffuseColor4f(1, 0.5f, 0, 1);
|
||||
gGL.begin(gGL.LINES);
|
||||
for (auto& neighbor : probe->mNeighbors)
|
||||
{
|
||||
if (probe->mViewerObject && neighbor->mViewerObject)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gGL.vertex3fv(po);
|
||||
gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
|
||||
gGL.diffuseColor4f(1, 1, 0, 1);
|
||||
gGL.begin(gGL.LINES);
|
||||
for (auto& neighbor : probe->mNeighbors)
|
||||
{
|
||||
if (probe->mViewerObject && neighbor->mViewerObject)
|
||||
{
|
||||
gGL.vertex3fv(po);
|
||||
gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
|
||||
}
|
||||
}
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
}
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
|
||||
#if 0
|
||||
LLSpatialGroup* group = probe->mGroup;
|
||||
|
|
@ -1095,7 +1229,6 @@ void LLReflectionMapManager::initReflectionMaps()
|
|||
mUpdatingProbe = nullptr;
|
||||
mRadiancePass = false;
|
||||
mRealtimeRadiancePass = false;
|
||||
mDefaultProbe = nullptr;
|
||||
|
||||
for (auto& probe : mProbes)
|
||||
{
|
||||
|
|
@ -1104,14 +1237,28 @@ void LLReflectionMapManager::initReflectionMaps()
|
|||
probe->mProbeIndex = -1;
|
||||
probe->mCubeArray = nullptr;
|
||||
probe->mCubeIndex = -1;
|
||||
probe->mNeighbors.clear();
|
||||
}
|
||||
|
||||
for (bool& is_free : mCubeFree)
|
||||
mCubeFree.clear();
|
||||
initCubeFree();
|
||||
|
||||
if (mDefaultProbe.isNull())
|
||||
{
|
||||
is_free = true;
|
||||
llassert(mProbes.empty()); // default probe MUST be the first probe created
|
||||
mDefaultProbe = new LLReflectionMap();
|
||||
mProbes.push_back(mDefaultProbe);
|
||||
}
|
||||
|
||||
mCubeFree[0] = false;
|
||||
llassert(mProbes[0] == mDefaultProbe);
|
||||
|
||||
mDefaultProbe->mCubeIndex = 0;
|
||||
mDefaultProbe->mCubeArray = mTexture;
|
||||
mDefaultProbe->mDistance = 64.f;
|
||||
mDefaultProbe->mRadius = 4096.f;
|
||||
mDefaultProbe->mProbeIndex = 0;
|
||||
touch_default_probe(mDefaultProbe);
|
||||
|
||||
}
|
||||
|
||||
if (mVertexBuffer.isNull())
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ private:
|
|||
void deleteProbe(U32 i);
|
||||
|
||||
// get a free cube index
|
||||
// if no cube indices are free, free one starting from the back of the probe list
|
||||
// returns -1 if allocation failed
|
||||
S32 allocateCubeIndex();
|
||||
|
||||
// update the neighbors of the given probe
|
||||
|
|
@ -137,12 +137,9 @@ private:
|
|||
// storage for reflection probe irradiance maps
|
||||
LLPointer<LLCubeMapArray> mIrradianceMaps;
|
||||
|
||||
// array indicating if a particular cubemap is free
|
||||
bool mCubeFree[LL_MAX_REFLECTION_PROBE_COUNT];
|
||||
// list of free cubemap indices
|
||||
std::list<S32> mCubeFree;
|
||||
|
||||
// start tracking the given spatial group
|
||||
void trackGroup(LLSpatialGroup* group);
|
||||
|
||||
// perform an update on the currently updating Probe
|
||||
void doProbeUpdate();
|
||||
|
||||
|
|
|
|||
|
|
@ -5689,7 +5689,7 @@ S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
|
|||
return count;
|
||||
}
|
||||
|
||||
void LLViewerObject::setDebugText(const std::string &utf8text)
|
||||
void LLViewerObject::setDebugText(const std::string &utf8text, const LLColor4& color)
|
||||
{
|
||||
if (utf8text.empty() && !mText)
|
||||
{
|
||||
|
|
@ -5700,7 +5700,7 @@ void LLViewerObject::setDebugText(const std::string &utf8text)
|
|||
{
|
||||
initHudText();
|
||||
}
|
||||
mText->setColor(LLColor4::white);
|
||||
mText->setColor(color);
|
||||
mText->setString(utf8text);
|
||||
mText->setZCompare(FALSE);
|
||||
mText->setDoFade(FALSE);
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ public:
|
|||
|
||||
void sendMaterialUpdate() const;
|
||||
|
||||
void setDebugText(const std::string &utf8text);
|
||||
void setDebugText(const std::string &utf8text, const LLColor4& color = LLColor4::white);
|
||||
void appendDebugText(const std::string &utf8text);
|
||||
void initHudText();
|
||||
void restoreHudText();
|
||||
|
|
|
|||
|
|
@ -6912,7 +6912,8 @@ void LLPipeline::bindScreenToTexture()
|
|||
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
|
||||
|
||||
void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex) {
|
||||
void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex)
|
||||
{
|
||||
dst->bindTarget();
|
||||
gDeferredBufferVisualProgram.bind();
|
||||
gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex);
|
||||
|
|
@ -6929,7 +6930,8 @@ void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32
|
|||
dst->flush();
|
||||
}
|
||||
|
||||
void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) {
|
||||
void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst)
|
||||
{
|
||||
// luminance sample and mipmap generation
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("luminance sample");
|
||||
|
|
@ -7054,7 +7056,8 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
|
|||
dst->flush();
|
||||
}
|
||||
|
||||
void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) {
|
||||
void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst)
|
||||
{
|
||||
|
||||
if (RenderScreenSpaceReflections && !gCubeSnapshot)
|
||||
{
|
||||
|
|
@ -7080,7 +7083,8 @@ void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget*
|
|||
}
|
||||
}
|
||||
|
||||
void LLPipeline::generateGlow(LLRenderTarget* src) {
|
||||
void LLPipeline::generateGlow(LLRenderTarget* src)
|
||||
{
|
||||
if (sRenderGlow)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("glow");
|
||||
|
|
@ -7177,7 +7181,8 @@ void LLPipeline::generateGlow(LLRenderTarget* src) {
|
|||
}
|
||||
}
|
||||
|
||||
void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
|
||||
void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
|
||||
{
|
||||
{
|
||||
llassert(!gCubeSnapshot);
|
||||
bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
|
||||
|
|
@ -7257,7 +7262,8 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
|
|||
}
|
||||
}
|
||||
|
||||
void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) {
|
||||
void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst)
|
||||
{
|
||||
|
||||
LL_PROFILE_GPU_ZONE("copyRenderTarget");
|
||||
dst->bindTarget();
|
||||
|
|
@ -7277,7 +7283,8 @@ void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) {
|
|||
dst->flush();
|
||||
}
|
||||
|
||||
void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) {
|
||||
void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst)
|
||||
{
|
||||
// Go ahead and do our glow combine here in our destination. We blit this later into the front buffer.
|
||||
|
||||
dst->bindTarget();
|
||||
|
|
@ -7296,7 +7303,8 @@ void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) {
|
|||
dst->flush();
|
||||
}
|
||||
|
||||
void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
|
||||
void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst)
|
||||
{
|
||||
{
|
||||
bool dof_enabled =
|
||||
(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
|
||||
|
|
@ -7462,10 +7470,12 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
|
|||
{ // combine result based on alpha
|
||||
|
||||
dst->bindTarget();
|
||||
if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete()) {
|
||||
if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete())
|
||||
{
|
||||
glViewport(0, 0, dst->getWidth(), dst->getHeight());
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
|
||||
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
|
||||
gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
|
||||
|
|
@ -7500,6 +7510,7 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
|
|||
|
||||
void LLPipeline::renderFinalize()
|
||||
{
|
||||
llassert(!gCubeSnapshot);
|
||||
LLVertexBuffer::unbind();
|
||||
LLGLState::checkStates();
|
||||
|
||||
|
|
@ -7520,22 +7531,20 @@ void LLPipeline::renderFinalize()
|
|||
gGL.setColorMask(true, true);
|
||||
glClearColor(0, 0, 0, 0);
|
||||
|
||||
if (!gCubeSnapshot)
|
||||
{
|
||||
copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
|
||||
|
||||
copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
|
||||
|
||||
generateLuminance(&mRT->screen, &mLuminanceMap);
|
||||
generateLuminance(&mRT->screen, &mLuminanceMap);
|
||||
|
||||
generateExposure(&mLuminanceMap, &mExposureMap);
|
||||
generateExposure(&mLuminanceMap, &mExposureMap);
|
||||
|
||||
gammaCorrect(&mRT->screen, &mPostMap);
|
||||
gammaCorrect(&mRT->screen, &mPostMap);
|
||||
|
||||
LLVertexBuffer::unbind();
|
||||
}
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
generateGlow(&mPostMap);
|
||||
generateGlow(&mPostMap);
|
||||
|
||||
combineGlow(&mPostMap, &mRT->screen);
|
||||
combineGlow(&mPostMap, &mRT->screen);
|
||||
|
||||
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
|
||||
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
|
||||
|
|
@ -7547,7 +7556,8 @@ void LLPipeline::renderFinalize()
|
|||
|
||||
applyFXAA(&mPostMap, &mRT->screen);
|
||||
LLRenderTarget* finalBuffer = &mRT->screen;
|
||||
if (RenderBufferVisualization > -1) {
|
||||
if (RenderBufferVisualization > -1)
|
||||
{
|
||||
finalBuffer = &mPostMap;
|
||||
switch (RenderBufferVisualization)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue