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 ead78ec588
commit 399088d09e
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);

View file

@ -72,7 +72,7 @@ struct ProbeRenderInst : public SystemInterface<ProbeRenderInst>
Point3F mProbeRefScale;
F32 mAtten;
GFXCubemapHandle mCubemap;
GFXCubemapHandle mPrefilterCubemap;
GFXCubemapHandle mIrradianceCubemap;
//Utilized in dynamic reflections
@ -97,6 +97,8 @@ struct ProbeRenderInst : public SystemInterface<ProbeRenderInst>
ProbeShapeType mProbeShapeType;
U32 mCubemapIndex;
public:
ProbeRenderInst();
@ -161,6 +163,18 @@ class RenderProbeMgr : public RenderBinManager
Vector<U32> mRegisteredProbes;
//maximum number of allowed probes
static const U32 PROBE_MAX_COUNT = 250;
//maximum number of rendered probes per frame adjust as needed
static const U32 PROBE_MAX_FRAME = 8;
//number of slots to allocate at once in the cubemap array
static const U32 PROBE_ARRAY_SLOT_BUFFER_SIZE = 10;
static const U32 PROBE_IRRAD_SIZE = 32;
static const U32 PROBE_PREFILTER_SIZE = 128;
static const GFXFormat PROBE_FORMAT = GFXFormatR8G8B8A8;// when hdr fixed GFXFormatR16G16B16A16F; look into bc6h compression
static const U32 INVALID_CUBE_SLOT = U32_MAX;
//Array rendering
U32 mEffectiveProbeCount;
S32 mMipCount;
@ -173,6 +187,11 @@ class RenderProbeMgr : public RenderBinManager
Vector<GFXCubemapHandle> cubeMaps;
Vector<GFXCubemapHandle> irradMaps;
bool hasSkylight;
GFXCubemapHandle skylightIrradMap;
GFXCubemapHandle skylightPrefilterMap;
Point4F skylightPos;
AlignedArray<Point4F> mProbePositions;
AlignedArray<Point4F> mProbeBBMin;
AlignedArray<Point4F> mProbeBBMax;
@ -180,8 +199,15 @@ class RenderProbeMgr : public RenderBinManager
AlignedArray<float> mProbeRadius;
AlignedArray<float> mProbeAttenuation;
GFXCubemapArrayHandle mCubemapArray;
GFXCubemapArrayHandle mIrradArray;
//number of cubemaps
U32 mCubeMapCount;
//number of cubemap slots allocated
U32 mCubeSlotCount;
//array of cubemap slots, due to the editor these may be mixed around as probes are added and deleted
bool mCubeMapSlots[PROBE_MAX_COUNT];
GFXCubemapArrayHandle mPrefilterArray;
GFXCubemapArrayHandle mIrradianceArray;
//Utilized in forward rendering
ProbeConstantMap mConstantLookup;
@ -191,10 +217,14 @@ class RenderProbeMgr : public RenderBinManager
//
SimObjectPtr<PostEffect> mProbeArrayEffect;
//Default skylight, used for shape editors, etc
ProbeRenderInst* mDefaultSkyLight;
public:
RenderProbeMgr();
RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder);
virtual ~RenderProbeMgr();
virtual bool onAdd();
virtual void onRemove();
// ConsoleObject
@ -219,6 +249,7 @@ protected:
GFXShaderConstBuffer *shaderConsts);
void _setupStaticParameters();
void updateProbeTexture(U32 probeIdx);
void _setupPerFrameParameters(const SceneRenderState *state);
virtual void addElement(RenderInst *inst);
virtual void render(SceneRenderState * state);
@ -230,6 +261,7 @@ protected:
public:
// RenderBinMgr
void updateProbes();
void updateProbeTexture(ProbeRenderInst* probe);
/// Returns the active LM.
static inline RenderProbeMgr* getProbeManager();
@ -249,6 +281,16 @@ public:
void bakeProbe(ReflectionProbe *probeInfo);
void bakeProbes();
U32 _findNextEmptyCubeSlot()
{
for (U32 i = 0; i < PROBE_MAX_COUNT; i++)
{
if (!mCubeMapSlots[i])
return i;
}
return INVALID_CUBE_SLOT;
}
};
RenderProbeMgr* RenderProbeMgr::getProbeManager()