diff options
author | Dave Parks <davep@lindenlab.com> | 2022-06-22 13:25:50 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2022-06-22 13:25:50 -0500 |
commit | d0d1b832d4983f35ab29947eb6fda54a8aa48f8a (patch) | |
tree | a07f61179a59d315d842dc08aa9d7fd52dc35e79 /indra/newview/llreflectionmapmanager.cpp | |
parent | 4273b262072553aaa1a805ff08008de95da47aac (diff) |
SL-17600 Proper irradiance probes.
Diffstat (limited to 'indra/newview/llreflectionmapmanager.cpp')
-rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 68 |
1 files changed, 63 insertions, 5 deletions
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(); } } |