From 93260cfeff2382dd1ffeecaef208d37bf21c2a01 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 4 May 2022 16:07:50 +0000 Subject: SL-17283 LLReflectionMapManager prototype. Remove snapshot code related overhead from reflection map renders. Add parallax correction and support for multiple reflection maps. --- indra/newview/llreflectionmapmanager.cpp | 106 +++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 indra/newview/llreflectionmapmanager.cpp (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp new file mode 100644 index 0000000000..95b72e1d3b --- /dev/null +++ b/indra/newview/llreflectionmapmanager.cpp @@ -0,0 +1,106 @@ +/** + * @file llreflectionmapmanager.cpp + * @brief LLReflectionMapManager class implementation + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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 "llreflectionmapmanager.h" +#include "llviewercamera.h" + +LLReflectionMapManager::LLReflectionMapManager() +{ + +} + +struct CompareReflectionMapDistance +{ + +}; + + +struct CompareProbeDistance +{ + bool operator()(const LLReflectionMap& lhs, const LLReflectionMap& rhs) + { + return lhs.mDistance < rhs.mDistance; + } +}; + +// helper class to seed octree with probes +void LLReflectionMapManager::update() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + + // naively drop probes every 16m as we move the camera around for now + // later, use LLSpatialPartition to manage probes + const F32 PROBE_SPACING = 16.f; + const U32 MAX_PROBES = 8; + + LLVector4a camera_pos; + camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); + + for (auto& probe : mProbes) + { + LLVector4a d; + d.setSub(camera_pos, probe.mOrigin); + probe.mDistance = d.getLength3().getF32(); + } + + if (mProbes.empty() || mProbes[0].mDistance > PROBE_SPACING) + { + addProbe(LLViewerCamera::instance().getOrigin()); + } + + // update distance to camera for all probes + std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance()); + + if (mProbes.size() > MAX_PROBES) + { + mProbes.resize(MAX_PROBES); + } +} + +void LLReflectionMapManager::addProbe(const LLVector3& pos) +{ + LLReflectionMap probe; + probe.update(pos, 1024); + mProbes.push_back(probe); +} + +void LLReflectionMapManager::getReflectionMaps(std::vector& maps) +{ + // just null out for now + U32 i = 0; + for (i = 0; i < maps.size() && i < mProbes.size(); ++i) + { + maps[i] = &(mProbes[i]); + } + + for (++i; i < maps.size(); ++i) + { + maps[i] = nullptr; + } +} + -- cgit v1.2.3 From 3400e5fd302c0d9dea6386c4d5bf38876f2cc287 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 16 May 2022 17:21:08 +0000 Subject: SL-17284 Reflection probe tuning and optimization take 1 --- indra/newview/llreflectionmapmanager.cpp | 516 +++++++++++++++++++++++++++++-- 1 file changed, 493 insertions(+), 23 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 95b72e1d3b..a6b704d57d 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -28,30 +28,84 @@ #include "llreflectionmapmanager.h" #include "llviewercamera.h" +#include "llspatialpartition.h" +#include "llviewerregion.h" +#include "pipeline.h" +#include "llviewershadermgr.h" + +extern BOOL gCubeSnapshot; +extern BOOL gTeleportDisplay; + +//#pragma optimize("", off) LLReflectionMapManager::LLReflectionMapManager() { - + for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) + { + mCubeFree[i] = true; + } } struct CompareReflectionMapDistance { - + }; struct CompareProbeDistance { - bool operator()(const LLReflectionMap& lhs, const LLReflectionMap& rhs) + bool operator()(const LLPointer& lhs, const LLPointer& rhs) { - return lhs.mDistance < rhs.mDistance; + return lhs->mDistance < rhs->mDistance; } }; // helper class to seed octree with probes void LLReflectionMapManager::update() { + if (!LLPipeline::sRenderDeferred || gTeleportDisplay) + { + return; + } + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + llassert(!gCubeSnapshot); // assert a snapshot is not in progress + if (LLAppViewer::instance()->logoutRequestSent()) + { + return; + } + + // =============== TODO -- move to an init function ================= + + if (mTexture.isNull()) + { + mTexture = new LLCubeMapArray(); + mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT); + } + + if (!mRenderTarget.isComplete()) + { + U32 color_fmt = GL_RGBA; + const bool use_depth_buffer = true; + const bool use_stencil_buffer = true; + U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 4; // super sample + mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE); + } + + if (mMipChain.empty()) + { + U32 res = LL_REFLECTION_PROBE_RESOLUTION*2; + U32 count = log2((F32)res) + 0.5f; + + mMipChain.resize(count); + for (int i = 0; i < count; ++i) + { + mMipChain[i].allocate(res, res, GL_RGB, false, false, LLTexUnit::TT_RECT_TEXTURE); + res /= 2; + } + } + + // =============== TODO -- move to an init function ================= // naively drop probes every 16m as we move the camera around for now // later, use LLSpatialPartition to manage probes @@ -61,46 +115,462 @@ void LLReflectionMapManager::update() LLVector4a camera_pos; camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); - for (auto& probe : mProbes) + // process kill list + for (int i = 0; i < mProbes.size(); ) { - LLVector4a d; - d.setSub(camera_pos, probe.mOrigin); - probe.mDistance = d.getLength3().getF32(); + auto& iter = std::find(mKillList.begin(), mKillList.end(), mProbes[i]); + if (iter != mKillList.end()) + { + deleteProbe(i); + mProbes.erase(mProbes.begin() + i); + mKillList.erase(iter); + } + else + { + ++i; + } } - if (mProbes.empty() || mProbes[0].mDistance > PROBE_SPACING) + mKillList.clear(); + + // process create list + for (auto& probe : mCreateList) { - addProbe(LLViewerCamera::instance().getOrigin()); + mProbes.push_back(probe); } - // update distance to camera for all probes - std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance()); + mCreateList.clear(); + + const F32 UPDATE_INTERVAL = 10.f; //update no more than once every 5 seconds + + bool did_update = false; + + if (mUpdatingProbe != nullptr) + { + did_update = true; + doProbeUpdate(); + } - if (mProbes.size() > MAX_PROBES) + for (int i = 0; i < mProbes.size(); ++i) { - mProbes.resize(MAX_PROBES); + LLReflectionMap* probe = mProbes[i]; + if (probe->getNumRefs() == 1) + { // no references held outside manager, delete this probe + deleteProbe(i); + --i; + continue; + } + + probe->mProbeIndex = i; + + LLVector4a d; + + if (probe->shouldUpdate() && !did_update && i < LL_REFLECTION_PROBE_COUNT) + { + if (probe->mCubeIndex == -1) + { + probe->mCubeArray = mTexture; + probe->mCubeIndex = allocateCubeIndex(); + } + + did_update = true; // only update one probe per frame + probe->autoAdjustOrigin(); + + mUpdatingProbe = probe; + doProbeUpdate(); + probe->mDirty = false; + } + + d.setSub(camera_pos, probe->mOrigin); + probe->mDistance = d.getLength3().getF32()-probe->mRadius; } + + // update distance to camera for all probes + std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance()); } void LLReflectionMapManager::addProbe(const LLVector3& pos) { - LLReflectionMap probe; - probe.update(pos, 1024); - mProbes.push_back(probe); + //LLReflectionMap* probe = new LLReflectionMap(); + //probe->update(pos, 1024); + //mProbes.push_back(probe); +} + +LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) +{ + LLReflectionMap* probe = new LLReflectionMap(); + probe->mGroup = group; + probe->mOrigin = group->getOctreeNode()->getCenter(); + probe->mDirty = true; + + if (gCubeSnapshot) + { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update + mCreateList.push_back(probe); + } + else + { + mProbes.push_back(probe); + } + + return probe; } void LLReflectionMapManager::getReflectionMaps(std::vector& maps) { - // just null out for now - U32 i = 0; - for (i = 0; i < maps.size() && i < mProbes.size(); ++i) + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + + U32 count = 0; + U32 lastIdx = 0; + for (U32 i = 0; count < maps.size() && i < mProbes.size(); ++i) + { + mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested + if (mProbes[i]->mCubeIndex != -1) + { + mProbes[i]->mProbeIndex = count; + maps[count++] = mProbes[i]; + } + else + { + mProbes[i]->mProbeIndex = -1; + } + lastIdx = i; + } + + // set remaining probe indices to -1 + for (U32 i = lastIdx+1; i < mProbes.size(); ++i) + { + mProbes[i]->mProbeIndex = -1; + } + + // null terminate list + if (count < maps.size()) + { + maps[count] = nullptr; + } +} + +LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group) +{ + if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) + { + OctreeNode* node = group->getOctreeNode(); + F32 size = node->getSize().getF32ptr()[0]; + if (size >= 7.f && size <= 17.f) + { + return addProbe(group); + } + } + + if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN) + { + OctreeNode* node = group->getOctreeNode(); + F32 size = node->getSize().getF32ptr()[0]; + if (size >= 15.f && size <= 17.f) + { + return addProbe(group); + } + } + + return nullptr; +} + +S32 LLReflectionMapManager::allocateCubeIndex() +{ + for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) + { + if (mCubeFree[i]) + { + mCubeFree[i] = false; + return i; + } + } + + // no cubemaps free, steal one from the back of the probe list + for (int i = mProbes.size() - 1; i >= LL_REFLECTION_PROBE_COUNT; --i) + { + if (mProbes[i]->mCubeIndex != -1) + { + S32 ret = mProbes[i]->mCubeIndex; + mProbes[i]->mCubeIndex = -1; + return ret; + } + } + + llassert(false); // should never fail to allocate, something is probably wrong with mCubeFree + return -1; +} + +void LLReflectionMapManager::deleteProbe(U32 i) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LLReflectionMap* probe = mProbes[i]; + + if (probe->mCubeIndex != -1) + { // mark the cube index used by this probe as being free + mCubeFree[probe->mCubeIndex] = true; + } + if (mUpdatingProbe == probe) + { + mUpdatingProbe = nullptr; + mUpdatingFace = 0; + } + + // remove from any Neighbors lists + for (auto& other : probe->mNeighbors) + { + auto& iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); + llassert(iter != other->mNeighbors.end()); + other->mNeighbors.erase(iter); + } + + mProbes.erase(mProbes.begin() + i); +} + + +void LLReflectionMapManager::doProbeUpdate() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + llassert(mUpdatingProbe != nullptr); + + mRenderTarget.bindTarget(); + mUpdatingProbe->update(mRenderTarget.getWidth(), mUpdatingFace); + mRenderTarget.flush(); + + // generate mipmaps { - maps[i] = &(mProbes[i]); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + + gReflectionMipProgram.bind(); + gGL.matrixMode(gGL.MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); + + gGL.matrixMode(gGL.MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + + gGL.flush(); + U32 res = LL_REFLECTION_PROBE_RESOLUTION*4; + + S32 mips = log2((F32) LL_REFLECTION_PROBE_RESOLUTION)+0.5f; + + for (int i = 0; i < mMipChain.size(); ++i) + { + mMipChain[i].bindTarget(); + + if (i == 0) + { + gGL.getTexUnit(0)->bind(&mRenderTarget); + } + else + { + gGL.getTexUnit(0)->bind(&(mMipChain[i - 1])); + } + + gGL.begin(gGL.QUADS); + + gGL.texCoord2f(0, 0); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(res, 0); + gGL.vertex2f(1, -1); + + gGL.texCoord2f(res, res); + gGL.vertex2f(1, 1); + + gGL.texCoord2f(0, res); + gGL.vertex2f(-1, 1); + gGL.end(); + gGL.flush(); + + res /= 2; + + S32 mip = i - (mMipChain.size() - mips); + + if (mip >= 0) + { + mTexture->bind(0); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, mUpdatingProbe->mCubeIndex * 6 + mUpdatingFace, 0, 0, res, res); + mTexture->unbind(); + } + mMipChain[i].flush(); + } + + gGL.popMatrix(); + gGL.matrixMode(gGL.MM_MODELVIEW); + gGL.popMatrix(); + + gReflectionMipProgram.unbind(); + } + + if (++mUpdatingFace == 6) + { + updateNeighbors(mUpdatingProbe); + mUpdatingProbe = nullptr; + mUpdatingFace = 0; + } +} + +void LLReflectionMapManager::rebuild() +{ + for (auto& probe : mProbes) + { + probe->mLastUpdateTime = 0.f; } +} - for (++i; i < maps.size(); ++i) +void LLReflectionMapManager::shift(const LLVector4a& offset) +{ + for (auto& probe : mProbes) { - maps[i] = nullptr; + probe->mOrigin.add(offset); } } +void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + + //remove from existing neighbors + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear"); + + for (auto& other : probe->mNeighbors) + { + auto& iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); + llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly + other->mNeighbors.erase(iter); + } + + probe->mNeighbors.clear(); + } + + // search for new neighbors + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search"); + for (auto& other : mProbes) + { + if (other != probe) + { + if (probe->intersects(other)) + { + probe->mNeighbors.push_back(other); + other->mNeighbors.push_back(probe); + } + } + } + } +} + +void LLReflectionMapManager::setUniforms() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + + // structure for packing uniform buffer object + // see class2/deferred/softenLightF.glsl + struct ReflectionProbeData + { + LLVector4 refSphere[LL_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space + GLint refIndex[LL_REFLECTION_PROBE_COUNT][4]; + GLint refNeighbor[4096]; + GLint refmapCount; + }; + + mReflectionMaps.resize(LL_REFLECTION_PROBE_COUNT); + getReflectionMaps(mReflectionMaps); + + ReflectionProbeData rpd; + + // load modelview matrix into matrix 4a + LLMatrix4a modelview; + modelview.loadu(gGLModelView); + LLVector4a oa; // scratch space for transformed origin + + S32 count = 0; + U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors + + for (auto* refmap : mReflectionMaps) + { + if (refmap == nullptr) + { + break; + } + + llassert(refmap->mProbeIndex == count); + llassert(mReflectionMaps[refmap->mProbeIndex] == refmap); + + llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged + + { + //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refSphere"); + + modelview.affineTransform(refmap->mOrigin, oa); + rpd.refSphere[count].set(oa.getF32ptr()); + rpd.refSphere[count].mV[3] = refmap->mRadius; + } + + rpd.refIndex[count][0] = refmap->mCubeIndex; + llassert(nc % 4 == 0); + rpd.refIndex[count][1] = nc / 4; + + S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors + { + //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors"); + //pack neghbor list + for (auto& neighbor : refmap->mNeighbors) + { + if (ni >= 4096) + { // out of space + break; + } + + GLint idx = neighbor->mProbeIndex; + if (idx == -1) + { + continue; + } + + // this neighbor may be sampled + rpd.refNeighbor[ni++] = idx; + } + } + + if (nc == ni) + { + //no neighbors, tag as empty + rpd.refIndex[count][1] = -1; + } + else + { + rpd.refIndex[count][2] = ni - nc; + + // move the cursor forward + nc = ni; + if (nc % 4 != 0) + { // jump to next power of 4 for compatibility with ivec4 + nc += 4 - (nc % 4); + } + } + + + count++; + } + + rpd.refmapCount = count; + + //copy rpd into uniform buffer object + if (mUBO == 0) + { + glGenBuffersARB(1, &mUBO); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); + glBindBufferARB(GL_UNIFORM_BUFFER, mUBO); + glBufferDataARB(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); + glBindBufferARB(GL_UNIFORM_BUFFER, 0); + } + + glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); +} -- cgit v1.2.3 From 53c692c9597551c9a1ba8eee346432de51d9d22d Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 17 May 2022 14:32:07 -0500 Subject: SL-17416 Quick 'n dirty reflection probe override hack. --- indra/newview/llreflectionmapmanager.cpp | 101 +++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index a6b704d57d..53c4857b0f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -274,6 +274,28 @@ LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* gr return nullptr; } +LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vobj) +{ + llassert(vobj != nullptr); + + LLReflectionMap* probe = new LLReflectionMap(); + probe->mViewerObject = vobj; + probe->mOrigin.load3(vobj->getPositionAgent().mV); + probe->mDirty = true; + + if (gCubeSnapshot) + { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update + mCreateList.push_back(probe); + } + else + { + mProbes.push_back(probe); + } + + return probe; +} + + S32 LLReflectionMapManager::allocateCubeIndex() { for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) @@ -513,6 +535,7 @@ void LLReflectionMapManager::setUniforms() rpd.refIndex[count][0] = refmap->mCubeIndex; llassert(nc % 4 == 0); rpd.refIndex[count][1] = nc / 4; + rpd.refIndex[count][3] = refmap->mViewerObject ? 10 : 1; S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { @@ -574,3 +597,81 @@ void LLReflectionMapManager::setUniforms() glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); } + + +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) + { + gGL.vertex3fv(po); + gGL.vertex3fv(neighbor->mOrigin.getF32ptr()); + } + gGL.end(); + gGL.flush(); + +#if 0 + LLSpatialGroup* group = probe->mGroup; + if (group) + { // draw lines from corners of object aabb to reflection probe + + const LLVector4a* bounds = group->getBounds(); + LLVector4a o = bounds[0]; + + gGL.flush(); + gGL.diffuseColor4f(0, 0, 1, 1); + F32* c = o.getF32ptr(); + + const F32* bc = bounds[0].getF32ptr(); + const F32* bs = bounds[1].getF32ptr(); + + // daaw blue lines from corners to center of node + gGL.begin(gGL.LINES); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] + bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] + bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] + bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] + bs[2]); + + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] - bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] - bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] - bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] - bs[2]); + gGL.end(); + + //draw yellow line from center of node to reflection probe origin + gGL.flush(); + gGL.diffuseColor4f(1, 1, 0, 1); + gGL.begin(gGL.LINES); + gGL.vertex3fv(c); + gGL.vertex3fv(po); + gGL.end(); + gGL.flush(); + } +#endif +} + +void LLReflectionMapManager::renderDebug() +{ + gDebugProgram.bind(); + + for (auto& probe : mProbes) + { + renderReflectionProbe(probe); + } + + gDebugProgram.unbind(); +} -- cgit v1.2.3 From 63878a60eb8ab6884ed3aeec63a28e5089636092 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 May 2022 23:09:57 -0500 Subject: SL-17416 Box reflection probe influence volumes --- indra/newview/llreflectionmapmanager.cpp | 44 ++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 53c4857b0f..f4fdc3993f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -141,10 +141,16 @@ void LLReflectionMapManager::update() mCreateList.clear(); - const F32 UPDATE_INTERVAL = 10.f; //update no more than once every 5 seconds + if (mProbes.empty()) + { + return; + } + const F32 UPDATE_INTERVAL = 5.f; //update no more than once every 5 seconds bool did_update = false; + LLReflectionMap* oldestProbe = mProbes[0]; + if (mUpdatingProbe != nullptr) { did_update = true; @@ -181,21 +187,30 @@ void LLReflectionMapManager::update() probe->mDirty = false; } + if (probe->mCubeArray.notNull() && + probe->mCubeIndex != -1 && + probe->mLastUpdateTime < oldestProbe->mLastUpdateTime) + { + oldestProbe = probe; + } + d.setSub(camera_pos, probe->mOrigin); probe->mDistance = d.getLength3().getF32()-probe->mRadius; } +#if 0 + if (mUpdatingProbe == nullptr && + oldestProbe->mCubeArray.notNull() && + oldestProbe->mCubeIndex != -1) + { // didn't find any probes to update, update the most out of date probe that's currently in use on next frame + mUpdatingProbe = oldestProbe; + } +#endif + // update distance to camera for all probes std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance()); } -void LLReflectionMapManager::addProbe(const LLVector3& pos) -{ - //LLReflectionMap* probe = new LLReflectionMap(); - //probe->update(pos, 1024); - //mProbes.push_back(probe); -} - LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) { LLReflectionMap* probe = new LLReflectionMap(); @@ -251,6 +266,7 @@ void LLReflectionMapManager::getReflectionMaps(std::vector& ma LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group) { +#if 1 if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) { OctreeNode* node = group->getOctreeNode(); @@ -270,7 +286,7 @@ LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* gr return addProbe(group); } } - +#endif return nullptr; } @@ -493,6 +509,7 @@ void LLReflectionMapManager::setUniforms() // see class2/deferred/softenLightF.glsl struct ReflectionProbeData { + LLMatrix4 refBox[LL_REFLECTION_PROBE_COUNT]; // object bounding box as needed LLVector4 refSphere[LL_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space GLint refIndex[LL_REFLECTION_PROBE_COUNT][4]; GLint refNeighbor[4096]; @@ -535,7 +552,14 @@ void LLReflectionMapManager::setUniforms() rpd.refIndex[count][0] = refmap->mCubeIndex; llassert(nc % 4 == 0); rpd.refIndex[count][1] = nc / 4; - rpd.refIndex[count][3] = refmap->mViewerObject ? 10 : 1; + rpd.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])) + { // negate priority to indicate this probe has a box influence volume + rpd.refIndex[count][3] = -rpd.refIndex[count][3]; + } S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { -- cgit v1.2.3 From 02fb1bd6103cad5538fc170e015f4329f3545542 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 May 2022 23:51:06 -0500 Subject: Make reflection probe ambiance controllable by a saved setting --- indra/newview/llreflectionmapmanager.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index f4fdc3993f..8aacbba6be 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -32,6 +32,7 @@ #include "llviewerregion.h" #include "pipeline.h" #include "llviewershadermgr.h" +#include "llviewercontrol.h" extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; @@ -514,6 +515,7 @@ void LLReflectionMapManager::setUniforms() GLint refIndex[LL_REFLECTION_PROBE_COUNT][4]; GLint refNeighbor[4096]; GLint refmapCount; + GLfloat reflectionAmbiance; }; mReflectionMaps.resize(LL_REFLECTION_PROBE_COUNT); @@ -521,6 +523,9 @@ void LLReflectionMapManager::setUniforms() ReflectionProbeData rpd; + static LLCachedControl ambiance(gSavedSettings, "RenderReflectionProbeAmbiance", 0.f); + rpd.reflectionAmbiance = ambiance; + // load modelview matrix into matrix 4a LLMatrix4a modelview; modelview.loadu(gGLModelView); -- cgit v1.2.3 From 3564b24e2a90e0772c37185cc5dcedca29d62ab8 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 19 May 2022 22:24:41 -0500 Subject: SL-17286 Reflection probe alpha/fullbright support. --- indra/newview/llreflectionmapmanager.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8aacbba6be..5fe510fb56 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -506,6 +506,8 @@ void LLReflectionMapManager::setUniforms() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + // TODO -- avoid repacking UBO unnecessarily + // structure for packing uniform buffer object // see class2/deferred/softenLightF.glsl struct ReflectionProbeData -- cgit v1.2.3 From 096ad1306d1a5db300592d9be87ab6762777d400 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 19 May 2022 22:36:03 -0500 Subject: SL-17286 Only update reflection probe UBO once per pipe flush --- indra/newview/llreflectionmapmanager.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 5fe510fb56..fb98a2a6d4 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -502,12 +502,10 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe) } } -void LLReflectionMapManager::setUniforms() +void LLReflectionMapManager::updateUniforms() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - // TODO -- avoid repacking UBO unnecessarily - // structure for packing uniform buffer object // see class2/deferred/softenLightF.glsl struct ReflectionProbeData @@ -578,7 +576,7 @@ void LLReflectionMapManager::setUniforms() { // out of space break; } - + GLint idx = neighbor->mProbeIndex; if (idx == -1) { @@ -589,7 +587,7 @@ void LLReflectionMapManager::setUniforms() rpd.refNeighbor[ni++] = idx; } } - + if (nc == ni) { //no neighbors, tag as empty @@ -606,8 +604,8 @@ void LLReflectionMapManager::setUniforms() nc += 4 - (nc % 4); } } - - + + count++; } @@ -625,7 +623,14 @@ void LLReflectionMapManager::setUniforms() glBufferDataARB(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); glBindBufferARB(GL_UNIFORM_BUFFER, 0); } +} +void LLReflectionMapManager::setUniforms() +{ + if (mUBO == 0) + { + updateUniforms(); + } glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); } -- cgit v1.2.3 From 6eaf8521abae0deeb1162f9c61747183110176b0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 20 May 2022 19:05:28 -0500 Subject: SL-17287 Instrument and optimize cubemap render. Fix for cubemap snapshots doing a full resolution render instead of a 512x512 render. --- indra/newview/llreflectionmapmanager.cpp | 65 ++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 29 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index fb98a2a6d4..db6622239d 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -39,6 +39,9 @@ extern BOOL gTeleportDisplay; //#pragma optimize("", off) +// experimental pipeline render target override, if this works, do something less hacky +LLPipeline::RenderTargetPack gProbeRT; + LLReflectionMapManager::LLReflectionMapManager() { for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) @@ -89,13 +92,20 @@ void LLReflectionMapManager::update() U32 color_fmt = GL_RGBA; const bool use_depth_buffer = true; const bool use_stencil_buffer = true; - U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 4; // super sample + U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE); + + // hack to allocate render targets using gPipeline code + auto* old_rt = gPipeline.mRT; + gPipeline.mRT = &gProbeRT; + gPipeline.allocateScreenBuffer(targetRes, targetRes); + gPipeline.allocateShadowBuffer(targetRes, targetRes); + gPipeline.mRT = old_rt; } if (mMipChain.empty()) { - U32 res = LL_REFLECTION_PROBE_RESOLUTION*2; + U32 res = LL_REFLECTION_PROBE_RESOLUTION; U32 count = log2((F32)res) + 0.5f; mMipChain.resize(count); @@ -150,7 +160,7 @@ void LLReflectionMapManager::update() bool did_update = false; - LLReflectionMap* oldestProbe = mProbes[0]; + LLReflectionMap* oldestProbe = nullptr; if (mUpdatingProbe != nullptr) { @@ -172,25 +182,9 @@ void LLReflectionMapManager::update() LLVector4a d; - if (probe->shouldUpdate() && !did_update && i < LL_REFLECTION_PROBE_COUNT) - { - if (probe->mCubeIndex == -1) - { - probe->mCubeArray = mTexture; - probe->mCubeIndex = allocateCubeIndex(); - } - - did_update = true; // only update one probe per frame - probe->autoAdjustOrigin(); - - mUpdatingProbe = probe; - doProbeUpdate(); - probe->mDirty = false; - } - - if (probe->mCubeArray.notNull() && - probe->mCubeIndex != -1 && - probe->mLastUpdateTime < oldestProbe->mLastUpdateTime) + if (!did_update && + i < LL_REFLECTION_PROBE_COUNT && + (oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) { oldestProbe = probe; } @@ -199,12 +193,21 @@ void LLReflectionMapManager::update() probe->mDistance = d.getLength3().getF32()-probe->mRadius; } -#if 0 - if (mUpdatingProbe == nullptr && - oldestProbe->mCubeArray.notNull() && - oldestProbe->mCubeIndex != -1) - { // didn't find any probes to update, update the most out of date probe that's currently in use on next frame - mUpdatingProbe = oldestProbe; +#if 1 + if (!did_update && oldestProbe != nullptr) + { + LLReflectionMap* probe = oldestProbe; + if (probe->mCubeIndex == -1) + { + probe->mCubeArray = mTexture; + probe->mCubeIndex = allocateCubeIndex(); + } + + probe->autoAdjustOrigin(); + + mUpdatingProbe = probe; + doProbeUpdate(); + probe->mDirty = false; } #endif @@ -372,7 +375,10 @@ void LLReflectionMapManager::doProbeUpdate() llassert(mUpdatingProbe != nullptr); mRenderTarget.bindTarget(); + auto* old_rt = gPipeline.mRT; + gPipeline.mRT = &gProbeRT; mUpdatingProbe->update(mRenderTarget.getWidth(), mUpdatingFace); + gPipeline.mRT = old_rt; mRenderTarget.flush(); // generate mipmaps @@ -390,12 +396,13 @@ void LLReflectionMapManager::doProbeUpdate() gGL.loadIdentity(); gGL.flush(); - U32 res = LL_REFLECTION_PROBE_RESOLUTION*4; + U32 res = LL_REFLECTION_PROBE_RESOLUTION*2; S32 mips = log2((F32) LL_REFLECTION_PROBE_RESOLUTION)+0.5f; for (int i = 0; i < mMipChain.size(); ++i) { + LL_PROFILE_GPU_ZONE("probe mip"); mMipChain[i].bindTarget(); if (i == 0) -- cgit v1.2.3 From 3b3d3d88d1755ac08c7d22721fa3fe1657f7c5fd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 24 May 2022 11:38:23 -0500 Subject: SL-17287 Don't update reflection probes when PBR is disabled. --- indra/newview/llreflectionmapmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index db6622239d..34055653d4 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -67,7 +67,7 @@ struct CompareProbeDistance // helper class to seed octree with probes void LLReflectionMapManager::update() { - if (!LLPipeline::sRenderDeferred || gTeleportDisplay) + if (!LLPipeline::sRenderPBR || gTeleportDisplay) { return; } @@ -634,6 +634,7 @@ void LLReflectionMapManager::updateUniforms() void LLReflectionMapManager::setUniforms() { + llassert(LLPipeline::sRenderPBR); if (mUBO == 0) { updateUniforms(); @@ -644,7 +645,6 @@ void LLReflectionMapManager::setUniforms() void renderReflectionProbe(LLReflectionMap* probe) { - F32* po = probe->mOrigin.getF32ptr(); //draw orange line from probe to neighbors -- cgit v1.2.3 From 220afbcda0961df86ad08bbd51d96b8c868b2e62 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 2 Jun 2022 18:42:38 -0500 Subject: SL-17285 Add proper reflection probe support to LLVOVolume, LLPrimitive, and LLPanelVolume --- indra/newview/llreflectionmapmanager.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 34055653d4..60396b6c60 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -127,18 +127,12 @@ void LLReflectionMapManager::update() camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); // process kill list - for (int i = 0; i < mProbes.size(); ) + for (auto& probe : mKillList) { - auto& iter = std::find(mKillList.begin(), mKillList.end(), mProbes[i]); - if (iter != mKillList.end()) + auto& iter = std::find(mProbes.begin(), mProbes.end(), probe); + if (iter != mProbes.end()) { - deleteProbe(i); - mProbes.erase(mProbes.begin() + i); - mKillList.erase(iter); - } - else - { - ++i; + deleteProbe(iter - mProbes.begin()); } } @@ -275,7 +269,7 @@ LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* gr { OctreeNode* node = group->getOctreeNode(); F32 size = node->getSize().getF32ptr()[0]; - if (size >= 7.f && size <= 17.f) + if (size >= 15.f && size <= 17.f) { return addProbe(group); } @@ -514,15 +508,15 @@ void LLReflectionMapManager::updateUniforms() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; // structure for packing uniform buffer object - // see class2/deferred/softenLightF.glsl + // see class3/deferred/reflectionProbeF.glsl struct ReflectionProbeData { LLMatrix4 refBox[LL_REFLECTION_PROBE_COUNT]; // object bounding box as needed LLVector4 refSphere[LL_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space + LLVector4 refParams[LL_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance) GLint refIndex[LL_REFLECTION_PROBE_COUNT][4]; GLint refNeighbor[4096]; GLint refmapCount; - GLfloat reflectionAmbiance; }; mReflectionMaps.resize(LL_REFLECTION_PROBE_COUNT); @@ -530,9 +524,6 @@ void LLReflectionMapManager::updateUniforms() ReflectionProbeData rpd; - static LLCachedControl ambiance(gSavedSettings, "RenderReflectionProbeAmbiance", 0.f); - rpd.reflectionAmbiance = ambiance; - // load modelview matrix into matrix 4a LLMatrix4a modelview; modelview.loadu(gGLModelView); @@ -573,6 +564,8 @@ void LLReflectionMapManager::updateUniforms() rpd.refIndex[count][3] = -rpd.refIndex[count][3]; } + rpd.refParams[count].set(refmap->getAmbiance(), 0.f, 0.f, 0.f); + S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors"); -- cgit v1.2.3 From 509476f95ed75ce8289ecd69b4c94d9912e1d3df Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 10 Jun 2022 01:13:41 -0500 Subject: SL-17574 Add probe detail combo box to advanced graphics preferences. Fix spot light shadows not working in probes. --- indra/newview/llreflectionmapmanager.cpp | 63 +++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 18 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 60396b6c60..dc733687c3 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -96,11 +96,13 @@ void LLReflectionMapManager::update() mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE); // hack to allocate render targets using gPipeline code + gCubeSnapshot = TRUE; auto* old_rt = gPipeline.mRT; gPipeline.mRT = &gProbeRT; gPipeline.allocateScreenBuffer(targetRes, targetRes); gPipeline.allocateShadowBuffer(targetRes, targetRes); gPipeline.mRT = old_rt; + gCubeSnapshot = FALSE; } if (mMipChain.empty()) @@ -154,6 +156,10 @@ void LLReflectionMapManager::update() bool did_update = false; + bool realtime = gSavedSettings.getS32("RenderReflectionProbeDetail") >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; + + LLReflectionMap* closestDynamic = nullptr; + LLReflectionMap* oldestProbe = nullptr; if (mUpdatingProbe != nullptr) @@ -183,11 +189,30 @@ void LLReflectionMapManager::update() oldestProbe = probe; } + if (realtime && + closestDynamic == nullptr && + probe->mCubeArray.notNull() && + probe->getIsDynamic()) + { + closestDynamic = probe; + } + d.setSub(camera_pos, probe->mOrigin); probe->mDistance = d.getLength3().getF32()-probe->mRadius; } -#if 1 + if (realtime && closestDynamic != nullptr) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); + // update the closest dynamic probe realtime + closestDynamic->autoAdjustOrigin(); + for (U32 i = 0; i < 6; ++i) + { + updateProbeFace(closestDynamic, i); + } + } + + // switch to updating the next oldest probe if (!did_update && oldestProbe != nullptr) { LLReflectionMap* probe = oldestProbe; @@ -201,9 +226,7 @@ void LLReflectionMapManager::update() mUpdatingProbe = probe; doProbeUpdate(); - probe->mDirty = false; } -#endif // update distance to camera for all probes std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance()); @@ -214,7 +237,6 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) LLReflectionMap* probe = new LLReflectionMap(); probe->mGroup = group; probe->mOrigin = group->getOctreeNode()->getCenter(); - probe->mDirty = true; if (gCubeSnapshot) { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update @@ -295,7 +317,6 @@ LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vo LLReflectionMap* probe = new LLReflectionMap(); probe->mViewerObject = vobj; probe->mOrigin.load3(vobj->getPositionAgent().mV); - probe->mDirty = true; if (gCubeSnapshot) { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update @@ -368,10 +389,23 @@ void LLReflectionMapManager::doProbeUpdate() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(mUpdatingProbe != nullptr); + updateProbeFace(mUpdatingProbe, mUpdatingFace); + + if (++mUpdatingFace == 6) + { + updateNeighbors(mUpdatingProbe); + mUpdatingProbe = nullptr; + mUpdatingFace = 0; + } +} + +void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) +{ mRenderTarget.bindTarget(); + // hacky hot-swap of camera specific render targets auto* old_rt = gPipeline.mRT; gPipeline.mRT = &gProbeRT; - mUpdatingProbe->update(mRenderTarget.getWidth(), mUpdatingFace); + probe->update(mRenderTarget.getWidth(), face); gPipeline.mRT = old_rt; mRenderTarget.flush(); @@ -390,9 +424,9 @@ void LLReflectionMapManager::doProbeUpdate() gGL.loadIdentity(); gGL.flush(); - U32 res = LL_REFLECTION_PROBE_RESOLUTION*2; + U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2; - S32 mips = log2((F32) LL_REFLECTION_PROBE_RESOLUTION)+0.5f; + S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f; for (int i = 0; i < mMipChain.size(); ++i) { @@ -409,10 +443,10 @@ void LLReflectionMapManager::doProbeUpdate() } gGL.begin(gGL.QUADS); - + gGL.texCoord2f(0, 0); gGL.vertex2f(-1, -1); - + gGL.texCoord2f(res, 0); gGL.vertex2f(1, -1); @@ -431,7 +465,7 @@ void LLReflectionMapManager::doProbeUpdate() if (mip >= 0) { mTexture->bind(0); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, mUpdatingProbe->mCubeIndex * 6 + mUpdatingFace, 0, 0, res, res); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); mTexture->unbind(); } mMipChain[i].flush(); @@ -443,13 +477,6 @@ void LLReflectionMapManager::doProbeUpdate() gReflectionMipProgram.unbind(); } - - if (++mUpdatingFace == 6) - { - updateNeighbors(mUpdatingProbe); - mUpdatingProbe = nullptr; - mUpdatingFace = 0; - } } void LLReflectionMapManager::rebuild() -- cgit v1.2.3 From 929abcd296199ab4ed7a0b08166e284502f7b8df Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 10 Jun 2022 16:36:38 -0500 Subject: SL-17523 Add reflection probe ambiance to windlight settings and integrate with UI and ReflectionMapManager --- indra/newview/llreflectionmapmanager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index dc733687c3..48ed22d79f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -33,6 +33,7 @@ #include "pipeline.h" #include "llviewershadermgr.h" #include "llviewercontrol.h" +#include "llenvironment.h" extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; @@ -559,6 +560,11 @@ void LLReflectionMapManager::updateUniforms() S32 count = 0; U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors + LLEnvironment& environment = LLEnvironment::instance(); + LLSettingsSky::ptr_t psky = environment.getCurrentSky(); + + F32 minimum_ambiance = psky->getReflectionProbeAmbiance(); + for (auto* refmap : mReflectionMaps) { if (refmap == nullptr) @@ -591,7 +597,7 @@ void LLReflectionMapManager::updateUniforms() rpd.refIndex[count][3] = -rpd.refIndex[count][3]; } - rpd.refParams[count].set(refmap->getAmbiance(), 0.f, 0.f, 0.f); + rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance()), 0.f, 0.f, 0.f); S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { -- cgit v1.2.3 From fb5ff6a5388dc9622089e9937e8d81bc319cf3dd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 17 Jun 2022 14:05:18 -0500 Subject: SL-17287 Slightly less hacky and much less crash cube snapshot render target allocation. --- indra/newview/llreflectionmapmanager.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 48ed22d79f..752427f0fa 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -38,11 +38,6 @@ extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; -//#pragma optimize("", off) - -// experimental pipeline render target override, if this works, do something less hacky -LLPipeline::RenderTargetPack gProbeRT; - LLReflectionMapManager::LLReflectionMapManager() { for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) @@ -95,15 +90,6 @@ void LLReflectionMapManager::update() const bool use_stencil_buffer = true; U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE); - - // hack to allocate render targets using gPipeline code - gCubeSnapshot = TRUE; - auto* old_rt = gPipeline.mRT; - gPipeline.mRT = &gProbeRT; - gPipeline.allocateScreenBuffer(targetRes, targetRes); - gPipeline.allocateShadowBuffer(targetRes, targetRes); - gPipeline.mRT = old_rt; - gCubeSnapshot = FALSE; } if (mMipChain.empty()) @@ -404,10 +390,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { mRenderTarget.bindTarget(); // hacky hot-swap of camera specific render targets - auto* old_rt = gPipeline.mRT; - gPipeline.mRT = &gProbeRT; + gPipeline.mRT = &gPipeline.mAuxillaryRT; probe->update(mRenderTarget.getWidth(), face); - gPipeline.mRT = old_rt; + gPipeline.mRT = &gPipeline.mMainRT; mRenderTarget.flush(); // generate mipmaps -- cgit v1.2.3 From 31e2fa5e50bc5aad265e8ec12613223eeb3ae3e1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 21 Jun 2022 22:44:30 -0500 Subject: SL-17600 WIP -- Proper radiance maps (not just mipped cubemaps). --- indra/newview/llreflectionmapmanager.cpp | 50 ++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 752427f0fa..025b8457c1 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -80,7 +80,8 @@ void LLReflectionMapManager::update() if (mTexture.isNull()) { mTexture = new LLCubeMapArray(); - mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT); + // store LL_REFLECTION_PROBE_COUNT+1 cube maps, final cube map is used for render target and radiance map generation source) + mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT+2); } if (!mRenderTarget.isComplete()) @@ -395,7 +396,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gPipeline.mRT = &gPipeline.mMainRT; mRenderTarget.flush(); - // generate mipmaps + // downsample to placeholder map { LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLGLDisable cull(GL_CULL_FACE); @@ -451,7 +452,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) if (mip >= 0) { mTexture->bind(0); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, LL_REFLECTION_PROBE_COUNT * 6 + face, 0, 0, res, res); mTexture->unbind(); } mMipChain[i].flush(); @@ -463,6 +465,48 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gReflectionMipProgram.unbind(); } + + if (face == 5) + { + //generate radiance map + gRadianceGenProgram.bind(); + S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + mTexture->bind(channel); + + for (int cf = 0; cf < 6; ++cf) + { // for each cube face + LLCoordFrame frame; + frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + + F32 mat[16]; + frame.getOpenGLRotation(mat); + gGL.loadMatrix(mat); + + for (int i = 0; i < mMipChain.size(); ++i) + { + mMipChain[i].bindTarget(); + static LLStaticHashedString sRoughness("roughness"); + static LLStaticHashedString sNumSamples("numSamples"); + + gRadianceGenProgram.uniform1i(sNumSamples, 32); + gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); + + gGL.begin(gGL.QUADS); + gGL.vertex3f(-1, -1, -1); + gGL.vertex3f(1, -1, -1); + gGL.vertex3f(1, 1, -1); + gGL.vertex3f(-1, 1, -1); + gGL.end(); + gGL.flush(); + + + + S32 res = mMipChain[i].getWidth(); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); + mMipChain[i].flush(); + } + } + } } void LLReflectionMapManager::rebuild() -- cgit v1.2.3 From d0d1b832d4983f35ab29947eb6fda54a8aa48f8a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 22 Jun 2022 13:25:50 -0500 Subject: SL-17600 Proper irradiance probes. --- indra/newview/llreflectionmapmanager.cpp | 68 +++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 5 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 025b8457c1..dfd0d1b9a9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -80,8 +80,11 @@ void LLReflectionMapManager::update() if (mTexture.isNull()) { mTexture = new LLCubeMapArray(); - // store LL_REFLECTION_PROBE_COUNT+1 cube maps, final cube map is used for render target and radiance map generation source) + // store LL_REFLECTION_PROBE_COUNT+2 cube maps, final two cube maps are used for render target and radiance map generation source) mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT+2); + + mIrradianceMaps = new LLCubeMapArray(); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT); } if (!mRenderTarget.isComplete()) @@ -396,6 +399,13 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gPipeline.mRT = &gPipeline.mMainRT; mRenderTarget.flush(); + S32 targetIdx = LL_REFLECTION_PROBE_COUNT; + + if (probe != mUpdatingProbe) + { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel + targetIdx += 1; + } + // downsample to placeholder map { LLGLDepthTest depth(GL_FALSE, GL_FALSE); @@ -453,7 +463,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { mTexture->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, LL_REFLECTION_PROBE_COUNT * 6 + face, 0, 0, res, res); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res); mTexture->unbind(); } mMipChain[i].flush(); @@ -472,7 +482,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gRadianceGenProgram.bind(); S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); - + static LLStaticHashedString sSourceIdx("sourceIdx"); + gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx); + for (int cf = 0; cf < 6; ++cf) { // for each cube face LLCoordFrame frame; @@ -499,13 +511,59 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.end(); gGL.flush(); - - S32 res = mMipChain[i].getWidth(); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); mMipChain[i].flush(); } } + gRadianceGenProgram.unbind(); + + //generate irradiance map + gIrradianceGenProgram.bind(); + channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + mTexture->bind(channel); + + gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); + + int start_mip = 0; + // find the mip target to start with based on irradiance map resolution + for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) + { + if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION) + { + break; + } + } + + for (int cf = 0; cf < 6; ++cf) + { // for each cube face + LLCoordFrame frame; + frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + + F32 mat[16]; + frame.getOpenGLRotation(mat); + gGL.loadMatrix(mat); + + for (int i = start_mip; i < mMipChain.size(); ++i) + { + mMipChain[i].bindTarget(); + + gGL.begin(gGL.QUADS); + gGL.vertex3f(-1, -1, -1); + gGL.vertex3f(1, -1, -1); + gGL.vertex3f(1, 1, -1); + gGL.vertex3f(-1, 1, -1); + gGL.end(); + gGL.flush(); + + S32 res = mMipChain[i].getWidth(); + mIrradianceMaps->bind(channel); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i-start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); + mTexture->bind(channel); + mMipChain[i].flush(); + } + } + gIrradianceGenProgram.unbind(); } } -- cgit v1.2.3 From 6540b4c480d1d4b4c8342a0d093d09f525485659 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 22 Jun 2022 19:56:26 -0500 Subject: SL-17600 Cubemap filter tuning. --- indra/newview/llreflectionmapmanager.cpp | 54 ++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 24 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index dfd0d1b9a9..bde8c0c51c 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -425,7 +425,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f; - for (int i = 0; i < mMipChain.size(); ++i) + //for (int i = 0; i < mMipChain.size(); ++i) + for (int i = 0; i < 1; ++i) { LL_PROFILE_GPU_ZONE("probe mip"); mMipChain[i].bindTarget(); @@ -464,6 +465,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mTexture->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); mTexture->unbind(); } mMipChain[i].flush(); @@ -485,24 +487,28 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) static LLStaticHashedString sSourceIdx("sourceIdx"); gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx); - for (int cf = 0; cf < 6; ++cf) - { // for each cube face - LLCoordFrame frame; - frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + static LLStaticHashedString sMipLevel("mipLevel"); - F32 mat[16]; - frame.getOpenGLRotation(mat); - gGL.loadMatrix(mat); + for (int i = 1; i < mMipChain.size(); ++i) + { + for (int cf = 0; cf < 6; ++cf) + { // for each cube face + LLCoordFrame frame; + frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + + F32 mat[16]; + frame.getOpenGLRotation(mat); + gGL.loadMatrix(mat); - for (int i = 0; i < mMipChain.size(); ++i) - { mMipChain[i].bindTarget(); static LLStaticHashedString sRoughness("roughness"); - static LLStaticHashedString sNumSamples("numSamples"); - gRadianceGenProgram.uniform1i(sNumSamples, 32); gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); - + gRadianceGenProgram.uniform1f(sMipLevel, llmax((F32)(i - 1), 0.f)); + if (i > 0) + { + gRadianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex); + } gGL.begin(gGL.QUADS); gGL.vertex3f(-1, -1, -1); gGL.vertex3f(1, -1, -1); @@ -523,7 +529,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); - gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); + gIrradianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex); int start_mip = 0; // find the mip target to start with based on irradiance map resolution @@ -535,17 +541,17 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } } - for (int cf = 0; cf < 6; ++cf) - { // for each cube face - LLCoordFrame frame; - frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + for (int i = start_mip; i < mMipChain.size(); ++i) + { + for (int cf = 0; cf < 6; ++cf) + { // for each cube face + LLCoordFrame frame; + frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); - F32 mat[16]; - frame.getOpenGLRotation(mat); - gGL.loadMatrix(mat); + F32 mat[16]; + frame.getOpenGLRotation(mat); + gGL.loadMatrix(mat); - for (int i = start_mip; i < mMipChain.size(); ++i) - { mMipChain[i].bindTarget(); gGL.begin(gGL.QUADS); @@ -558,7 +564,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 res = mMipChain[i].getWidth(); mIrradianceMaps->bind(channel); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i-start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); mTexture->bind(channel); mMipChain[i].flush(); } -- cgit v1.2.3 From 7ab3e7cde31e861459817e4cf24a041631684d95 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Thu, 23 Jun 2022 22:45:52 -0700 Subject: clang compatibility fixes for llreflectionmapmanager.cpp and llvovolume.h --- indra/newview/llreflectionmapmanager.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index bde8c0c51c..583c6de77b 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -109,12 +109,6 @@ void LLReflectionMapManager::update() } } - // =============== TODO -- move to an init function ================= - - // naively drop probes every 16m as we move the camera around for now - // later, use LLSpatialPartition to manage probes - const F32 PROBE_SPACING = 16.f; - const U32 MAX_PROBES = 8; LLVector4a camera_pos; camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); @@ -122,7 +116,7 @@ void LLReflectionMapManager::update() // process kill list for (auto& probe : mKillList) { - auto& iter = std::find(mProbes.begin(), mProbes.end(), probe); + auto const & iter = std::find(mProbes.begin(), mProbes.end(), probe); if (iter != mProbes.end()) { deleteProbe(iter - mProbes.begin()); @@ -143,7 +137,6 @@ void LLReflectionMapManager::update() { return; } - const F32 UPDATE_INTERVAL = 5.f; //update no more than once every 5 seconds bool did_update = false; @@ -366,7 +359,7 @@ void LLReflectionMapManager::deleteProbe(U32 i) // remove from any Neighbors lists for (auto& other : probe->mNeighbors) { - auto& iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); + auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); llassert(iter != other->mNeighbors.end()); other->mNeighbors.erase(iter); } @@ -599,7 +592,7 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe) for (auto& other : probe->mNeighbors) { - auto& iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); + auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly other->mNeighbors.erase(iter); } -- cgit v1.2.3 From 9c6b197b3eacabb21ba098b7d1f6017f3de34432 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 29 Aug 2022 18:46:48 -0500 Subject: SL-18037 Workaround AMD driver bug (drop reflection probe count to 16 on amd) --- indra/newview/llreflectionmapmanager.cpp | 47 ++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 583c6de77b..b285cc531e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -40,7 +40,7 @@ extern BOOL gTeleportDisplay; LLReflectionMapManager::LLReflectionMapManager() { - for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) + for (int i = 0; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) { mCubeFree[i] = true; } @@ -76,16 +76,7 @@ void LLReflectionMapManager::update() } // =============== TODO -- move to an init function ================= - - if (mTexture.isNull()) - { - mTexture = new LLCubeMapArray(); - // store LL_REFLECTION_PROBE_COUNT+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT+2); - - mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT); - } + initReflectionMaps(); if (!mRenderTarget.isComplete()) { @@ -167,7 +158,7 @@ void LLReflectionMapManager::update() LLVector4a d; if (!did_update && - i < LL_REFLECTION_PROBE_COUNT && + i < mReflectionProbeCount && (oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) { oldestProbe = probe; @@ -317,7 +308,7 @@ LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vo S32 LLReflectionMapManager::allocateCubeIndex() { - for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) + for (int i = 0; i < mReflectionProbeCount; ++i) { if (mCubeFree[i]) { @@ -327,7 +318,7 @@ S32 LLReflectionMapManager::allocateCubeIndex() } // no cubemaps free, steal one from the back of the probe list - for (int i = mProbes.size() - 1; i >= LL_REFLECTION_PROBE_COUNT; --i) + for (int i = mProbes.size() - 1; i >= mReflectionProbeCount; --i) { if (mProbes[i]->mCubeIndex != -1) { @@ -392,7 +383,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gPipeline.mRT = &gPipeline.mMainRT; mRenderTarget.flush(); - S32 targetIdx = LL_REFLECTION_PROBE_COUNT; + S32 targetIdx = mReflectionProbeCount; if (probe != mUpdatingProbe) { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel @@ -625,15 +616,15 @@ void LLReflectionMapManager::updateUniforms() // see class3/deferred/reflectionProbeF.glsl struct ReflectionProbeData { - LLMatrix4 refBox[LL_REFLECTION_PROBE_COUNT]; // object bounding box as needed - LLVector4 refSphere[LL_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space - LLVector4 refParams[LL_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance) - GLint refIndex[LL_REFLECTION_PROBE_COUNT][4]; + LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; // object bounding box as needed + LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space + LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance) + GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; GLint refNeighbor[4096]; GLint refmapCount; }; - mReflectionMaps.resize(LL_REFLECTION_PROBE_COUNT); + mReflectionMaps.resize(mReflectionProbeCount); getReflectionMaps(mReflectionMaps); ReflectionProbeData rpd; @@ -830,3 +821,19 @@ void LLReflectionMapManager::renderDebug() gDebugProgram.unbind(); } + +void LLReflectionMapManager::initReflectionMaps() +{ + if (mTexture.isNull()) + { + mReflectionProbeCount = llclamp(gSavedSettings.getS32("RenderReflectionProbeCount"), 1, LL_MAX_REFLECTION_PROBE_COUNT); + + mTexture = new LLCubeMapArray(); + + // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) + mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, mReflectionProbeCount + 2); + + mIrradianceMaps = new LLCubeMapArray(); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount); + } +} -- cgit v1.2.3 From c9f893b1003b2d9db01362430dbbfa59a91d4fd7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 31 Aug 2022 11:36:00 -0500 Subject: SL-18065 WIP -- Adjust max virtual size to keep debug floater readable. Make assert on shutdown less frequent (still not gone, likely race condition). Fix unrelated assertion in reflection probes. --- indra/newview/llreflectionmapmanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index b285cc531e..d349b7e024 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -166,7 +166,7 @@ void LLReflectionMapManager::update() if (realtime && closestDynamic == nullptr && - probe->mCubeArray.notNull() && + probe->mCubeIndex != -1 && probe->getIsDynamic()) { closestDynamic = probe; @@ -324,6 +324,7 @@ S32 LLReflectionMapManager::allocateCubeIndex() { S32 ret = mProbes[i]->mCubeIndex; mProbes[i]->mCubeIndex = -1; + mProbes[i]->mCubeArray = nullptr; return ret; } } -- cgit v1.2.3 From 2082443220fe344bb027c3acbf50fea0a99159c3 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 1 Sep 2022 10:58:27 -0700 Subject: SL-17967 - Git rid of ARB that is in core --- indra/newview/llreflectionmapmanager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index b285cc531e..b441236251 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -724,14 +724,14 @@ void LLReflectionMapManager::updateUniforms() //copy rpd into uniform buffer object if (mUBO == 0) { - glGenBuffersARB(1, &mUBO); + glGenBuffers(1, &mUBO); } { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); - glBindBufferARB(GL_UNIFORM_BUFFER, mUBO); - glBufferDataARB(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); - glBindBufferARB(GL_UNIFORM_BUFFER, 0); + glBindBuffer(GL_UNIFORM_BUFFER, mUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); } } -- cgit v1.2.3 From ef98be881c3f13e7668f75cb0d302261053d9804 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Thu, 1 Sep 2022 17:30:48 -0400 Subject: Use an SRGB buffer for initial reflection map capture for proper linear sampling Fix irradiance gen up vector to be properly normalized --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index d349b7e024..677e920031 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -80,7 +80,7 @@ void LLReflectionMapManager::update() if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGBA; + U32 color_fmt = GL_SRGB8_ALPHA8; const bool use_depth_buffer = true; const bool use_stencil_buffer = true; U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample -- cgit v1.2.3 From 04d3a29a699cd0a4c08ab096bfbab153e65c1fd1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 19 Sep 2022 17:27:33 -0500 Subject: SL-18190 Faster better stronger radiance/irradiance maps --- indra/newview/llreflectionmapmanager.cpp | 40 ++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 97277ee798..57ec51221e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -410,8 +410,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f; - //for (int i = 0; i < mMipChain.size(); ++i) - for (int i = 0; i < 1; ++i) + for (int i = 0; i < mMipChain.size(); ++i) { LL_PROFILE_GPU_ZONE("probe mip"); mMipChain[i].bindTarget(); @@ -447,10 +446,14 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) if (mip >= 0) { + LL_PROFILE_GPU_ZONE("probe mip copy"); mTexture->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + if (i == 0) + { + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + } mTexture->unbind(); } mMipChain[i].flush(); @@ -474,8 +477,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) static LLStaticHashedString sMipLevel("mipLevel"); + mMipChain[1].bindTarget(); + U32 res = mMipChain[1].getWidth(); + for (int i = 1; i < mMipChain.size(); ++i) { + LL_PROFILE_GPU_ZONE("probe radiance gen"); for (int cf = 0; cf < 6; ++cf) { // for each cube face LLCoordFrame frame; @@ -485,15 +492,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) frame.getOpenGLRotation(mat); gGL.loadMatrix(mat); - mMipChain[i].bindTarget(); static LLStaticHashedString sRoughness("roughness"); gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, llmax((F32)(i - 1), 0.f)); - if (i > 0) - { - gRadianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex); - } + gGL.begin(gGL.QUADS); gGL.vertex3f(-1, -1, -1); gGL.vertex3f(1, -1, -1); @@ -501,12 +504,17 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.vertex3f(-1, 1, -1); gGL.end(); gGL.flush(); - - S32 res = mMipChain[i].getWidth(); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - mMipChain[i].flush(); + } + + if (i != mMipChain.size() - 1) + { + res /= 2; + glViewport(0, 0, res, res); } } + gRadianceGenProgram.unbind(); //generate irradiance map @@ -514,7 +522,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); - gIrradianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex); + gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); int start_mip = 0; // find the mip target to start with based on irradiance map resolution @@ -528,6 +536,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) for (int i = start_mip; i < mMipChain.size(); ++i) { + LL_PROFILE_GPU_ZONE("probe irradiance gen"); + glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); for (int cf = 0; cf < 6; ++cf) { // for each cube face LLCoordFrame frame; @@ -537,8 +547,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) frame.getOpenGLRotation(mat); gGL.loadMatrix(mat); - mMipChain[i].bindTarget(); - gGL.begin(gGL.QUADS); gGL.vertex3f(-1, -1, -1); gGL.vertex3f(1, -1, -1); @@ -551,9 +559,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mIrradianceMaps->bind(channel); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); mTexture->bind(channel); - mMipChain[i].flush(); } } + + mMipChain[1].flush(); + gIrradianceGenProgram.unbind(); } } -- cgit v1.2.3 From d3b4c4aecef1b7815f6d47ffee1e00eb08cbb431 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 19 Sep 2022 19:07:34 -0500 Subject: SL-18190 Don't generate mips for irradiance maps because they're never sampled. --- indra/newview/llreflectionmapmanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 57ec51221e..2de31a5754 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -534,8 +534,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } } - for (int i = start_mip; i < mMipChain.size(); ++i) + //for (int i = start_mip; i < mMipChain.size(); ++i) { + int i = start_mip; LL_PROFILE_GPU_ZONE("probe irradiance gen"); glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); for (int cf = 0; cf < 6; ++cf) -- cgit v1.2.3 From 1eeee12ecb4753cc4b651e18474bb80de45fcede Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 20 Sep 2022 12:28:45 -0500 Subject: SL-18190 Don't allocate mips for irradiance maps because they're never generated. Disable OpenGL core profile on Intel by default. --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 2de31a5754..9c6d7ea26f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -846,6 +846,6 @@ void LLReflectionMapManager::initReflectionMaps() mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, mReflectionProbeCount + 2); mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); } } -- cgit v1.2.3 From c466e44334fd60c8270b68c70b8ae999b8dbd395 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 20 Sep 2022 19:09:26 -0500 Subject: SL-18190 Reduce banding (stay in linear space as much as possible, increase precision of reflection probes). Faster radiance and irradiance map generation. --- indra/newview/llreflectionmapmanager.cpp | 76 ++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 32 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 9c6d7ea26f..2aa1f06eaf 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -80,7 +80,7 @@ void LLReflectionMapManager::update() if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_SRGB8_ALPHA8; + U32 color_fmt = GL_RGB10_A2; const bool use_depth_buffer = true; const bool use_stencil_buffer = true; U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample @@ -95,7 +95,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGB, false, false, LLTexUnit::TT_RECT_TEXTURE); + mMipChain[i].allocate(res, res, GL_RGB10_A2, false, false, LLTexUnit::TT_RECT_TEXTURE); res /= 2; } } @@ -450,10 +450,10 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mTexture->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res); - if (i == 0) - { - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); - } + //if (i == 0) + //{ + //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + //} mTexture->unbind(); } mMipChain[i].flush(); @@ -470,19 +470,27 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { //generate radiance map gRadianceGenProgram.bind(); + mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); + S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); static LLStaticHashedString sSourceIdx("sourceIdx"); gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx); - static LLStaticHashedString sMipLevel("mipLevel"); + mMipChain[0].bindTarget(); + U32 res = mMipChain[0].getWidth(); - mMipChain[1].bindTarget(); - U32 res = mMipChain[1].getWidth(); - - for (int i = 1; i < mMipChain.size(); ++i) + for (int i = 0; i < mMipChain.size(); ++i) { LL_PROFILE_GPU_ZONE("probe radiance gen"); + static LLStaticHashedString sMipLevel("mipLevel"); + static LLStaticHashedString sRoughness("roughness"); + static LLStaticHashedString sWidth("u_width"); + + gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); + gRadianceGenProgram.uniform1f(sMipLevel, i); + gRadianceGenProgram.uniform1i(sWidth, mMipChain[i].getWidth()); + for (int cf = 0; cf < 6; ++cf) { // for each cube face LLCoordFrame frame; @@ -492,18 +500,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) frame.getOpenGLRotation(mat); gGL.loadMatrix(mat); - static LLStaticHashedString sRoughness("roughness"); - - gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); - gRadianceGenProgram.uniform1f(sMipLevel, llmax((F32)(i - 1), 0.f)); - - gGL.begin(gGL.QUADS); - gGL.vertex3f(-1, -1, -1); - gGL.vertex3f(1, -1, -1); - gGL.vertex3f(1, 1, -1); - gGL.vertex3f(-1, 1, -1); - gGL.end(); - gGL.flush(); + mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); } @@ -523,7 +520,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mTexture->bind(channel); gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); - + mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); int start_mip = 0; // find the mip target to start with based on irradiance map resolution for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) @@ -548,13 +545,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) frame.getOpenGLRotation(mat); gGL.loadMatrix(mat); - gGL.begin(gGL.QUADS); - gGL.vertex3f(-1, -1, -1); - gGL.vertex3f(1, -1, -1); - gGL.vertex3f(1, 1, -1); - gGL.vertex3f(-1, 1, -1); - gGL.end(); - gGL.flush(); + mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); S32 res = mMipChain[i].getWidth(); mIrradianceMaps->bind(channel); @@ -563,7 +554,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } } - mMipChain[1].flush(); + mMipChain[0].flush(); gIrradianceGenProgram.unbind(); } @@ -848,4 +839,25 @@ void LLReflectionMapManager::initReflectionMaps() mIrradianceMaps = new LLCubeMapArray(); mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); } + + if (mVertexBuffer.isNull()) + { + U32 mask = LLVertexBuffer::MAP_VERTEX; + LLPointer buff = new LLVertexBuffer(mask, GL_STATIC_DRAW); + buff->allocateBuffer(4, 0, TRUE); + + LLStrider v; + + buff->getVertexStrider(v); + + v[0] = LLVector3(-1, -1, -1); + v[1] = LLVector3(1, -1, -1); + v[2] = LLVector3(-1, 1, -1); + v[3] = LLVector3(1, 1, -1); + + buff->flush(); + + mVertexBuffer = buff; + + } } -- cgit v1.2.3 From e5d463ca200bdfa93b8c65e588d490c2f23e3918 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 22 Sep 2022 17:27:18 -0500 Subject: SL-17705 Backwards compatibility pass. Support OpenGL pre-4.0 by disabling reflection probes and anti-aliasing. Get render parity with current release viewer when reflection probes are disabled. --- indra/newview/llreflectionmapmanager.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 2aa1f06eaf..6108fe84d3 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -63,7 +63,7 @@ struct CompareProbeDistance // helper class to seed octree with probes void LLReflectionMapManager::update() { - if (!LLPipeline::sRenderPBR || gTeleportDisplay) + if (!LLPipeline::sReflectionProbesEnabled || gTeleportDisplay) { return; } @@ -130,8 +130,9 @@ void LLReflectionMapManager::update() } bool did_update = false; - - bool realtime = gSavedSettings.getS32("RenderReflectionProbeDetail") >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; + + static LLCachedControl sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); + bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; LLReflectionMap* closestDynamic = nullptr; @@ -613,6 +614,11 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe) void LLReflectionMapManager::updateUniforms() { + if (!LLPipeline::sReflectionProbesEnabled) + { + return; + } + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; // structure for packing uniform buffer object @@ -740,7 +746,11 @@ void LLReflectionMapManager::updateUniforms() void LLReflectionMapManager::setUniforms() { - llassert(LLPipeline::sRenderPBR); + if (!LLPipeline::sReflectionProbesEnabled) + { + return; + } + if (mUBO == 0) { updateUniforms(); -- cgit v1.2.3 From 64cfcea3f4ea6d8120bdf2dedc034f61eb2c07fc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 23 Sep 2022 18:13:20 -0500 Subject: SL-18190 Reduce banding - experiment with RGB16F reflection probes --- indra/newview/llreflectionmapmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 6108fe84d3..4b2a2a382a 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -80,7 +80,7 @@ void LLReflectionMapManager::update() if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGB10_A2; + U32 color_fmt = GL_RGB16F; const bool use_depth_buffer = true; const bool use_stencil_buffer = true; U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample @@ -95,7 +95,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGB10_A2, false, false, LLTexUnit::TT_RECT_TEXTURE); + mMipChain[i].allocate(res, res, GL_RGB16F, false, false, LLTexUnit::TT_RECT_TEXTURE); res /= 2; } } -- cgit v1.2.3 From 1900df361558313f10e8b27ada03bcefd41241d9 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 4 Oct 2022 12:20:19 -0500 Subject: SL-18293, SL-18190 -- Fix for debug displays not showing up (wireframe still busted). WIP on reflection probe/PBR driven water shader. --- indra/newview/llreflectionmapmanager.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 4b2a2a382a..cbefb93ca9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -34,6 +34,7 @@ #include "llviewershadermgr.h" #include "llviewercontrol.h" #include "llenvironment.h" +#include "llstartup.h" extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; @@ -63,7 +64,7 @@ struct CompareProbeDistance // helper class to seed octree with probes void LLReflectionMapManager::update() { - if (!LLPipeline::sReflectionProbesEnabled || gTeleportDisplay) + if (!LLPipeline::sReflectionProbesEnabled || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE) { return; } @@ -212,7 +213,11 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) { LLReflectionMap* probe = new LLReflectionMap(); probe->mGroup = group; - probe->mOrigin = group->getOctreeNode()->getCenter(); + + if (group) + { + probe->mOrigin = group->getOctreeNode()->getCenter(); + } if (gCubeSnapshot) { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update @@ -272,7 +277,9 @@ LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* gr return addProbe(group); } } - +#endif + +#if 0 if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN) { OctreeNode* node = group->getOctreeNode(); -- cgit v1.2.3 From 9448db5d4af7bba094e5bc51f85e5c2491d3f5a1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 6 Oct 2022 18:40:01 -0500 Subject: SL-18190 Water shader WIP. Better parallax correction for sphere probes. Reduce probe memory footprint. Remove framebuffer copies and move to deprecate stencil buffer usage. --- indra/newview/llreflectionmapmanager.cpp | 37 ++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index cbefb93ca9..8f1ee8f70b 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -83,7 +83,7 @@ void LLReflectionMapManager::update() { U32 color_fmt = GL_RGB16F; const bool use_depth_buffer = true; - const bool use_stencil_buffer = true; + const bool use_stencil_buffer = false; U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE); } @@ -96,7 +96,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGB16F, false, false, LLTexUnit::TT_RECT_TEXTURE); + mMipChain[i].allocate(res, res, GL_RGBA16F, false, false, LLTexUnit::TT_RECT_TEXTURE); res /= 2; } } @@ -385,12 +385,10 @@ void LLReflectionMapManager::doProbeUpdate() void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { - mRenderTarget.bindTarget(); // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; probe->update(mRenderTarget.getWidth(), face); gPipeline.mRT = &gPipeline.mMainRT; - mRenderTarget.flush(); S32 targetIdx = mReflectionProbeCount; @@ -399,12 +397,15 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) targetIdx += 1; } + gGL.setColorMask(true, true); + // downsample to placeholder map { LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLGLDisable cull(GL_CULL_FACE); gReflectionMipProgram.bind(); + gGL.matrixMode(gGL.MM_MODELVIEW); gGL.pushMatrix(); gGL.loadIdentity(); @@ -418,6 +419,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f; + S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); + + LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen; + LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen; + for (int i = 0; i < mMipChain.size(); ++i) { LL_PROFILE_GPU_ZONE("probe mip"); @@ -425,13 +432,24 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) if (i == 0) { - gGL.getTexUnit(0)->bind(&mRenderTarget); + + gGL.getTexUnit(diffuseChannel)->bind(screen_rt); } else { - gGL.getTexUnit(0)->bind(&(mMipChain[i - 1])); + gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1])); } + gGL.getTexUnit(depthChannel)->bind(depth_rt, true); + + static LLStaticHashedString resScale("resScale"); + static LLStaticHashedString znear("znear"); + static LLStaticHashedString zfar("zfar"); + + gReflectionMipProgram.uniform1f(resScale, (F32) (1 << i)); + gReflectionMipProgram.uniform1f(znear, probe->getNearClip()); + gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP); + gGL.begin(gGL.QUADS); gGL.texCoord2f(0, 0); @@ -471,6 +489,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.matrixMode(gGL.MM_MODELVIEW); gGL.popMatrix(); + gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE); + gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE); gReflectionMipProgram.unbind(); } @@ -851,10 +871,10 @@ void LLReflectionMapManager::initReflectionMaps() mTexture = new LLCubeMapArray(); // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, mReflectionProbeCount + 2); + mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 4, mReflectionProbeCount + 2); mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE); } if (mVertexBuffer.isNull()) @@ -875,6 +895,5 @@ void LLReflectionMapManager::initReflectionMaps() buff->flush(); mVertexBuffer = buff; - } } -- cgit v1.2.3 From dafa93304335c3c48042e4b5a014dea2480f253f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 11 Oct 2022 16:33:51 -0500 Subject: SL-18190 Fix for mystery circle showing up on east side of reflection probes. Add one probe to rule them all as a fallback for pixels that aren't inside any influence volume. --- indra/newview/llreflectionmapmanager.cpp | 33 ++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8f1ee8f70b..19f0a8d089 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -41,10 +41,13 @@ extern BOOL gTeleportDisplay; LLReflectionMapManager::LLReflectionMapManager() { - for (int i = 0; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) + for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) { mCubeFree[i] = true; } + + // cube index 0 is reserved for the fallback probe + mCubeFree[0] = false; } struct CompareReflectionMapDistance @@ -102,6 +105,15 @@ 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; + } + + mDefaultProbe->mOrigin.load3(LLViewerCamera::getInstance()->getOrigin().mV); + LLVector4a camera_pos; camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); @@ -174,8 +186,11 @@ void LLReflectionMapManager::update() closestDynamic = probe; } - d.setSub(camera_pos, probe->mOrigin); - probe->mDistance = d.getLength3().getF32()-probe->mRadius; + if (probe != mDefaultProbe) + { + d.setSub(camera_pos, probe->mOrigin); + probe->mDistance = d.getLength3().getF32() - probe->mRadius; + } } if (realtime && closestDynamic != nullptr) @@ -196,7 +211,8 @@ void LLReflectionMapManager::update() if (probe->mCubeIndex == -1) { probe->mCubeArray = mTexture; - probe->mCubeIndex = allocateCubeIndex(); + + probe->mCubeIndex = probe == mDefaultProbe ? 0 : allocateCubeIndex(); } probe->autoAdjustOrigin(); @@ -346,6 +362,8 @@ void LLReflectionMapManager::deleteProbe(U32 i) LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; LLReflectionMap* probe = mProbes[i]; + llassert(probe != mDefaultProbe); + if (probe->mCubeIndex != -1) { // mark the cube index used by this probe as being free mCubeFree[probe->mCubeIndex] = true; @@ -429,7 +447,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { LL_PROFILE_GPU_ZONE("probe mip"); mMipChain[i].bindTarget(); - if (i == 0) { @@ -607,6 +624,10 @@ void LLReflectionMapManager::shift(const LLVector4a& offset) void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + if (mDefaultProbe == probe) + { + return; + } //remove from existing neighbors { @@ -627,7 +648,7 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe) LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search"); for (auto& other : mProbes) { - if (other != probe) + if (other != mDefaultProbe && other != probe) { if (probe->intersects(other)) { -- cgit v1.2.3 From 97277e74a9d966ed441e51f844f9012f55cca3dc Mon Sep 17 00:00:00 2001 From: Jonathan Goodman Date: Mon, 14 Nov 2022 18:12:22 +0000 Subject: Merged in SL-18332 (pull request #1194) First pass of Screen Space Reflections Approved-by: Dave Parks --- indra/newview/llreflectionmapmanager.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 19f0a8d089..8282aa2507 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -88,7 +88,7 @@ void LLReflectionMapManager::update() const bool use_depth_buffer = true; const bool use_stencil_buffer = false; U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample - mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE); + mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_TEXTURE); } if (mMipChain.empty()) @@ -99,7 +99,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGBA16F, false, false, LLTexUnit::TT_RECT_TEXTURE); + mMipChain[i].allocate(res, res, GL_RGBA16F, false, false, LLTexUnit::TT_TEXTURE); res /= 2; } } @@ -437,8 +437,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f; - S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); - S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); + S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); + S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE); LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen; LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen; @@ -472,13 +472,13 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.texCoord2f(0, 0); gGL.vertex2f(-1, -1); - gGL.texCoord2f(res, 0); + gGL.texCoord2f(1.f, 0); gGL.vertex2f(1, -1); - gGL.texCoord2f(res, res); + gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(1, 1); - gGL.texCoord2f(0, res); + gGL.texCoord2f(0, 1.f); gGL.vertex2f(-1, 1); gGL.end(); gGL.flush(); @@ -506,8 +506,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.matrixMode(gGL.MM_MODELVIEW); gGL.popMatrix(); - gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE); - gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE); + gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_TEXTURE); gReflectionMipProgram.unbind(); } -- cgit v1.2.3 From dc4f65a2ec1fdd65a77223baaadec38ba38c3bb6 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 30 Nov 2022 14:22:10 -0600 Subject: SL-18745 Fix for LLVertexBuffer assertion on shutdown. --- indra/newview/llreflectionmapmanager.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8282aa2507..e8ad813ed2 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -918,3 +918,26 @@ void LLReflectionMapManager::initReflectionMaps() mVertexBuffer = buff; } } + +void LLReflectionMapManager::cleanup() +{ + mVertexBuffer = nullptr; + mRenderTarget.release(); + + mMipChain.clear(); + + mTexture = nullptr; + mIrradianceMaps = nullptr; + + mProbes.clear(); + mKillList.clear(); + mCreateList.clear(); + + mReflectionMaps.clear(); + mUpdatingFace = 0; + + mDefaultProbe = nullptr; + + glDeleteBuffers(1, &mUBO); + mUBO = 0; +} -- cgit v1.2.3 From ed2b768da29f8dc4f96b463fe4d4087deab75a37 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 2 Dec 2022 09:56:42 -0600 Subject: SL-18745 Fix for assert on teleport. --- indra/newview/llreflectionmapmanager.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e8ad813ed2..088b83a8e9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -40,6 +40,11 @@ extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; LLReflectionMapManager::LLReflectionMapManager() +{ + initCubeFree(); +} + +void LLReflectionMapManager::initCubeFree() { for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) { @@ -50,12 +55,6 @@ LLReflectionMapManager::LLReflectionMapManager() mCubeFree[0] = false; } -struct CompareReflectionMapDistance -{ - -}; - - struct CompareProbeDistance { bool operator()(const LLPointer& lhs, const LLPointer& rhs) @@ -79,7 +78,6 @@ void LLReflectionMapManager::update() return; } - // =============== TODO -- move to an init function ================= initReflectionMaps(); if (!mRenderTarget.isComplete()) @@ -937,7 +935,11 @@ void LLReflectionMapManager::cleanup() mUpdatingFace = 0; mDefaultProbe = nullptr; + mUpdatingProbe = nullptr; glDeleteBuffers(1, &mUBO); mUBO = 0; + + // note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state + initCubeFree(); } -- cgit v1.2.3 From d0af1ca7cb2174c479139692ed764ccaca92a8d5 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 16 Dec 2022 13:35:16 -0600 Subject: SL-18780 Feedback cloud coverage into reflection probe ambiance to recover legacy behavior of cloud coverage brightening ambient lighting without destroying the ability to have good probe driven ambiance. --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 088b83a8e9..1472abcec2 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -695,7 +695,7 @@ void LLReflectionMapManager::updateUniforms() LLEnvironment& environment = LLEnvironment::instance(); LLSettingsSky::ptr_t psky = environment.getCurrentSky(); - F32 minimum_ambiance = psky->getReflectionProbeAmbiance(); + F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(); for (auto* refmap : mReflectionMaps) { -- cgit v1.2.3 From 4711241dd523e64b68ef51e2b9e52a95b04e7034 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 16 Dec 2022 13:57:31 -0600 Subject: SL-18731 Fix for runaway feedback loops on reflection probe ambiance --- indra/newview/llreflectionmapmanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 1472abcec2..d9d6341617 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -696,6 +696,7 @@ void LLReflectionMapManager::updateUniforms() LLSettingsSky::ptr_t psky = environment.getCurrentSky(); F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(); + F32 ambscale = gCubeSnapshot ? 0.5f : 1.f; for (auto* refmap : mReflectionMaps) { @@ -729,7 +730,7 @@ void LLReflectionMapManager::updateUniforms() rpd.refIndex[count][3] = -rpd.refIndex[count][3]; } - rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance()), 0.f, 0.f, 0.f); + rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, 0.f, 0.f, 0.f); S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { -- cgit v1.2.3 From 7bd9d21e19b923096ba2b5ea3cbc8be3e13d7aa0 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 19 Jan 2023 09:13:45 -0600 Subject: Optimizations, decruft, and intel compatibility pass (#53) SL-18869, SL-18772 Overhaul VBO management, restore occlusion culling, intel compatibility pass, etc --- indra/newview/llreflectionmapmanager.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index d9d6341617..b87406cb6e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -513,7 +513,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { //generate radiance map gRadianceGenProgram.bind(); - mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); + mVertexBuffer->setBuffer(); S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); @@ -563,7 +563,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mTexture->bind(channel); gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); - mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); + mVertexBuffer->setBuffer(); int start_mip = 0; // find the mip target to start with based on irradiance map resolution for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) @@ -900,8 +900,8 @@ void LLReflectionMapManager::initReflectionMaps() if (mVertexBuffer.isNull()) { U32 mask = LLVertexBuffer::MAP_VERTEX; - LLPointer buff = new LLVertexBuffer(mask, GL_STATIC_DRAW); - buff->allocateBuffer(4, 0, TRUE); + LLPointer buff = new LLVertexBuffer(mask); + buff->allocateBuffer(4, 0); LLStrider v; @@ -912,7 +912,7 @@ void LLReflectionMapManager::initReflectionMaps() v[2] = LLVector3(-1, 1, -1); v[3] = LLVector3(1, 1, -1); - buff->flush(); + buff->unmapBuffer(); mVertexBuffer = buff; } -- cgit v1.2.3 From 3ef31cb9b28f7b026e109eab69d383dddc922850 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 27 Jan 2023 17:24:22 -0600 Subject: SL-19203 et al -- Integrate SSR with reflection probes, tweak probe blending. (#63) * SL-19203 WIP -- Integrate SSR with reflection probes. Decruft LLRenderTarget. * SL-19203 WIP -- Re-integrate SSR. Incidental decruft. * SL-19203 WIP -- SSR frame delta correction (still broken for Z) * SL-19203 WIP -- SSR frame delta Z fix * SL-19203 WIP -- Make SSR toggleable again and disable SSR in cube snapshots. * SL-19203 WIP -- Soften sphere probe transitions and fix reflections on void water (make fallback probe a simple terrain+water+sky probe). Remove parallax correction for automatic probes to reduce artifacts. * SL-19203 Tune probe blending. * SL-19203 Cleanup. --- indra/newview/llreflectionmapmanager.cpp | 40 ++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index b87406cb6e..128aa99ccc 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -39,6 +39,14 @@ extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; +static void touch_default_probe(LLReflectionMap* probe) +{ + LLVector3 origin = LLViewerCamera::getInstance()->getOrigin(); + origin.mV[2] += 64.f; + + probe->mOrigin.load3(origin.mV); +} + LLReflectionMapManager::LLReflectionMapManager() { initCubeFree(); @@ -83,10 +91,8 @@ void LLReflectionMapManager::update() if (!mRenderTarget.isComplete()) { U32 color_fmt = GL_RGB16F; - const bool use_depth_buffer = true; - const bool use_stencil_buffer = false; U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample - mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_TEXTURE); + mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } if (mMipChain.empty()) @@ -97,7 +103,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGBA16F, false, false, LLTexUnit::TT_TEXTURE); + mMipChain[i].allocate(res, res, GL_RGBA16F); res /= 2; } } @@ -108,9 +114,8 @@ void LLReflectionMapManager::update() 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); } - - mDefaultProbe->mOrigin.load3(LLViewerCamera::getInstance()->getOrigin().mV); LLVector4a camera_pos; camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); @@ -155,6 +160,8 @@ void LLReflectionMapManager::update() doProbeUpdate(); } + //LL_INFOS() << mProbes.size() << LL_ENDL; + for (int i = 0; i < mProbes.size(); ++i) { LLReflectionMap* probe = mProbes[i]; @@ -403,7 +410,26 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; - probe->update(mRenderTarget.getWidth(), face); + + if (probe == mDefaultProbe) + { + touch_default_probe(probe); + + gPipeline.pushRenderTypeMask(); + + //only render sky, water, terrain, and clouds + gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES); + + probe->update(mRenderTarget.getWidth(), face); + + gPipeline.popRenderTypeMask(); + } + else + { + probe->update(mRenderTarget.getWidth(), face); + } + gPipeline.mRT = &gPipeline.mMainRT; S32 targetIdx = mReflectionProbeCount; -- cgit v1.2.3 From 10b8dcc497599042655dcc4037c9ae98d494bd6f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 30 Jan 2023 18:56:19 -0600 Subject: SL-19015 Bump probe resolution back to 256 by default (drop to 128 if vram < 2GB), remove irradiance map feedback loop (one bounce, but but more stable and allows for much brighter first bounce), make sky contribution to irradiance not tint the world blue. Make irradiance that appears in radiance maps match world irradiance. --- indra/newview/llreflectionmapmanager.cpp | 187 ++++++++++++++++++------------- 1 file changed, 109 insertions(+), 78 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 128aa99ccc..ee05849130 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -39,6 +39,10 @@ extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; +// get the next highest power of two of v (or v if v is already a power of two) +//defined in llvertexbuffer.cpp +extern U32 nhpo2(U32 v); + static void touch_default_probe(LLReflectionMap* probe) { LLVector3 origin = LLViewerCamera::getInstance()->getOrigin(); @@ -91,13 +95,13 @@ void LLReflectionMapManager::update() if (!mRenderTarget.isComplete()) { U32 color_fmt = GL_RGB16F; - U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample + U32 targetRes = mProbeResolution * 2; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } if (mMipChain.empty()) { - U32 res = LL_REFLECTION_PROBE_RESOLUTION; + U32 res = mProbeResolution; U32 count = log2((F32)res) + 0.5f; mMipChain.resize(count); @@ -401,11 +405,27 @@ void LLReflectionMapManager::doProbeUpdate() if (++mUpdatingFace == 6) { updateNeighbors(mUpdatingProbe); - mUpdatingProbe = nullptr; mUpdatingFace = 0; + if (mRadiancePass) + { + mUpdatingProbe = nullptr; + mRadiancePass = false; + } + else + { + mRadiancePass = true; + } } } +// Do the reflection map update render passes. +// For every 12 calls of this function, one complete reflection probe radiance map and irradiance map is generated +// First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate +// a simple mip chain (not convolution filter). +// At the end of these passes, an irradiance map is generated for this probe and placed into the irradiance cube map array at the index for this probe +// The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. +// At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe. +// In effect this simulates single-bounce lighting. void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { // hacky hot-swap of camera specific render targets @@ -432,11 +452,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gPipeline.mRT = &gPipeline.mMainRT; - S32 targetIdx = mReflectionProbeCount; + S32 sourceIdx = mReflectionProbeCount; if (probe != mUpdatingProbe) { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel - targetIdx += 1; + sourceIdx += 1; } gGL.setColorMask(true, true); @@ -457,9 +477,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.loadIdentity(); gGL.flush(); - U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2; + U32 res = mProbeResolution * 2; - S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f; + S32 mips = log2((F32)mProbeResolution) + 0.5f; S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE); @@ -516,7 +536,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) LL_PROFILE_GPU_ZONE("probe mip copy"); mTexture->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); //if (i == 0) //{ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); @@ -537,89 +557,98 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) if (face == 5) { - //generate radiance map - gRadianceGenProgram.bind(); - mVertexBuffer->setBuffer(); - - S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - mTexture->bind(channel); - static LLStaticHashedString sSourceIdx("sourceIdx"); - gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx); - mMipChain[0].bindTarget(); - U32 res = mMipChain[0].getWidth(); + static LLStaticHashedString sSourceIdx("sourceIdx"); - for (int i = 0; i < mMipChain.size(); ++i) + if (mRadiancePass) { - LL_PROFILE_GPU_ZONE("probe radiance gen"); - static LLStaticHashedString sMipLevel("mipLevel"); - static LLStaticHashedString sRoughness("roughness"); - static LLStaticHashedString sWidth("u_width"); + //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) + gRadianceGenProgram.bind(); + mVertexBuffer->setBuffer(); - gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); - gRadianceGenProgram.uniform1f(sMipLevel, i); - gRadianceGenProgram.uniform1i(sWidth, mMipChain[i].getWidth()); + S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + mTexture->bind(channel); + gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); + gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); - for (int cf = 0; cf < 6; ++cf) - { // for each cube face - LLCoordFrame frame; - frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + U32 res = mMipChain[0].getWidth(); - F32 mat[16]; - frame.getOpenGLRotation(mat); - gGL.loadMatrix(mat); + for (int i = 0; i < mMipChain.size(); ++i) + { + LL_PROFILE_GPU_ZONE("probe radiance gen"); + static LLStaticHashedString sMipLevel("mipLevel"); + static LLStaticHashedString sRoughness("roughness"); + static LLStaticHashedString sWidth("u_width"); - mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); - - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - } + gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); + gRadianceGenProgram.uniform1f(sMipLevel, i); + gRadianceGenProgram.uniform1i(sWidth, mMipChain[i].getWidth()); - if (i != mMipChain.size() - 1) - { - res /= 2; - glViewport(0, 0, res, res); - } - } + for (int cf = 0; cf < 6; ++cf) + { // for each cube face + LLCoordFrame frame; + frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + + F32 mat[16]; + frame.getOpenGLRotation(mat); + gGL.loadMatrix(mat); + + mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); - gRadianceGenProgram.unbind(); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); + } - //generate irradiance map - gIrradianceGenProgram.bind(); - channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - mTexture->bind(channel); + if (i != mMipChain.size() - 1) + { + res /= 2; + glViewport(0, 0, res, res); + } + } - gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); - mVertexBuffer->setBuffer(); - int start_mip = 0; - // find the mip target to start with based on irradiance map resolution - for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) + gRadianceGenProgram.unbind(); + } + else if (!mRadiancePass) { - if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION) + //generate irradiance map + gIrradianceGenProgram.bind(); + S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + mTexture->bind(channel); + + gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); + gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); + + mVertexBuffer->setBuffer(); + int start_mip = 0; + // find the mip target to start with based on irradiance map resolution + for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) { - break; + if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION) + { + break; + } } - } - //for (int i = start_mip; i < mMipChain.size(); ++i) - { - int i = start_mip; - LL_PROFILE_GPU_ZONE("probe irradiance gen"); - glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); - for (int cf = 0; cf < 6; ++cf) - { // for each cube face - LLCoordFrame frame; - frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); - - F32 mat[16]; - frame.getOpenGLRotation(mat); - gGL.loadMatrix(mat); - - mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); - - S32 res = mMipChain[i].getWidth(); - mIrradianceMaps->bind(channel); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - mTexture->bind(channel); + //for (int i = start_mip; i < mMipChain.size(); ++i) + { + int i = start_mip; + LL_PROFILE_GPU_ZONE("probe irradiance gen"); + glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); + for (int cf = 0; cf < 6; ++cf) + { // for each cube face + LLCoordFrame frame; + frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + + F32 mat[16]; + frame.getOpenGLRotation(mat); + gGL.loadMatrix(mat); + + mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); + + S32 res = mMipChain[i].getWidth(); + mIrradianceMaps->bind(channel); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); + mTexture->bind(channel); + } } } @@ -722,7 +751,7 @@ void LLReflectionMapManager::updateUniforms() LLSettingsSky::ptr_t psky = environment.getCurrentSky(); F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(); - F32 ambscale = gCubeSnapshot ? 0.5f : 1.f; + F32 ambscale = gCubeSnapshot && !mRadiancePass ? 0.f : 1.f; for (auto* refmap : mReflectionMaps) { @@ -912,12 +941,14 @@ void LLReflectionMapManager::initReflectionMaps() { if (mTexture.isNull()) { + mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512)); + mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 mReflectionProbeCount = llclamp(gSavedSettings.getS32("RenderReflectionProbeCount"), 1, LL_MAX_REFLECTION_PROBE_COUNT); mTexture = new LLCubeMapArray(); // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 4, mReflectionProbeCount + 2); + mTexture->allocate(mProbeResolution, 4, mReflectionProbeCount + 2); mIrradianceMaps = new LLCubeMapArray(); mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE); -- cgit v1.2.3 From c9d56e212aa0117661f9c76545ca84b39412bae7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 31 Jan 2023 15:01:05 -0600 Subject: SL-19015 Balance sun/sky ambiance with punctual light ambiance. Prevent irradiance maps from being brighter than the environment. --- indra/newview/llreflectionmapmanager.cpp | 49 +++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index ee05849130..e622f54756 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -406,7 +406,7 @@ void LLReflectionMapManager::doProbeUpdate() { updateNeighbors(mUpdatingProbe); mUpdatingFace = 0; - if (mRadiancePass) + if (isRadiancePass()) { mUpdatingProbe = nullptr; mRadiancePass = false; @@ -460,12 +460,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } gGL.setColorMask(true, true); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); // downsample to placeholder map { - LLGLDepthTest depth(GL_FALSE, GL_FALSE); - LLGLDisable cull(GL_CULL_FACE); - gReflectionMipProgram.bind(); gGL.matrixMode(gGL.MM_MODELVIEW); @@ -560,7 +560,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mMipChain[0].bindTarget(); static LLStaticHashedString sSourceIdx("sourceIdx"); - if (mRadiancePass) + if (isRadiancePass()) { //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) gRadianceGenProgram.bind(); @@ -607,16 +607,20 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gRadianceGenProgram.unbind(); } - else if (!mRadiancePass) + else { //generate irradiance map gIrradianceGenProgram.bind(); S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); + static LLCachedControl ambiance_scale(gSavedSettings, "RenderReflectionProbeAmbianceScale", 8.f); + static LLStaticHashedString ambiance_scale_str("ambiance_scale"); + + gIrradianceGenProgram.uniform1f(ambiance_scale_str, ambiance_scale); gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); - + mVertexBuffer->setBuffer(); int start_mip = 0; // find the mip target to start with based on irradiance map resolution @@ -726,12 +730,28 @@ void LLReflectionMapManager::updateUniforms() // see class3/deferred/reflectionProbeF.glsl struct ReflectionProbeData { - LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; // object bounding box as needed - LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space - LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance) - GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; - GLint refNeighbor[4096]; - GLint refmapCount; + // 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]; + + // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space + LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; + + // extra parameters (currently only ambiance in .x) + LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; + + // 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]; + + // numbrer of active refmaps + GLint refmapCount; }; mReflectionMaps.resize(mReflectionProbeCount); @@ -751,7 +771,8 @@ void LLReflectionMapManager::updateUniforms() LLSettingsSky::ptr_t psky = environment.getCurrentSky(); F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(); - F32 ambscale = gCubeSnapshot && !mRadiancePass ? 0.f : 1.f; + F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; + for (auto* refmap : mReflectionMaps) { -- cgit v1.2.3 From 4259ea79535e88ef6d8ec8415c53c28d0c2d89ac Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 3 Feb 2023 11:34:11 -0600 Subject: SL-19150 Fix for stuttering real-time reflection probes. --- indra/newview/llreflectionmapmanager.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e622f54756..4fd10b85ad 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -206,11 +206,21 @@ void LLReflectionMapManager::update() { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); // update the closest dynamic probe realtime + // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames closestDynamic->autoAdjustOrigin(); + + // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set + // lighting values etc + bool radiance_pass = isRadiancePass(); + mRadiancePass = mRealtimeRadiancePass; for (U32 i = 0; i < 6; ++i) { updateProbeFace(closestDynamic, i); } + mRealtimeRadiancePass = !mRealtimeRadiancePass; + + // restore "isRadiancePass" + mRadiancePass = radiance_pass; } // switch to updating the next oldest probe -- cgit v1.2.3 From 055883beb5709dfb4814c8c5e90ea326abc07724 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 7 Feb 2023 12:59:38 -0600 Subject: SL-18780 Turn down contribution of cloud shadow to reflection probe ambiance and make the value a debug setting. --- indra/newview/llreflectionmapmanager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 4fd10b85ad..04bce58114 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -780,7 +780,9 @@ void LLReflectionMapManager::updateUniforms() LLEnvironment& environment = LLEnvironment::instance(); LLSettingsSky::ptr_t psky = environment.getCurrentSky(); - F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(); + static LLCachedControl cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f); + F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale); + F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; -- cgit v1.2.3 From 0a2cd5a30222e51b744fde9b823dc8cd1de7236c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 8 Feb 2023 10:28:15 -0600 Subject: DRTVWR-559 Quick fix for radiance map filter using wrong resolution parameter. --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 04bce58114..fd2906fa37 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -592,7 +592,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, i); - gRadianceGenProgram.uniform1i(sWidth, mMipChain[i].getWidth()); + gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); for (int cf = 0; cf < 6; ++cf) { // for each cube face -- cgit v1.2.3 From fa1d6066a11fae064ef577795c354b89beb352c3 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 15 Feb 2023 12:06:57 -0600 Subject: SL-19220 Have manual sphere probes live-track their associated LLViewerObjects --- indra/newview/llreflectionmapmanager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index fd2906fa37..8f342fc0bb 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -799,8 +799,10 @@ void LLReflectionMapManager::updateUniforms() llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged { - //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refSphere"); - + if (refmap->mViewerObject) + { // have active manual probes live-track the object they're associated with + refmap->mOrigin.load3(refmap->mViewerObject->getPositionAgent().mV); + } modelview.affineTransform(refmap->mOrigin, oa); rpd.refSphere[count].set(oa.getF32ptr()); rpd.refSphere[count].mV[3] = refmap->mRadius; -- cgit v1.2.3 From 74275f590e75fc8b1685b77a39529cc91ad084b9 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 15 Feb 2023 14:47:33 -0600 Subject: SL-18927 Warn *before* destroying content, not after. Followup from last commit -- immediately apply scale to sphere probes. --- indra/newview/llreflectionmapmanager.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8f342fc0bb..4377f26633 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -802,6 +802,8 @@ void LLReflectionMapManager::updateUniforms() if (refmap->mViewerObject) { // have active manual probes live-track the object they're associated with refmap->mOrigin.load3(refmap->mViewerObject->getPositionAgent().mV); + refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f; + } modelview.affineTransform(refmap->mOrigin, oa); rpd.refSphere[count].set(oa.getF32ptr()); -- cgit v1.2.3 From cd0944caa692e6440f85d21fa706636fc5e46e27 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 17 Feb 2023 14:55:06 -0600 Subject: SL-19239 Redo integration of Sascha's radiance map filter. --- indra/newview/llreflectionmapmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 4377f26633..e760bc794c 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -94,7 +94,7 @@ void LLReflectionMapManager::update() if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGB16F; + U32 color_fmt = GL_RGB16; U32 targetRes = mProbeResolution * 2; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } @@ -107,7 +107,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGBA16F); + mMipChain[i].allocate(res, res, GL_RGBA16); res /= 2; } } -- cgit v1.2.3 From 19f7497d9a01731cbd82be4b522d8b879cdcb8a0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 21 Feb 2023 20:42:25 -0600 Subject: DRTVWR-559 WIP -- occlusion culling for reflection probes -- has a defect for objects close to the camera at some angles and leaks query objects, will follow up. --- indra/newview/llreflectionmapmanager.cpp | 54 +++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 7 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e760bc794c..bfc8b595c2 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -157,6 +157,7 @@ void LLReflectionMapManager::update() LLReflectionMap* closestDynamic = nullptr; LLReflectionMap* oldestProbe = nullptr; + LLReflectionMap* oldestOccluded = nullptr; if (mUpdatingProbe != nullptr) { @@ -179,12 +180,27 @@ void LLReflectionMapManager::update() probe->mProbeIndex = i; LLVector4a d; - - if (!did_update && - i < mReflectionProbeCount && - (oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) + + if (probe->mOccluded) { - oldestProbe = probe; + if (oldestOccluded == nullptr) + { + oldestOccluded = probe; + } + else if (probe->mLastUpdateTime < oldestOccluded->mLastUpdateTime) + { + oldestOccluded = probe; + } + } + else + { + if (!did_update && + i < mReflectionProbeCount && + (oldestProbe == nullptr || + probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) + { + oldestProbe = probe; + } } if (realtime && @@ -240,6 +256,13 @@ void LLReflectionMapManager::update() doProbeUpdate(); } + if (oldestOccluded) + { + // as far as this occluded probe is concerned, an origin/radius update is as good as a full update + oldestOccluded->autoAdjustOrigin(); + oldestOccluded->mLastUpdateTime = gFrameTimeSeconds; + } + // update distance to camera for all probes std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance()); } @@ -277,8 +300,11 @@ void LLReflectionMapManager::getReflectionMaps(std::vector& ma mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested if (mProbes[i]->mCubeIndex != -1) { - mProbes[i]->mProbeIndex = count; - maps[count++] = mProbes[i]; + if (!mProbes[i]->mOccluded) + { + mProbes[i]->mProbeIndex = count; + maps[count++] = mProbes[i]; + } } else { @@ -1038,3 +1064,17 @@ void LLReflectionMapManager::cleanup() // note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state initCubeFree(); } + +void LLReflectionMapManager::doOcclusion() +{ + LLVector4a eye; + eye.load3(LLViewerCamera::instance().getOrigin().mV); + + for (auto& probe : mProbes) + { + if (probe != nullptr) + { + probe->doOcclusion(eye); + } + } +} -- cgit v1.2.3 From 65d69ce80dca112ea0bfd06f2749d4d6fcb366b4 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 22 Feb 2023 11:01:18 -0600 Subject: DRTVWR-559 Fix for stall in probe occlusion culling and fix for culled neighbors getting sampled (badly). --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index bfc8b595c2..608585acf5 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -862,7 +862,7 @@ void LLReflectionMapManager::updateUniforms() } GLint idx = neighbor->mProbeIndex; - if (idx == -1) + if (idx == -1 || neighbor->mOccluded) { continue; } -- cgit v1.2.3 From e5e94b5fa832c62dc0df239fdb4aefc23e559c0c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 23 Feb 2023 11:47:24 -0600 Subject: DRTVWR-559 Fix for irradiance maps going black at 128x128 radiance map resolution. Improve radiance map anti-aliasing and default to 128x128 everywhere. --- indra/newview/llreflectionmapmanager.cpp | 66 ++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 28 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 608585acf5..acb3612416 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -95,7 +95,7 @@ void LLReflectionMapManager::update() if (!mRenderTarget.isComplete()) { U32 color_fmt = GL_RGB16; - U32 targetRes = mProbeResolution * 2; // super sample + U32 targetRes = mProbeResolution * 4; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } @@ -502,8 +502,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) // downsample to placeholder map { - gReflectionMipProgram.bind(); - gGL.matrixMode(gGL.MM_MODELVIEW); gGL.pushMatrix(); gGL.loadIdentity(); @@ -515,21 +513,50 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.flush(); U32 res = mProbeResolution * 2; + static LLStaticHashedString resScale("resScale"); + static LLStaticHashedString direction("direction"); + static LLStaticHashedString znear("znear"); + static LLStaticHashedString zfar("zfar"); + + LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen; + LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen; + + // perform a gaussian blur on the super sampled render before downsampling + { + gGaussianProgram.bind(); + gGaussianProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2)); + S32 diffuseChannel = gGaussianProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); + + // horizontal + gGaussianProgram.uniform2f(direction, 1.f, 0.f); + gGL.getTexUnit(diffuseChannel)->bind(screen_rt); + mRenderTarget.bindTarget(); + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mRenderTarget.flush(); + + // vertical + gGaussianProgram.uniform2f(direction, 0.f, 1.f); + gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget); + screen_rt->bindTarget(); + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + screen_rt->flush(); + } + + S32 mips = log2((F32)mProbeResolution) + 0.5f; + gReflectionMipProgram.bind(); S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE); - LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen; - LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen; - for (int i = 0; i < mMipChain.size(); ++i) { LL_PROFILE_GPU_ZONE("probe mip"); mMipChain[i].bindTarget(); if (i == 0) { - gGL.getTexUnit(diffuseChannel)->bind(screen_rt); } else @@ -539,30 +566,13 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.getTexUnit(depthChannel)->bind(depth_rt, true); - static LLStaticHashedString resScale("resScale"); - static LLStaticHashedString znear("znear"); - static LLStaticHashedString zfar("zfar"); - - gReflectionMipProgram.uniform1f(resScale, (F32) (1 << i)); + gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2)); gReflectionMipProgram.uniform1f(znear, probe->getNearClip()); gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP); - gGL.begin(gGL.QUADS); - - gGL.texCoord2f(0, 0); - gGL.vertex2f(-1, -1); - - gGL.texCoord2f(1.f, 0); - gGL.vertex2f(1, -1); - - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2f(1, 1); - - gGL.texCoord2f(0, 1.f); - gGL.vertex2f(-1, 1); - gGL.end(); - gGL.flush(); - + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + res /= 2; S32 mip = i - (mMipChain.size() - mips); -- cgit v1.2.3 From e5a2f85005bbf94f39ef048dbfe43276990f1154 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 27 Feb 2023 16:53:56 -0600 Subject: SL-19226 Reimplement water fresnel offset/scale, exposure balance for midday, adjust reflections off, and decruft depth buffer error correction shenanigans that are no longer used. --- indra/newview/llreflectionmapmanager.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index acb3612416..7716898376 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -107,7 +107,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGBA16); + mMipChain[i].allocate(res, res, GL_RGB16); res /= 2; } } @@ -475,7 +475,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) //only render sky, water, terrain, and clouds gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES); probe->update(mRenderTarget.getWidth(), face); @@ -519,7 +519,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) static LLStaticHashedString zfar("zfar"); LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen; - LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen; // perform a gaussian blur on the super sampled render before downsampling { @@ -549,7 +548,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gReflectionMipProgram.bind(); S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); - S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE); for (int i = 0; i < mMipChain.size(); ++i) { @@ -564,12 +562,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1])); } - gGL.getTexUnit(depthChannel)->bind(depth_rt, true); - + gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2)); - gReflectionMipProgram.uniform1f(znear, probe->getNearClip()); - gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP); - + gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -597,7 +592,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.popMatrix(); gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_TEXTURE); gReflectionMipProgram.unbind(); } @@ -1021,7 +1015,7 @@ void LLReflectionMapManager::initReflectionMaps() mTexture = new LLCubeMapArray(); // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(mProbeResolution, 4, mReflectionProbeCount + 2); + mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); mIrradianceMaps = new LLCubeMapArray(); mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE); -- cgit v1.2.3 From d5e558fffc0722398a9b4c2df681f2a6ce247b7f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 28 Feb 2023 08:49:15 -0600 Subject: SL-19277 Fix for fallback probe sometimes getting occluded and making void water dark after teleport. Never default to having reflections off. --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 7716898376..9962d0c10c 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1076,7 +1076,7 @@ void LLReflectionMapManager::doOcclusion() for (auto& probe : mProbes) { - if (probe != nullptr) + if (probe != nullptr && probe != mDefaultProbe) { probe->doOcclusion(eye); } -- cgit v1.2.3 From bc7856098f70371dd392c74689df267cce819aa7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 2 Mar 2023 16:36:03 -0600 Subject: SL-19281 Unify handling of haze and gamma between fullbright and not and move haze back to sRGB color space to stay consistent with sky colors. Also fix broken "roughness" stuck at 0.2. --- indra/newview/llreflectionmapmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 9962d0c10c..61d8756490 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -814,7 +814,7 @@ void LLReflectionMapManager::updateUniforms() F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale); F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; - + F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f; for (auto* refmap : mReflectionMaps) { @@ -852,7 +852,7 @@ void LLReflectionMapManager::updateUniforms() rpd.refIndex[count][3] = -rpd.refIndex[count][3]; } - rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, 0.f, 0.f, 0.f); + rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, 0.f, 0.f); S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { -- cgit v1.2.3 From 29b3727b8cc833c664a79a242c9043e6070041e8 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 7 Mar 2023 14:06:01 -0600 Subject: SL-19355 Irradiance rebalance. --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 61d8756490..90c4436a04 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -815,7 +815,7 @@ void LLReflectionMapManager::updateUniforms() F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f; - + for (auto* refmap : mReflectionMaps) { if (refmap == nullptr) -- cgit v1.2.3 From 14293833c9c54411633b4851174e12eea51c2b0c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 13 Mar 2023 10:45:37 -0500 Subject: DRTVWR-559 Fix for GL error on Intel Iris GPU. --- indra/newview/llreflectionmapmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 90c4436a04..c664dbbe9e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -94,7 +94,7 @@ void LLReflectionMapManager::update() if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGB16; + U32 color_fmt = GL_RGB16F; U32 targetRes = mProbeResolution * 4; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } @@ -107,7 +107,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGB16); + mMipChain[i].allocate(res, res, GL_RGB16F); res /= 2; } } -- cgit v1.2.3 From 8c7c4c424d07e39191e827f441af406724829b50 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 22 Mar 2023 10:38:24 -0500 Subject: DRTVWR-559 Quality pass -- Fix sky banding, fix off-by-one-mip in reflection probes (thanks Rye), remove noiseMap from light shaders (removes speckles), make irradiance maps RGB16F instead of RGBA16. Use actual luminance for sky instead of max color component during irradiance map pass. --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index c664dbbe9e..58ce571505 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1018,7 +1018,7 @@ void LLReflectionMapManager::initReflectionMaps() mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); } if (mVertexBuffer.isNull()) -- cgit v1.2.3 From 6162b9208a087f78eba609d3fe9da5c8385f7ade Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 30 Mar 2023 10:41:04 -0500 Subject: DRTVWR-559 Add RenderAutomaticReflectionProbes control. Tweak automatic exposure. --- indra/newview/llreflectionmapmanager.cpp | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 58ce571505..6828078f4f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -328,29 +328,20 @@ void LLReflectionMapManager::getReflectionMaps(std::vector& ma LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group) { -#if 1 - if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) + static LLCachedControl automatic_probes(gSavedSettings, "RenderAutomaticReflectionProbes", 2); + if (automatic_probes > 1) { - OctreeNode* node = group->getOctreeNode(); - F32 size = node->getSize().getF32ptr()[0]; - if (size >= 15.f && size <= 17.f) + if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) { - return addProbe(group); + OctreeNode* node = group->getOctreeNode(); + F32 size = node->getSize().getF32ptr()[0]; + if (size >= 15.f && size <= 17.f) + { + return addProbe(group); + } } } -#endif -#if 0 - if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN) - { - OctreeNode* node = group->getOctreeNode(); - F32 size = node->getSize().getF32ptr()[0]; - if (size >= 15.f && size <= 17.f) - { - return addProbe(group); - } - } -#endif return nullptr; } -- cgit v1.2.3 From b5917fbd16022e4c4d2cf7ef41b21fdea4828c9e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 30 Mar 2023 13:14:23 -0500 Subject: DRTVWR-559 Reduce probe flashing and exposure flickering. --- indra/newview/llreflectionmapmanager.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 6828078f4f..e9df67c724 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -181,7 +181,11 @@ void LLReflectionMapManager::update() LLVector4a d; - if (probe->mOccluded) + if (probe->mComplete) + { + probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f); + } + if (probe->mOccluded && probe->mComplete) { if (oldestOccluded == nullptr) { @@ -300,7 +304,7 @@ void LLReflectionMapManager::getReflectionMaps(std::vector& ma mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested if (mProbes[i]->mCubeIndex != -1) { - if (!mProbes[i]->mOccluded) + if (!mProbes[i]->mOccluded && mProbes[i]->mComplete) { mProbes[i]->mProbeIndex = count; maps[count++] = mProbes[i]; @@ -385,6 +389,7 @@ S32 LLReflectionMapManager::allocateCubeIndex() S32 ret = mProbes[i]->mCubeIndex; mProbes[i]->mCubeIndex = -1; mProbes[i]->mCubeArray = nullptr; + mProbes[i]->mComplete = false; return ret; } } @@ -435,6 +440,7 @@ void LLReflectionMapManager::doProbeUpdate() mUpdatingFace = 0; if (isRadiancePass()) { + mUpdatingProbe->mComplete = true; mUpdatingProbe = nullptr; mRadiancePass = false; } @@ -768,7 +774,10 @@ void LLReflectionMapManager::updateUniforms() // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; - // extra parameters (currently only ambiance in .x) + // extra parameters + // x - irradiance scale + // y - radiance scale + // z - fade in LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; // indices used by probe: @@ -843,7 +852,7 @@ void LLReflectionMapManager::updateUniforms() rpd.refIndex[count][3] = -rpd.refIndex[count][3]; } - rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, 0.f, 0.f); + rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, refmap->mFadeIn, 0.f); S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { -- cgit v1.2.3 From e8114dbe14cc71664f6a27bbe727ff8c25fbc643 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 30 Mar 2023 14:53:01 -0500 Subject: SL-19517 Fix for RenderReflectionProbeCount other than 256 causing black reflections. --- indra/newview/llreflectionmapmanager.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e9df67c724..624eead68e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1006,11 +1006,15 @@ void LLReflectionMapManager::renderDebug() void LLReflectionMapManager::initReflectionMaps() { - if (mTexture.isNull()) + static LLCachedControl probe_count(gSavedSettings, "RenderReflectionProbeCount", LL_MAX_REFLECTION_PROBE_COUNT); + + U32 count = llclamp((S32) probe_count, 1, LL_MAX_REFLECTION_PROBE_COUNT); + + if (mTexture.isNull() || mReflectionProbeCount != count) { + mReflectionProbeCount = count; mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512)); mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 - mReflectionProbeCount = llclamp(gSavedSettings.getS32("RenderReflectionProbeCount"), 1, LL_MAX_REFLECTION_PROBE_COUNT); mTexture = new LLCubeMapArray(); @@ -1019,6 +1023,26 @@ void LLReflectionMapManager::initReflectionMaps() mIrradianceMaps = new LLCubeMapArray(); mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); + + // reset probe state + mUpdatingFace = 0; + mUpdatingProbe = nullptr; + mRadiancePass = false; + mRealtimeRadiancePass = false; + mDefaultProbe = nullptr; + + for (auto& probe : mProbes) + { + probe->mComplete = false; + probe->mProbeIndex = -1; + probe->mCubeArray = nullptr; + probe->mCubeIndex = -1; + } + + for (bool& is_free : mCubeFree) + { + is_free = true; + } } if (mVertexBuffer.isNull()) -- cgit v1.2.3 From 70bdf55439a57116cbd2c9bb32e78a8ada251d78 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 30 Mar 2023 16:24:04 -0500 Subject: SL-19517 Followup -- fix broken fallback probe. Adjust water brightness. --- indra/newview/llreflectionmapmanager.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 624eead68e..09ac7e57a4 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1043,6 +1043,8 @@ void LLReflectionMapManager::initReflectionMaps() { is_free = true; } + + mCubeFree[0] = false; } if (mVertexBuffer.isNull()) -- cgit v1.2.3 From 698966f8e7ddcc0b123a83d7c4e381778f8cd8ab Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 4 Apr 2023 12:29:12 -0500 Subject: =?UTF-8?q?SL-19538=20Remove=20hacky=20ambiance=20scale=20and=20ta?= =?UTF-8?q?ke=20the=20mittens=20off=20probe=20a=E2=80=A6=20(#151)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SL-19538 Remove hacky ambiance scale and take the mittens off probe ambiance values. Fix for sky brightening being done in sRGB space. --- indra/newview/llreflectionmapmanager.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 09ac7e57a4..bccd76415f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -651,10 +651,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); - static LLCachedControl ambiance_scale(gSavedSettings, "RenderReflectionProbeAmbianceScale", 8.f); - static LLStaticHashedString ambiance_scale_str("ambiance_scale"); - - gIrradianceGenProgram.uniform1f(ambiance_scale_str, ambiance_scale); gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); -- cgit v1.2.3 From 1f79379bf215c5368337c64b4f72c7c9ef3e09c2 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 5 Apr 2023 11:55:51 -0500 Subject: SL-19538 Followup -- tune exposure parameters and clamp local light ambiance. Make render targets 16F and scrube NaNs (thanks Rye). Update midday. (#154) --- indra/newview/llreflectionmapmanager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index bccd76415f..8252b4be36 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -464,6 +464,13 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; + mLightScale = 1.f; + static LLCachedControl max_local_light_ambiance(gSavedSettings, "RenderReflectionProbeMaxLocalLightAmbiance", 8.f); + if (!isRadiancePass() && probe->getAmbiance() > max_local_light_ambiance) + { + mLightScale = max_local_light_ambiance / probe->getAmbiance(); + } + if (probe == mDefaultProbe) { touch_default_probe(probe); -- cgit v1.2.3 From de73cf7599e934441fe760f53163b0504c03adc7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 7 Apr 2023 11:06:09 -0500 Subject: SL-19538 Remove clouds from irradiance maps and don't conflate max probe samples with max probe neighbors, and don't move manual probes after they are complete (removes flickering around Sponza). --- indra/newview/llreflectionmapmanager.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8252b4be36..dc84b0b10e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -861,6 +861,9 @@ void LLReflectionMapManager::updateUniforms() { //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors"); //pack neghbor list + const U32 max_neighbors = 64; + U32 neighbor_count = 0; + for (auto& neighbor : refmap->mNeighbors) { if (ni >= 4096) @@ -876,6 +879,12 @@ void LLReflectionMapManager::updateUniforms() // this neighbor may be sampled rpd.refNeighbor[ni++] = idx; + + neighbor_count++; + if (neighbor_count >= max_neighbors) + { + break; + } } } -- cgit v1.2.3 From 413ce656c8e910bf3758afc3fa354e07be2d4561 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 7 Apr 2023 14:10:53 -0500 Subject: SL-19538 Clear probes on sky setting slam. Better probe update prioritization. Incidental decruft. --- indra/newview/llreflectionmapmanager.cpp | 60 +++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 13 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index dc84b0b10e..fd80936496 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -75,6 +75,23 @@ struct CompareProbeDistance } }; +// 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) + { //neither probe is complete, use distance + return a->mDistance < b->mDistance; + } + else if (a->mComplete && b->mComplete) + { //both probes are complete, use combination of distance and last update time + return (a->mDistance - (gFrameTimeSeconds - a->mLastUpdateTime)) < + (b->mDistance - (gFrameTimeSeconds - b->mLastUpdateTime)); + } + + // one of these probes is not complete, if b is complete, a is higher priority + return b->mComplete; +} + // helper class to seed octree with probes void LLReflectionMapManager::update() { @@ -181,6 +198,12 @@ void LLReflectionMapManager::update() LLVector4a d; + if (probe != mDefaultProbe) + { + d.setSub(camera_pos, probe->mOrigin); + probe->mDistance = d.getLength3().getF32() - probe->mRadius; + } + if (probe->mComplete) { probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f); @@ -201,7 +224,7 @@ void LLReflectionMapManager::update() if (!did_update && i < mReflectionProbeCount && (oldestProbe == nullptr || - probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) + check_priority(probe, oldestProbe))) { oldestProbe = probe; } @@ -214,12 +237,6 @@ void LLReflectionMapManager::update() { closestDynamic = probe; } - - if (probe != mDefaultProbe) - { - d.setSub(camera_pos, probe->mOrigin); - probe->mDistance = d.getLength3().getF32() - probe->mRadius; - } } if (realtime && closestDynamic != nullptr) @@ -702,12 +719,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } } -void LLReflectionMapManager::rebuild() +void LLReflectionMapManager::reset() { - for (auto& probe : mProbes) - { - probe->mLastUpdateTime = 0.f; - } + mReset = true; } void LLReflectionMapManager::shift(const LLVector4a& offset) @@ -950,12 +964,30 @@ void renderReflectionProbe(LLReflectionMap* probe) 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(); + #if 0 LLSpatialGroup* group = probe->mGroup; if (group) @@ -1022,8 +1054,9 @@ void LLReflectionMapManager::initReflectionMaps() U32 count = llclamp((S32) probe_count, 1, LL_MAX_REFLECTION_PROBE_COUNT); - if (mTexture.isNull() || mReflectionProbeCount != count) + if (mTexture.isNull() || mReflectionProbeCount != count || mReset) { + mReset = false; mReflectionProbeCount = count; mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512)); mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 @@ -1045,6 +1078,7 @@ void LLReflectionMapManager::initReflectionMaps() for (auto& probe : mProbes) { + probe->mLastUpdateTime = 0.f; probe->mComplete = false; probe->mProbeIndex = -1; probe->mCubeArray = nullptr; -- cgit v1.2.3 From 474739226433a74cdca05a949586139a9c9c0bbd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 8 Apr 2023 11:22:50 -0500 Subject: SL-19538 Nudge probe scheduler to unstick probes that are "complete". --- indra/newview/llreflectionmapmanager.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index fd80936496..ea2db63560 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -75,6 +75,11 @@ struct CompareProbeDistance } }; +static F32 update_score(LLReflectionMap* p) +{ + return gFrameTimeSeconds - p->mLastUpdateTime - p->mDistance*0.1f; +} + // return true if a is higher priority for an update than b static bool check_priority(LLReflectionMap* a, LLReflectionMap* b) { @@ -83,9 +88,8 @@ static bool check_priority(LLReflectionMap* a, LLReflectionMap* b) return a->mDistance < b->mDistance; } else if (a->mComplete && b->mComplete) - { //both probes are complete, use combination of distance and last update time - return (a->mDistance - (gFrameTimeSeconds - a->mLastUpdateTime)) < - (b->mDistance - (gFrameTimeSeconds - b->mLastUpdateTime)); + { //both probes are complete, use update_score metric + return update_score(a) > update_score(b); } // one of these probes is not complete, if b is complete, a is higher priority @@ -203,9 +207,15 @@ void LLReflectionMapManager::update() d.setSub(camera_pos, probe->mOrigin); probe->mDistance = d.getLength3().getF32() - probe->mRadius; } + else if (probe->mComplete) + { + // make default probe have a distance of 64m for the purposes of prioritization (if it's already been generated once) + probe->mDistance = 64.f; + } if (probe->mComplete) { + probe->autoAdjustOrigin(); probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f); } if (probe->mOccluded && probe->mComplete) @@ -285,6 +295,7 @@ void LLReflectionMapManager::update() } // 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()); } -- cgit v1.2.3 From 37eee397b70e2a13a1309025207d1c301f7070c5 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 18 Apr 2023 19:11:38 -0500 Subject: DRTVWR-559 Add control for automatic reflection probes to advanced preferences and featuretable. Remove Reflections checkbox. Don't persist reflection probe volume display between sessions. Incidental decruft. --- indra/newview/llreflectionmapmanager.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index ea2db63560..88edbc9224 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -173,6 +173,8 @@ void LLReflectionMapManager::update() bool did_update = false; static LLCachedControl sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); + static LLCachedControl sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); + bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; LLReflectionMap* closestDynamic = nullptr; @@ -198,6 +200,11 @@ void LLReflectionMapManager::update() continue; } + if (probe != mDefaultProbe && !probe->isRelevant()) + { + continue; + } + probe->mProbeIndex = i; LLVector4a d; @@ -270,6 +277,13 @@ void LLReflectionMapManager::update() mRadiancePass = radiance_pass; } + static LLCachedControl sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 20.f); + if (sLevel == 0 && + gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime < sUpdatePeriod) + { // when probes are disabled don't update the default probe more often than once every 20 seconds + oldestProbe = nullptr; + } + // switch to updating the next oldest probe if (!did_update && oldestProbe != nullptr) { @@ -360,17 +374,13 @@ void LLReflectionMapManager::getReflectionMaps(std::vector& ma LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group) { - static LLCachedControl automatic_probes(gSavedSettings, "RenderAutomaticReflectionProbes", 2); - if (automatic_probes > 1) + if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) { - if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) + OctreeNode* node = group->getOctreeNode(); + F32 size = node->getSize().getF32ptr()[0]; + if (size >= 15.f && size <= 17.f) { - OctreeNode* node = group->getOctreeNode(); - F32 size = node->getSize().getF32ptr()[0]; - if (size >= 15.f && size <= 17.f) - { - return addProbe(group); - } + return addProbe(group); } } -- cgit v1.2.3 From 5d862c994c18b155bc761fa16dd4070281a1345e Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 25 Apr 2023 14:48:16 -0500 Subject: DRTVWR-559 Optimization pass on probe allocation and search. Incidental decruft. --- indra/newview/llreflectionmapmanager.cpp | 315 ++++++++++++++++++++++--------- 1 file changed, 231 insertions(+), 84 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 88edbc9224..2235453e47 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -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& lhs, const LLPointer& 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 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& 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& 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& 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()) -- cgit v1.2.3 From 46e04fe273ce88c52c08a6417a01ec89bd4e89e9 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 23 May 2023 16:11:43 -0500 Subject: DRTVWR-559 Remove RenderReflectionProbeCount (which is bugged) and lean on RenderReflectionProbeLevel for preferences (which works). --- indra/newview/llreflectionmapmanager.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 2235453e47..5dc93dbeb8 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1205,9 +1205,7 @@ void LLReflectionMapManager::renderDebug() void LLReflectionMapManager::initReflectionMaps() { - static LLCachedControl probe_count(gSavedSettings, "RenderReflectionProbeCount", LL_MAX_REFLECTION_PROBE_COUNT); - - U32 count = llclamp((S32) probe_count, 1, LL_MAX_REFLECTION_PROBE_COUNT); + U32 count = LL_MAX_REFLECTION_PROBE_COUNT; if (mTexture.isNull() || mReflectionProbeCount != count || mReset) { -- cgit v1.2.3 From 50ec54831de88926ca13c9a72d89006ceda6c355 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 1 Jun 2023 19:49:23 -0500 Subject: DRTVWR-559 Revert skies to be very close to release and disable tone mapping when probe ambiance is zero. Hack for desaturating legacy materials has been removed for performance and quality reasons. Adds a new setting for auto adjusting legacy skies. This is the PBR "opt out" button. If disabled, legacy skies will disable tonemapping, automatic probe ambiance, and HDR/exposure. If enabled, legacy skies will behave as if probe ambiance and HDR scale are 1.0, and ambient will be cut in half. HDR scale will act as a sky brightener, but will automatically adjust dynamic exposure so the sky will be properly exposed. If you want relatively even exposure all the time, set HDR Scale to 1.0. If you want a high range of exposures between indoor/dark areas and outdoor/bright areas, increase HDR Scale. Also tuned up SSAO (thanks Rye!). Reviewed with Brad. --- indra/newview/llreflectionmapmanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 5dc93dbeb8..15d41c4161 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -915,7 +915,8 @@ void LLReflectionMapManager::updateUniforms() LLSettingsSky::ptr_t psky = environment.getCurrentSky(); static LLCachedControl cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f); - F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale); + static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust); F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f; -- cgit v1.2.3 From ad956699c08620903150b9adfc2e8c34ccf5c390 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 13 Jun 2023 14:45:12 -0500 Subject: SL-19811 Update fallback probe every 2 seconds to smooth out water cloud updates. --- indra/newview/llreflectionmapmanager.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 15d41c4161..e30aba3df7 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -323,11 +323,17 @@ void LLReflectionMapManager::update() mRadiancePass = radiance_pass; } - static LLCachedControl sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 20.f); - if (sLevel == 0 && - gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime < sUpdatePeriod) - { // when probes are disabled don't update the default probe more often than once every 20 seconds - oldestProbe = nullptr; + static LLCachedControl sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f); + if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod) + { + if (sLevel == 0) + { // when probes are disabled don't update the default probe more often than the prescribed update period + oldestProbe = nullptr; + } + } + else if (sLevel > 0) + { // when probes are enabled don't update the default probe less often than the prescribed update period + oldestProbe = mDefaultProbe; } // switch to updating the next oldest probe -- cgit v1.2.3 From 85967398ff8591170d89374652a6998ff6cd3d69 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 21 Jun 2023 20:50:50 -0500 Subject: SL-19792 Fix for visible gaps in water between region water and void water. --- indra/newview/llreflectionmapmanager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e30aba3df7..779fe8bfd9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -924,8 +924,9 @@ void LLReflectionMapManager::updateUniforms() static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust); - F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; - F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f; + bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass(); + F32 ambscale = is_ambiance_pass ? 0.f : 1.f; + F32 radscale = is_ambiance_pass ? 0.5f : 1.f; for (auto* refmap : mReflectionMaps) { -- cgit v1.2.3 From ca47c7ff44ed0f5f1582f3a3dc5a31fcb3454885 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 27 Jun 2023 20:11:01 -0500 Subject: DRTVWR-559 Fix for manual probes not updating as often as they should when nearby (bad distance calculation) --- indra/newview/llreflectionmapmanager.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 779fe8bfd9..bb0bb04797 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -253,6 +253,10 @@ void LLReflectionMapManager::update() if (probe != mDefaultProbe) { + if (probe->mViewerObject) //make sure probes track the viewer objects they are attached to + { + probe->mOrigin.load3(probe->mViewerObject->getPositionAgent().mV); + } d.setSub(camera_pos, probe->mOrigin); probe->mDistance = d.getLength3().getF32() - probe->mRadius; } -- cgit v1.2.3 From bc4e90ea5e462662f90c860d69aaa53b88f189c5 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 2 Oct 2023 14:19:04 -0500 Subject: SL-20124 Wipe reflection probes when applying parcel EEP settings and pause updates on probes until transition completes. --- indra/newview/llreflectionmapmanager.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index bb0bb04797..915c8893a4 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -244,11 +244,14 @@ void LLReflectionMapManager::update() continue; } - if (probe != mDefaultProbe && !probe->isRelevant()) - { + if (probe != mDefaultProbe && + (!probe->isRelevant() || mPaused)) + { // skip irrelevant probes (or all non-default probes if paused) continue; } + + LLVector4a d; if (probe != mDefaultProbe) @@ -807,6 +810,16 @@ void LLReflectionMapManager::reset() mReset = true; } +void LLReflectionMapManager::pause() +{ + mPaused = true; +} + +void LLReflectionMapManager::resume() +{ + mPaused = false; +} + void LLReflectionMapManager::shift(const LLVector4a& offset) { for (auto& probe : mProbes) -- cgit v1.2.3 From 09aedbb7a9b4bfa56b7acd3250d10c483a5ac219 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 16 Oct 2023 13:54:38 -0500 Subject: SL-20258 Fix for LSL spamming new probes into the scene deadlocking probe updater. Add probe update debug display. --- indra/newview/llreflectionmapmanager.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 915c8893a4..283c97ff0a 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -39,6 +39,8 @@ extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; +static U32 sUpdateCount = 0; + // get the next highest power of two of v (or v if v is already a power of two) //defined in llvertexbuffer.cpp extern U32 nhpo2(U32 v); @@ -91,7 +93,7 @@ static bool check_priority(LLReflectionMap* a, LLReflectionMap* b) return false; } else if (b->mCubeIndex == -1) - { // certainly higher priority than b + { // b is not a candidate for updating, a is higher priority by default return true; } else if (!a->mComplete && !b->mComplete) @@ -103,7 +105,13 @@ static bool check_priority(LLReflectionMap* a, LLReflectionMap* b) return update_score(a) > update_score(b); } - // one of these probes is not complete, if b is complete, a is higher priority + // a or b is not complete, + if (sUpdateCount % 3 == 0) + { // every third update, allow complete probes to cut in line in front of non-complete probes to avoid spammy probe generators from deadlocking scheduler (SL-20258)) + return !b->mComplete; + } + + // prioritize incomplete probe return b->mComplete; } @@ -351,6 +359,7 @@ void LLReflectionMapManager::update() probe->autoAdjustOrigin(); + sUpdateCount++; mUpdatingProbe = probe; doProbeUpdate(); } @@ -537,8 +546,14 @@ void LLReflectionMapManager::doProbeUpdate() updateProbeFace(mUpdatingProbe, mUpdatingFace); + bool debug_updates = gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PROBE_UPDATES) && mUpdatingProbe->mViewerObject; + if (++mUpdatingFace == 6) { + if (debug_updates) + { + mUpdatingProbe->mViewerObject->setDebugText(llformat("%.1f", (F32)gFrameTimeSeconds), LLColor4(1, 1, 1, 1)); + } updateNeighbors(mUpdatingProbe); mUpdatingFace = 0; if (isRadiancePass()) @@ -552,6 +567,10 @@ void LLReflectionMapManager::doProbeUpdate() mRadiancePass = true; } } + else if (debug_updates) + { + mUpdatingProbe->mViewerObject->setDebugText(llformat("%.1f", (F32)gFrameTimeSeconds), LLColor4(1, 1, 0, 1)); + } } // Do the reflection map update render passes. -- cgit v1.2.3 From a29f7c3b4ac50951aa86a71cb6ba20b712533c70 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 23 Oct 2023 13:54:00 -0500 Subject: SL-20498 Preserve default probe when resetting reflection probes. --- indra/newview/llreflectionmapmanager.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 283c97ff0a..72f7e23b0c 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1258,13 +1258,18 @@ void LLReflectionMapManager::initReflectionMaps() mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512)); mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 - mTexture = new LLCubeMapArray(); + if (mTexture.isNull() || + mTexture->getWidth() != mProbeResolution || + mReflectionProbeCount + 2 != mTexture->getCount()) + { + mTexture = new LLCubeMapArray(); - // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); + // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) + mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); - mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); + mIrradianceMaps = new LLCubeMapArray(); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); + } // reset probe state mUpdatingFace = 0; @@ -1272,6 +1277,9 @@ void LLReflectionMapManager::initReflectionMaps() mRadiancePass = false; mRealtimeRadiancePass = false; + // if default probe already exists, remember whether or not it's complete (SL-20498) + bool default_complete = mDefaultProbe.isNull() ? false : mDefaultProbe->mComplete; + for (auto& probe : mProbes) { probe->mLastUpdateTime = 0.f; @@ -1299,6 +1307,8 @@ void LLReflectionMapManager::initReflectionMaps() mDefaultProbe->mDistance = 64.f; mDefaultProbe->mRadius = 4096.f; mDefaultProbe->mProbeIndex = 0; + mDefaultProbe->mComplete = default_complete; + touch_default_probe(mDefaultProbe); } -- cgit v1.2.3