ソースを参照

Merge pull request #1836 from Azaezel/shadowSlips

motion based updates for shadow caching
Areloch 8 年 前
コミット
7fac8b75e1

+ 9 - 6
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

+ 1 - 1
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; }
 

+ 10 - 0
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<void(void)> ShadowMapManager::smShadowDeactivateSignal;

+ 31 - 8
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<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)) || //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;
       }

+ 7 - 4
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<DynamicShadowRenderPassManager> mDynamicShadowRPM;
    LightManager* mLightManager;
    ShadowMapManager* mShadowManager;
+   Point3F mPrevCamPos;
+   Point3F mPrevCamRot;
+   F32 mPrevCamFov;
 };
 
 class ShadowRenderPassManager : public RenderPassManager