mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 08:04:40 +00:00
Re-implements the dynamic cubemap mode option for reflection probes
This commit is contained in:
parent
c2bbab774a
commit
5289fdf7f1
5 changed files with 115 additions and 14 deletions
|
|
@ -83,7 +83,7 @@ ImplementEnumType(ReflectionModeEnum,
|
||||||
{ ReflectionProbe::NoReflection, "No Reflections", "This probe does not provide any local reflection data"},
|
{ ReflectionProbe::NoReflection, "No Reflections", "This probe does not provide any local reflection data"},
|
||||||
{ ReflectionProbe::StaticCubemap, "Static Cubemap", "Uses a static CubemapData" },
|
{ ReflectionProbe::StaticCubemap, "Static Cubemap", "Uses a static CubemapData" },
|
||||||
{ ReflectionProbe::BakedCubemap, "Baked Cubemap", "Uses a cubemap baked from the probe's current position" },
|
{ ReflectionProbe::BakedCubemap, "Baked Cubemap", "Uses a cubemap baked from the probe's current position" },
|
||||||
//{ ReflectionProbe::DynamicCubemap, "Dynamic Cubemap", "Uses a cubemap baked from the probe's current position, updated at a set rate" },
|
{ ReflectionProbe::DynamicCubemap, "Dynamic Cubemap", "Uses a cubemap baked from the probe's current position, updated at a set rate" },
|
||||||
EndImplementEnumType;
|
EndImplementEnumType;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -122,7 +122,7 @@ ReflectionProbe::ReflectionProbe() :
|
||||||
mEditorShapeInst = NULL;
|
mEditorShapeInst = NULL;
|
||||||
mEditorShape = NULL;
|
mEditorShape = NULL;
|
||||||
|
|
||||||
mRefreshRateMS = 200;
|
mRefreshRateMS = 500;
|
||||||
mDynamicLastBakeMS = 0;
|
mDynamicLastBakeMS = 0;
|
||||||
|
|
||||||
mMaxDrawDistance = 75;
|
mMaxDrawDistance = 75;
|
||||||
|
|
@ -176,6 +176,8 @@ void ReflectionProbe::initPersistFields()
|
||||||
|
|
||||||
addField("StaticCubemap", TypeCubemapName, Offset(mCubemapName, ReflectionProbe), "Cubemap used instead of reflection texture if fullReflect is off.");
|
addField("StaticCubemap", TypeCubemapName, Offset(mCubemapName, ReflectionProbe), "Cubemap used instead of reflection texture if fullReflect is off.");
|
||||||
|
|
||||||
|
addField("DynamicReflectionRefreshMS", TypeS32, Offset(mRefreshRateMS, ReflectionProbe), "How often the dynamic cubemap is refreshed in milliseconds. Only works when the ReflectionMode is set to DynamicCubemap.");
|
||||||
|
|
||||||
addProtectedField("Bake", TypeBool, Offset(mBake, ReflectionProbe),
|
addProtectedField("Bake", TypeBool, Offset(mBake, ReflectionProbe),
|
||||||
&_doBake, &defaultProtectedGetFn, "Regenerate Voxel Grid", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
|
&_doBake, &defaultProtectedGetFn, "Regenerate Voxel Grid", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
|
||||||
endGroup("Reflection");
|
endGroup("Reflection");
|
||||||
|
|
@ -434,6 +436,7 @@ U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream
|
||||||
stream->write(mProbeUniqueID);
|
stream->write(mProbeUniqueID);
|
||||||
stream->write((U32)mReflectionModeType);
|
stream->write((U32)mReflectionModeType);
|
||||||
stream->write(mCubemapName);
|
stream->write(mCubemapName);
|
||||||
|
stream->write(mRefreshRateMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->writeFlag(mask & EnabledMask))
|
if (stream->writeFlag(mask & EnabledMask))
|
||||||
|
|
@ -487,6 +490,8 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||||
if(oldReflectModeType != mReflectionModeType || oldCubemapName != mCubemapName)
|
if(oldReflectModeType != mReflectionModeType || oldCubemapName != mCubemapName)
|
||||||
mCubemapDirty = true;
|
mCubemapDirty = true;
|
||||||
|
|
||||||
|
stream->read(&mRefreshRateMS);
|
||||||
|
|
||||||
mDirty = true;
|
mDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -582,7 +587,7 @@ void ReflectionProbe::updateProbeParams()
|
||||||
|
|
||||||
void ReflectionProbe::processDynamicCubemap()
|
void ReflectionProbe::processDynamicCubemap()
|
||||||
{
|
{
|
||||||
//if (!mProbeInfo)
|
/*if (!mProbeInfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mEnabled = false;
|
mEnabled = false;
|
||||||
|
|
@ -591,7 +596,18 @@ void ReflectionProbe::processDynamicCubemap()
|
||||||
{
|
{
|
||||||
mProbeInfo->mPrefilterCubemap = mDynamicCubemap;
|
mProbeInfo->mPrefilterCubemap = mDynamicCubemap;
|
||||||
|
|
||||||
//mCubeReflector.registerReflector(this, reflectorDesc); //need to decide how we wanna do the reflectorDesc. static name or a field
|
if (reflectorDesc == nullptr)
|
||||||
|
{
|
||||||
|
//find it
|
||||||
|
if (!Sim::findObject("DefaultCubeDesc", reflectorDesc))
|
||||||
|
{
|
||||||
|
mProbeInfo->mIsEnabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mCubeReflector.unregisterReflector();
|
||||||
|
mCubeReflector.registerReflector(this, reflectorDesc); //need to decide how we wanna do the reflectorDesc. static name or a field
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEnabled)
|
if (mEnabled)
|
||||||
|
|
@ -603,7 +619,68 @@ void ReflectionProbe::processDynamicCubemap()
|
||||||
|
|
||||||
//Update the probe manager with our new texture!
|
//Update the probe manager with our new texture!
|
||||||
//if (!mProbeInfo->mIsSkylight && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
|
//if (!mProbeInfo->mIsSkylight && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
|
||||||
// PROBEMGR->updateProbeTexture(mProbeInfo->mProbeIdx);
|
// PROBEMGR->updateProbeTexture(mProbeInfo->mProbeIdx);*/
|
||||||
|
|
||||||
|
if (!mProbeInfo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mProbeInfo->mIsEnabled = false;
|
||||||
|
|
||||||
|
if (mReflectionModeType != DynamicCubemap)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (reflectorDesc == nullptr)
|
||||||
|
{
|
||||||
|
//find it
|
||||||
|
if (!Sim::findObject("DefaultCubeDesc", reflectorDesc))
|
||||||
|
{
|
||||||
|
mProbeInfo->mIsEnabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCubeReflector.unregisterReflector();
|
||||||
|
mCubeReflector.registerReflector(this, reflectorDesc); //need to decide how we wanna do the reflectorDesc. static name or a field
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCubeReflector.getCubemap())
|
||||||
|
{
|
||||||
|
U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
|
||||||
|
U32 prefilterMipLevels = mLog2(F32(resolution));
|
||||||
|
|
||||||
|
//Prep it with whatever resolution we've dictated for our bake
|
||||||
|
mIrridianceMap->mCubemap->initDynamic(resolution, PROBEMGR->PROBE_FORMAT);
|
||||||
|
mPrefilterMap->mCubemap->initDynamic(resolution, PROBEMGR->PROBE_FORMAT);
|
||||||
|
|
||||||
|
GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false);
|
||||||
|
|
||||||
|
IBLUtilities::GenerateIrradianceMap(renderTarget, mCubeReflector.getCubemap(), mIrridianceMap->mCubemap);
|
||||||
|
IBLUtilities::GeneratePrefilterMap(renderTarget, mCubeReflector.getCubemap(), prefilterMipLevels, mPrefilterMap->mCubemap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIrridianceMap == nullptr || mIrridianceMap->mCubemap.isNull())
|
||||||
|
{
|
||||||
|
Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked irradiance map at %s", getIrradianceMapPath().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPrefilterMap == nullptr || mPrefilterMap->mCubemap.isNull())
|
||||||
|
{
|
||||||
|
Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mProbeInfo->mPrefilterCubemap = mPrefilterMap->mCubemap;
|
||||||
|
mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
|
||||||
|
|
||||||
|
if (mEnabled && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
|
||||||
|
{
|
||||||
|
mProbeInfo->mIsEnabled = true;
|
||||||
|
|
||||||
|
mCubemapDirty = false;
|
||||||
|
|
||||||
|
//Update the probe manager with our new texture!
|
||||||
|
PROBEMGR->updateProbeTexture(mProbeInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReflectionProbe::processBakedCubemap()
|
void ReflectionProbe::processBakedCubemap()
|
||||||
|
|
@ -818,10 +895,12 @@ String ReflectionProbe::getIrradianceMapPath()
|
||||||
|
|
||||||
void ReflectionProbe::bake()
|
void ReflectionProbe::bake()
|
||||||
{
|
{
|
||||||
if (mReflectionModeType != BakedCubemap)
|
bool writeFile = mReflectionModeType == BakedCubemap ? true : false;
|
||||||
|
|
||||||
|
if (mReflectionModeType == StaticCubemap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PROBEMGR->bakeProbe(this);
|
PROBEMGR->bakeProbe(this, writeFile);
|
||||||
|
|
||||||
setMaskBits(-1);
|
setMaskBits(-1);
|
||||||
}
|
}
|
||||||
|
|
@ -864,8 +943,10 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
|
||||||
|
|
||||||
if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS))
|
if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS))
|
||||||
{
|
{
|
||||||
bake();
|
//bake();
|
||||||
mDynamicLastBakeMS = Platform::getRealMilliseconds();
|
mDynamicLastBakeMS = Platform::getRealMilliseconds();
|
||||||
|
|
||||||
|
processDynamicCubemap();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Submit our probe to actually do the probe action
|
//Submit our probe to actually do the probe action
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ protected:
|
||||||
|
|
||||||
String cubeDescName;
|
String cubeDescName;
|
||||||
U32 cubeDescId;
|
U32 cubeDescId;
|
||||||
|
CubeReflector mCubeReflector;
|
||||||
ReflectorDesc *reflectorDesc;
|
ReflectorDesc *reflectorDesc;
|
||||||
|
|
||||||
//Utilized in dynamic reflections
|
//Utilized in dynamic reflections
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,14 @@ void Skylight::prepRenderImage(SceneRenderState *state)
|
||||||
|
|
||||||
mProbeInfo->setPosition(camPos);
|
mProbeInfo->setPosition(camPos);
|
||||||
|
|
||||||
|
if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS))
|
||||||
|
{
|
||||||
|
//bake();
|
||||||
|
mDynamicLastBakeMS = Platform::getRealMilliseconds();
|
||||||
|
|
||||||
|
processDynamicCubemap();
|
||||||
|
}
|
||||||
|
|
||||||
//Submit our probe to actually do the probe action
|
//Submit our probe to actually do the probe action
|
||||||
// Get a handy pointer to our RenderPassmanager
|
// Get a handy pointer to our RenderPassmanager
|
||||||
//RenderPassManager *renderPass = state->getRenderPass();
|
//RenderPassManager *renderPass = state->getRenderPass();
|
||||||
|
|
|
||||||
|
|
@ -853,7 +853,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
|
||||||
//PROFILE_END();
|
//PROFILE_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderProbeMgr::bakeProbe(ReflectionProbe *probe)
|
void RenderProbeMgr::bakeProbe(ReflectionProbe *probe, bool writeFiles)
|
||||||
{
|
{
|
||||||
GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
|
GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
|
||||||
|
|
||||||
|
|
@ -865,7 +865,12 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe *probe)
|
||||||
U32 prefilterMipLevels = mLog2(F32(resolution));
|
U32 prefilterMipLevels = mLog2(F32(resolution));
|
||||||
bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false);
|
bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false);
|
||||||
|
|
||||||
ReflectionProbe *clientProbe = static_cast<ReflectionProbe*>(probe->getClientObject());
|
ReflectionProbe* clientProbe = nullptr;
|
||||||
|
|
||||||
|
if (probe->isClientObject())
|
||||||
|
clientProbe = probe;
|
||||||
|
else
|
||||||
|
clientProbe = static_cast<ReflectionProbe*>(probe->getClientObject());
|
||||||
|
|
||||||
if (clientProbe == nullptr)
|
if (clientProbe == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
@ -960,10 +965,14 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe *probe)
|
||||||
U32 endMSTime = Platform::getRealMilliseconds();
|
U32 endMSTime = Platform::getRealMilliseconds();
|
||||||
F32 diffTime = F32(endMSTime - startMSTime);
|
F32 diffTime = F32(endMSTime - startMSTime);
|
||||||
Con::warnf("RenderProbeMgr::bake() - Finished Capture! Took %g milliseconds", diffTime);
|
Con::warnf("RenderProbeMgr::bake() - Finished Capture! Took %g milliseconds", diffTime);
|
||||||
Con::warnf("RenderProbeMgr::bake() - Beginning save now!");
|
|
||||||
|
|
||||||
IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap);
|
if (writeFiles)
|
||||||
IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap);
|
{
|
||||||
|
Con::warnf("RenderProbeMgr::bake() - Beginning save now!");
|
||||||
|
|
||||||
|
IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap);
|
||||||
|
IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,7 @@ class RenderProbeMgr : public RenderBinManager
|
||||||
|
|
||||||
bool mProbesDirty;
|
bool mProbesDirty;
|
||||||
|
|
||||||
|
public:
|
||||||
//maximum number of allowed probes
|
//maximum number of allowed probes
|
||||||
static const U32 PROBE_MAX_COUNT = 250;
|
static const U32 PROBE_MAX_COUNT = 250;
|
||||||
//maximum number of rendered probes per frame adjust as needed
|
//maximum number of rendered probes per frame adjust as needed
|
||||||
|
|
@ -235,6 +236,7 @@ class RenderProbeMgr : public RenderBinManager
|
||||||
static const GFXFormat PROBE_FORMAT = GFXFormatR16G16B16A16F;// GFXFormatR8G8B8A8;// when hdr fixed GFXFormatR16G16B16A16F; look into bc6h compression
|
static const GFXFormat PROBE_FORMAT = GFXFormatR16G16B16A16F;// GFXFormatR8G8B8A8;// when hdr fixed GFXFormatR16G16B16A16F; look into bc6h compression
|
||||||
static const U32 INVALID_CUBE_SLOT = U32_MAX;
|
static const U32 INVALID_CUBE_SLOT = U32_MAX;
|
||||||
|
|
||||||
|
private:
|
||||||
//Array rendering
|
//Array rendering
|
||||||
U32 mEffectiveProbeCount;
|
U32 mEffectiveProbeCount;
|
||||||
S32 mMipCount;
|
S32 mMipCount;
|
||||||
|
|
@ -344,7 +346,7 @@ public:
|
||||||
/// Debug rendering
|
/// Debug rendering
|
||||||
static bool smRenderReflectionProbes;
|
static bool smRenderReflectionProbes;
|
||||||
|
|
||||||
void bakeProbe(ReflectionProbe *probeInfo);
|
void bakeProbe(ReflectionProbe *probeInfo, bool writeFile = true);
|
||||||
void bakeProbes();
|
void bakeProbes();
|
||||||
|
|
||||||
void getProbeTextureData(ProbeTextureArrayData* probeTextureSet);
|
void getProbeTextureData(ProbeTextureArrayData* probeTextureSet);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue