diff --git a/Engine/source/lighting/shadowMap/lightShadowMap.cpp b/Engine/source/lighting/shadowMap/lightShadowMap.cpp index 8be673ec2..3359db622 100644 --- a/Engine/source/lighting/shadowMap/lightShadowMap.cpp +++ b/Engine/source/lighting/shadowMap/lightShadowMap.cpp @@ -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 diff --git a/Engine/source/lighting/shadowMap/lightShadowMap.h b/Engine/source/lighting/shadowMap/lightShadowMap.h index d96481192..c98dc4de5 100644 --- a/Engine/source/lighting/shadowMap/lightShadowMap.h +++ b/Engine/source/lighting/shadowMap/lightShadowMap.h @@ -163,7 +163,7 @@ public: void render( RenderPassManager* renderPass, const SceneRenderState *diffuseState, - bool _dynamic); + bool _dynamic, bool _forceUpdate); U32 getLastUpdate() const { return mLastUpdate; } diff --git a/Engine/source/lighting/shadowMap/shadowMapManager.cpp b/Engine/source/lighting/shadowMap/shadowMapManager.cpp index 7fd50cd78..0b58abc37 100644 --- a/Engine/source/lighting/shadowMap/shadowMapManager.cpp +++ b/Engine/source/lighting/shadowMap/shadowMapManager.cpp @@ -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 ShadowMapManager::smShadowDeactivateSignal; diff --git a/Engine/source/lighting/shadowMap/shadowMapPass.cpp b/Engine/source/lighting/shadowMap/shadowMapPass.cpp index dea7305b5..d18e4dc7d 100644 --- a/Engine/source/lighting/shadowMap/shadowMapPass.cpp +++ b/Engine/source/lighting/shadowMap/shadowMapPass.cpp @@ -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,28 @@ 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(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)) || //update if we're teleporting + ((curCamMatrix.getForwardVector() - mPrevCamRot).lenSquared() > mPow(smShadowsTurnRate*M_PI_F / 180, 2)) || //update if we're turning too fast + (control->getCameraFov()) != mPrevCamFov) //update if we're zooming or unzooming + forceUpdate = true; + + mPrevCamRot = curCamMatrix.getForwardVector(); + mPrevCamPos = curCamMatrix.getPosition(); + mPrevCamFov = control->getCameraFov(); + // 2 Shadow Maps per Light. This may fail. for ( U32 i = 0; i < shadowMaps.size(); i += 2 ) { @@ -226,8 +249,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; } diff --git a/Engine/source/lighting/shadowMap/shadowMapPass.h b/Engine/source/lighting/shadowMap/shadowMapPass.h index 45e908c91..5a8115b4f 100644 --- a/Engine/source/lighting/shadowMap/shadowMapPass.h +++ b/Engine/source/lighting/shadowMap/shadowMapPass.h @@ -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,9 @@ private: SimObjectPtr mDynamicShadowRPM; LightManager* mLightManager; ShadowMapManager* mShadowManager; + Point3F mPrevCamPos; + Point3F mPrevCamRot; + F32 mPrevCamFov; }; class ShadowRenderPassManager : public RenderPassManager