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;
}
void LightShadowMap::render( RenderPassManager* renderPass,
const SceneRenderState *diffuseState,
bool _dynamic)
void LightShadowMap::render(RenderPassManager* renderPass,
const SceneRenderState *diffuseState,
bool _dynamic, bool _forceUpdate)
{
// control how often shadow maps are refreshed
if (!_dynamic && (mStaticRefreshTimer->getElapsedMs() < getLightInfo()->getStaticRefreshFreq()))
return;
if (!_forceUpdate)
{
// control how often shadow maps are refreshed
if (!_dynamic && (mStaticRefreshTimer->getElapsedMs() < getLightInfo()->getStaticRefreshFreq()))
return;
}
mStaticRefreshTimer->reset();
/* TODO: find out why this is causing issue with translucent objects

View file

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

View file

@ -78,6 +78,16 @@ AFTER_MODULE_INIT( Sim )
Con::NotifyDelegate shadowCallback( &ShadowMapManager::updateShadowDisable );
Con::addVariableNotify( "$pref::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;

View file

@ -39,6 +39,7 @@
#include "gfx/gfxDebugEvent.h"
#include "platform/platformTimer.h"
#include "T3D/gameBase/gameConnection.h"
const String ShadowMapPass::PassTypeName("ShadowMap");
@ -55,11 +56,10 @@ bool ShadowMapPass::smDisableShadows = false;
bool ShadowMapPass::smDisableShadowsEditor = false;
bool ShadowMapPass::smDisableShadowsPref = false;
/// milliseconds before static redraw
S32 ShadowMapPass::smStaticShadowUpdateFreq = 32;
/// milliseconds before dynamic redraw
S32 ShadowMapPass::smDynamicShadowUpdateFreq = 16;
/// distance moved per frame before forcing a shadow update
F32 ShadowMapPass::smShadowsTeleportDist = 4;
/// angle turned per frame before forcing a shadow update
F32 ShadowMapPass::smShadowsTurnRate = 1;
/// We have a default 8ms render budget for shadow rendering.
U32 ShadowMapPass::smRenderBudgetMs = 8;
@ -89,7 +89,8 @@ ShadowMapPass::ShadowMapPass(LightManager* lightManager, ShadowMapManager* shado
mDynamicShadowRPM->addManager( new RenderImposterMgr( 0.6f, 0.6f ) );
mActiveLights = 0;
mPrevCamPos = Point3F::Zero;
mPrevCamRot = Point3F::Zero;
mTimer = PlatformTimer::create();
Con::addVariable( "$ShadowStats::activeMaps", TypeS32, &smActiveShadowMaps,
@ -214,6 +215,26 @@ void ShadowMapPass::render( SceneManager *sceneManager,
mTimer->getElapsedMs();
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.
for ( U32 i = 0; i < shadowMaps.size(); i += 2 )
{
@ -226,8 +247,8 @@ void ShadowMapPass::render( SceneManager *sceneManager,
mShadowManager->setLightShadowMap(lsm);
mShadowManager->setLightDynamicShadowMap( dlsm );
lsm->render(mShadowRPM, diffuseState, false);
dlsm->render(mDynamicShadowRPM, diffuseState, true);
lsm->render(mShadowRPM, diffuseState, false, forceUpdate);
dlsm->render(mDynamicShadowRPM, diffuseState, true, forceUpdate);
++smUpdatedShadowMaps;
}

View file

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