diff options
Diffstat (limited to 'indra/newview/llreflectionmapmanager.cpp')
| -rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 521 |
1 files changed, 350 insertions, 171 deletions
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 2708d5edf0..aa48035aa8 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -54,6 +54,7 @@ #endif LLPointer<LLImageGL> gEXRImage; +//LLTrace::BlockTimerStatHandle FTM_RENDER_RADIANCE("Render Radiance"); void load_exr(const std::string& filename) { @@ -144,13 +145,14 @@ static void touch_default_probe(LLReflectionMap* probe) LLReflectionMapManager::LLReflectionMapManager() { + mDynamicProbeCount = LL_MAX_REFLECTION_PROBE_COUNT; initCubeFree(); } void LLReflectionMapManager::initCubeFree() { // start at 1 because index 0 is reserved for mDefaultProbe - for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) + for (U32 i = 1; i < mDynamicProbeCount; ++i) { mCubeFree.push_back(i); } @@ -210,6 +212,7 @@ void LLReflectionMapManager::update() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("reflection manager update"); llassert(!gCubeSnapshot); // assert a snapshot is not in progress if (LLAppViewer::instance()->logoutRequestSent()) { @@ -221,13 +224,83 @@ void LLReflectionMapManager::update() resume(); } + static LLCachedControl<F32> sProbeUpdateSlowDown(gSavedSettings, "MPRenderProbeSlowDown", 0.05); + + bool realtime = mRenderReflectionProbeDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; + + if(sProbeUpdateSlowDown > 0.0) + { + if ( mLastUpdate > 0.f ) + { + F32 elapsed = gFrameTimeSeconds - mLastUpdate; + if (elapsed > 0.0 && elapsed < sProbeUpdateSlowDown) + { + return; + } + } + } + + mLastUpdate = gFrameTimeSeconds; + + mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f); + + { + U32 probe_count_temp = mDynamicProbeCount; + if (mRenderReflectionProbeDynamicAllocation > -1) + { + if (mRenderReflectionProbeLevel == 0) + { + mDynamicProbeCount = 1; + } + else if (mRenderReflectionProbeLevel == 1) + { + mDynamicProbeCount = (U32)mProbes.size(); + } + else if (mRenderReflectionProbeLevel == 2) + { + mDynamicProbeCount = llmax((U32)mProbes.size(), 128); + } + else + { + mDynamicProbeCount = 256; + } + + if (mRenderReflectionProbeDynamicAllocation > 1) + { + // Round mDynamicProbeCount to the nearest increment of 16 + mDynamicProbeCount = ((mDynamicProbeCount + mRenderReflectionProbeDynamicAllocation / 2) / mRenderReflectionProbeDynamicAllocation) * 16; + mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, mRenderReflectionProbeCount); + } + else + { + mDynamicProbeCount = llclamp(mDynamicProbeCount + mRenderReflectionProbeDynamicAllocation, 1, mRenderReflectionProbeCount); + } + } + else + { + mDynamicProbeCount = mRenderReflectionProbeCount; + } + + mDynamicProbeCount = llmin(mDynamicProbeCount, LL_MAX_REFLECTION_PROBE_COUNT); + + if (mDynamicProbeCount != probe_count_temp) + mResetFade = 1.f; + } + initReflectionMaps(); static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); + static LLCachedControl<U32> MPColorPrecision(gSavedSettings, "MPColorPrecision", 0); + + U32 color_fmt = render_hdr ? GL_R11F_G11F_B10F : GL_RGB8; + + if(MPColorPrecision == 1) + { + color_fmt = GL_RGB8; + } if (!mRenderTarget.isComplete()) { - U32 color_fmt = render_hdr ? GL_R11F_G11F_B10F : GL_RGB8; U32 targetRes = mProbeResolution * 4; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } @@ -240,7 +313,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (U32 i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, render_hdr ? GL_R11F_G11F_B10F : GL_RGB8); + mMipChain[i].allocate(res, res, color_fmt); res /= 2; } } @@ -278,11 +351,6 @@ void LLReflectionMapManager::update() bool did_update = false; - static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); - static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); - - bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; - LLReflectionMap* closestDynamic = nullptr; LLReflectionMap* oldestProbe = nullptr; @@ -315,6 +383,10 @@ void LLReflectionMapManager::update() probe->mCubeArray = nullptr; probe->mCubeIndex = -1; probe->mComplete = false; + probe->mCompletedCount = 0; + probe->mLastUpdateTime = 0.0; + probe->mNextUpdateTime = 0.0; + probe->mFadeIn = 0; } } @@ -335,6 +407,10 @@ void LLReflectionMapManager::update() } } + mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f); + + static LLCachedControl<F32> sDefaultUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.0); + for (unsigned int i = 0; i < mProbes.size(); ++i) { LLReflectionMap* probe = mProbes[i]; @@ -351,6 +427,8 @@ void LLReflectionMapManager::update() continue; } + // Calculating distance + LLVector4a d; if (probe != mDefaultProbe) @@ -362,13 +440,14 @@ void LLReflectionMapManager::update() d.setSub(camera_pos, probe->mOrigin); probe->mDistance = d.getLength3().getF32() - probe->mRadius; } - else if (probe->mComplete) + else if (mDefaultProbe->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; } else { + probe->mNextUpdateTime = 0.f; probe->mDistance = -4096.f; //boost priority of default probe when it's not complete } @@ -377,8 +456,13 @@ void LLReflectionMapManager::update() probe->autoAdjustOrigin(); probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f); } + + // Guess oldest probe + if (probe->mOccluded && probe->mComplete) { + // occluded probe + if (oldestOccluded == nullptr) { oldestOccluded = probe; @@ -407,7 +491,7 @@ void LLReflectionMapManager::update() closestDynamic = probe; } - if (sLevel == 0) + if (mRenderReflectionProbeLevel == 0) { // only update default probe when coverage is set to none llassert(probe == mDefaultProbe); @@ -415,6 +499,8 @@ void LLReflectionMapManager::update() } } + // realtime + if (realtime && closestDynamic != nullptr) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); @@ -430,21 +516,23 @@ void LLReflectionMapManager::update() { updateProbeFace(closestDynamic, i); } + if(mRealtimeRadiancePass) updateProbeRadiance(closestDynamic); + else updateProbeIrradiance(closestDynamic); mRealtimeRadiancePass = !mRealtimeRadiancePass; // restore "isRadiancePass" mRadiancePass = radiance_pass; } - static LLCachedControl<F32> sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f); - if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod) + if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sDefaultUpdatePeriod) { - if (sLevel == 0) +// if (sLevel == 0 && mDefaultProbe->mComplete) + if (mRenderReflectionProbeLevel == 0) { // when probes are disabled don't update the default probe more often than the prescribed update period oldestProbe = nullptr; } } - else if (sLevel > 0) + else if (mRenderReflectionProbeLevel > 0) { // when probes are enabled don't update the default probe less often than the prescribed update period oldestProbe = mDefaultProbe; } @@ -455,11 +543,21 @@ void LLReflectionMapManager::update() LLReflectionMap* probe = oldestProbe; llassert(probe->mCubeIndex != -1); + bool shouldUpdate = true; + + if( probe->mNextUpdateTime > 0.f && gFrameTimeSeconds < probe->mNextUpdateTime) + { + shouldUpdate = false; + } + + if(shouldUpdate) + { probe->autoAdjustOrigin(); sUpdateCount++; mUpdatingProbe = probe; doProbeUpdate(); + } } if (oldestOccluded) @@ -470,6 +568,14 @@ void LLReflectionMapManager::update() } } +void LLReflectionMapManager::refreshSettings() +{ + mRenderReflectionProbeDetail = gSavedSettings.getS32("RenderReflectionProbeDetail"); + mRenderReflectionProbeLevel = gSavedSettings.getS32("RenderReflectionProbeLevel"); + mRenderReflectionProbeCount = gSavedSettings.getU32("RenderReflectionProbeCount"); + mRenderReflectionProbeDynamicAllocation = gSavedSettings.getS32("RenderReflectionProbeDynamicAllocation"); +} + LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) { if (gGLManager.mGLVersion < 4.05f || !LLPipeline::sReflectionProbesEnabled) @@ -505,6 +611,16 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) return probe; } +U32 LLReflectionMapManager::probeCount() +{ + return mDynamicProbeCount; +} + +U32 LLReflectionMapManager::probeMemory() +{ + return (mDynamicProbeCount * 6 * (mProbeResolution * mProbeResolution) * 4) / 1024 / 1024 + (mDynamicProbeCount * 6 * (LL_IRRADIANCE_MAP_RESOLUTION * LL_IRRADIANCE_MAP_RESOLUTION) * 4) / 1024 / 1024; +} + struct CompareProbeDepth { bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs) @@ -657,11 +773,19 @@ void LLReflectionMapManager::doProbeUpdate() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(mUpdatingProbe != nullptr); - updateProbeFace(mUpdatingProbe, mUpdatingFace); + if(mUpdatingFace < 6) + { + updateProbeFace(mUpdatingProbe, mUpdatingFace); + } + else + { + if(isRadiancePass()) updateProbeRadiance(mUpdatingProbe); + else updateProbeIrradiance(mUpdatingProbe); + } bool debug_updates = gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PROBE_UPDATES) && mUpdatingProbe->mViewerObject; - if (++mUpdatingFace == 6) + if (mUpdatingFace == 6) { if (debug_updates) { @@ -671,7 +795,23 @@ void LLReflectionMapManager::doProbeUpdate() mUpdatingFace = 0; if (isRadiancePass()) { + static LLCachedControl<F32> sMPUpdatePeriod(gSavedSettings, "MPRenderProbeUpdatePeriod", 15.0); + mUpdatingProbe->mComplete = true; + mUpdatingProbe->mCompletedCount++; + + LL_WARNS() << "Probe updated (" << mUpdatingProbe->mCompletedCount << ")" << LL_ENDL; + + if(mUpdatingProbe->mCompletedCount < 5) + { + //probe->mNextUpdateTime = gFrameTimeSeconds + fmax( ((F32)sMPUpdatePeriod / 2.0), 0.25); + mUpdatingProbe->mNextUpdateTime = gFrameTimeSeconds + 1.0; + } + else + { + mUpdatingProbe->mNextUpdateTime = gFrameTimeSeconds + fmax( (F32)sMPUpdatePeriod, 0.10); + } + mUpdatingProbe = nullptr; mRadiancePass = false; } @@ -680,9 +820,14 @@ void LLReflectionMapManager::doProbeUpdate() mRadiancePass = true; } } - else if (debug_updates) + else { + ++mUpdatingFace; + + if (debug_updates) + { mUpdatingProbe->mViewerObject->setDebugText(llformat("%.1f", (F32)gFrameTimeSeconds), LLColor4(1, 1, 0, 1)); + } } } @@ -696,6 +841,8 @@ void LLReflectionMapManager::doProbeUpdate() // In effect this simulates single-bounce lighting. void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("probe update"); // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; @@ -722,7 +869,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } else { - llassert(gSavedSettings.getS32("RenderReflectionProbeLevel") > 0); // should never update a probe that's not the default probe if reflection coverage is none + llassert(mRenderReflectionProbeLevel > 0); // should never update a probe that's not the default probe if reflection coverage is none probe->update(mRenderTarget.getWidth(), face); } @@ -735,7 +882,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) sourceIdx += 1; } - gGL.setColorMask(true, true); + gGL.setColorMask(true, false); LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLGLDisable cull(GL_CULL_FACE); LLGLDisable blend(GL_BLEND); @@ -769,7 +916,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) // horizontal gGaussianProgram.uniform2f(direction, 1.f, 0.f); gGL.getTexUnit(diffuseChannel)->bind(screen_rt); - mRenderTarget.bindTarget(); + mRenderTarget.bindTarget("", 1); + mRenderTarget.clear(0); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); mRenderTarget.flush(); @@ -777,7 +925,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) // vertical gGaussianProgram.uniform2f(direction, 0.f, 1.f); gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget); - screen_rt->bindTarget(); + screen_rt->bindTarget("", 1); + screen_rt->clear(0); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); screen_rt->flush(); @@ -792,7 +941,10 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) for (int i = 0; i < mMipChain.size(); ++i) { LL_PROFILE_GPU_ZONE("probe mip"); - mMipChain[i].bindTarget(); + + mMipChain[i].bindTarget("probe face ", 0); + mMipChain[i].clear(0); + if (i == 0) { gGL.getTexUnit(diffuseChannel)->bind(screen_rt); @@ -836,17 +988,118 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE); gReflectionMipProgram.unbind(); } +} - if (face == 5) - { - mMipChain[0].bindTarget(); - static LLStaticHashedString sSourceIdx("sourceIdx"); +// ===================== IRRADIANCE ================================ - if (isRadiancePass()) +void LLReflectionMapManager::updateProbeIrradiance(LLReflectionMap* probe) +{ + LL_PROFILE_GPU_ZONE("probe irradiance gen"); + + static LLStaticHashedString sMipLevel("mipLevel"); + static LLStaticHashedString sRoughness("roughness"); + static LLStaticHashedString sWidth("u_width"); + + S32 sourceIdx = mReflectionProbeCount; + + if (probe != mUpdatingProbe) + { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel + sourceIdx += 1; + } + + gGL.setColorMask(true, false); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + + static LLStaticHashedString sSourceIdx("sourceIdx"); + + + mMipChain[0].bindTarget("irradiance", 0); + mMipChain[0].clear(); + + gIrradianceGenProgram.bind(); + +#if GL_VERSION_4_0 + S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + mTexture->bind(channel); +#endif + + 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) + { + if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION) { - //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) - gRadianceGenProgram.bind(); - mVertexBuffer->setBuffer(); + break; + } + } + + 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) + { + 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(); +#if GL_VERSION_4_0 + 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); +#endif + //mMipChain[0].clear(0); + } + + mMipChain[0].flush(); + gIrradianceGenProgram.unbind(); +} + +// ==================== RADIANCE =========================== + +void LLReflectionMapManager::updateProbeRadiance(LLReflectionMap* probe) +{ + LL_PROFILE_GPU_ZONE("probe radiance gen"); + static LLStaticHashedString sMipLevel("mipLevel"); + static LLStaticHashedString sRoughness("roughness"); + static LLStaticHashedString sWidth("u_width"); + + S32 sourceIdx = mReflectionProbeCount; + + if (probe != mUpdatingProbe) + { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel + sourceIdx += 1; + } + + gGL.setColorMask(true, false); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + + static LLStaticHashedString sSourceIdx("sourceIdx"); + + //LL_RECORD_BLOCK_TIME(FTM_RENDER_RADIANCE); + + mMipChain[0].bindTarget("radiance", 0); + mMipChain[0].clear(); + + gRadianceGenProgram.bind(); + mVertexBuffer->setBuffer(); #if GL_VERSION_4_0 S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); @@ -855,22 +1108,19 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, 1.f); + gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); U32 res = mMipChain[0].getWidth(); 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"); + glViewport(0, 0, res, res); - gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, (GLfloat)i); - gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); + gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); 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]); @@ -883,70 +1133,18 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) #if GL_VERSION_4_0 glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); #endif + LOG_GLERROR("glCopyTexSubImage3D"); } if (i != mMipChain.size() - 1) { res /= 2; - glViewport(0, 0, res, res); } - } + } gRadianceGenProgram.unbind(); - } - else - { - //generate irradiance map - gIrradianceGenProgram.bind(); -#if GL_VERSION_4_0 - S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - mTexture->bind(channel); -#endif - - 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) - { - 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(); -#if GL_VERSION_4_0 - 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); -#endif - } - } - } - - mMipChain[0].flush(); - - gIrradianceGenProgram.unbind(); - } + mMipChain[0].flush(); + //mTexture->unbind(); } void LLReflectionMapManager::reset() @@ -1021,61 +1219,20 @@ void LLReflectionMapManager::updateUniforms() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("rmmu - uniforms") - // structure for packing uniform buffer object - // see class3/deferred/reflectionProbeF.glsl - struct ReflectionProbeData - { - // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of - // the box probe - LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; - - LLMatrix4 heroBox; - - // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space - LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; - - // extra parameters - // x - irradiance scale - // y - radiance scale - // z - fade in - // w - znear - LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; - - LLVector4 heroSphere; - - // indices used by probe: - // [i][0] - cubemap array index for this probe - // [i][1] - index into "refNeighbor" for probes that intersect this probe - // [i][2] - number of probes that intersect this probe, or -1 for no neighbors - // [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes) - GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; - - // list of neighbor indices - GLint refNeighbor[4096]; - - GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth - // numbrer of active refmaps - GLint refmapCount; - - GLint heroShape; - GLint heroMipCount; - GLint heroProbeCount; - }; mReflectionMaps.resize(mReflectionProbeCount); getReflectionMaps(mReflectionMaps); - ReflectionProbeData rpd; - F32 minDepth[256]; for (int i = 0; i < 256; ++i) { - rpd.refBucket[i][0] = mReflectionProbeCount; - rpd.refBucket[i][1] = mReflectionProbeCount; - rpd.refBucket[i][2] = mReflectionProbeCount; - rpd.refBucket[i][3] = mReflectionProbeCount; + mProbeData.refBucket[i][0] = mReflectionProbeCount; + mProbeData.refBucket[i][1] = mReflectionProbeCount; + mProbeData.refBucket[i][2] = mReflectionProbeCount; + mProbeData.refBucket[i][3] = mReflectionProbeCount; minDepth[i] = FLT_MAX; } @@ -1095,7 +1252,11 @@ void LLReflectionMapManager::updateUniforms() bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass(); F32 ambscale = is_ambiance_pass ? 0.f : 1.f; + ambscale *= mResetFade; + ambscale = llmax(0, ambscale); F32 radscale = is_ambiance_pass ? 0.5f : 1.f; + radscale *= mResetFade; + radscale = llmax(0, radscale); for (auto* refmap : mReflectionMaps) { @@ -1121,7 +1282,7 @@ void LLReflectionMapManager::updateUniforms() if (refmap->mMinDepth < minDepth[i]) { minDepth[i] = refmap->mMinDepth; - rpd.refBucket[i][0] = refmap->mProbeIndex; + mProbeData.refBucket[i][0] = refmap->mProbeIndex; } } } @@ -1134,7 +1295,7 @@ void LLReflectionMapManager::updateUniforms() { if (refmap->mViewerObject && refmap->mViewerObject->getVolume()) { // have active manual probes live-track the object they're associated with - LLVOVolume* vobj = (LLVOVolume*)refmap->mViewerObject; + LLVOVolume* vobj = (LLVOVolume*)refmap->mViewerObject.get(); refmap->mOrigin.load3(vobj->getPositionAgent().mV); @@ -1149,23 +1310,23 @@ void LLReflectionMapManager::updateUniforms() } } modelview.affineTransform(refmap->mOrigin, oa); - rpd.refSphere[count].set(oa.getF32ptr()); - rpd.refSphere[count].mV[3] = refmap->mRadius; + mProbeData.refSphere[count].set(oa.getF32ptr()); + mProbeData.refSphere[count].mV[3] = refmap->mRadius; } - rpd.refIndex[count][0] = refmap->mCubeIndex; + mProbeData.refIndex[count][0] = refmap->mCubeIndex; llassert(nc % 4 == 0); - rpd.refIndex[count][1] = nc / 4; - rpd.refIndex[count][3] = refmap->mPriority; + mProbeData.refIndex[count][1] = nc / 4; + mProbeData.refIndex[count][3] = refmap->mPriority; // for objects that are reflection probes, use the volume as the influence volume of the probe // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres - if (refmap->getBox(rpd.refBox[count])) + if (refmap->getBox(mProbeData.refBox[count])) { // negate priority to indicate this probe has a box influence volume - rpd.refIndex[count][3] = -rpd.refIndex[count][3]; + mProbeData.refIndex[count][3] = -mProbeData.refIndex[count][3]; } - rpd.refParams[count].set( + mProbeData.refParams[count].set( llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale radscale, // radiance scale refmap->mFadeIn, // fade in weight @@ -1192,7 +1353,7 @@ void LLReflectionMapManager::updateUniforms() } // this neighbor may be sampled - rpd.refNeighbor[ni++] = idx; + mProbeData.refNeighbor[ni++] = idx; neighbor_count++; if (neighbor_count >= max_neighbors) @@ -1205,11 +1366,11 @@ void LLReflectionMapManager::updateUniforms() if (nc == ni) { //no neighbors, tag as empty - rpd.refIndex[count][1] = -1; + mProbeData.refIndex[count][1] = -1; } else { - rpd.refIndex[count][2] = ni - nc; + mProbeData.refIndex[count][2] = ni - nc; // move the cursor forward nc = ni; @@ -1247,19 +1408,19 @@ void LLReflectionMapManager::updateUniforms() } #endif - rpd.refmapCount = count; + mProbeData.refmapCount = count; gPipeline.mHeroProbeManager.updateUniforms(); // Get the hero data. - rpd.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox; - rpd.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere; - rpd.heroShape = gPipeline.mHeroProbeManager.mHeroData.heroShape; - rpd.heroMipCount = gPipeline.mHeroProbeManager.mHeroData.heroMipCount; - rpd.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount; + mProbeData.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox; + mProbeData.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere; + mProbeData.heroShape = gPipeline.mHeroProbeManager.mHeroData.heroShape; + mProbeData.heroMipCount = gPipeline.mHeroProbeManager.mHeroData.heroMipCount; + mProbeData.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount; - //copy rpd into uniform buffer object + //copy mProbeData into uniform buffer object if (mUBO == 0) { glGenBuffers(1, &mUBO); @@ -1268,7 +1429,7 @@ void LLReflectionMapManager::updateUniforms() { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); glBindBuffer(GL_UNIFORM_BUFFER, mUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); + glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &mProbeData, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } @@ -1402,12 +1563,15 @@ void LLReflectionMapManager::renderDebug() void LLReflectionMapManager::initReflectionMaps() { - U32 count = LL_MAX_REFLECTION_PROBE_COUNT; - static LLCachedControl<U32> ref_probe_res(gSavedSettings, "RenderReflectionProbeResolution", 128U); U32 probe_resolution = nhpo2(llclamp(ref_probe_res(), (U32)64, (U32)512)); - if (mTexture.isNull() || mReflectionProbeCount != count || mProbeResolution != probe_resolution || mReset) + + bool shouldInit = mTexture.isNull() || mReflectionProbeCount != mDynamicProbeCount || mProbeResolution != probe_resolution || mReset; + + if (shouldInit) { + //LL_WARNS() << "====== initReflectionMaps() =======" << LL_ENDL; + if(mProbeResolution != probe_resolution) { mRenderTarget.release(); @@ -1415,9 +1579,8 @@ void LLReflectionMapManager::initReflectionMaps() } gEXRImage = nullptr; - mReset = false; - mReflectionProbeCount = count; + mReflectionProbeCount = mDynamicProbeCount; mProbeResolution = probe_resolution; mMaxProbeLOD = log2f((F32)mProbeResolution) - 1.f; // number of mips - 1 @@ -1425,15 +1588,25 @@ void LLReflectionMapManager::initReflectionMaps() mTexture->getWidth() != mProbeResolution || mReflectionProbeCount + 2 != mTexture->getCount()) { - mTexture = new LLCubeMapArray(); - static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); - // 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, true, render_hdr); + if (mTexture) + { + mTexture = new LLCubeMapArray(*mTexture, mProbeResolution, mReflectionProbeCount + 2); - mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr); + mIrradianceMaps = new LLCubeMapArray(*mIrradianceMaps, LL_IRRADIANCE_MAP_RESOLUTION, mReflectionProbeCount); + } + else + { + 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, true, render_hdr); + + mIrradianceMaps = new LLCubeMapArray(); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr); + } } // reset probe state @@ -1448,11 +1621,14 @@ void LLReflectionMapManager::initReflectionMaps() for (auto& probe : mProbes) { probe->mLastUpdateTime = 0.f; + probe->mNextUpdateTime = 0.f; probe->mComplete = false; + probe->mCompletedCount = 0; probe->mProbeIndex = -1; probe->mCubeArray = nullptr; probe->mCubeIndex = -1; probe->mNeighbors.clear(); + probe->mFadeIn = 0; } mCubeFree.clear(); @@ -1473,6 +1649,9 @@ void LLReflectionMapManager::initReflectionMaps() mDefaultProbe->mRadius = 4096.f; mDefaultProbe->mProbeIndex = 0; mDefaultProbe->mComplete = default_complete; + mDefaultProbe->mCompletedCount = 0; + mDefaultProbe->mLastUpdateTime = 0.f; + mDefaultProbe->mNextUpdateTime = 0.f; touch_default_probe(mDefaultProbe); } |
