vault backup: 2024-12-17 10:55:22
This commit is contained in:
@@ -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提出:
|
||||
|
Reference in New Issue
Block a user