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/GraphicsPipeline/ScreenSpaceReflections.cpp

195 lines
7.9 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"
#include "ScreenSpaceReflections.h"
#include "DriverD3D.h"
#include "D3DPostProcess.h"
#include "../../Common/ReverseDepth.h"
void CScreenSpaceReflectionsPass::Init()
{
}
void CScreenSpaceReflectionsPass::Shutdown()
{
}
void CScreenSpaceReflectionsPass::Reset()
{
m_passRaytracing.Reset();
m_passComposition.Reset();
m_passCopy.Reset();
m_passDownsample0.Reset();
m_passDownsample1.Reset();
m_passDownsample2.Reset();
m_passBlur0.Reset();
m_passBlur1.Reset();
m_passBlur2.Reset();
}
void CScreenSpaceReflectionsPass::Execute()
{
CD3D9Renderer* const __restrict rd = gcpRendD3D;
if (!CRenderer::CV_r_SSReflections || !CTexture::s_ptexHDRTarget) // Sketch mode disables HDR rendering
{
return;
}
PROFILE_LABEL_SCOPE("SS_REFLECTIONS");
if (CRenderer::CV_r_SlimGBuffer)
{
rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER];
}
// Store current state
const uint32 prevPersFlags = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags;
Matrix44 mViewProj = rd->m_ViewMatrix * rd->m_ProjMatrix;
if (rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH)
{
mViewProj = ReverseDepthHelper::Convert(mViewProj);
rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_REVERSE_DEPTH;
rd->GetGraphicsPipeline().UpdatePerViewConstantBuffer();
}
Matrix44 mViewport(0.5f, 0, 0, 0,
0, -0.5f, 0, 0,
0, 0, 1.0f, 0,
0.5f, 0.5f, 0, 1.0f);
const uint32 numGPUs = rd->GetActiveGPUCount();
#if AZ_RENDER_TO_TEXTURE_GEM_ENABLED
const CCamera& camera = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_cam;
const AZ::EntityId cameraID = camera.GetEntityId();
const int frameID = camera.GetFrameUpdateId();
const uint32 prevViewProjID = max((frameID - (int)numGPUs) % MAX_GPU_NUM, 0);
auto iter = m_prevViewProj[prevViewProjID].find(cameraID);
if (iter == m_prevViewProj[prevViewProjID].end())
{
// initialize with the current view projection in case this is a one-off render.
m_prevViewProj[prevViewProjID].insert({cameraID, mViewProj});
}
Matrix44 mViewProjPrev = m_prevViewProj[prevViewProjID][cameraID] * mViewport;
#else
const int frameID = SPostEffectsUtils::m_iFrameCounter;
Matrix44 mViewProjPrev = m_prevViewProj[max((frameID - (int)numGPUs) % MAX_GPU_NUM, 0)] * mViewport;
#endif //if AZ_RENDER_TO_TEXTURE_GEM_ENABLED
int texStateLinear = CTexture::GetTexState(STexState(FILTER_LINEAR, true));
int texStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true));
int texStateLinearBorder = CTexture::GetTexState(STexState(FILTER_LINEAR, TADDR_BORDER, TADDR_BORDER, TADDR_BORDER, 0));
CShader* pShader = CShaderMan::s_shDeferredShading;
{
PROFILE_LABEL_SCOPE("SSR_RAYTRACE");
if (CRenderer::CV_r_SlimGBuffer)
{
rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER];
}
CCryNameTSCRC techRaytrace("SSR_Raytrace");
static CCryNameR viewProjName("g_mViewProj");
static CCryNameR viewProjprevName("g_mViewProjPrev");
CTexture* destRT = CRenderer::CV_r_SSReflHalfRes ? CTexture::s_ptexHDRTargetScaled[0] : CTexture::s_ptexHDRTarget;
m_passRaytracing.SetRenderTarget(0, destRT);
m_passRaytracing.SetTechnique(pShader, techRaytrace, rd->m_RP.m_FlagsShader_RT);
m_passRaytracing.SetState(GS_NODEPTHTEST);
m_passRaytracing.SetTextureSamplerPair(0, CTexture::s_ptexZTarget, texStatePoint);
m_passRaytracing.SetTextureSamplerPair(1, CTexture::s_ptexSceneNormalsMap, texStateLinear);
m_passRaytracing.SetTextureSamplerPair(2, CTexture::s_ptexSceneSpecular, texStateLinear);
m_passRaytracing.SetTextureSamplerPair(3, CTexture::s_ptexZTargetScaled, texStatePoint);
m_passRaytracing.SetTextureSamplerPair(4, CTexture::s_ptexHDRTargetPrev, texStateLinearBorder);
m_passRaytracing.SetTextureSamplerPair(5, CTexture::s_ptexHDRMeasuredLuminance[rd->RT_GetCurrGpuID()], texStatePoint);
m_passRaytracing.SetRequireWorldPos(true);
m_passRaytracing.BeginConstantUpdate();
pShader->FXSetPSFloat(viewProjName, (Vec4*)mViewProj.GetData(), 4);
pShader->FXSetPSFloat(viewProjprevName, (Vec4*)mViewProjPrev.GetData(), 4);
m_passRaytracing.Execute();
}
if (!CRenderer::CV_r_SSReflHalfRes)
{
m_passCopy.Execute(CTexture::s_ptexHDRTarget, CTexture::s_ptexHDRTargetScaled[0]);
}
// Convolve sharp reflections
m_passDownsample0.Execute(CTexture::s_ptexHDRTargetScaled[0], CTexture::s_ptexHDRTargetScaled[1]);
m_passBlur0.Execute(CTexture::s_ptexHDRTargetScaled[1], CTexture::s_ptexHDRTargetScaledTempRT[1], 1.0f, 3.0f);
m_passDownsample1.Execute(CTexture::s_ptexHDRTargetScaled[1], CTexture::s_ptexHDRTargetScaled[2]);
m_passBlur1.Execute(CTexture::s_ptexHDRTargetScaled[2], CTexture::s_ptexHDRTargetScaledTempRT[2], 1.0f, 3.0f);
m_passDownsample2.Execute(CTexture::s_ptexHDRTargetScaled[2], CTexture::s_ptexHDRTargetScaled[3]);
m_passBlur2.Execute(CTexture::s_ptexHDRTargetScaled[3], CTexture::s_ptexHDRTargetScaledTempRT[3], 1.0f, 3.0f);
{
PROFILE_LABEL_SCOPE("SSR_COMPOSE");
if (CRenderer::CV_r_SlimGBuffer)
{
rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER];
}
static CCryNameTSCRC techComposition("SSReflection_Comp");
CTexture* destTex = CTexture::s_ptexHDRTargetScaledTmp[0];
destTex->Unbind();
m_passComposition.SetRenderTarget(0, destTex);
m_passComposition.SetTechnique(pShader, techComposition, rd->m_RP.m_FlagsShader_RT);
m_passComposition.SetState(GS_NODEPTHTEST);
CTexture* smoothnessTex = CTexture::s_ptexSceneSpecular;
// smoothness is encoded in the normal texture for slim GBuffer optimization
if (CRenderer::CV_r_SlimGBuffer)
{
smoothnessTex = CTexture::s_ptexSceneNormalsMap;
}
m_passComposition.SetTextureSamplerPair(0, smoothnessTex, texStateLinear);
m_passComposition.SetTextureSamplerPair(1, CTexture::s_ptexHDRTargetScaled[0], texStateLinear);
m_passComposition.SetTextureSamplerPair(2, CTexture::s_ptexHDRTargetScaled[1], texStateLinear);
m_passComposition.SetTextureSamplerPair(3, CTexture::s_ptexHDRTargetScaled[2], texStateLinear);
m_passComposition.SetTextureSamplerPair(4, CTexture::s_ptexHDRTargetScaled[3], texStateLinear);
m_passComposition.BeginConstantUpdate();
m_passComposition.Execute();
}
#if AZ_RENDER_TO_TEXTURE_GEM_ENABLED
m_prevViewProj[frameID % MAX_GPU_NUM][cameraID] = mViewProj;
#else
// Update array used for MGPU support
m_prevViewProj[frameID % MAX_GPU_NUM] = mViewProj;
#endif // if AZ_RENDER_TO_TEXTURE_GEM_ENABLED
// Restore original state
rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags = prevPersFlags;
if (rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH)
{
uint32 depthState = ReverseDepthHelper::ConvertDepthFunc(rd->m_RP.m_CurState);
rd->FX_SetState(rd->m_RP.m_CurState, rd->m_RP.m_CurAlphaRef, depthState);
rd->GetGraphicsPipeline().UpdatePerViewConstantBuffer();
}
}