From b121735e3cc7dbadf6fe3aca469457269c6e3dce Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Sun, 8 Sep 2024 16:10:35 -0400 Subject: [PATCH] Backport probe/mirror fixes --- indra/newview/llheroprobemanager.cpp | 77 +++++++----- indra/newview/llheroprobemanager.h | 21 ++-- indra/newview/llpanelvolume.cpp | 2 +- indra/newview/llreflectionmap.cpp | 4 +- indra/newview/llreflectionmap.h | 12 +- indra/newview/llreflectionmapmanager.cpp | 150 ++++++++++++----------- indra/newview/llreflectionmapmanager.h | 4 +- indra/newview/llviewerobject.h | 7 +- indra/newview/llvovolume.cpp | 6 +- indra/newview/llvovolume.h | 14 +-- 10 files changed, 159 insertions(+), 138 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 852116958b3..6e1f833dcd1 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -91,19 +91,19 @@ void LLHeroProbeManager::update() if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGB16F; + U32 color_fmt = GL_RGBA16F; mRenderTarget.allocate(mProbeResolution, mProbeResolution, color_fmt, true); } if (mMipChain.empty()) { U32 res = mProbeResolution; - U32 count = log2((F32)res) + 0.5f; + U32 count = (U32)(log2((F32)res) + 0.5f); mMipChain.resize(count); - for (int i = 0; i < count; ++i) + for (U32 i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGB16F); + mMipChain[i].allocate(res, res, GL_RGBA16F); res /= 2; } } @@ -122,6 +122,7 @@ void LLHeroProbeManager::update() // Find our nearest hero candidate. float last_distance = 99999.f; float camera_center_distance = 99999.f; + mNearestHero = nullptr; for (auto vo : mHeroVOList) { if (vo && !vo->isDead() && vo->mDrawable.notNull() && vo->isReflectionProbe() && vo->getReflectionProbeIsBox()) @@ -189,26 +190,22 @@ void LLHeroProbeManager::update() LLVector3(0, 0, -1) }; - // Iterate through each face of the cube - for (int i = 0; i < 6; i++) - { - float cube_facing = fmax(-1, fmin(1.0f, cameraDirection * cubeFaces[i])); - - cube_facing = 1 - cube_facing; - - mFaceUpdateList[i] = ceilf(cube_facing * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); - } - - mProbes[0]->mOrigin = probe_pos; + mProbes[0]->mRadius = mNearestHero->getScale().magVec() * 0.5f; } else { mNearestHero = nullptr; + mDefaultProbe->mViewerObject = nullptr; } mHeroProbeStrength = 1; } + else + { + mNearestHero = nullptr; + mDefaultProbe->mViewerObject = nullptr; + } } void LLHeroProbeManager::renderProbes() @@ -221,9 +218,10 @@ void LLHeroProbeManager::renderProbes() static LLCachedControl<S32> sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); static LLCachedControl<S32> sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); + static LLCachedControl<S32> sUpdateRate(gSavedSettings, "RenderHeroProbeUpdateRate", 0); F32 near_clip = 0.01f; - if (mNearestHero != nullptr && (gPipeline.RenderHeroProbeUpdateRate == 0 || (gFrameCount % gPipeline.RenderHeroProbeUpdateRate) == 0) && + if (mNearestHero != nullptr && !gTeleportDisplay && !gDisconnected && !LLAppViewer::instance()->logoutRequestSent()) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); @@ -231,22 +229,36 @@ void LLHeroProbeManager::renderProbes() bool radiance_pass = gPipeline.mReflectionMapManager.isRadiancePass(); gPipeline.mReflectionMapManager.mRadiancePass = true; - mRenderingMirror = true; + mRenderingMirror = true; - doOcclusion(); + S32 rate = sUpdateRate; - for (U32 j = 0; j < mProbes.size(); j++) + // rate must be divisor of 6 (1, 2, 3, or 6) + if (rate < 1) + { + rate = 1; + } + else if (rate > 3) { + rate = 6; + } + + if (!mProbes.empty() && !mProbes[0].isNull() && !mProbes[0]->mOccluded) + { + LL_PROFILE_ZONE_NUM(gFrameCount % rate); + LL_PROFILE_ZONE_NUM(rate); + for (U32 i = 0; i < 6; ++i) { - if (mFaceUpdateList[i] > 0 && mCurrentProbeUpdateFrame % mFaceUpdateList[i] == 0) - { - updateProbeFace(mProbes[j], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip); - mCurrentProbeUpdateFrame = 0; + if ((gFrameCount % rate) == (i % rate)) + { // update 6/rate faces per frame + LL_PROFILE_ZONE_NUM(i); + updateProbeFace(mProbes[0], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip); } } - generateRadiance(mProbes[j]); + generateRadiance(mProbes[0]); } + mRenderingMirror = false; gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass; @@ -254,8 +266,6 @@ void LLHeroProbeManager::renderProbes() mProbes[0]->mViewerObject = mNearestHero; mProbes[0]->autoAdjustOrigin(); } - - mCurrentProbeUpdateFrame++; } // Do the reflection map update render passes. @@ -330,7 +340,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool gGaussianProgram.unbind(); } - S32 mips = log2((F32)mProbeResolution) + 0.5f; + S32 mips = (S32)(log2((F32)mProbeResolution) + 0.5f); gReflectionMipProgram.bind(); S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); @@ -360,7 +370,8 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool res /= 2; - S32 mip = i - (mMipChain.size() - mips); + llassert(mMipChain.size() <= size_t(S32_MAX)); + GLint mip = i - (S32(mMipChain.size()) - mips); if (mip >= 0) { @@ -388,6 +399,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool // Useful when we may not always be rendering a full set of faces of the probe. void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; S32 sourceIdx = mReflectionProbeCount; // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes. @@ -418,7 +430,7 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) static LLStaticHashedString sStrength("probe_strength"); gHeroRadianceGenProgram.uniform1f(sRoughness, (F32) i / (F32) (mMipChain.size() - 1)); - gHeroRadianceGenProgram.uniform1f(sMipLevel, i); + gHeroRadianceGenProgram.uniform1f(sMipLevel, (GLfloat)i); gHeroRadianceGenProgram.uniform1i(sWidth, mProbeResolution); gHeroRadianceGenProgram.uniform1f(sStrength, 1); @@ -487,7 +499,8 @@ void LLHeroProbeManager::updateUniforms() mHeroData.heroSphere.mV[3] = mProbes[0]->mRadius; } - mHeroData.heroMipCount = mMipChain.size(); + llassert(mMipChain.size() <= size_t(S32_MAX)); + mHeroData.heroMipCount = S32(mMipChain.size()); } void LLHeroProbeManager::renderDebug() @@ -518,7 +531,7 @@ void LLHeroProbeManager::initReflectionMaps() mReset = false; mReflectionProbeCount = count; mProbeResolution = gSavedSettings.getS32("RenderHeroProbeResolution"); - mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 + mMaxProbeLOD = log2f((F32)mProbeResolution) - 1.f; // number of mips - 1 mTexture = new LLCubeMapArray(); @@ -588,7 +601,7 @@ void LLHeroProbeManager::doOcclusion() for (auto& probe : mProbes) { - if (probe != nullptr && probe != mDefaultProbe) + if (probe != nullptr) { probe->doOcclusion(eye); } diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 123cadf8082..58a94a3de82 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -51,18 +51,18 @@ class alignas(16) LLHeroProbeManager { LL_ALIGN_NEW public: - enum class DetailLevel + enum class DetailLevel { STATIC_ONLY = 0, STATIC_AND_DYNAMIC, REALTIME = 2 }; - // allocate an environment map of the given resolution + // allocate an environment map of the given resolution LLHeroProbeManager(); ~LLHeroProbeManager(); - // release any GL state + // release any GL state void cleanup(); // maintain reflection probes @@ -90,11 +90,11 @@ class alignas(16) LLHeroProbeManager LLVector3 mMirrorPosition; LLVector3 mMirrorNormal; HeroProbeData mHeroData; - + private: friend class LLPipeline; friend class LLReflectionMapManager; - + // update UBO used for rendering (call only once per render pipe flush) void updateUniforms(); @@ -118,7 +118,7 @@ class alignas(16) LLHeroProbeManager // update the specified face of the specified probe void updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip); void generateRadiance(LLReflectionMap *probe); - + // list of active reflection maps std::vector<LLPointer<LLReflectionMap>> mProbes; @@ -129,10 +129,10 @@ class alignas(16) LLHeroProbeManager // resolution of reflection probes U32 mProbeResolution = 1024; - + // maximum LoD of reflection probes (mip levels - 1) F32 mMaxProbeLOD = 6.f; - + F32 mHeroProbeStrength = 1.f; bool mIsInTransition = false; @@ -140,10 +140,7 @@ class alignas(16) LLHeroProbeManager bool mReset = false; bool mRenderingMirror = false; - std::map<int, int> mFaceUpdateList; - - U32 mCurrentProbeUpdateFrame = 0; - + std::vector<LLPointer<LLVOVolume>> mHeroVOList; LLPointer<LLVOVolume> mNearestHero; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 0807fafee08..a6ffb3c619a 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -1270,7 +1270,7 @@ void LLPanelVolume::onPasteLight() if (clipboard.has("reflection_probe")) { - volobjp->setIsReflectionProbe(TRUE); + volobjp->setIsReflectionProbe(true); volobjp->setReflectionProbeIsBox(clipboard["reflection_probe"]["is_box"].asBoolean()); volobjp->setReflectionProbeAmbiance((F32)clipboard["reflection_probe"]["ambiance"].asReal()); volobjp->setReflectionProbeNearClip((F32)clipboard["reflection_probe"]["near_clip"].asReal()); diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 99993f26b45..dbddef8460c 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -220,7 +220,7 @@ F32 LLReflectionMap::getNearClip() if (mViewerObject && mViewerObject->getVolume()) { - ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeNearClip(); + ret = mViewerObject->getReflectionProbeNearClip(); } else if (mGroup) { @@ -241,7 +241,7 @@ bool LLReflectionMap::getIsDynamic() mViewerObject && mViewerObject->getVolume()) { - return ((LLVOVolume*)mViewerObject)->getReflectionProbeIsDynamic(); + return mViewerObject->getReflectionProbeIsDynamic(); } return false; diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index 9e888f20d0d..117ea4cfa66 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -36,7 +36,7 @@ class alignas(16) LLReflectionMap : public LLRefCount { LL_ALIGN_NEW public: - + enum class ProbeType { ALL = 0, @@ -44,8 +44,8 @@ class alignas(16) LLReflectionMap : public LLRefCount IRRADIANCE, REFLECTION }; - - // allocate an environment map of the given resolution + + // allocate an environment map of the given resolution LLReflectionMap(); ~LLReflectionMap(); @@ -86,7 +86,7 @@ class alignas(16) LLReflectionMap : public LLRefCount // point at which environment map was last generated from (in agent space) LLVector4a mOrigin; - + // distance from main viewer camera F32 mDistance = -1.f; @@ -106,7 +106,7 @@ class alignas(16) LLReflectionMap : public LLRefCount // cube map used to sample this environment map LLPointer<LLCubeMapArray> mCubeArray; S32 mCubeIndex = -1; // index into cube map array or -1 if not currently stored in cube map array - + // probe has had at least one full update and is ready to render bool mComplete = false; @@ -136,7 +136,7 @@ class alignas(16) LLReflectionMap : public LLRefCount GLuint mOcclusionQuery = 0; bool mOccluded = false; U32 mOcclusionPendingFrames = 0; - + ProbeType mType; }; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 9a650412ad4..69da7b965e9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -67,7 +67,7 @@ void load_exr(const std::string& filename) const char* err = NULL; // or nullptr in C++11 int ret = LoadEXRWithLayer(&out, &width, &height, filename.c_str(), /* layername */ nullptr, &err); - if (ret == TINYEXR_SUCCESS) + if (ret == TINYEXR_SUCCESS) { U32 texName = 0; LLImageGL::generateTextures(1, &texName); @@ -80,6 +80,8 @@ void load_exr(const std::string& filename) gGL.getTexUnit(0)->bind(gEXRImage); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGBA, GL_FLOAT, out); + + free(out); // release memory of image data glGenerateMipmap(GL_TEXTURE_2D); @@ -87,12 +89,12 @@ void load_exr(const std::string& filename) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } - else + else { LLSD notif_args; notif_args["WHAT"] = filename; notif_args["REASON"] = "Unknown"; - if (err) + if (err) { notif_args["REASON"] = std::string(err); FreeEXRErrorMessage(err); // release memory of error message. @@ -220,8 +222,28 @@ void LLReflectionMapManager::update() initReflectionMaps(); + if (!mRenderTarget.isComplete()) + { + U32 color_fmt = GL_RGB16F; + U32 targetRes = mProbeResolution * 4; // super sample + mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); + } + + if (mMipChain.empty()) + { + U32 res = mProbeResolution; + U32 count = (U32)(log2((F32)res) + 0.5f); + + mMipChain.resize(count); + for (U32 i = 0; i < count; ++i) + { + mMipChain[i].allocate(res, res, GL_RGB16F); + res /= 2; + } + } + llassert(mProbes[0] == mDefaultProbe); - + LLVector4a camera_pos; camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); @@ -231,12 +253,12 @@ void LLReflectionMapManager::update() auto const & iter = std::find(mProbes.begin(), mProbes.end(), probe); if (iter != mProbes.end()) { - deleteProbe(iter - mProbes.begin()); + deleteProbe((U32)(iter - mProbes.begin())); } } mKillList.clear(); - + // process create list for (auto& probe : mCreateList) { @@ -252,12 +274,12 @@ void LLReflectionMapManager::update() bool did_update = false; - + static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; - + LLReflectionMap* closestDynamic = nullptr; LLReflectionMap* oldestProbe = nullptr; @@ -296,7 +318,7 @@ void LLReflectionMapManager::update() // next distribute the free indices U32 count = llmin(mReflectionProbeCount, (U32)mProbes.size()); - for (S32 i = 1; i < count && !mCubeFree.empty(); ++i) + for (U32 i = 1; i < count && !mCubeFree.empty(); ++i) { // find the closest probe that needs a cube index LLReflectionMap* probe = mProbes[i]; @@ -310,7 +332,7 @@ void LLReflectionMapManager::update() } } - for (int i = 0; i < mProbes.size(); ++i) + for (unsigned int i = 0; i < mProbes.size(); ++i) { LLReflectionMap* probe = mProbes[i]; if (probe->getNumRefs() == 1) @@ -319,8 +341,8 @@ void LLReflectionMapManager::update() --i; continue; } - - if (probe != mDefaultProbe.get() && + + if (probe != mDefaultProbe.get() && (!probe->isRelevant() || mPaused)) { // skip irrelevant probes (or all non-default probes if paused) continue; @@ -422,7 +444,7 @@ void LLReflectionMapManager::update() { LLReflectionMap* probe = oldestProbe; llassert(probe->mCubeIndex != -1); - + probe->autoAdjustOrigin(); sUpdateCount++; @@ -530,17 +552,22 @@ void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& ma LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group) { - if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) + if (!group) { - OctreeNode* node = group->getOctreeNode(); - F32 size = node->getSize().getF32ptr()[0]; - if (size >= 15.f && size <= 17.f) - { - return addProbe(group); - } + return nullptr; } - - return nullptr; + LLSpatialPartition* part = group->getSpatialPartition(); + if (!part || part->mPartitionType != LLViewerRegion::PARTITION_VOLUME) + { + return nullptr; + } + OctreeNode* node = group->getOctreeNode(); + F32 size = node->getSize().getF32ptr()[0]; + if (size < 15.f || size > 17.f) + { + return nullptr; + } + return addProbe(group); } LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vobj) @@ -610,7 +637,7 @@ void LLReflectionMapManager::doProbeUpdate() llassert(mUpdatingProbe != nullptr); updateProbeFace(mUpdatingProbe, mUpdatingFace); - + bool debug_updates = gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PROBE_UPDATES) && mUpdatingProbe->mViewerObject; if (++mUpdatingFace == 6) @@ -663,11 +690,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) 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_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES); - + probe->update(mRenderTarget.getWidth(), face); gPipeline.popRenderTypeMask(); @@ -676,7 +703,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { probe->update(mRenderTarget.getWidth(), face); } - + gPipeline.mRT = &gPipeline.mMainRT; S32 sourceIdx = mReflectionProbeCount; @@ -735,7 +762,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } - S32 mips = log2((F32)mProbeResolution) + 0.5f; + S32 mips = (S32)(log2((F32)mProbeResolution) + 0.5f); gReflectionMipProgram.bind(); S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); @@ -753,15 +780,15 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1])); } - + gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2)); - + gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - + res /= 2; - S32 mip = i - (mMipChain.size() - mips); + GLint mip = i - (static_cast<GLint>(mMipChain.size()) - mips); if (mip >= 0) { @@ -813,7 +840,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) static LLStaticHashedString sWidth("u_width"); gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); - gRadianceGenProgram.uniform1f(sMipLevel, i); + gRadianceGenProgram.uniform1f(sMipLevel, (GLfloat)i); gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); for (int cf = 0; cf < 6; ++cf) @@ -848,7 +875,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) 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 @@ -925,7 +952,7 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe) //remove from existing neighbors { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear"); - + for (auto& other : probe->mNeighbors) { auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); @@ -1036,7 +1063,7 @@ void LLReflectionMapManager::updateUniforms() 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) { if (refmap == nullptr) @@ -1054,8 +1081,8 @@ void LLReflectionMapManager::updateUniforms() // 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); + unsigned int depth_min = llclamp(llfloor(refmap->mMinDepth), 0, 255); + unsigned int depth_max = llclamp(llfloor(refmap->mMaxDepth), 0, 255); for (U32 i = depth_min; i <= depth_max; ++i) { if (refmap->mMinDepth < minDepth[i]) @@ -1167,7 +1194,7 @@ void LLReflectionMapManager::updateUniforms() { // fill in gaps in refBucket S32 probe_idx = mReflectionProbeCount; - + for (int i = 0; i < 256; ++i) { if (i < count) @@ -1344,18 +1371,22 @@ void LLReflectionMapManager::initReflectionMaps() { U32 count = LL_MAX_REFLECTION_PROBE_COUNT; - static LLCachedControl<U32> probe_res_cc(gSavedSettings, "RenderReflectionProbeResolution", 128); - U32 probe_resolution = nhpo2(llclamp(probe_res_cc(), (U32)64, (U32)512)); - bool probe_resolution_changed = mProbeResolution != probe_resolution; - - if (mTexture.isNull() || mReflectionProbeCount != count || probe_resolution_changed || mReset) + static LLCachedControl<U32> ref_probe_res(gSavedSettings, "RenderReflectionProbeResolution", 128U); + U32 probe_resolution = nhpo2(llclamp(ref_probe_res(), (U32)64, (U32)512)); + if (mTexture.isNull() || mReflectionProbeCount != count || mProbeResolution != probe_resolution || mReset) { + if(mProbeResolution != probe_resolution) + { + mRenderTarget.release(); + mMipChain.clear(); + } + gEXRImage = nullptr; mReset = false; mReflectionProbeCount = count; mProbeResolution = probe_resolution; - mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 + mMaxProbeLOD = log2f((F32)mProbeResolution) - 1.f; // number of mips - 1 if (mTexture.isNull() || mTexture->getWidth() != mProbeResolution || @@ -1410,31 +1441,6 @@ void LLReflectionMapManager::initReflectionMaps() touch_default_probe(mDefaultProbe); } - if (probe_resolution_changed) - { - mRenderTarget.release(); - mMipChain.clear(); - } - - if (!mRenderTarget.isComplete()) - { - U32 color_fmt = GL_RGB16F; - U32 targetRes = mProbeResolution * 4; // super sample - mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); - } - - if (mMipChain.empty()) - { - U32 res = mProbeResolution; - U32 count = log2((F32)res) + 0.5f; - - mMipChain.resize(count); - for (int i = 0; i < count; ++i) - { - mMipChain[i].allocate(res, res, GL_RGB16F); - res /= 2; - } - } if (mVertexBuffer.isNull()) { @@ -1443,9 +1449,9 @@ void LLReflectionMapManager::initReflectionMaps() buff->allocateBuffer(4, 0); LLStrider<LLVector3> v; - + buff->getVertexStrider(v); - + v[0] = LLVector3(-1, -1, -1); v[1] = LLVector3(1, -1, -1); v[2] = LLVector3(-1, 1, -1); @@ -1473,7 +1479,7 @@ void LLReflectionMapManager::cleanup() mReflectionMaps.clear(); mUpdatingFace = 0; - + mDefaultProbe = nullptr; mUpdatingProbe = nullptr; diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 5c0651bc248..f81fb307386 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -67,7 +67,7 @@ class alignas(16) LLReflectionMapManager // add a probe for the given spatial group LLReflectionMap* addProbe(LLSpatialGroup* group = nullptr); - + // Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size() // If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr. // maps -- presized array of Reflection Map pointers @@ -160,7 +160,7 @@ class alignas(16) LLReflectionMapManager // update the specified face of the specified probe void updateProbeFace(LLReflectionMap* probe, U32 face); - + // list of active reflection maps std::vector<LLPointer<LLReflectionMap> > mProbes; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 4e002560a28..ab415717bb6 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -276,7 +276,12 @@ class LLViewerObject virtual BOOL isMesh() const { return FALSE; } virtual BOOL isRiggedMesh() const { return FALSE; } virtual BOOL hasLightTexture() const { return FALSE; } - virtual BOOL isReflectionProbe() const { return FALSE; } + virtual bool isReflectionProbe() const { return false; } + virtual F32 getReflectionProbeAmbiance() const { return 0.f; } + virtual F32 getReflectionProbeNearClip() const { return 0.f; } + virtual bool getReflectionProbeIsBox() const { return false; } + virtual bool getReflectionProbeIsDynamic() const { return false; }; + virtual bool getReflectionProbeIsMirror() const { return false; }; // This method returns true if the object is over land owned by // the agent, one of its groups, or it encroaches and diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b674e897e36..2294ca1c588 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3343,14 +3343,14 @@ F32 LLVOVolume::getLightCutoff() const } } -BOOL LLVOVolume::isReflectionProbe() const +bool LLVOVolume::isReflectionProbe() const { return getReflectionProbeParams() != nullptr; } -bool LLVOVolume::setIsReflectionProbe(BOOL is_probe) +bool LLVOVolume::setIsReflectionProbe(bool is_probe) { - BOOL was_probe = isReflectionProbe(); + bool was_probe = isReflectionProbe(); if (is_probe != was_probe) { if (is_probe) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index b93baf211a1..055a0120a1a 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -300,19 +300,19 @@ class LLVOVolume final : public LLViewerObject F32 getLightCutoff() const; // Reflection Probes - bool setIsReflectionProbe(BOOL is_probe); + bool setIsReflectionProbe(bool is_probe); bool setReflectionProbeAmbiance(F32 ambiance); bool setReflectionProbeNearClip(F32 near_clip); bool setReflectionProbeIsBox(bool is_box); bool setReflectionProbeIsDynamic(bool is_dynamic); bool setReflectionProbeIsMirror(bool is_mirror); - BOOL isReflectionProbe() const override; - F32 getReflectionProbeAmbiance() const; - F32 getReflectionProbeNearClip() const; - bool getReflectionProbeIsBox() const; - bool getReflectionProbeIsDynamic() const; - bool getReflectionProbeIsMirror() const; + bool isReflectionProbe() const override; + F32 getReflectionProbeAmbiance() const override; + F32 getReflectionProbeNearClip() const override; + bool getReflectionProbeIsBox() const override; + bool getReflectionProbeIsDynamic() const override; + bool getReflectionProbeIsMirror() const override; // Flexible Objects U32 getVolumeInterfaceID() const; -- GitLab