BVB Source Codes

CRYENGINE Show ShadowCache.cpp Source code

Return Download CRYENGINE: download ShadowCache.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "ShadowCache.h"
  5. #include "LightEntity.h"
  6. #include "VisAreas.h"
  7.  
  8. const float ShadowCache::AO_FRUSTUM_SLOPE_BIAS = 0.5f;
  9.  
  10. void ShadowCache::InitShadowFrustum(ShadowMapFrustumPtr& pFr, int nLod, int nFirstStaticLod, float fDistFromViewDynamicLod, float fRadiusDynamicLod, const SRenderingPassInfo& passInfo)
  11. {
  12.         FUNCTION_PROFILER_3DENGINE;
  13.         assert(nLod >= 0);
  14.  
  15.         if (!pFr)
  16.                 pFr = new ShadowMapFrustum;
  17.  
  18.         if (!pFr->pShadowCacheData)
  19.                 pFr->pShadowCacheData = std::make_shared<ShadowMapFrustum::ShadowCacheData>();
  20.  
  21.         // check if we have come too close to the border of the map
  22.         ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy = m_nUpdateStrategy;
  23.         if (nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate && Get3DEngine()->m_CachedShadowsBounds.IsReset())
  24.         {
  25.                 const float fDistFromCenter = (passInfo.GetCamera().GetPosition() - pFr->aabbCasters.GetCenter()).GetLength() + fDistFromViewDynamicLod + fRadiusDynamicLod;
  26.                 if (fDistFromCenter > pFr->aabbCasters.GetSize().x / 2.0f)
  27.                 {
  28.                         nUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate;
  29.  
  30.                         if (!gEnv->IsEditing())
  31.                         {
  32.                                 CryLog("Update required for cached shadow map %d.", nLod - nFirstStaticLod);
  33.                                 CryLog("\tConsider increasing shadow cache resolution (r_ShadowsCacheResolutions) " \
  34.                                   "or setting up manual bounds for cached shadows via flow graph if this happens too often");
  35.                         }
  36.                 }
  37.         }
  38.  
  39.         AABB projectionBoundsLS(AABB::RESET);
  40.         const int nTexRes = GetRenderer()->GetCachedShadowsResolution()[nLod - nFirstStaticLod];
  41.  
  42.         // non incremental update: set new bounding box and estimate near/far planes
  43.         if (nUpdateStrategy != ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate)
  44.         {
  45.                 Matrix34 matView = Matrix34(GetViewMatrix(passInfo).GetTransposed());
  46.  
  47.                 if (!Get3DEngine()->m_CachedShadowsBounds.IsReset())
  48.                 {
  49.                         float fBoxScale = powf(Get3DEngine()->m_fCachedShadowsCascadeScale, (float)nLod - nFirstStaticLod);
  50.                         Vec3 fBoxScaleXY(max(1.f, fBoxScale));
  51.                         fBoxScaleXY.z = 1.f;
  52.  
  53.                         Vec3 vExt = Get3DEngine()->m_CachedShadowsBounds.GetSize().CompMul(fBoxScaleXY * 0.5f);
  54.                         Vec3 vCenter = Get3DEngine()->m_CachedShadowsBounds.GetCenter();
  55.  
  56.                         pFr->aabbCasters = AABB(vCenter - vExt, vCenter + vExt);
  57.                         projectionBoundsLS = AABB::CreateTransformedAABB(matView, pFr->aabbCasters);
  58.                 }
  59.                 else
  60.                 {
  61.                         const float fDesiredPixelDensity = fRadiusDynamicLod / GetCVars()->e_ShadowsMaxTexRes;
  62.                         GetCasterBox(pFr->aabbCasters, projectionBoundsLS, fDesiredPixelDensity * nTexRes, matView, passInfo);
  63.                 }
  64.         }
  65.  
  66.         // finally init frustum
  67.         InitCachedFrustum(pFr, nUpdateStrategy, nLod, nTexRes, m_pLightEntity->m_light.m_Origin, projectionBoundsLS, passInfo);
  68.         pFr->m_eFrustumType = ShadowMapFrustum::e_GsmCached;
  69.         pFr->bBlendFrustum = GetCVars()->e_ShadowsBlendCascades > 0;
  70.         pFr->fBlendVal = pFr->bBlendFrustum ? GetCVars()->e_ShadowsBlendCascadesVal : 1.0f;
  71.  
  72.         // frustum debug
  73.         {
  74.                 const ColorF cascadeColors[] = { Col_Red, Col_Green, Col_Blue, Col_Yellow, Col_Magenta, Col_Cyan };
  75.                 const uint colorCount = CRY_ARRAY_COUNT(cascadeColors);
  76.  
  77.                 if (GetCVars()->e_ShadowsCacheUpdate > 2)
  78.                         Get3DEngine()->DrawBBox(pFr->aabbCasters, cascadeColors[pFr->nShadowMapLod % colorCount]);
  79.  
  80.                 if (GetCVars()->e_ShadowsFrustums > 0)
  81.                         pFr->DrawFrustum(GetRenderer(), std::numeric_limits<int>::max());
  82.         }
  83. }
  84.  
  85. void ShadowCache::InitCachedFrustum(ShadowMapFrustumPtr& pFr, ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy, int nLod, int nTexSize, const Vec3& vLightPos, const AABB& projectionBoundsLS, const SRenderingPassInfo& passInfo)
  86. {
  87.         pFr->ResetCasterLists();
  88.         pFr->nTexSize = nTexSize;
  89.  
  90.         if (nUpdateStrategy != ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate)
  91.         {
  92.                 pFr->pShadowCacheData->Reset();
  93.                 pFr->nShadowGenMask = 1;
  94.  
  95.                 assert(m_pLightEntity->m_light.m_pOwner);
  96.                 pFr->pLightOwner = m_pLightEntity->m_light.m_pOwner;
  97.                 pFr->m_Flags = m_pLightEntity->m_light.m_Flags;
  98.                 pFr->nUpdateFrameId = passInfo.GetFrameID();
  99.                 pFr->nShadowMapLod = nLod;
  100.                 pFr->vProjTranslation = pFr->aabbCasters.GetCenter();
  101.                 pFr->vLightSrcRelPos = vLightPos - pFr->aabbCasters.GetCenter();
  102.                 pFr->fNearDist = -projectionBoundsLS.max.z;
  103.                 pFr->fFarDist = -projectionBoundsLS.min.z;
  104.                 pFr->fRendNear = pFr->fNearDist;
  105.                 pFr->fFOV = (float)RAD2DEG(atan_tpl(0.5 * projectionBoundsLS.GetSize().y / pFr->fNearDist)) * 2.f;
  106.                 pFr->fProjRatio = projectionBoundsLS.GetSize().x / projectionBoundsLS.GetSize().y;
  107.                 pFr->fRadius = m_pLightEntity->m_light.m_fRadius;
  108.                 pFr->fRendNear = pFr->fNearDist;
  109.                 pFr->fFrustrumSize = 1.0f / (Get3DEngine()->m_fGsmRange * pFr->aabbCasters.GetRadius() * 2.0f);
  110.  
  111.                 const float arrWidthS[] = { 1.94f, 1.0f, 0.8f, 0.5f, 0.3f, 0.3f, 0.3f, 0.3f };
  112.                 pFr->fWidthS = pFr->fWidthT = arrWidthS[nLod];
  113.                 pFr->fBlurS = pFr->fBlurT = 0.0f;
  114.         }
  115.  
  116.         const bool bExcludeDynamicDistanceShadows = GetCVars()->e_DynamicDistanceShadows != 0;
  117.         const bool bUseCastersHull = (nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eFullUpdateTimesliced);
  118.         const int maxNodesPerFrame = (nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate)
  119.                                      ? MAX_RENDERNODES_PER_FRAME* GetRenderer()->GetActiveGPUCount()
  120.                                      : std::numeric_limits<int>::max();
  121.  
  122.         m_pObjManager->MakeStaticShadowCastersList(((CLightEntity*)m_pLightEntity->m_light.m_pOwner)->m_pNotCaster, pFr,
  123.                                                    bUseCastersHull ? &m_pLightEntity->GetCastersHull() : nullptr,
  124.                                                    bExcludeDynamicDistanceShadows ? ERF_DYNAMIC_DISTANCESHADOWS : 0, maxNodesPerFrame, passInfo);
  125.         AddTerrainCastersToFrustum(pFr, passInfo);
  126.  
  127.         pFr->pShadowCacheData->mProcessedCasters.insert(pFr->castersList.begin(), pFr->castersList.end());
  128.         pFr->pShadowCacheData->mProcessedCasters.insert(pFr->jobExecutedCastersList.begin(), pFr->jobExecutedCastersList.end());
  129.         pFr->RequestUpdate();
  130.         pFr->bIncrementalUpdate = nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate && !pFr->pShadowCacheData->mProcessedCasters.empty();
  131. }
  132.  
  133. void ShadowCache::InitHeightMapAOFrustum(ShadowMapFrustumPtr& pFr, int nLod, const SRenderingPassInfo& passInfo)
  134. {
  135.         FUNCTION_PROFILER_3DENGINE;
  136.         assert(nLod >= 0);
  137.  
  138.         if (!pFr)
  139.                 pFr = new ShadowMapFrustum;
  140.  
  141.         if (!pFr->pShadowCacheData)
  142.                 pFr->pShadowCacheData = std::make_shared<ShadowMapFrustum::ShadowCacheData>();
  143.  
  144.         static ICVar* pHeightMapAORes = gEnv->pConsole->GetCVar("r_HeightMapAOResolution");
  145.         static ICVar* pHeightMapAORange = gEnv->pConsole->GetCVar("r_HeightMapAORange");
  146.  
  147.         ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy = m_nUpdateStrategy;
  148.  
  149.         // check if we have come too close to the border of the map
  150.         const float fDistFromCenter = (passInfo.GetCamera().GetPosition() - pFr->aabbCasters.GetCenter()).GetLength() + pHeightMapAORange->GetFVal() * 0.25f;
  151.         if (fDistFromCenter > pFr->aabbCasters.GetSize().x / 2.0f)
  152.         {
  153.                 nUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate;
  154.  
  155.                 if (!gEnv->IsEditing())
  156.                 {
  157.                         CryLog("Update required for height map AO.");
  158.                         CryLog("\tConsider increasing height map AO range (r_HeightMapAORange) if this happens too often");
  159.                 }
  160.         }
  161.  
  162.         AABB projectionBoundsLS(AABB::RESET);
  163.  
  164.         // non incremental update: set new bounding box and estimate near/far planes
  165.         if (nUpdateStrategy != ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate)
  166.         {
  167.                 // Top down view
  168.                 Matrix34 topDownView(IDENTITY);
  169.                 topDownView.m03 = -passInfo.GetCamera().GetPosition().x;
  170.                 topDownView.m13 = -passInfo.GetCamera().GetPosition().y;
  171.                 topDownView.m23 = -passInfo.GetCamera().GetPosition().z - m_pLightEntity->m_light.m_Origin.GetLength();
  172.  
  173.                 GetCasterBox(pFr->aabbCasters, projectionBoundsLS, pHeightMapAORange->GetFVal() / 2.0f, topDownView, passInfo);
  174.  
  175.                 // snap to texels
  176.                 const float fSnap = pHeightMapAORange->GetFVal() / pHeightMapAORes->GetFVal();
  177.                 pFr->aabbCasters.min.x = fSnap * int(pFr->aabbCasters.min.x / fSnap);
  178.                 pFr->aabbCasters.min.y = fSnap * int(pFr->aabbCasters.min.y / fSnap);
  179.                 pFr->aabbCasters.min.z = fSnap * int(pFr->aabbCasters.min.z / fSnap);
  180.  
  181.                 pFr->aabbCasters.max.x = pFr->aabbCasters.min.x + pHeightMapAORange->GetFVal();
  182.                 pFr->aabbCasters.max.y = pFr->aabbCasters.min.y + pHeightMapAORange->GetFVal();
  183.                 pFr->aabbCasters.max.z = fSnap * int(pFr->aabbCasters.max.z / fSnap);
  184.  
  185.                 pFr->fDepthSlopeBias = AO_FRUSTUM_SLOPE_BIAS;
  186.                 pFr->fDepthConstBias = 0;
  187.  
  188.                 pFr->mLightViewMatrix.SetIdentity();
  189.                 pFr->mLightViewMatrix.m30 = -pFr->aabbCasters.GetCenter().x;
  190.                 pFr->mLightViewMatrix.m31 = -pFr->aabbCasters.GetCenter().y;
  191.                 pFr->mLightViewMatrix.m32 = -pFr->aabbCasters.GetCenter().z - m_pLightEntity->m_light.m_Origin.GetLength();
  192.  
  193.                 mathMatrixOrtho(&pFr->mLightProjMatrix, projectionBoundsLS.GetSize().x, projectionBoundsLS.GetSize().y, -projectionBoundsLS.max.z, -projectionBoundsLS.min.z);
  194.         }
  195.  
  196.         const Vec3 lightPos = pFr->aabbCasters.GetCenter() + Vec3(0, 0, 1) * m_pLightEntity->m_light.m_Origin.GetLength();
  197.  
  198.         // finally init frustum
  199.         const int nTexRes = (int)clamp_tpl(pHeightMapAORes->GetFVal(), 0.f, 16384.f);
  200.         InitCachedFrustum(pFr, nUpdateStrategy, nLod, nTexRes, lightPos, projectionBoundsLS, passInfo);
  201.         pFr->m_eFrustumType = ShadowMapFrustum::e_HeightMapAO;
  202. }
  203.  
  204. void ShadowCache::GetCasterBox(AABB& BBoxWS, AABB& BBoxLS, float fRadius, const Matrix34& matView, const SRenderingPassInfo& passInfo)
  205. {
  206.         AABB projectionBoundsLS;
  207.  
  208.         BBoxWS = AABB(passInfo.GetCamera().GetPosition(), fRadius);
  209.         BBoxLS = AABB(matView.TransformPoint(passInfo.GetCamera().GetPosition()), fRadius);
  210.  
  211.         // try to get tighter near/far plane from casters
  212.         AABB casterBoxLS(AABB::RESET);
  213.         for (int nSID = 0; nSID < Get3DEngine()->m_pObjectsTree.Count(); nSID++)
  214.         {
  215.                 if (Get3DEngine()->IsSegmentSafeToUse(nSID))
  216.                         casterBoxLS.Add(Get3DEngine()->m_pObjectsTree[nSID]->GetShadowCastersBox(&BBoxWS, &matView));
  217.         }
  218.  
  219.         if (CVisAreaManager* pVisAreaManager = GetVisAreaManager())
  220.         {
  221.                 for (int i = 0; i < pVisAreaManager->m_lstVisAreas.Count(); ++i)
  222.                         if (pVisAreaManager->m_lstVisAreas[i] && pVisAreaManager->m_lstVisAreas[i]->m_pObjectsTree)
  223.                                 casterBoxLS.Add(pVisAreaManager->m_lstVisAreas[i]->m_pObjectsTree->GetShadowCastersBox(&BBoxWS, &matView));
  224.  
  225.                 for (int i = 0; i < pVisAreaManager->m_lstPortals.Count(); ++i)
  226.                         if (pVisAreaManager->m_lstPortals[i] && pVisAreaManager->m_lstPortals[i]->m_pObjectsTree)
  227.                                 casterBoxLS.Add(pVisAreaManager->m_lstPortals[i]->m_pObjectsTree->GetShadowCastersBox(&BBoxWS, &matView));
  228.         }
  229.  
  230.         if (!casterBoxLS.IsReset() && casterBoxLS.GetSize().z < 2 * fRadius)
  231.         {
  232.                 float fDepthRange = 2.0f * max(Get3DEngine()->m_fSunClipPlaneRange, casterBoxLS.GetSize().z);
  233.                 BBoxLS.max.z = casterBoxLS.max.z + 0.5f; // slight offset here to counter edge case where polygons are projection plane aligned and would come to lie directly on the near plane
  234.                 BBoxLS.min.z = casterBoxLS.max.z - fDepthRange;
  235.         }
  236. }
  237.  
  238. Matrix44 ShadowCache::GetViewMatrix(const SRenderingPassInfo& passInfo)
  239. {
  240.         const Vec3 zAxis(0.f, 0.f, 1.f);
  241.         const Vec3 yAxis(0.f, 1.f, 0.f);
  242.  
  243.         Vec3 At = passInfo.GetCamera().GetPosition();
  244.         Vec3 Eye = m_pLightEntity->m_light.m_Origin;
  245.         Vec3 Up = fabsf((Eye - At).GetNormalized().Dot(zAxis)) > 0.9995f ? yAxis : zAxis;
  246.  
  247.         Matrix44 result;
  248.         mathMatrixLookAt(&result, Eye, At, Up);
  249.  
  250.         return result;
  251. }
  252.  
  253. void ShadowCache::AddTerrainCastersToFrustum(ShadowMapFrustum* pFr, const SRenderingPassInfo& passInfo)
  254. {
  255.         FUNCTION_PROFILER_3DENGINE;
  256.  
  257.         if ((Get3DEngine()->m_bSunShadowsFromTerrain || pFr->m_eFrustumType == ShadowMapFrustum::e_HeightMapAO) && !pFr->bIsMGPUCopy)
  258.         {
  259.                 PodArray<CTerrainNode*> lstTerrainNodes;
  260.                 GetTerrain()->IntersectWithBox(pFr->aabbCasters, &lstTerrainNodes, GetDefSID());
  261.  
  262.                 for (int s = 0; s < lstTerrainNodes.Count(); s++)
  263.                 {
  264.                         CTerrainNode* pNode = lstTerrainNodes[s];
  265.  
  266.                         int nLod = pNode->GetAreaLOD(passInfo);
  267.                         if (nLod == MML_NOT_SET)
  268.                                 continue;
  269.  
  270.                         if (!pNode->GetLeafData() || !pNode->GetLeafData()->m_pRenderMesh || pNode->m_cCurrGeomMML != pNode->m_cNewGeomMML)
  271.                                 continue;
  272.  
  273.                         uint64 nodeHash = HashTerrainNode(pNode, nLod);
  274.                         if (pFr->pShadowCacheData->mProcessedTerrainCasters.find(nodeHash) != pFr->pShadowCacheData->mProcessedTerrainCasters.end())
  275.                                 continue;
  276.  
  277.                         pFr->pShadowCacheData->mProcessedTerrainCasters.insert(nodeHash);
  278.                         pFr->castersList.Add(pNode);
  279.                 }
  280.  
  281.                 if (!pFr->castersList.IsEmpty())
  282.                         pFr->RequestUpdate();
  283.         }
  284. }
  285.  
  286. ILINE uint64 ShadowCache::HashValue(uint64 value)
  287. {
  288.         uint64 hash = value * kHashMul;
  289.         hash ^= (hash >> 47);
  290.         hash *= kHashMul;
  291.         return hash;
  292. }
  293.  
  294. ILINE uint64 ShadowCache::HashTerrainNode(const CTerrainNode* pNode, int lod)
  295. {
  296.         uint64 hashPointer = (uint64)HashValue(alias_cast<UINT_PTR>(pNode));
  297.         uint64 hashLod = HashValue(lod);
  298.  
  299.         uint64 a = (hashLod ^ hashPointer) * kHashMul;
  300.         a ^= (a >> 47);
  301.         uint64 b = (hashPointer ^ a) * kHashMul;
  302.         b ^= (b >> 47);
  303.         return b * kHashMul;
  304. }
  305.  
downloadShadowCache.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top