WIP of timmy's changes merged in. Not properly initializing the probes/array slots just yet.

This commit is contained in:
Areloch 2019-03-24 18:18:44 -05:00
parent ba8948a5b1
commit 26471aaa77
10 changed files with 485 additions and 159 deletions

View file

@ -78,20 +78,21 @@ ProbeRenderInst::ProbeRenderInst() : SystemInterface(),
mDirty(false),
mPriority(1.0f),
mScore(0.0f),
mCubemap(NULL),
mPrefilterCubemap(NULL),
mIrradianceCubemap(NULL),
mRadius(1.0f),
mProbeRefOffset(0, 0, 0),
mProbeRefScale(1,1,1),
mAtten(0.0)
mAtten(0.0),
mCubemapIndex(0)
{
}
ProbeRenderInst::~ProbeRenderInst()
{
if (mCubemap && mCubemap.isValid())
if (mPrefilterCubemap && mPrefilterCubemap.isValid())
{
mCubemap.free();
mPrefilterCubemap.free();
}
if (mIrradianceCubemap && mIrradianceCubemap.isValid())
{
@ -102,7 +103,7 @@ ProbeRenderInst::~ProbeRenderInst()
void ProbeRenderInst::set(const ProbeRenderInst *probeInfo)
{
mTransform = probeInfo->mTransform;
mCubemap = probeInfo->mCubemap;
mPrefilterCubemap = probeInfo->mPrefilterCubemap;
mIrradianceCubemap = probeInfo->mIrradianceCubemap;
mRadius = probeInfo->mRadius;
mProbeShapeType = probeInfo->mProbeShapeType;
@ -183,6 +184,13 @@ RenderProbeMgr::RenderProbeMgr()
mProbeArrayEffect = nullptr;
smProbeManager = this;
mCubeMapCount = 0;
for (U32 i = 0; i < PROBE_MAX_COUNT; i++)
{
mCubeMapSlots[i] = false;
}
}
RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
@ -203,6 +211,37 @@ RenderProbeMgr::~RenderProbeMgr()
mConstantLookup.clear();
}
bool RenderProbeMgr::onAdd()
{
if (!Parent::onAdd())
return false;
mIrradianceArray = GFXCubemapArrayHandle(GFX->createCubemapArray());
mPrefilterArray = GFXCubemapArrayHandle(GFX->createCubemapArray());
//pre-allocate a few slots
mIrradianceArray->init(PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_IRRAD_SIZE, PROBE_FORMAT);
mPrefilterArray->init(PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_PREFILTER_SIZE, PROBE_FORMAT);
mCubeSlotCount = PROBE_ARRAY_SLOT_BUFFER_SIZE;
//create our own default default skylight
mDefaultSkyLight = new ProbeRenderInst;
mDefaultSkyLight->mProbeShapeType = ProbeRenderInst::Skylight;
if (!mDefaultSkyLight->mIrradianceCubemap.set("core/art/pbr/default_irradiance.dds"))
{
Con::errorf("RenderProbeMgr::onAdd: Failed to load default irradiance cubemap");
return false;
}
if (!mDefaultSkyLight->mPrefilterCubemap.set("core/art/pbr/default_prefilter.dds"))
{
Con::errorf("RenderProbeMgr::onAdd: Failed to load default prefilter cubemap");
return false;
}
return true;
}
void RenderProbeMgr::onRemove()
{
Parent::onRemove();
@ -246,6 +285,38 @@ void RenderProbeMgr::registerProbe(U32 probeIdx)
mRegisteredProbes.push_back_unique(probeIdx);
const U32 cubeIndex = _findNextEmptyCubeSlot();
if (cubeIndex == INVALID_CUBE_SLOT)
{
Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot.");
return;
}
//check if we need to resize the cubemap array
if (cubeIndex >= mCubeSlotCount)
{
//alloc temp array handles
GFXCubemapArrayHandle irr = GFXCubemapArrayHandle(GFX->createCubemapArray());
GFXCubemapArrayHandle prefilter = GFXCubemapArrayHandle(GFX->createCubemapArray());
irr->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_IRRAD_SIZE, PROBE_FORMAT);
prefilter->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_PREFILTER_SIZE, PROBE_FORMAT);
mIrradianceArray->copyTo(irr);
mPrefilterArray->copyTo(prefilter);
//assign the temp handles to the new ones, this will destroy the old ones as well
mIrradianceArray = irr;
mPrefilterArray = prefilter;
mCubeSlotCount += PROBE_ARRAY_SLOT_BUFFER_SIZE;
}
ProbeRenderInst::all[probeIdx]->mCubemapIndex = cubeIndex;
//mark cubemap slot as taken
mCubeMapSlots[cubeIndex] = true;
mCubeMapCount++;
//rebuild our probe data
_setupStaticParameters();
}
@ -258,6 +329,13 @@ void RenderProbeMgr::unregisterProbe(U32 probeIdx)
mRegisteredProbes.remove(probeIdx);
if (ProbeRenderInst::all[probeIdx]->mCubemapIndex == INVALID_CUBE_SLOT)
return;
//mark cubemap slot as available now
mCubeMapSlots[ProbeRenderInst::all[probeIdx]->mCubemapIndex] = false;
mCubeMapCount--;
//rebuild our probe data
_setupStaticParameters();
}
@ -314,6 +392,16 @@ void RenderProbeMgr::_setupStaticParameters()
cubeMaps.clear();
irradMaps.clear();
if (probeCount != 0 && ProbeRenderInst::all[0]->mPrefilterCubemap != nullptr)
{
//Get our mipCount
mMipCount = ProbeRenderInst::all[0]->mPrefilterCubemap.getPointer()->getMipMapLevels();
}
else
{
mMipCount = 1;
}
for (U32 i = 0; i < probeCount; i++)
{
if (mEffectiveProbeCount >= MAXPROBECOUNT)
@ -323,19 +411,23 @@ void RenderProbeMgr::_setupStaticParameters()
if (!curEntry.mIsEnabled)
continue;
if (curEntry.mCubemap.isNull() || curEntry.mIrradianceCubemap.isNull())
if (curEntry.mIsSkylight)
{
skylightPos = curEntry.getPosition();
skylightPrefilterMap = curEntry.mPrefilterCubemap;
skylightIrradMap = curEntry.mIrradianceCubemap;
hasSkylight = true;
continue;
}
if (!curEntry.mCubemap->isInitialised())
continue;
if (!curEntry.mIrradianceCubemap->isInitialised())
continue;
//if (curEntry.mIsSkylight)
//if (curEntry.mCubemap.isNull() || curEntry.mIrradianceCubemap.isNull())
// continue;
mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels();
//if (!curEntry.mCubemap->isInitialized())
// continue;
//if (!curEntry.mIrradianceCubemap->isInitialized())
// continue;
//Setup
Point3F probePos = curEntry.getPosition();
@ -354,22 +446,40 @@ void RenderProbeMgr::_setupStaticParameters()
curEntry.mAtten,
1);
cubeMaps.push_back(curEntry.mCubemap);
irradMaps.push_back(curEntry.mIrradianceCubemap);
//cubeMaps.push_back(curEntry.mCubemap);
//irradMaps.push_back(curEntry.mIrradianceCubemap);
mEffectiveProbeCount++;
}
if (mEffectiveProbeCount != 0)
{
mCubemapArray = GFXCubemapArrayHandle(GFX->createCubemapArray());
mIrradArray = GFXCubemapArrayHandle(GFX->createCubemapArray());
//mPrefilterArray = GFXCubemapArrayHandle(GFX->createCubemapArray());
//mIrradianceArray = GFXCubemapArrayHandle(GFX->createCubemapArray());
mCubemapArray->initStatic(cubeMaps.address(), cubeMaps.size());
mIrradArray->initStatic(irradMaps.address(), irradMaps.size());
//mPrefilterArray->initStatic(cubeMaps.address(), cubeMaps.size());
//mIrradianceArray->initStatic(irradMaps.address(), irradMaps.size());
}
}
void RenderProbeMgr::updateProbeTexture(ProbeRenderInst* probe)
{
S32 probeIdx = ProbeRenderInst::all.find_next(probe);
if (probeIdx != -1) //i mean, the opposite shouldn't even be possible
updateProbeTexture(probeIdx);
}
void RenderProbeMgr::updateProbeTexture(U32 probeIdx)
{
if (probeIdx >= ProbeRenderInst::all.size())
return;
const U32 cubeIndex = ProbeRenderInst::all[probeIdx]->mCubemapIndex;
mIrradianceArray->updateTexture(ProbeRenderInst::all[probeIdx]->mIrradianceCubemap, cubeIndex);
mPrefilterArray->updateTexture(ProbeRenderInst::all[probeIdx]->mPrefilterCubemap, cubeIndex);
}
void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
{
PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters);
@ -607,11 +717,11 @@ void RenderProbeMgr::render( SceneRenderState *state )
//updateProbes();
// Early out if nothing to draw.
if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || mEffectiveProbeCount == 0
|| !state->isDiffusePass() || cubeMaps.empty() || irradMaps.empty())
if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || !state->isDiffusePass() || (mEffectiveProbeCount == 0
|| mCubeMapCount != 0 && !hasSkylight))
{
getProbeArrayEffect()->setSkip(true);
return;
getProbeArrayEffect()->setSkip(true);
return;
}
GFXTransformSaver saver;
@ -625,10 +735,18 @@ void RenderProbeMgr::render( SceneRenderState *state )
//Array rendering
//U32 probeCount = ProbeRenderInst::all.size();
mProbeArrayEffect->setShaderConst("$hasSkylight", (float)hasSkylight);
if (hasSkylight)
{
mProbeArrayEffect->setCubemapTexture(6, skylightPrefilterMap);
mProbeArrayEffect->setCubemapTexture(7, skylightIrradMap);
}
if (mEffectiveProbeCount != 0)
{
mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray);
mProbeArrayEffect->setCubemapArrayTexture(5, mIrradArray);
mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray);
mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray);
String useDebugAtten = Con::getVariable("$Probes::showAttenuation", "0");
mProbeArrayEffect->setShaderMacro("DEBUGVIZ_ATTENUATION", useDebugAtten);