motion based updates for shadow caching

adds a $pref::Shadows::teleportDis and $pref::Shadows::turnRate (defaults 4, and 1 respectively)
if either is exceeded during a given frame, shadow chaches are forced to refresh themselves.
This commit is contained in:
Azaezel 2016-11-29 14:13:23 -06:00
parent 7af95e6a8e
commit 01419d7935
5 changed files with 55 additions and 19 deletions

View file

@ -304,13 +304,16 @@ bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants*
return false; return false;
} }
void LightShadowMap::render( RenderPassManager* renderPass, void LightShadowMap::render(RenderPassManager* renderPass,
const SceneRenderState *diffuseState, const SceneRenderState *diffuseState,
bool _dynamic) bool _dynamic, bool _forceUpdate)
{ {
// control how often shadow maps are refreshed if (!_forceUpdate)
if (!_dynamic && (mStaticRefreshTimer->getElapsedMs() < getLightInfo()->getStaticRefreshFreq())) {
return; // control how often shadow maps are refreshed
if (!_dynamic && (mStaticRefreshTimer->getElapsedMs() < getLightInfo()->getStaticRefreshFreq()))
return;
}
mStaticRefreshTimer->reset(); mStaticRefreshTimer->reset();
/* TODO: find out why this is causing issue with translucent objects /* TODO: find out why this is causing issue with translucent objects

View file

@ -163,7 +163,7 @@ public:
void render( RenderPassManager* renderPass, void render( RenderPassManager* renderPass,
const SceneRenderState *diffuseState, const SceneRenderState *diffuseState,
bool _dynamic); bool _dynamic, bool _forceUpdate);
U32 getLastUpdate() const { return mLastUpdate; } U32 getLastUpdate() const { return mLastUpdate; }

View file

@ -78,6 +78,16 @@ AFTER_MODULE_INIT( Sim )
Con::NotifyDelegate shadowCallback( &ShadowMapManager::updateShadowDisable ); Con::NotifyDelegate shadowCallback( &ShadowMapManager::updateShadowDisable );
Con::addVariableNotify( "$pref::Shadows::disable", shadowCallback ); Con::addVariableNotify( "$pref::Shadows::disable", shadowCallback );
Con::addVariableNotify( "$Shadows::disable", shadowCallback ); Con::addVariableNotify( "$Shadows::disable", shadowCallback );
Con::addVariable("$pref::Shadows::teleportDist",
TypeF32, &ShadowMapPass::smShadowsTeleportDist,
"Minimum distance moved per frame to determine that we are teleporting.\n");
Con::addVariableNotify("$pref::Shadows::teleportDist", shadowCallback);
Con::addVariable("$pref::Shadows::turnRate",
TypeF32, &ShadowMapPass::smShadowsTurnRate,
"Minimum angle moved per frame to determine that we are turning quickly.\n");
Con::addVariableNotify("$pref::Shadows::turnRate", shadowCallback);
} }
Signal<void(void)> ShadowMapManager::smShadowDeactivateSignal; Signal<void(void)> ShadowMapManager::smShadowDeactivateSignal;

View file

@ -39,6 +39,7 @@
#include "gfx/gfxDebugEvent.h" #include "gfx/gfxDebugEvent.h"
#include "platform/platformTimer.h" #include "platform/platformTimer.h"
#include "T3D/gameBase/gameConnection.h"
const String ShadowMapPass::PassTypeName("ShadowMap"); const String ShadowMapPass::PassTypeName("ShadowMap");
@ -55,11 +56,10 @@ bool ShadowMapPass::smDisableShadows = false;
bool ShadowMapPass::smDisableShadowsEditor = false; bool ShadowMapPass::smDisableShadowsEditor = false;
bool ShadowMapPass::smDisableShadowsPref = false; bool ShadowMapPass::smDisableShadowsPref = false;
/// milliseconds before static redraw /// distance moved per frame before forcing a shadow update
S32 ShadowMapPass::smStaticShadowUpdateFreq = 32; F32 ShadowMapPass::smShadowsTeleportDist = 4;
/// milliseconds before dynamic redraw /// angle turned per frame before forcing a shadow update
S32 ShadowMapPass::smDynamicShadowUpdateFreq = 16; F32 ShadowMapPass::smShadowsTurnRate = 1;
/// We have a default 8ms render budget for shadow rendering. /// We have a default 8ms render budget for shadow rendering.
U32 ShadowMapPass::smRenderBudgetMs = 8; U32 ShadowMapPass::smRenderBudgetMs = 8;
@ -89,7 +89,8 @@ ShadowMapPass::ShadowMapPass(LightManager* lightManager, ShadowMapManager* shado
mDynamicShadowRPM->addManager( new RenderImposterMgr( 0.6f, 0.6f ) ); mDynamicShadowRPM->addManager( new RenderImposterMgr( 0.6f, 0.6f ) );
mActiveLights = 0; mActiveLights = 0;
mPrevCamPos = Point3F::Zero;
mPrevCamRot = Point3F::Zero;
mTimer = PlatformTimer::create(); mTimer = PlatformTimer::create();
Con::addVariable( "$ShadowStats::activeMaps", TypeS32, &smActiveShadowMaps, Con::addVariable( "$ShadowStats::activeMaps", TypeS32, &smActiveShadowMaps,
@ -214,6 +215,26 @@ void ShadowMapPass::render( SceneManager *sceneManager,
mTimer->getElapsedMs(); mTimer->getElapsedMs();
mTimer->reset(); mTimer->reset();
// Must have a connection and control object
GameConnection* conn = GameConnection::getConnectionToServer();
if (!conn)
return;
GameBase * control = dynamic_cast<GameBase*>(conn->getControlObject());
if (!control)
return;
bool forceUpdate = false;
//force an update if we're jumping around (respawning, ect)
MatrixF curCamMatrix = control->getTransform();
if (((curCamMatrix.getPosition() - mPrevCamPos).lenSquared() > mPow(smShadowsTeleportDist, 2)) ||
((curCamMatrix.getForwardVector() - mPrevCamRot).lenSquared() > mPow(smShadowsTurnRate*M_PI_F / 180, 2)))
forceUpdate = true;
mPrevCamRot = curCamMatrix.getForwardVector();
mPrevCamPos = curCamMatrix.getPosition();
// 2 Shadow Maps per Light. This may fail. // 2 Shadow Maps per Light. This may fail.
for ( U32 i = 0; i < shadowMaps.size(); i += 2 ) for ( U32 i = 0; i < shadowMaps.size(); i += 2 )
{ {
@ -226,8 +247,8 @@ void ShadowMapPass::render( SceneManager *sceneManager,
mShadowManager->setLightShadowMap(lsm); mShadowManager->setLightShadowMap(lsm);
mShadowManager->setLightDynamicShadowMap( dlsm ); mShadowManager->setLightDynamicShadowMap( dlsm );
lsm->render(mShadowRPM, diffuseState, false); lsm->render(mShadowRPM, diffuseState, false, forceUpdate);
dlsm->render(mDynamicShadowRPM, diffuseState, true); dlsm->render(mDynamicShadowRPM, diffuseState, true, forceUpdate);
++smUpdatedShadowMaps; ++smUpdatedShadowMaps;
} }

View file

@ -84,10 +84,10 @@ public:
static bool smDisableShadowsEditor; static bool smDisableShadowsEditor;
static bool smDisableShadowsPref; static bool smDisableShadowsPref;
/// milliseconds before static redraw /// distance moved per frame before forcing a shadow update
static S32 smStaticShadowUpdateFreq; static F32 smShadowsTeleportDist;
/// milliseconds before dynamic redraw /// angle turned per frame before forcing a shadow update
static S32 smDynamicShadowUpdateFreq; static F32 smShadowsTurnRate;
private: private:
@ -112,6 +112,8 @@ private:
SimObjectPtr<DynamicShadowRenderPassManager> mDynamicShadowRPM; SimObjectPtr<DynamicShadowRenderPassManager> mDynamicShadowRPM;
LightManager* mLightManager; LightManager* mLightManager;
ShadowMapManager* mShadowManager; ShadowMapManager* mShadowManager;
Point3F mPrevCamPos;
Point3F mPrevCamRot;
}; };
class ShadowRenderPassManager : public RenderPassManager class ShadowRenderPassManager : public RenderPassManager