You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/RenderDll/XRenderD3D9/D3D_SVO.cpp

1714 lines
60 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "RenderDll_precompiled.h"
#if defined(FEATURE_SVO_GI)
#include "DriverD3D.h"
#include "I3DEngine.h"
#include "D3DPostProcess.h"
#include "D3D_SVO.h"
#include "D3DTiledShading.h"
#include "../Common/Include_HLSL_CPP_Shared.h"
#include "../Common/TypedConstantBuffer.h"
#include "../Common/Textures/TextureManager.h"
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
CSvoRenderer* CSvoRenderer::s_pInstance = 0;
CSvoRenderer::CSvoRenderer()
{
m_pRT_AIR_MIN =
m_pRT_AIR_MAX =
m_pRT_AIR_SHAD =
m_pRT_NID_0 = NULL;
m_nTexStateTrilinear = CTexture::GetTexState(STexState(FILTER_TRILINEAR, true));
m_nTexStateLinear = CTexture::GetTexState(STexState(FILTER_LINEAR, true));
m_nTexStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true));
m_nTexStateLinearWrap = CTexture::GetTexState(STexState(FILTER_LINEAR, false));
m_pNoiseTex = nullptr;
m_pRsmNormlMap = m_pRsmColorMap = 0;
m_pRsmPoolNor = m_pRsmPoolCol = 0;
m_pShader = nullptr;
ZeroStruct(m_arrNodesForUpdate);
ZeroStruct(m_nCurPropagationPassID);
SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::RegisterMutex, &m_renderMutex);
}
void SSvoTargetsSet::Release()
{
SAFE_RELEASE(pRT_RGB_DEM_MIN_0);
SAFE_RELEASE(pRT_ALD_DEM_MIN_0);
SAFE_RELEASE(pRT_RGB_DEM_MAX_0);
SAFE_RELEASE(pRT_ALD_DEM_MAX_0);
SAFE_RELEASE(pRT_RGB_DEM_MIN_1);
SAFE_RELEASE(pRT_ALD_DEM_MIN_1);
SAFE_RELEASE(pRT_RGB_DEM_MAX_1);
SAFE_RELEASE(pRT_ALD_DEM_MAX_1);
SAFE_RELEASE(pRT_FIN_OUT_0);
SAFE_RELEASE(pRT_FIN_OUT_1);
SAFE_RELEASE(pRT_ALD_0);
SAFE_RELEASE(pRT_ALD_1);
SAFE_RELEASE(pRT_RGB_0);
SAFE_RELEASE(pRT_RGB_1);
}
CSvoRenderer::~CSvoRenderer()
{
m_tsDiff.Release();
m_tsSpec.Release();
SAFE_RELEASE(m_pRT_AIR_MIN);
SAFE_RELEASE(m_pRT_AIR_MAX);
SAFE_RELEASE(m_pRT_AIR_SHAD);
SAFE_RELEASE(m_pRT_NID_0);
SAFE_RELEASE(m_pRsmColorMap);
SAFE_RELEASE(m_pRsmNormlMap);
SAFE_RELEASE(m_pRsmPoolCol);
SAFE_RELEASE(m_pRsmPoolNor);
SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::UnregisterMutex);
}
CSvoRenderer* CSvoRenderer::GetInstance(bool bCheckAlloce)
{
if (!s_pInstance && bCheckAlloce)
{
s_pInstance = new CSvoRenderer();
}
return s_pInstance;
}
void CSvoRenderer::Release()
{
SAFE_DELETE(s_pInstance);
}
void CSvoRenderer::UpdateCompute()
{
if (!IsActive())
{
return;
}
UpdatePassConstantBuffer();
static int nTI_Compute_FrameId = -1;
if (nTI_Compute_FrameId == gRenDev->GetFrameID(false))
{
return;
}
nTI_Compute_FrameId = gRenDev->GetFrameID(false);
gEnv->p3DEngine->GetSvoStaticTextures(m_texInfo, &m_arrLightsStatic, &m_arrLightsDynamic);
if (m_texInfo.pTexTree == nullptr)
{
return;
}
CD3D9Renderer* rd = gcpRendD3D;
if (!m_pShader)
{
gcpRendD3D->m_cEF.mfRefreshSystemShader("Total_Illumination", m_pShader);
}
m_nodesForStaticUpdate.Clear();
m_nodesForDynamicUpdate.Clear();
if (GetIntegratioMode())
{
gEnv->p3DEngine->GetSvoBricksForUpdate(m_arrNodeInfo, false);
for (int n = 0; n < m_arrNodeInfo.Count(); n++)
{
m_nodesForStaticUpdate.Add(m_arrNodeInfo[n]);
}
m_arrNodeInfo.Clear();
}
if (GetIntegratioMode())
{
gEnv->p3DEngine->GetSvoBricksForUpdate(m_arrNodeInfo, true);
for (int n = 0; n < m_arrNodeInfo.Count(); n++)
{
m_nodesForDynamicUpdate.Add(m_arrNodeInfo[n]);
}
m_arrNodeInfo.Clear();
}
{
// get UAV access
vp_RGB0.Init(m_texInfo.pTexRgb0);
vp_RGB1.Init(m_texInfo.pTexRgb1);
vp_DYNL.Init(m_texInfo.pTexDynl);
vp_RGB2.Init(m_texInfo.pTexRgb2);
vp_RGB3.Init(m_texInfo.pTexRgb3);
vp_NORM.Init(m_texInfo.pTexNorm);
vp_ALDI.Init(m_texInfo.pTexAldi);
vp_OPAC.Init(m_texInfo.pTexOpac);
}
if (!IsActive() || !m_texInfo.bSvoReady || !GetIntegratioMode())
{
return;
}
// force sync shaders compiling
int nPrevAsync = CRenderer::CV_r_shadersasynccompiling;
CRenderer::CV_r_shadersasynccompiling = 0;
// clear pass
{
PROFILE_LABEL_SCOPE("TI_INJECT_CLEAR");
for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForStaticUpdate.Count(); )
{
ExecuteComputeShader(m_pShader, "ComputeClearBricks", eCS_ClearBricks, &nNodesForUpdateStartIndex, 0, m_nodesForStaticUpdate);
}
}
{
PROFILE_LABEL_SCOPE("TI_INJECT_LIGHT");
for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForStaticUpdate.Count(); )
{
ExecuteComputeShader(m_pShader, "ComputeDirectStaticLighting", eCS_InjectStaticLights, &nNodesForUpdateStartIndex, 0, m_nodesForStaticUpdate);
}
}
if (gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal())
{
if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() > 1)
{
PROFILE_LABEL_SCOPE("TI_INJECT_REFL0");
m_nCurPropagationPassID = 0;
for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForStaticUpdate.Count(); )
{
ExecuteComputeShader(m_pShader, "ComputePropagateLighting", eCS_PropagateLighting_1to2, &nNodesForUpdateStartIndex, 0, m_nodesForStaticUpdate);
}
}
if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() > 2)
{
PROFILE_LABEL_SCOPE("TI_INJECT_REFL1");
m_nCurPropagationPassID++;
for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForStaticUpdate.Count(); )
{
ExecuteComputeShader(m_pShader, "ComputePropagateLighting", eCS_PropagateLighting_2to3, &nNodesForUpdateStartIndex, 0, m_nodesForStaticUpdate);
}
}
}
static int nLightsDynamicCountPrevFrame = 0;
if ((m_arrLightsDynamic.Count() || nLightsDynamicCountPrevFrame))
{
PROFILE_LABEL_SCOPE("TI_INJECT_DYNL");
// TODO: cull not affected nodes
for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForDynamicUpdate.Count(); )
{
ExecuteComputeShader(m_pShader, "ComputeDirectDynamicLighting", eCS_InjectDynamicLights, &nNodesForUpdateStartIndex, 0, m_nodesForDynamicUpdate);
}
}
nLightsDynamicCountPrevFrame = m_arrLightsDynamic.Count();
CRenderer::CV_r_shadersasynccompiling = nPrevAsync;
}
void CSvoRenderer::ExecuteComputeShader(CShader* pSH, const char* szTechFinalName, EComputeStages eRenderStage, int* pnNodesForUpdateStartIndex, [[maybe_unused]] int nObjPassId, PodArray<I3DEngine::SSvoNodeInfo>& arrNodesForUpdate)
{
FUNCTION_PROFILER_RENDERER;
CD3D9Renderer* const __restrict rd = gcpRendD3D;
SetShaderFlags(true, false);
SD3DPostEffectsUtils::ShBeginPass(pSH, szTechFinalName, FEF_DONTSETSTATES);
if (!gRenDev->m_RP.m_pShader)
{
gEnv->pLog->LogWarning("%s: Technique not found: %s", __FUNC__, szTechFinalName);
(*pnNodesForUpdateStartIndex) += 1000;
return;
}
{
static CCryNameR param("SVO_PropagationPass");
Vec4 value((float)(m_nCurPropagationPassID), 0, 0, 0);
m_pShader->FXSetCSFloat(param, (Vec4*)&value, 1);
}
{
static CCryNameR parameterName6("SVO_FrameIdByte");
Vec4 ttt((float)(rd->GetFrameID(false) & 255), (float)rd->GetFrameID(false), 3, 4);
if (rd->GetActiveGPUCount() > 1)
{
ttt.x = 0;
}
m_pShader->FXSetCSFloat(parameterName6, (Vec4*)&ttt, 1);
}
{
static CCryNameR parameterName6("SVO_CamPos");
Vec4 ttt(gEnv->pSystem->GetViewCamera().GetPosition(), 0);
m_pShader->FXSetCSFloat(parameterName6, (Vec4*)&ttt, 1);
}
{
Matrix44A mViewProj;
mViewProj = gcpRendD3D->m_ViewProjMatrix;
mViewProj.Transpose();
static CCryNameR paramName("g_mViewProj");
m_pShader->FXSetCSFloat(paramName, alias_cast<Vec4*>(&mViewProj), 4);
static CCryNameR paramNamePrev("g_mViewProjPrev");
m_pShader->FXSetPSFloat(paramNamePrev, alias_cast<Vec4*>(&m_matViewProjPrev), 4);
}
{
const CameraViewParameters& rc = gcpRendD3D->GetViewParameters();
float zn = rc.fNear;
float zf = rc.fFar;
float hfov = gcpRendD3D->GetCamera().GetHorizontalFov();
Vec4 f;
f[0] = zf / (zf - zn);
f[1] = zn / (zn - zf);
f[2] = 1.0f / hfov;
f[3] = 1.0f;
static CCryNameR paramName("SVO_ProjRatio");
m_pShader->FXSetCSFloat(paramName, alias_cast<Vec4*>(&f), 1);
}
// setup SVO textures
ID3D11DeviceContext* pDeviceCtx = &gcpRendD3D->GetDeviceContext();
UINT UAVInitialCounts = 0;
if (eRenderStage == eCS_InjectStaticLights)
{
SetupLightSources(m_arrLightsStatic, m_pShader, false);
SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate);
// update RGB1
pDeviceCtx->CSSetUnorderedAccessViews(2, 1, &vp_RGB0.pUAV, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB1.pUAV, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_NORM.pUAV, &UAVInitialCounts);
if (vp_DYNL.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &vp_DYNL.pUAV, &UAVInitialCounts);
}
SetupSvoTexturesForRead(m_texInfo, eHWSC_Compute, 0);
SetupRsmSun(eHWSC_Compute);
}
else if (eRenderStage == eCS_InjectDynamicLights)
{
BindTiledLights(m_arrLightsDynamic, eHWSC_Compute);
SetupLightSources(m_arrLightsDynamic, m_pShader, false);
SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate);
// update RGB
pDeviceCtx->CSSetUnorderedAccessViews(2, 1, &vp_RGB0.pUAV, &UAVInitialCounts);
if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() == 1)
{
pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB1.pUAV, &UAVInitialCounts);
}
if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() == 2)
{
pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB2.pUAV, &UAVInitialCounts);
}
if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() == 3)
{
pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB3.pUAV, &UAVInitialCounts);
}
pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_DYNL.pUAV, &UAVInitialCounts);
SetupSvoTexturesForRead(m_texInfo, eHWSC_Compute, 0);
if (!m_pNoiseTex)
{
m_pNoiseTex = CTextureManager::Instance()->GetDefaultTexture("DissolveNoiseMap");
}
m_pNoiseTex->Apply(15, m_nTexStateLinearWrap, -1, -1, -1, eHWSC_Compute);
SetupRsmSun(eHWSC_Compute);
}
else if (eRenderStage == eCS_PropagateLighting_1to2)
{
SetupLightSources(m_arrLightsStatic, m_pShader, false);
SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate);
// update RGB2
if (vp_RGB0.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(0, 1, &vp_RGB0.pUAV, &UAVInitialCounts);
}
SetupSvoTexturesForRead(m_texInfo, eHWSC_Compute, 1); // input
if (vp_RGB2.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_RGB2.pUAV, &UAVInitialCounts);
}
if (vp_ALDI.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &vp_ALDI.pUAV, &UAVInitialCounts);
}
if (vp_DYNL.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_DYNL.pUAV, &UAVInitialCounts);
}
}
else if (eRenderStage == eCS_PropagateLighting_2to3)
{
SetupLightSources(m_arrLightsStatic, m_pShader, false);
SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate);
// update RGB3
if (vp_RGB0.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(0, 1, &vp_RGB0.pUAV, &UAVInitialCounts);
}
SetupSvoTexturesForRead(m_texInfo, eHWSC_Compute, 2); // input
if (vp_RGB3.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_RGB3.pUAV, &UAVInitialCounts);
}
if (vp_ALDI.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &vp_ALDI.pUAV, &UAVInitialCounts);
}
if (vp_DYNL.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_DYNL.pUAV, &UAVInitialCounts);
}
}
else if (eRenderStage == eCS_ClearBricks)
{
SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate);
if (vp_RGB3.pUAV)
{
pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &vp_RGB3.pUAV, &UAVInitialCounts);
}
pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB1.pUAV, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_RGB2.pUAV, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(0, 1, &vp_ALDI.pUAV, &UAVInitialCounts);
}
{
rd->FX_Commit();
uint32 nDispatchSizeX = 128;
uint32 nDispatchSizeY = 16;
#ifdef CINEBOX_APP
pDeviceCtx->Dispatch(nDispatchSizeX, nDispatchSizeY, 1);
#else
rd->m_DevMan.Dispatch(nDispatchSizeX, nDispatchSizeY, 1);
#endif
SD3DPostEffectsUtils::ShEndPass();
}
D3DUnorderedAccessView* pUAVNULL = NULL;
pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &pUAVNULL, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &pUAVNULL, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &pUAVNULL, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(2, 1, &pUAVNULL, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(1, 1, &pUAVNULL, &UAVInitialCounts);
pDeviceCtx->CSSetUnorderedAccessViews(0, 1, &pUAVNULL, &UAVInitialCounts);
CTexture::GetByID(vp_RGB0.nTexId)->Unbind();
CTexture::GetByID(vp_RGB1.nTexId)->Unbind();
CTexture::GetByID(vp_DYNL.nTexId)->Unbind();
CTexture::GetByID(vp_RGB2.nTexId)->Unbind();
CTexture::GetByID(vp_RGB3.nTexId)->Unbind();
CTexture::GetByID(vp_NORM.nTexId)->Unbind();
CTexture::GetByID(vp_ALDI.nTexId)->Unbind();
CTexture::GetByID(vp_OPAC.nTexId)->Unbind();
gcpRendD3D->GetTiledShading().UnbindForwardShadingResources(eHWSC_Compute);
pSH->FXEnd();
}
CTexture* CSvoRenderer::GetGBuffer(int nId) // simplify branch compatibility
{
CTexture* pRes;
if (nId == 0)
{
pRes = CTexture::s_ptexSceneDiffuse;
}
else if (nId == 1)
{
pRes = CTexture::s_ptexSceneNormalsMap;
}
else if (nId == 2)
{
pRes = CTexture::s_ptexSceneSpecular;
}
else
{
pRes = 0;
}
return pRes;
}
void CSvoRenderer::ConeTracePass(SSvoTargetsSet* pTS)
{
CheckAllocateRT(pTS == &m_tsSpec);
if (!IsActive() || !m_pShader)
{
return;
}
const char* szTechFinalName = "ConeTracePass";
if (m_texInfo.bSvoFreeze)
{
return;
}
CD3D9Renderer* const __restrict rd = gcpRendD3D;
rd->FX_PushRenderTarget(0, pTS->pRT_ALD_0, NULL);
rd->FX_PushRenderTarget(1, pTS->pRT_RGB_0, NULL);
if (m_texInfo.pTexTree)
{
SetShaderFlags(pTS == &m_tsDiff);
SD3DPostEffectsUtils::ShBeginPass(m_pShader, szTechFinalName, FEF_DONTSETTEXTURES /*| FEF_DONTSETSTATES*/);
{
Matrix44A matView;
matView = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_cam.GetViewMatrix();
Vec3 zAxis = matView.GetRow(1);
matView.SetRow(1, -matView.GetRow(2));
matView.SetRow(2, zAxis);
float z = matView.m13;
matView.m13 = -matView.m23;
matView.m23 = z;
SetupRsmSun(eHWSC_Pixel);
static int nReprojFrameId = -1;
if ((pTS == &m_tsDiff) && nReprojFrameId != rd->GetFrameID(false))
{
nReprojFrameId = rd->GetFrameID(false);
Matrix44A matProj;
const CCamera& cam = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_cam;
mathMatrixPerspectiveFov(&matProj, cam.GetFov(), cam.GetProjRatio(), cam.GetNearPlane(), cam.GetFarPlane());
static Matrix44A matPrevView = matView;
static Matrix44A matPrevProj = matProj;
rd->GetReprojectionMatrix(m_matReproj, matView, matProj, matPrevView, matPrevProj, cam.GetFarPlane());
matPrevView = matView;
matPrevProj = matProj;
}
{
static CCryNameR parameterName5("SVO_ReprojectionMatrix");
m_pShader->FXSetPSFloat(parameterName5, (Vec4*)m_matReproj.GetData(), 3);
}
{
static CCryNameR parameterName6("SVO_FrameIdByte");
Vec4 ttt((float)(rd->GetFrameID(false) & 255), (float)rd->GetFrameID(false), 3, 4);
if (rd->GetActiveGPUCount() > 1)
{
ttt.x = 0;
}
m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1);
}
{
static CCryNameR parameterName6("SVO_CamPos");
Vec4 ttt(gEnv->pSystem->GetViewCamera().GetPosition(), 0);
m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1);
}
{
Matrix44A mViewProj;
mViewProj = gcpRendD3D->m_ViewProjMatrix;
mViewProj.Transpose();
static CCryNameR paramName("g_mViewProj");
m_pShader->FXSetPSFloat(paramName, alias_cast<Vec4*>(&mViewProj), 4);
static CCryNameR paramNamePrev("g_mViewProjPrev");
m_pShader->FXSetPSFloat(paramNamePrev, alias_cast<Vec4*>(&m_matViewProjPrev), 4);
}
{
float fSizeRatioW = float(rd->GetWidth() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Width);
float fSizeRatioH = float(rd->GetHeight() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Height);
static CCryNameR parameterName6("SVO_TargetResScale");
static int nPrevWidth = 0;
Vec4 ttt(fSizeRatioW, fSizeRatioH, gEnv->pConsole->GetCVar("e_svoTemporalFilteringBase")->GetFVal(),
(float)(nPrevWidth != (pTS->pRT_ALD_0->GetWidth() + 1) || (rd->m_RP.m_nRendFlags & SHDF_CUBEMAPGEN) || (rd->GetActiveGPUCount() > 1)));
m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1);
nPrevWidth = (pTS->pRT_ALD_0->GetWidth() + 1);
}
{
Matrix44A matView2;
matView2 = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_cam.GetViewMatrix();
Vec3 zAxis2 = matView2.GetRow(1);
matView2.SetRow(1, -matView2.GetRow(2));
matView2.SetRow(2, zAxis2);
float z2 = matView2.m13;
matView2.m13 = -matView2.m23;
matView2.m23 = z2;
static CCryNameR paramName2("TI_CameraMatrix");
m_pShader->FXSetPSFloat(paramName2, (Vec4*)matView2.GetData(), 3);
}
{
Vec3 pvViewFrust[8];
const CameraViewParameters& rc = gcpRendD3D->GetViewParameters();
rc.CalcVerts(pvViewFrust);
static CCryNameR parameterName0("SVO_FrustumVerticesCam0");
static CCryNameR parameterName1("SVO_FrustumVerticesCam1");
static CCryNameR parameterName2("SVO_FrustumVerticesCam2");
static CCryNameR parameterName3("SVO_FrustumVerticesCam3");
Vec4 ttt0(pvViewFrust[4] - rc.vOrigin, 0);
Vec4 ttt1(pvViewFrust[5] - rc.vOrigin, 0);
Vec4 ttt2(pvViewFrust[6] - rc.vOrigin, 0);
Vec4 ttt3(pvViewFrust[7] - rc.vOrigin, 0);
m_pShader->FXSetPSFloat(parameterName0, (Vec4*)&ttt0, 1);
m_pShader->FXSetPSFloat(parameterName1, (Vec4*)&ttt1, 1);
m_pShader->FXSetPSFloat(parameterName2, (Vec4*)&ttt2, 1);
m_pShader->FXSetPSFloat(parameterName3, (Vec4*)&ttt3, 1);
}
if (pTS->pRT_ALD_1 && pTS->pRT_ALD_1)
{
static int nPrevWidth = 0;
if (nPrevWidth != (pTS->pRT_ALD_1->GetWidth()))
{
CTextureManager::Instance()->GetWhiteTexture()->Apply(10, m_nTexStateLinear);
CTextureManager::Instance()->GetWhiteTexture()->Apply(11, m_nTexStateLinear);
nPrevWidth = pTS->pRT_ALD_1->GetWidth();
}
else
{
pTS->pRT_ALD_1->Apply(10, m_nTexStateLinear);
pTS->pRT_RGB_1->Apply(11, m_nTexStateLinear);
}
}
}
rd->FX_SetState(GS_NODEPTHTEST);
SetupSvoTexturesForRead(m_texInfo, eHWSC_Pixel, (gEnv->pConsole->GetCVar("e_svoTI_Active")->GetIVal() ? gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() : 0), 0, 0);
CTexture::s_ptexZTarget->Apply(4, m_nTexStatePoint);
{
GetGBuffer(1)->Apply(5, m_nTexStatePoint);
GetGBuffer(2)->Apply(7, m_nTexStatePoint);
GetGBuffer(0)->Apply(14, m_nTexStatePoint);
}
if (!GetIntegratioMode() && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal() && m_arrLightsDynamic.Count())
{
BindTiledLights(m_arrLightsDynamic, eHWSC_Pixel);
SetupLightSources(m_arrLightsDynamic, m_pShader, true);
}
{
const bool setupCloudShadows = rd->m_bShadowsEnabled && rd->m_bCloudShadowsEnabled;
if (setupCloudShadows)
{
// cloud shadow map
CTexture* pCloudShadowTex(rd->GetCloudShadowTextureId() > 0 ? CTexture::GetByID(rd->GetCloudShadowTextureId()) : CTextureManager::Instance()->GetWhiteTexture());
assert(pCloudShadowTex);
STexState pTexStateLinearClamp;
pTexStateLinearClamp.SetFilterMode(FILTER_LINEAR);
pTexStateLinearClamp.SetClampMode(false, false, false);
int nTexStateLinearClampID = CTexture::GetTexState(pTexStateLinearClamp);
pCloudShadowTex->Apply(15, m_nTexStateLinearWrap);
}
else
{
CTextureManager::Instance()->GetWhiteTexture()->Apply(15, m_nTexStateLinearWrap);
}
}
rd->FX_Commit();
SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexCurrentSceneDiffuseAccMap->GetWidth(), CTexture::s_ptexCurrentSceneDiffuseAccMap->GetHeight());
gcpRendD3D->GetTiledShading().UnbindForwardShadingResources(eHWSC_Pixel);
SD3DPostEffectsUtils::ShEndPass();
}
rd->FX_PopRenderTarget(0);
rd->FX_PopRenderTarget(1);
}
void CSvoRenderer::DrawPonts(PodArray<SVF_P3F_C4B_T2F>& arrVerts)
{
SPostEffectsUtils::UpdateFrustumCorners();
CVertexBuffer strip(arrVerts.GetElements(), eVF_P3F_C4B_T2F);
gRenDev->DrawPrimitivesInternal(&strip, arrVerts.Count(), eptPointList);
}
void CSvoRenderer::UpdateRender()
{
int nPrevAsync = CRenderer::CV_r_shadersasynccompiling;
if (gEnv->IsEditor())
{
CRenderer::CV_r_shadersasynccompiling = 0;
}
{
PROFILE_LABEL_SCOPE("TI_GEN_DIFF");
ConeTracePass(&m_tsDiff);
}
if (GetIntegratioMode() == 2)
{
PROFILE_LABEL_SCOPE("TI_GEN_SPEC");
ConeTracePass(&m_tsSpec);
}
{
PROFILE_LABEL_SCOPE("TI_DEMOSAIC_DIFF");
DemosaicPass(&m_tsDiff);
}
if (GetIntegratioMode() == 2)
{
PROFILE_LABEL_SCOPE("TI_DEMOSAIC_SPEC");
DemosaicPass(&m_tsSpec);
}
{
PROFILE_LABEL_SCOPE("TI_UPSCALE_DIFF");
UpScalePass(&m_tsDiff);
}
if (GetIntegratioMode() == 2)
{
PROFILE_LABEL_SCOPE("TI_UPSCALE_SPEC");
UpScalePass(&m_tsSpec);
}
{
m_matViewProjPrev = gcpRendD3D->m_ViewProjMatrix;
m_matViewProjPrev.Transpose();
}
if (gEnv->IsEditor())
{
CRenderer::CV_r_shadersasynccompiling = nPrevAsync;
}
}
void CSvoRenderer::DemosaicPass(SSvoTargetsSet* pTS)
{
const char* szTechFinalName = "DemosaicPass";
if (!IsActive() || !m_pShader)
{
return;
}
if (m_texInfo.bSvoFreeze)
{
return;
}
{ // SVO
if (!pTS->pRT_ALD_0 || !pTS->pRT_ALD_0)
{
return;
}
CD3D9Renderer* const __restrict rd = gcpRendD3D;
rd->FX_PushRenderTarget(0, pTS->pRT_RGB_DEM_MIN_0, NULL, -1, false, 1);
rd->FX_PushRenderTarget(1, pTS->pRT_ALD_DEM_MIN_0, NULL, -1, false, 1);
rd->FX_PushRenderTarget(2, pTS->pRT_RGB_DEM_MAX_0, NULL, -1, false, 1);
rd->FX_PushRenderTarget(3, pTS->pRT_ALD_DEM_MAX_0, NULL, -1, false, 1);
if (m_texInfo.pTexTree)
{
SetShaderFlags(pTS == &m_tsDiff);
SD3DPostEffectsUtils::ShBeginPass(m_pShader, szTechFinalName, FEF_DONTSETTEXTURES);
rd->FX_SetState(GS_NODEPTHTEST);
CTexture::s_ptexZTarget->Apply(4, m_nTexStatePoint);
GetGBuffer(1)->Apply(5, m_nTexStatePoint);
GetGBuffer(2)->Apply(7, m_nTexStatePoint);
GetGBuffer(0)->Apply(14, m_nTexStatePoint);
{
static CCryNameR parameterName5("SVO_ReprojectionMatrix");
m_pShader->FXSetPSFloat(parameterName5, (Vec4*)m_matReproj.GetData(), 3);
}
{
float fSizeRatioW = float(rd->GetWidth() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Width);
float fSizeRatioH = float(rd->GetHeight() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Height);
static CCryNameR parameterName6("SVO_TargetResScale");
static int nPrevWidth = 0;
Vec4 ttt(fSizeRatioW, fSizeRatioH, gEnv->pConsole->GetCVar("e_svoTemporalFilteringBase")->GetFVal(),
(float)(nPrevWidth != (pTS->pRT_ALD_0->GetWidth() + 1) || (rd->m_RP.m_nRendFlags & SHDF_CUBEMAPGEN) || (rd->GetActiveGPUCount() > 1)));
m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1);
nPrevWidth = (pTS->pRT_ALD_0->GetWidth() + 1);
}
{
static CCryNameR parameterName6("SVO_FrameIdByte");
Vec4 ttt((float)(rd->GetFrameID(false) & 255), (float)rd->GetFrameID(false), 3, 4);
if (rd->GetActiveGPUCount() > 1)
{
ttt.x = 0;
}
m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1);
}
{
static CCryNameR parameterName6("SVO_CamPos");
Vec4 ttt(gEnv->pSystem->GetViewCamera().GetPosition(), 0);
m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1);
}
{
Matrix44A mViewProj;
mViewProj = gcpRendD3D->m_ViewProjMatrix;
mViewProj.Transpose();
static CCryNameR paramName("g_mViewProj");
m_pShader->FXSetPSFloat(paramName, alias_cast<Vec4*>(&mViewProj), 4);
static CCryNameR paramNamePrev("g_mViewProjPrev");
m_pShader->FXSetPSFloat(paramNamePrev, alias_cast<Vec4*>(&m_matViewProjPrev), 4);
}
{
Matrix44A matView;
matView = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_cam.GetViewMatrix();
Vec3 zAxis = matView.GetRow(1);
matView.SetRow(1, -matView.GetRow(2));
matView.SetRow(2, zAxis);
float z = matView.m13;
matView.m13 = -matView.m23;
matView.m23 = z;
static CCryNameR paramName2("TI_CameraMatrix");
m_pShader->FXSetPSFloat(paramName2, (Vec4*)matView.GetData(), 3);
}
pTS->pRT_ALD_0->Apply(10, m_nTexStateLinear);
pTS->pRT_RGB_0->Apply(11, m_nTexStateLinear);
pTS->pRT_RGB_DEM_MIN_1->Apply(0, m_nTexStateLinear);
pTS->pRT_ALD_DEM_MIN_1->Apply(1, m_nTexStateLinear);
pTS->pRT_RGB_DEM_MAX_1->Apply(2, m_nTexStateLinear);
pTS->pRT_ALD_DEM_MAX_1->Apply(3, m_nTexStateLinear);
SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexCurrentSceneDiffuseAccMap->GetWidth(), CTexture::s_ptexCurrentSceneDiffuseAccMap->GetHeight());
SD3DPostEffectsUtils::ShEndPass();
}
rd->FX_PopRenderTarget(0);
rd->FX_PopRenderTarget(1);
rd->FX_PopRenderTarget(2);
rd->FX_PopRenderTarget(3);
}
}
void CSvoRenderer::SetupLightSources(PodArray<I3DEngine::SLightTI>& lightsTI, CShader* pShader, bool bPS)
{
const int nLightGroupsNum = 2;
static CCryNameR paramNamesLightPos[nLightGroupsNum] =
{
CCryNameR("SVO_LightPos0"),
CCryNameR("SVO_LightPos1"),
};
static CCryNameR paramNamesLightDir[nLightGroupsNum] =
{
CCryNameR("SVO_LightDir0"),
CCryNameR("SVO_LightDir1"),
};
static CCryNameR paramNamesLightCol[nLightGroupsNum] =
{
CCryNameR("SVO_LightCol0"),
CCryNameR("SVO_LightCol1"),
};
for (int g = 0; g < nLightGroupsNum; g++)
{
Vec4 LightPos[4];
Vec4 LightDir[4];
Vec4 LightCol[4];
for (int x = 0; x < 4; x++)
{
int nId = g * 4 + x;
LightPos[x] = (nId < lightsTI.Count()) ? lightsTI[nId].vPosR : Vec4(0, 0, 0, 0);
LightDir[x] = (nId < lightsTI.Count()) ? lightsTI[nId].vDirF : Vec4(0, 0, 0, 0);
LightCol[x] = (nId < lightsTI.Count()) ? lightsTI[nId].vCol : Vec4(0, 0, 0, 0);
}
if (bPS)
{
pShader->FXSetPSFloat(paramNamesLightPos[g], alias_cast<Vec4*>(&LightPos[0][0]), 4);
pShader->FXSetPSFloat(paramNamesLightDir[g], alias_cast<Vec4*>(&LightDir[0][0]), 4);
pShader->FXSetPSFloat(paramNamesLightCol[g], alias_cast<Vec4*>(&LightCol[0][0]), 4);
}
else
{ // CS
pShader->FXSetCSFloat(paramNamesLightPos[g], alias_cast<Vec4*>(&LightPos[0][0]), 4);
pShader->FXSetCSFloat(paramNamesLightDir[g], alias_cast<Vec4*>(&LightDir[0][0]), 4);
pShader->FXSetCSFloat(paramNamesLightCol[g], alias_cast<Vec4*>(&LightCol[0][0]), 4);
}
}
}
void CSvoRenderer::SetupNodesForUpdate(int& nNodesForUpdateStartIndex, PodArray<I3DEngine::SSvoNodeInfo>& arrNodesForUpdate)
{
static CCryNameR paramNames[SVO_MAX_NODE_GROUPS] =
{
CCryNameR("SVO_NodesForUpdate0"),
CCryNameR("SVO_NodesForUpdate1"),
CCryNameR("SVO_NodesForUpdate2"),
CCryNameR("SVO_NodesForUpdate3"),
};
for (int g = 0; g < SVO_MAX_NODE_GROUPS; g++)
{
float matVal[4][4];
for (int x = 0; x < 4; x++)
{
for (int y = 0; y < 4; y++)
{
int nId = nNodesForUpdateStartIndex + g * 16 + x * 4 + y;
matVal[x][y] = 0.1f + ((nId < arrNodesForUpdate.Count()) ? arrNodesForUpdate[nId].nAtlasOffset : -2);
if (nId < arrNodesForUpdate.Count())
{
float fNodeSize = arrNodesForUpdate[nId].wsBox.GetSize().x;
}
}
}
m_pShader->FXSetCSFloat(paramNames[g], alias_cast<Vec4*>(&matVal[0][0]), 4);
}
nNodesForUpdateStartIndex += 4 * 4 * SVO_MAX_NODE_GROUPS; // 128
}
void CSvoRenderer::SetupSvoTexturesForRead(I3DEngine::SSvoStaticTexInfo& texInfo, EHWShaderClass eShaderClass, int nStage, int nStageOpa, int nStageNorm)
{
((CTexture*)texInfo.pTexTree)->Apply(0, m_nTexStatePoint, -1, -1, -1, eShaderClass);
CTextureManager::Instance()->GetBlackTexture()->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass);
if (nStage == 0)
{
CTexture::GetByID(vp_RGB0.nTexId)->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass);
}
else if (nStage == 1)
{
CTexture::GetByID(vp_RGB1.nTexId)->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass);
}
else if (nStage == 2)
{
CTexture::GetByID(vp_RGB2.nTexId)->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass);
}
else if (nStage == 3)
{
CTexture::GetByID(vp_RGB3.nTexId)->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass);
}
if (nStageNorm == 0)
{
CTexture::GetByID(vp_NORM.nTexId)->Apply(2, m_nTexStateLinear, -1, -1, -1, eShaderClass);
}
if (nStageOpa == 0)
{
((CTexture*)texInfo.pTexOpac)->Apply(3, m_nTexStateLinear, -1, -1, -1, eShaderClass);
}
if (texInfo.pGlobalSpecCM)
{
((CTexture*)texInfo.pGlobalSpecCM)->Apply(6, m_nTexStateTrilinear, -1, -1, -1, eShaderClass);
}
}
void CSvoRenderer::CheckAllocateRT(bool bSpecPass)
{
int nWidth = gcpRendD3D->GetWidth();
int nHeight = gcpRendD3D->GetHeight();
int nResScaleBase = 2;
int nInW = (nWidth / nResScaleBase);
int nInH = (nHeight / nResScaleBase);
if (!bSpecPass)
{
CheckCreateUpdateRT(m_tsDiff.pRT_ALD_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_ALD");
CheckCreateUpdateRT(m_tsDiff.pRT_ALD_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_ALD");
CheckCreateUpdateRT(m_tsDiff.pRT_RGB_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_RGB");
CheckCreateUpdateRT(m_tsDiff.pRT_RGB_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_RGB");
CheckCreateUpdateRT(m_tsSpec.pRT_ALD_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_ALD");
CheckCreateUpdateRT(m_tsSpec.pRT_ALD_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_ALD");
CheckCreateUpdateRT(m_tsSpec.pRT_RGB_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_RGB");
CheckCreateUpdateRT(m_tsSpec.pRT_RGB_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_RGB");
CheckCreateUpdateRT(m_tsDiff.pRT_RGB_DEM_MIN_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_FIN_RGB_MIN");
CheckCreateUpdateRT(m_tsDiff.pRT_ALD_DEM_MIN_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_FIN_ALD_MIN");
CheckCreateUpdateRT(m_tsDiff.pRT_RGB_DEM_MAX_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_FIN_RGB_MAX");
CheckCreateUpdateRT(m_tsDiff.pRT_ALD_DEM_MAX_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_FIN_ALD_MAX");
CheckCreateUpdateRT(m_tsDiff.pRT_RGB_DEM_MIN_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_FIN_RGB_MIN");
CheckCreateUpdateRT(m_tsDiff.pRT_ALD_DEM_MIN_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_FIN_ALD_MIN");
CheckCreateUpdateRT(m_tsDiff.pRT_RGB_DEM_MAX_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_FIN_RGB_MAX");
CheckCreateUpdateRT(m_tsDiff.pRT_ALD_DEM_MAX_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_FIN_ALD_MAX");
CheckCreateUpdateRT(m_tsDiff.pRT_FIN_OUT_0, nWidth, nHeight, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_FIN_DIFF_OUT");
CheckCreateUpdateRT(m_tsDiff.pRT_FIN_OUT_1, nWidth, nHeight, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_FIN_DIFF_OUT");
CheckCreateUpdateRT(m_tsSpec.pRT_RGB_DEM_MIN_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_FIN_RGB_MIN");
CheckCreateUpdateRT(m_tsSpec.pRT_ALD_DEM_MIN_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_FIN_ALD_MIN");
CheckCreateUpdateRT(m_tsSpec.pRT_RGB_DEM_MAX_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_FIN_RGB_MAX");
CheckCreateUpdateRT(m_tsSpec.pRT_ALD_DEM_MAX_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_FIN_ALD_MAX");
CheckCreateUpdateRT(m_tsSpec.pRT_RGB_DEM_MIN_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_FIN_RGB_MIN");
CheckCreateUpdateRT(m_tsSpec.pRT_ALD_DEM_MIN_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_FIN_ALD_MIN");
CheckCreateUpdateRT(m_tsSpec.pRT_RGB_DEM_MAX_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_FIN_RGB_MAX");
CheckCreateUpdateRT(m_tsSpec.pRT_ALD_DEM_MAX_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_FIN_ALD_MAX");
CheckCreateUpdateRT(m_tsSpec.pRT_FIN_OUT_0, nWidth, nHeight, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_FIN_SPEC_OUT");
CheckCreateUpdateRT(m_tsSpec.pRT_FIN_OUT_1, nWidth, nHeight, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_FIN_SPEC_OUT");
// swap ping-pong RT
std::swap(m_tsDiff.pRT_ALD_0, m_tsDiff.pRT_ALD_1);
std::swap(m_tsDiff.pRT_RGB_0, m_tsDiff.pRT_RGB_1);
std::swap(m_tsDiff.pRT_RGB_DEM_MIN_0, m_tsDiff.pRT_RGB_DEM_MIN_1);
std::swap(m_tsDiff.pRT_ALD_DEM_MIN_0, m_tsDiff.pRT_ALD_DEM_MIN_1);
std::swap(m_tsDiff.pRT_RGB_DEM_MAX_0, m_tsDiff.pRT_RGB_DEM_MAX_1);
std::swap(m_tsDiff.pRT_ALD_DEM_MAX_0, m_tsDiff.pRT_ALD_DEM_MAX_1);
std::swap(m_tsDiff.pRT_FIN_OUT_0, m_tsDiff.pRT_FIN_OUT_1);
std::swap(m_tsSpec.pRT_ALD_0, m_tsSpec.pRT_ALD_1);
std::swap(m_tsSpec.pRT_RGB_0, m_tsSpec.pRT_RGB_1);
std::swap(m_tsSpec.pRT_RGB_DEM_MIN_0, m_tsSpec.pRT_RGB_DEM_MIN_1);
std::swap(m_tsSpec.pRT_ALD_DEM_MIN_0, m_tsSpec.pRT_ALD_DEM_MIN_1);
std::swap(m_tsSpec.pRT_RGB_DEM_MAX_0, m_tsSpec.pRT_RGB_DEM_MAX_1);
std::swap(m_tsSpec.pRT_ALD_DEM_MAX_0, m_tsSpec.pRT_ALD_DEM_MAX_1);
std::swap(m_tsSpec.pRT_FIN_OUT_0, m_tsSpec.pRT_FIN_OUT_1);
}
}
bool CSvoRenderer::IsShaderItemUsedForVoxelization(SShaderItem& rShaderItem, [[maybe_unused]] IRenderNode* pRN)
{
CShader* pS = (CShader*)rShaderItem.m_pShader;
CShaderResources* pR = (CShaderResources*)rShaderItem.m_pShaderResources;
// skip some objects marked by level designer
// if(pRN && pRN->IsRenderNode() && pRN->GetIntegrationType())
// return false;
// skip transparent meshes except decals
// if((pR->Opacity() != 1.f) && !(pS->GetFlags()&EF_DECAL))
// return false;
// skip windows
if (pS && pS->GetShaderType() == eST_Glass)
{
return false;
}
// skip water
if (pS && pS->GetShaderType() == eST_Water)
{
return false;
}
return true;
}
namespace
{
const float ACTIVATION_MODE_DISABLED = -1.0f;
float GetActivationModeAsFloat()
{
auto* instance = CSvoRenderer::GetInstance();
float modeAsFloat = ACTIVATION_MODE_DISABLED;
int32 modeAsInt = instance->GetIntegratioMode();
if (instance->IsActive())
{
if (modeAsInt == 0 && gEnv->pConsole->GetCVar("e_svoTI_UseLightProbes")->GetIVal())
{ // AO modulates diffuse and specular
modeAsFloat = 0.0f;
}
else if (modeAsInt <= 1)
{ // GI replaces diffuse and modulates specular
modeAsFloat = 1.0f;
}
else if (modeAsInt == 2)
{ // GI replaces diffuse and specular
modeAsFloat = 2.0f;
}
}
return modeAsFloat;
}
}
void CSvoRenderer::UpdatePassConstantBuffer()
{
CSvoRenderer* svoRenderer = CSvoRenderer::GetInstance();
CTypedConstantBuffer<HLSL_PerPassConstantBuffer_Svo> cb(m_PassConstantBuffer);
// SvoParams4 is used by forward tiled shaders even if GI is disabled, it contains info about GI mode and also is GI active or not
cb->PerPass_SvoParams4 = Vec4(0.0f, -1.0f, 0.0f, 0.0f);
if (svoRenderer)
{
AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero());
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb);
const float terrainSizeX = terrainAabb.GetXExtent();
cb->PerPass_SvoTreeSettings0 = Vec4(
(float)terrainSizeX,
gEnv->pConsole->GetCVar("e_svoMinNodeSize")->GetFVal(),
(float)svoRenderer->m_texInfo.nBrickSize,
128.f);
cb->PerPass_SvoTreeSettings1 = Vec4(
gEnv->pConsole->GetCVar("e_svoMaxNodeSize")->GetFVal(),
0.0f,
0.0f,
0.0f);
cb->PerPass_SvoParams0 = Vec4(
1.0f,
0.0f,
0.0f,
0.0f);
cb->PerPass_SvoParams1 = Vec4(
1.f / (gEnv->pConsole->GetCVar("e_svoTI_DiffuseConeWidth")->GetFVal() + 0.00001f),
gEnv->pConsole->GetCVar("e_svoTI_ConeMaxLength")->GetFVal(),
0.0f,
(svoRenderer->m_texInfo.bSvoReady && gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal()) ? 1.0f : 0.0f);
cb->PerPass_SvoParams2 = Vec4(
gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal(),
0.0f,
gEnv->pConsole->GetCVar("e_svoTI_Saturation")->GetFVal(),
0.0f);
cb->PerPass_SvoParams3 = Vec4(
1.0f,
0.0f,
0.0f,
(svoRenderer->m_texInfo.bSvoReady && gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal()) ? 1.0f : 0.0f);
{
cb->PerPass_SvoParams4.x = gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetRed")->GetFVal();
cb->PerPass_SvoParams4.y = gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetGreen")->GetFVal();
cb->PerPass_SvoParams4.z = gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetBlue")->GetFVal();
cb->PerPass_SvoParams4.w = gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetBias")->GetFVal();
}
cb->PerPass_SvoParams5 = Vec4(
0.0f,
0.0f,
gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetFVal() - 1.f,
svoRenderer->m_texInfo.fGlobalSpecCM_Mult);
cb->PerPass_SvoParams6 = Vec4(
1.0f,
gEnv->IsEditing() ? 0 : (gEnv->pConsole->GetCVar("e_svoTemporalFilteringMinDistance")->GetFVal() / gcpRendD3D->GetViewParameters().fFar),
0.0f,
0.0f);
}
m_PassConstantBuffer = cb.GetDeviceConstantBuffer();
cb.CopyToDevice();
auto& devManager = gcpRendD3D->m_DevMan;
devManager.BindConstantBuffer(eHWSC_Compute, m_PassConstantBuffer.get(), eConstantBufferShaderSlot_PerPass);
devManager.BindConstantBuffer(eHWSC_Pixel, m_PassConstantBuffer.get(), eConstantBufferShaderSlot_PerPass);
}
Vec4 CSvoRenderer::GetDisabledPerFrameShaderParameters()
{
Vec4 params;
params.x = 0.0f;
params.y = ACTIVATION_MODE_DISABLED;
params.z = 0.0f;
params.z = 0.0f;
return params;
}
Vec4 CSvoRenderer::GetPerFrameShaderParameters() const
{
Vec4 params;
params.x = 1.f;
params.y = GetActivationModeAsFloat();
params.z = 0.0f;
params.w = 0.0f;
return params;
}
void CSvoRenderer::DebugDrawStats(const RPProfilerStats* pBasicStats, float& ypos, const float ystep, float xposms)
{
ColorF color = Col_Yellow;
const EDrawTextFlags txtFlags = (EDrawTextFlags)(eDrawText_2D | eDrawText_800x600 | eDrawText_FixedSize | eDrawText_Monospace);
#define SVO_Draw2dLabel(labelName) \
gRenDev->Draw2dLabel(60, ypos += ystep, 2, &color.r, false, (const char*)(((const char*)(#labelName)) + 10)); \
if (pBasicStats[labelName].gpuTimeMax > 0.01) { \
gRenDev->Draw2dLabelEx(xposms, ypos, 2, color, txtFlags, "%5.2f Aver=%5.2f Max=%5.2f", \
pBasicStats[labelName].gpuTime, pBasicStats[labelName].gpuTimeSmoothed, pBasicStats[labelName].gpuTimeMax); } \
else{ \
gRenDev->Draw2dLabelEx(xposms, ypos, 2, color, txtFlags, "%5.2f", pBasicStats[labelName].gpuTime); } \
SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_CLEAR);
SVO_Draw2dLabel(eRPPSTATS_TI_VOXELIZE);
SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_AIR);
SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_LIGHT);
SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_REFL0);
SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_REFL1);
SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_DYNL);
SVO_Draw2dLabel(eRPPSTATS_TI_NID_DIFF);
SVO_Draw2dLabel(eRPPSTATS_TI_GEN_DIFF);
SVO_Draw2dLabel(eRPPSTATS_TI_GEN_SPEC);
SVO_Draw2dLabel(eRPPSTATS_TI_GEN_AIR);
SVO_Draw2dLabel(eRPPSTATS_TI_DEMOSAIC_DIFF);
SVO_Draw2dLabel(eRPPSTATS_TI_DEMOSAIC_SPEC);
SVO_Draw2dLabel(eRPPSTATS_TI_UPSCALE_DIFF);
SVO_Draw2dLabel(eRPPSTATS_TI_UPSCALE_SPEC);
}
void CSvoRenderer::SetShaderFlags(bool bDiffuseMode, bool bPixelShader)
{
{
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0];
}
if (m_texInfo.pGlobalSpecCM && GetIntegratioMode()) // use global env CM
{
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1];
}
else
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE1];
{
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE2];
}
{
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE3];
}
if (bDiffuseMode) // diffuse or specular rendering
{
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4];
}
else
{
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE4];
}
if (GetIntegratioMode()) // ignore colors and normals for AO only mode
{
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5];
}
else
{
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE5];
}
{
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_HW_PCF_COMPARE];
}
if (bPixelShader && !GetIntegratioMode() && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal()) // read sun light and shadow map during final cone tracing
{
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ];
}
else
{
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ];
}
if (bPixelShader && !GetIntegratioMode() && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal() && m_arrLightsDynamic.Count()) // read sun light and shadow map during final cone tracing
{
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_POINT_LIGHT];
}
else
{
gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_POINT_LIGHT];
}
}
int CSvoRenderer::GetIntegratioMode()
{
return gEnv->pConsole->GetCVar("e_svoTI_IntegrationMode")->GetIVal();
}
bool CSvoRenderer::IsActive()
{
static ICVar* e_GI = gEnv->pConsole->GetCVar("e_GI");
static ICVar* e_svoTI_Active = gEnv->pConsole->GetCVar("e_svoTi_Active");
//Unable to find cvars, clearly can't be active.
if (!e_GI || !e_svoTI_Active)
{
return false;
}
return e_GI->GetIVal() && CSvoRenderer::s_pInstance && e_svoTI_Active->GetIVal();
}
bool CSvoRenderer::SetSamplers(int nCustomID, EHWShaderClass eSHClass, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit)
{
CSvoRenderer* pSR = CSvoRenderer::GetInstance();
if (!pSR)
{
return false;
}
switch (nCustomID)
{
case TO_SVOTREE:
case TO_SVOTRIS:
case TO_SVOGLCM:
case TO_SVORGBS:
case TO_SVONORM:
case TO_SVOOPAC:
{
CTexture* pTex = CTextureManager::Instance()->GetBlackTexture();
if (pSR->m_texInfo.pTexTree)
{
if (nCustomID == TO_SVOTREE)
{
nCustomID = pSR->m_texInfo.pTexTree->GetTextureID();
}
if (nCustomID == TO_SVORGBS)
{
if (pSR->m_texInfo.pTexRgb0)
{
nCustomID = pSR->m_texInfo.pTexRgb0->GetTextureID();
}
}
if (nCustomID == TO_SVONORM)
{
nCustomID = pSR->m_texInfo.pTexNorm->GetTextureID();
}
if (nCustomID == TO_SVOOPAC)
{
nCustomID = pSR->m_texInfo.pTexOpac->GetTextureID();
}
if (nCustomID > 0)
{
pTex = CTexture::GetByID(nCustomID);
}
}
pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, -1, eSHClass);
return true;
}
}
return false;
}
CTexture* CSvoRenderer::GetDiffuseFinRT()
{
return m_tsDiff.pRT_FIN_OUT_0;
}
CTexture* CSvoRenderer::GetSpecularFinRT()
{
return m_tsSpec.pRT_FIN_OUT_0;
}
void CSvoRenderer::UpScalePass(SSvoTargetsSet* pTS)
{
const char* szTechFinalName = "UpScalePass";
if (!IsActive() || !m_pShader)
{
return;
}
CD3D9Renderer* const __restrict rd = gcpRendD3D;
rd->FX_PushRenderTarget(0, pTS->pRT_FIN_OUT_0, NULL, -1, false, 1);
SetShaderFlags(pTS == &m_tsDiff);
SD3DPostEffectsUtils::ShBeginPass(m_pShader, szTechFinalName, FEF_DONTSETTEXTURES);
if (!gRenDev->m_RP.m_pShader)
{
gEnv->pLog->LogWarning("Error: %s: Technique not found: %s", __FUNC__, szTechFinalName);
rd->FX_PopRenderTarget(0);
return;
}
CTexture::s_ptexZTarget->Apply(4, m_nTexStatePoint);
GetGBuffer(1)->Apply(5, m_nTexStatePoint);
GetGBuffer(2)->Apply(7, m_nTexStatePoint);
GetGBuffer(0)->Apply(14, m_nTexStatePoint);
pTS->pRT_ALD_DEM_MIN_0->Apply(10, m_nTexStatePoint);
pTS->pRT_RGB_DEM_MIN_0->Apply(11, m_nTexStatePoint);
pTS->pRT_ALD_DEM_MAX_0->Apply(12, m_nTexStatePoint);
pTS->pRT_RGB_DEM_MAX_0->Apply(13, m_nTexStatePoint);
pTS->pRT_FIN_OUT_1->Apply(9, m_nTexStatePoint);
if (pTS == &m_tsSpec && m_tsDiff.pRT_FIN_OUT_0)
{
m_tsDiff.pRT_FIN_OUT_0->Apply(15, m_nTexStatePoint);
}
else
{
CTextureManager::Instance()->GetBlackTexture()->Apply(15, m_nTexStatePoint);
}
{
static CCryNameR parameterName6("SVO_SrcPixSize");
Vec4 ttt(0, 0, 0, 0);
ttt.x = 1.f / float(pTS->pRT_ALD_DEM_MIN_0->GetWidth());
ttt.y = 1.f / float(pTS->pRT_ALD_DEM_MIN_0->GetHeight());
m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1);
}
{
static CCryNameR parameterName5("SVO_ReprojectionMatrix");
m_pShader->FXSetPSFloat(parameterName5, (Vec4*)m_matReproj.GetData(), 3);
}
{
float fSizeRatioW = float(rd->GetWidth() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Width);
float fSizeRatioH = float(rd->GetHeight() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Height);
static CCryNameR parameterName6("SVO_TargetResScale");
static int nPrevWidth = 0;
Vec4 ttt(fSizeRatioW, fSizeRatioH, gEnv->pConsole->GetCVar("e_svoTemporalFilteringBase")->GetFVal(),
(float)(nPrevWidth != (pTS->pRT_ALD_0->GetWidth() + 1) || (rd->m_RP.m_nRendFlags & SHDF_CUBEMAPGEN) || (rd->GetActiveGPUCount() > 1)));
m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1);
nPrevWidth = (pTS->pRT_ALD_0->GetWidth() + 1);
}
{
Matrix44A mViewProj;
mViewProj = gcpRendD3D->m_ViewProjMatrix;
mViewProj.Transpose();
static CCryNameR paramName("g_mViewProj");
m_pShader->FXSetPSFloat(paramName, alias_cast<Vec4*>(&mViewProj), 4);
static CCryNameR paramNamePrev("g_mViewProjPrev");
m_pShader->FXSetPSFloat(paramNamePrev, alias_cast<Vec4*>(&m_matViewProjPrev), 4);
}
SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexCurrentSceneDiffuseAccMap->GetWidth(), CTexture::s_ptexCurrentSceneDiffuseAccMap->GetHeight());
SD3DPostEffectsUtils::ShEndPass();
rd->FX_PopRenderTarget(0);
}
void CSvoRenderer::SetupRsmSun(const EHWShaderClass eShClass)
{
CD3D9Renderer* const __restrict rd = gcpRendD3D;
int nLightID = 0;
threadID m_nThreadID = gcpRendD3D->m_RP.m_nProcessThreadID;
int m_nRecurseLevel = SRendItem::m_RecurseLevel[m_nThreadID];
int nDLights = rd->m_RP.m_DLights[m_nThreadID][m_nRecurseLevel].Num();
int nFrustumIdx = nLightID;// + nDLights;
int nStartIdx = SRendItem::m_StartFrust[m_nThreadID][nFrustumIdx];
int nEndIdx = SRendItem::m_EndFrust[m_nThreadID][nFrustumIdx];
static CCryNameR lightProjParamName("SVO_RsmSunShadowProj");
static CCryNameR rsmSunColParameterName("SVO_RsmSunCol");
static CCryNameR rsmSunDirParameterName("SVO_RsmSunDir");
Matrix44A shadowMat;
shadowMat.SetIdentity();
int nFrIdx = 0;
for (nFrIdx = nStartIdx; nFrIdx < nEndIdx; nFrIdx++)
{
ShadowMapFrustum& firstFrustum = rd->m_RP.m_SMFrustums[m_nThreadID][m_nRecurseLevel][nFrIdx];
if (firstFrustum.nShadowMapLod == 2)
{
break;
}
}
if ((nEndIdx > nFrIdx) && GetRsmColorMap(rd->m_RP.m_SMFrustums[m_nThreadID][m_nRecurseLevel][nFrIdx]))
{
ShadowMapFrustum& firstFrustum = rd->m_RP.m_SMFrustums[m_nThreadID][m_nRecurseLevel][nFrIdx];
rd->ConfigShadowTexgen(0, &firstFrustum, 0);
if (firstFrustum.bUseShadowsPool)
{
STexState TS;
TS.SetFilterMode(FILTER_POINT);
TS.SetClampMode(TADDR_CLAMP, TADDR_CLAMP, TADDR_CLAMP);
TS.m_bSRGBLookup = false;
CTexture::s_ptexRT_ShadowPool->Apply(12, CTexture::GetTexState(TS), EFTT_UNKNOWN, -1, -1, eShClass);
}
else
{
firstFrustum.pDepthTex->Apply(12, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass);
GetRsmColorMap(firstFrustum)->Apply(13, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass);
GetRsmNormlMap(firstFrustum)->Apply(9, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass);
}
// set up shadow matrix
shadowMat = gRenDev->m_TempMatrices[0][0];
const Vec4 vEye(gRenDev->GetViewParameters().vOrigin, 0.f);
Vec4 vecTranslation(vEye.Dot((Vec4&)shadowMat.m00), vEye.Dot((Vec4&)shadowMat.m10), vEye.Dot((Vec4&)shadowMat.m20), vEye.Dot((Vec4&)shadowMat.m30));
shadowMat.m03 += vecTranslation.x;
shadowMat.m13 += vecTranslation.y;
shadowMat.m23 += vecTranslation.z;
shadowMat.m33 += vecTranslation.w;
(Vec4&)shadowMat.m20 *= gRenDev->m_cEF.m_TempVecs[2].x;
SetShaderFloat(eShClass, lightProjParamName, alias_cast<Vec4*>(&shadowMat), 4);
Vec4 ttt(gEnv->p3DEngine->GetSunColor(), gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal());
SetShaderFloat(eShClass, rsmSunColParameterName, (Vec4*)&ttt, 1);
Vec4 ttt2(gEnv->p3DEngine->GetSunDirNormalized(), 0);
SetShaderFloat(eShClass, rsmSunDirParameterName, (Vec4*)&ttt2, 1);
}
else
{
CTextureManager::Instance()->GetBlackTexture()->Apply(12, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass);
CTextureManager::Instance()->GetBlackTexture()->Apply(13, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass);
CTextureManager::Instance()->GetBlackTexture()->Apply(9, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass);
SetShaderFloat(eShClass, lightProjParamName, alias_cast<Vec4*>(&shadowMat), 4);
Vec4 ttt(0, 0, 0, 0);
SetShaderFloat(eShClass, rsmSunColParameterName, (Vec4*)&ttt, 1);
Vec4 ttt2(0, 0, 0, 0);
SetShaderFloat(eShClass, rsmSunDirParameterName, (Vec4*)&ttt2, 1);
}
}
ISvoRenderer* CD3D9Renderer::GetISvoRenderer()
{
return CSvoRenderer::GetInstance(true);
}
void CSvoRenderer::SetShaderFloat(const EHWShaderClass eShClass, const CCryNameR& NameParam, const Vec4* fParams, int nParams)
{
if (eShClass == eHWSC_Pixel)
{
m_pShader->FXSetPSFloat(NameParam, fParams, nParams);
}
else if (eShClass == eHWSC_Compute)
{
m_pShader->FXSetCSFloat(NameParam, fParams, nParams);
}
else if (eShClass == eHWSC_Vertex)
{
m_pShader->FXSetVSFloat(NameParam, fParams, nParams);
}
}
void CSvoRenderer::BindTiledLights(PodArray<I3DEngine::SLightTI>& lightsTI, EHWShaderClass shaderType)
{
gcpRendD3D->GetTiledShading().BindForwardShadingResources(NULL, shaderType);
STiledLightShadeInfo* tiledLightShadeInfo = gcpRendD3D->GetTiledShading().GetTiledLightShadeInfo();
for (int l = 0; l < lightsTI.Count(); l++)
{
I3DEngine::SLightTI& svoLight = lightsTI[l];
if (!svoLight.vDirF.w)
{
continue;
}
const int tlTypeRegularProjector = 6;
Vec4 worldViewPos = Vec4(gcpRendD3D->GetViewParameters().vOrigin, 0);
for (uint32 lightIdx = 0; lightIdx <= 255 && tiledLightShadeInfo[lightIdx].posRad != Vec4(0, 0, 0, 0); ++lightIdx)
{
if ((tiledLightShadeInfo[lightIdx].lightType == tlTypeRegularProjector) && svoLight.vPosR.IsEquivalent(tiledLightShadeInfo[lightIdx].posRad + worldViewPos, .5f))
{
if (svoLight.vCol.w > 0)
{
svoLight.vCol.w = ((float)lightIdx + 100);
}
else
{
svoLight.vCol.w = -((float)lightIdx + 100);
}
}
}
}
}
CTexture* CSvoRenderer::GetRsmColorMap(ShadowMapFrustum& rFr, bool bCheckUpdate)
{
if (IsActive() && (rFr.nShadowMapLod == 2) && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal())
{
if (bCheckUpdate)
{
CSvoRenderer::GetInstance()->CheckCreateUpdateRT(CSvoRenderer::GetInstance()->m_pRsmColorMap, rFr.nShadowMapSize, rFr.nShadowMapSize, eTF_R8G8B8A8, eTT_2D, FT_STATE_CLAMP, "SVO_SUN_RSM_COLOR");
}
return CSvoRenderer::GetInstance()->m_pRsmColorMap;
}
if (IsActive() && rFr.bUseShadowsPool && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal() && rFr.m_Flags & DLF_USE_FOR_SVOGI)
{
if (bCheckUpdate)
{
CSvoRenderer::GetInstance()->CheckCreateUpdateRT(CSvoRenderer::GetInstance()->m_pRsmPoolCol, gcpRendD3D->m_nShadowPoolWidth, gcpRendD3D->m_nShadowPoolHeight, eTF_R8G8B8A8, eTT_2D, FT_STATE_CLAMP, "SVO_PRJ_RSM_COLOR");
}
return CSvoRenderer::GetInstance()->m_pRsmPoolCol;
}
return NULL;
}
CTexture* CSvoRenderer::GetRsmNormlMap(ShadowMapFrustum& rFr, bool bCheckUpdate)
{
if (IsActive() && (rFr.nShadowMapLod == 2) && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal())
{
if (bCheckUpdate)
{
CSvoRenderer::GetInstance()->CheckCreateUpdateRT(CSvoRenderer::GetInstance()->m_pRsmNormlMap, rFr.nShadowMapSize, rFr.nShadowMapSize, eTF_R8G8B8A8, eTT_2D, FT_STATE_CLAMP, "SVO_SUN_RSM_NORMAL");
}
return CSvoRenderer::GetInstance()->m_pRsmNormlMap;
}
if (IsActive() && rFr.bUseShadowsPool && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal() && rFr.m_Flags & DLF_USE_FOR_SVOGI)
{
if (bCheckUpdate)
{
CSvoRenderer::GetInstance()->CheckCreateUpdateRT(CSvoRenderer::GetInstance()->m_pRsmPoolNor, gcpRendD3D->m_nShadowPoolWidth, gcpRendD3D->m_nShadowPoolHeight, eTF_R8G8B8A8, eTT_2D, FT_STATE_CLAMP, "SVO_PRJ_RSM_NORMAL");
}
return CSvoRenderer::GetInstance()->m_pRsmPoolNor;
}
return NULL;
}
void CSvoRenderer::CheckCreateUpdateRT(CTexture*& pTex, int nWidth, int nHeight, ETEX_Format eTF, [[maybe_unused]] ETEX_Type eTT, [[maybe_unused]] int nTexFlags, const char* szName)
{
if ((!pTex) || (pTex->GetWidth() != nWidth) || (pTex->GetHeight() != nHeight) || (pTex->GetTextureDstFormat() != eTF))
{
SAFE_RELEASE(pTex);
char szNameEx[256] = "";
sprintf_s(szNameEx, "%s_%d_%d", szName, nWidth, nHeight); // workaround for RT management bug
SD3DPostEffectsUtils::CreateRenderTarget(szNameEx, pTex, nWidth, nHeight, Clr_Unknown, false, false, eTF);
//iLog->Log("Realloc RT %dx%d, %s, %s", nWidth, nHeight, CTexture::NameForTextureFormat(eTF), szName);
}
}
void CSvoRenderer::SVoxPool::Init(ITexture* _pTex)
{
CTexture* pTex = (CTexture*)_pTex;
if (pTex)
{
pUAV = (D3DUnorderedAccessView*)((CTexture*)pTex)->GetDeviceUAV();
nTexId = pTex->GetTextureID();
}
}
#endif