diff options
Diffstat (limited to 'indra/newview/llheroprobemanager.cpp')
-rw-r--r-- | indra/newview/llheroprobemanager.cpp | 164 |
1 files changed, 97 insertions, 67 deletions
diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 2a81919856..10b743ceef 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -114,20 +114,13 @@ void LLHeroProbeManager::update() for (auto vo : mHeroVOList) { - if (vo && !vo->isDead()) + if (vo && !vo->isDead() && vo->mDrawable.notNull()) { - if (vo->mDrawable.notNull()) + float distance = (LLViewerCamera::instance().getOrigin() - vo->getPositionAgent()).magVec(); + if (distance < last_distance) { - if (vo->mDrawable->mDistanceWRTCamera < last_distance) - { - mNearestHero = vo; - last_distance = vo->mDrawable->mDistanceWRTCamera; - } - } - else - { - // Valid drawables only please. Unregister this one. - unregisterViewerObject(vo); + mNearestHero = vo; + last_distance = distance; } } else @@ -135,13 +128,13 @@ void LLHeroProbeManager::update() unregisterViewerObject(vo); } } - + if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull()) { LLVector3 hero_pos = mNearestHero->getPositionAgent(); LLVector3 face_normal = LLVector3(0, 0, 1); - - face_normal *= mNearestHero->mDrawable->getXform()->getWorldRotation(); + + face_normal *= mNearestHero->mDrawable->getWorldRotation(); face_normal.normalize(); LLVector3 offset = camera_pos - hero_pos; @@ -155,6 +148,33 @@ void LLHeroProbeManager::update() probe_pos.load3(point.mV); + + // Collect the list of faces that need updating based upon the camera's rotation. + LLVector3 cam_direction = LLVector3(0, 0, 1) * LLViewerCamera::instance().getQuaternion(); + cam_direction.normalize(); + + static LLVector3 cubeFaces[6] = { + LLVector3(1, 0, 0), + LLVector3(-1, 0, 0), + LLVector3(0, 1, 0), + LLVector3(0, -1, 0), + LLVector3(0, 0, 1), + LLVector3(0, 0, -1) + }; + + for (int i = 0; i < 6; i++) + { + float shouldUpdate = fminf(1, (fmaxf(-1, cam_direction * cubeFaces[i]) * 0.5 + 0.5)); + + int updateRate = ceilf((1 - shouldUpdate) * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); + + // Chances are this is a face that's non-visible to the camera when it's being reflected. + // Set it to 0. It will be skipped below. + if (updateRate == gPipeline.RenderHeroProbeConservativeUpdateMultiplier) + updateRate = 0; + + mFaceUpdateList[i] = updateRate; + } } else { @@ -185,13 +205,23 @@ void LLHeroProbeManager::update() { for (U32 i = 0; i < 6; ++i) { - updateProbeFace(mProbes[j], i, near_clip); + if (mFaceUpdateList[i] > 0 && mCurrentProbeUpdateFrame % mFaceUpdateList[i] == 0) + { + updateProbeFace(mProbes[j], i, near_clip); + mCurrentProbeUpdateFrame = 0; + } } + generateRadiance(mProbes[j]); } mRenderingMirror = false; gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass; + + mProbes[0]->mViewerObject = mNearestHero; + mProbes[0]->autoAdjustOrigin(); } + + mCurrentProbeUpdateFrame++; } // Do the reflection map update render passes. @@ -242,7 +272,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n LLRenderTarget *screen_rt = &gPipeline.mHeroProbeRT.screen; LLRenderTarget *depth_rt = &gPipeline.mHeroProbeRT.deferredScreen; - + // perform a gaussian blur on the super sampled render before downsampling { gGaussianProgram.bind(); @@ -318,14 +348,25 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE); gReflectionMipProgram.unbind(); } +} + +// Separate out radiance generation as a separate stage. +// This is to better enable independent control over how we generate radiance vs. having it coupled with processing the final face of the probe. +// Useful when we may not always be rendering a full set of faces of the probe. +void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) +{ + S32 sourceIdx = mReflectionProbeCount; - if (face == 5) + // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes. + sourceIdx += 1; { mMipChain[0].bindTarget(); static LLStaticHashedString sSourceIdx("sourceIdx"); { - //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) + + + // generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) gHeroRadianceGenProgram.bind(); mVertexBuffer->setBuffer(); @@ -334,10 +375,10 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n gHeroRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength); - + U32 res = mMipChain[0].getWidth(); - for (int i = 0; i < mMipChain.size(); ++i) + for (int i = 0; i < mMipChain.size() / 4; ++i) { LL_PROFILE_GPU_ZONE("probe radiance gen"); static LLStaticHashedString sMipLevel("mipLevel"); @@ -351,7 +392,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n gHeroRadianceGenProgram.uniform1f(sStrength, 1); for (int cf = 0; cf < 6; ++cf) - { // for each cube face + { // for each cube face LLCoordFrame frame; frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); @@ -380,55 +421,43 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n void LLHeroProbeManager::updateUniforms() { - if (!LLPipeline::sReflectionProbesEnabled) + if (!gPipeline.RenderMirrors) { return; } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - struct HeroProbeData - { - LLVector4 heroPosition[1]; - GLint heroProbeCount = 1; - }; - - HeroProbeData hpd; - LLMatrix4a modelview; modelview.loadu(gGLModelView); LLVector4a oa; // scratch space for transformed origin oa.set(0, 0, 0, 0); - hpd.heroProbeCount = 1; - modelview.affineTransform(mProbes[0]->mOrigin, oa); - hpd.heroPosition[0].set(oa.getF32ptr()); - - //copy rpd into uniform buffer object - if (mUBO == 0) - { - glGenBuffers(1, &mUBO); - } - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); - glBindBuffer(GL_UNIFORM_BUFFER, mUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - } -} - -void LLHeroProbeManager::setUniforms() -{ - if (!LLPipeline::sReflectionProbesEnabled) + mHeroData.heroProbeCount = 1; + + if (mNearestHero != nullptr && !mNearestHero->isDead()) { - return; - } - - if (mUBO == 0) - { - updateUniforms(); + if (mNearestHero->getReflectionProbeIsBox()) + { + LLVector3 s = mNearestHero->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f)); + mProbes[0]->mRadius = s.magVec(); + } + else + { + mProbes[0]->mRadius = mNearestHero->getScale().mV[0] * 0.5f; + } + + modelview.affineTransform(mProbes[0]->mOrigin, oa); + mHeroData.heroShape = 0; + if (!mProbes[0]->getBox(mHeroData.heroBox)) + { + mHeroData.heroShape = 1; + } + + mHeroData.heroSphere.set(oa.getF32ptr()); + mHeroData.heroSphere.mV[3] = mProbes[0]->mRadius; } - glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); + + mHeroData.heroMipCount = mMipChain.size(); } void LLHeroProbeManager::renderDebug() @@ -517,9 +546,6 @@ void LLHeroProbeManager::cleanup() mDefaultProbe = nullptr; mUpdatingProbe = nullptr; - - glDeleteBuffers(1, &mUBO); - mUBO = 0; mHeroVOList.clear(); mNearestHero = nullptr; @@ -539,21 +565,25 @@ void LLHeroProbeManager::doOcclusion() } } -void LLHeroProbeManager::registerViewerObject(LLVOVolume* drawablep) +bool LLHeroProbeManager::registerViewerObject(LLVOVolume* drawablep) { llassert(drawablep != nullptr); - if (mHeroVOList.find(drawablep) == mHeroVOList.end()) + if (std::find(mHeroVOList.begin(), mHeroVOList.end(), drawablep) == mHeroVOList.end()) { // Probe isn't in our list for consideration. Add it. - mHeroVOList.insert(drawablep); + mHeroVOList.push_back(drawablep); + return true; } + + return false; } void LLHeroProbeManager::unregisterViewerObject(LLVOVolume* drawablep) { - if (mHeroVOList.find(drawablep) != mHeroVOList.end()) + std::vector<LLVOVolume*>::iterator found_itr = std::find(mHeroVOList.begin(), mHeroVOList.end(), drawablep); + if (found_itr != mHeroVOList.end()) { - mHeroVOList.erase(drawablep); + mHeroVOList.erase(found_itr); } } |