vault backup: 2024-12-17 10:55:22

This commit is contained in:
2024-12-17 10:55:22 +08:00
parent 8ba555c357
commit 276f05e2ce
3 changed files with 121 additions and 3 deletions

View File

@@ -901,6 +901,119 @@ void FDeferredShadingSceneRenderer::RenderDeferredShadowProjections(
RenderShadowProjections():
1. 取得当前FVisibleLightInfo、FLightSceneProxy创建FProjectedShadowInfoArray DistanceFieldShadows、NormalShadows。
2. 遍历VisibleLightInfo.ShadowsToProject按照阴影特征将每个FProjectedShadowInfo加入DistanceFieldShadows、NormalShadows。
3. 调用Lambda RenderNormalShadows()来渲染ScreenShadowMaskTexture与ScreenShadowMaskSubPixelTexture。
4. 遍历DistanceFieldShadows调用FProjectedShadowInfo->RenderRayTracedDistanceFieldProjection()来渲染距离场阴影。
### FSceneRenderer::RenderShadowProjections()
```c++
void FSceneRenderer::RenderShadowProjections(
FRDGBuilder& GraphBuilder,
FRDGTextureRef OutputTexture,
const FMinimalSceneTextures& SceneTextures,
const FLightSceneProxy* LightSceneProxy,
TArrayView<const FProjectedShadowInfo* const> Shadows,
bool bSubPixelShadow,
bool bProjectingForForwardShading)
{
CheckShadowDepthRenderCompleted();
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
{
const FViewInfo& View = Views[ViewIndex];
const FExclusiveDepthStencil ExclusiveDepthStencil = FExclusiveDepthStencil::DepthRead_StencilWrite;
if (bSubPixelShadow && !HairStrands::HasViewHairStrandsData(View))
{
continue;
}
View.BeginRenderView();
// Sanity check
if (bSubPixelShadow)
{
check(View.HairStrandsViewData.VisibilityData.HairOnlyDepthTexture);
}
FShadowProjectionPassParameters CommonPassParameters;
CommonPassParameters.SceneTextures = SceneTextures.GetSceneTextureShaderParameters(View.FeatureLevel);
CommonPassParameters.HairStrands = HairStrands::BindHairStrandsViewUniformParameters(View);
if (Strata::IsStrataEnabled())
{
CommonPassParameters.Strata = Strata::BindStrataGlobalUniformParameters(View);
}
CommonPassParameters.RenderTargets[0] = FRenderTargetBinding(OutputTexture, ERenderTargetLoadAction::ELoad);
CommonPassParameters.RenderTargets.DepthStencil =
bSubPixelShadow ?
FDepthStencilBinding(View.HairStrandsViewData.VisibilityData.HairOnlyDepthTexture, ERenderTargetLoadAction::ELoad, ERenderTargetLoadAction::ELoad, ExclusiveDepthStencil) :
FDepthStencilBinding(SceneTextures.Depth.Target, ERenderTargetLoadAction::ELoad, ERenderTargetLoadAction::ELoad, ExclusiveDepthStencil);
RDG_GPU_MASK_SCOPE(GraphBuilder, View.GPUMask);
RDG_EVENT_SCOPE_CONDITIONAL(GraphBuilder, Views.Num() > 1, "View%d", ViewIndex);
// Project the shadow depth buffers onto the scene.
for (const FProjectedShadowInfo* ProjectedShadowInfo : Shadows)
{
if (ProjectedShadowInfo->bAllocated)
{
// Only project the shadow if it's large enough in this particular view (split screen, etc... may have shadows that are large in one view but irrelevantly small in others)
if (ProjectedShadowInfo->FadeAlphas[ViewIndex] > 1.0f / 256.0f)
{
if (ProjectedShadowInfo->bOnePassPointLightShadow)
{
ProjectedShadowInfo->RenderOnePassPointLightProjection(GraphBuilder, CommonPassParameters, ViewIndex, View, LightSceneProxy, bProjectingForForwardShading, bSubPixelShadow);
}
else
{
ProjectedShadowInfo->RenderProjection(GraphBuilder, CommonPassParameters, ViewIndex, &View, LightSceneProxy, this, bProjectingForForwardShading, bSubPixelShadow);
}
}
}
}
}
}
```
### Shader
投射阴影渲染用Shader为
- ShadowProjectionVertexShader.usf
- FShadowProjectionNoTransformVS直接输出顶点坐标。
- FShadowVolumeBoundProjectionVS
- ShadowProjectionPixelShader.usf
- TShadowProjectionPS
- TShadowProjectionFromTranslucencyPS
- TDirectionalPercentageCloserShadowProjectionPS
- TModulatedShadowProjection
PS. 向往Blog 以上可知对ScreenShadowMaskTexture执行绘制时是在屏幕空间进行的并且ScreenShadowMask会被叠加多次视光源的阴影实例个数而定不同的通道存储了不同类型的阴影信息。
## RenderLight()
```c++
// Render the light to the scene color buffer, conditionally using the attenuation buffer or a 1x1 white texture as input
if (bDirectLighting)
{
for (int32 ViewIndex = 0, ViewCount = Views.Num(); ViewIndex < ViewCount; ++ViewIndex)
{
const FViewInfo& View = Views[ViewIndex];
// If the light elided the screen space shadow mask, sample directly from the packed shadow mask
int32 VirtualShadowMapId = INDEX_NONE;
if (bElideScreenShadowMask)
{
INC_DWORD_STAT(STAT_VSMLocalProjectionOnePassFast);
VirtualShadowMapId = VisibleLightInfo.GetVirtualShadowMapId(&View);
}
RDG_EVENT_SCOPE_CONDITIONAL(GraphBuilder, ViewCount > 1, "View%d", ViewIndex);
SCOPED_GPU_MASK(GraphBuilder.RHICmdList, View.GPUMask);
RenderLight(GraphBuilder, Scene, View, SceneTextures, &LightSceneInfo, VirtualShadowMapId != INDEX_NONE ? nullptr : ScreenShadowMaskTexture, LightingChannelsTexture, false /*bRenderOverlap*/, true /*bCloudShadow*/, VirtualShadowMapArray.GetUniformBuffer(), ShadowSceneRenderer->VirtualShadowMapMaskBits, VirtualShadowMapId);
}
}
```
使用ScreenShadowMaskTexture来渲染阴影。
# 半程阴影
由晨风&Neverwind提出