128 lines
4.9 KiB
Markdown
128 lines
4.9 KiB
Markdown
---
|
||
title: Untitled
|
||
date: 2024-12-08 12:18:54
|
||
excerpt:
|
||
tags:
|
||
rating: ⭐
|
||
---
|
||
# 阴影
|
||
## 阴影类型
|
||
- **Static Shadow**
|
||
- **Cascading Shadow Map**
|
||
- **Per Object Shadow**:可移动组件使用的逐物体阴影应用阴影图到物体的包围盒,因此包围盒必须是精确的。对于骨骼网格,这意味着它们应该有一个物理资产。对于粒子系统,任何固定的边界框必须足够大,以容纳所有的粒子。_在网格的Lighting属性组中,Dynamic Inset Shadow可以开启逐物体阴影,对需要高质量高精度的物体非常有用。_
|
||
- **Dynamic Shadow**:可移动光源在所有物体上投射出完全动态的阴影(和光)。这种光源的任何数据不会被烘焙到光照图中,它可以自由地在所有东西上投射动态阴影。静态网格、骨架网格、粒子效果等等将完全从可移动光源投射和接收动态阴影。
|
||
- **Capsule Shadow**
|
||
- **Contact Shadow**
|
||
- **Distance Field Shadow**
|
||
|
||
## 相关类型
|
||
- ShadowRendering.h
|
||
**FProjectedShadowInfo**:存储投影阴影先关信息。包含各种变换矩阵、阴影渲染函数以及渲染参数、灯光&场景&图元信息。
|
||
- SceneRendering.h
|
||
FVisibleLightInfo:可见光源信息, 主要是阴影相关的信息.
|
||
FVisibleLightViewInfo:
|
||
|
||
## DynamicShadows
|
||
### InitDynamicShadows() => CreateDynamicShadows()
|
||
InitViews() => FSceneRenderer::InitDynamicShadows()
|
||
PS. UE5.3中相关逻辑移动到***CreateDynamicShadows()*** 中了。InitDynamicShadows() => BeginInitDynamicShadows() => BeginGatherShadowPrimitives() => CreateDynamicShadows()
|
||
|
||
计算各种灯光类型,之后调用:
|
||
- CreateWholeSceneProjectedShadow()
|
||
- AddViewDependentWholeSceneShadowsForView()
|
||
- SetupInteractionShadows()
|
||
### CreateWholeSceneProjectedShadow
|
||
|
||
|
||
|
||
# 阴影偏移
|
||
可以考虑的Buffer有
|
||
- ShadowDepths
|
||
- CustomDepth
|
||
|
||
# 相关Paas
|
||
1. ShadowDepths
|
||
2. Lights
|
||
1. DirectLighting
|
||
1. UnbatchedLights
|
||
1. ShadowProjectionOnOpaque
|
||
# ShadowDepths
|
||
- FSceneRenderer::RenderShadowDepthMaps():位于CustomDepth之前。
|
||
- RenderVirtualShadowMaps()
|
||
- RenderShadowDepthMapAtlases()
|
||
- SortedShadowsForShadowDepthPass.ShadowMapCubemaps循环
|
||
-
|
||
# Lights
|
||
### Shader
|
||
ShadowProjectionPixelShader.usf
|
||
- TShadowProjectionPS:
|
||
- TDirectionalPercentageCloserShadowProjectionPS:方向光投影
|
||
- TSpotPercentageCloserShadowProjectionPS:SpotLight
|
||
- FOnePassPointShadowProjectionPS(Moible?)
|
||
|
||
### 相关函数
|
||
- FDeferredShadingSceneRenderer::RenderLights()
|
||
- FDeferredShadingSceneRenderer::RenderDeferredShadowProjections()
|
||
- FSceneRenderer::RenderShadowProjections()
|
||
- FProjectedShadowInfo::SetupFrustumForProjection():构建阴影投影4棱椎平面信息。
|
||
- FProjectedShadowInfo::SetupProjectionStencilMask():
|
||
|
||
# 其他
|
||
顺序:
|
||
RenderCustomDepthPass
|
||
|
||
FSceneRenderer::CreateDynamicShadows
|
||
=>
|
||
FSceneRenderer::CreatePerObjectProjectedShadow
|
||
|
||
```c++
|
||
if (!IsForwardShadingEnabled(ShaderPlatform))
|
||
{
|
||
// Dynamic shadows are synced later when using the deferred path to make more headroom for tasks.
|
||
FinishInitDynamicShadows(GraphBuilder, InitViewTaskDatas.DynamicShadows, InstanceCullingManager, ExternalAccessQueue);
|
||
}
|
||
```
|
||
|
||
```c++
|
||
if (RendererOutput == ERendererOutput::DepthPrepassOnly)
|
||
{
|
||
RenderOcclusionLambda();
|
||
|
||
if (bUpdateNaniteStreaming)
|
||
{
|
||
Nanite::GStreamingManager.SubmitFrameStreamingRequests(GraphBuilder);
|
||
}
|
||
|
||
CopySceneCaptureComponentToTarget(GraphBuilder, SceneTextures, ViewFamilyTexture, ViewFamily, Views);
|
||
}
|
||
else
|
||
{
|
||
GVRSImageManager.PrepareImageBasedVRS(GraphBuilder, ViewFamily, SceneTextures);
|
||
|
||
if (!IsForwardShadingEnabled(ShaderPlatform))
|
||
{
|
||
// Dynamic shadows are synced later when using the deferred path to make more headroom for tasks.
|
||
FinishInitDynamicShadows(GraphBuilder, InitViewTaskDatas.DynamicShadows, InstanceCullingManager, ExternalAccessQueue);
|
||
}
|
||
|
||
// Update groom only visible in shadow
|
||
if (IsHairStrandsEnabled(EHairStrandsShaderType::All, Scene->GetShaderPlatform()) && RendererOutput == ERendererOutput::FinalSceneColor)
|
||
{
|
||
UpdateHairStrandsBookmarkParameters(Scene, Views, HairStrandsBookmarkParameters);
|
||
|
||
// Interpolation for cards/meshes only visible in shadow needs to happen after the shadow jobs are completed
|
||
const bool bRunHairStrands = HairStrandsBookmarkParameters.HasInstances() && (Views.Num() > 0);
|
||
if (bRunHairStrands)
|
||
{
|
||
RunHairStrandsBookmark(GraphBuilder, EHairStrandsBookmark::ProcessCardsAndMeshesInterpolation_ShadowView, HairStrandsBookmarkParameters);
|
||
}
|
||
}
|
||
|
||
// NOTE: The ordering of the lights is used to select sub-sets for different purposes, e.g., those that support clustered deferred.
|
||
FSortedLightSetSceneInfo& SortedLightSet = *GraphBuilder.AllocObject<FSortedLightSetSceneInfo>();
|
||
{
|
||
RDG_CSV_STAT_EXCLUSIVE_SCOPE(GraphBuilder, SortLights);
|
||
RDG_GPU_STAT_SCOPE(GraphBuilder, SortLights);
|
||
ComputeLightGridOutput = GatherLightsAndComputeLightGrid(GraphBuilder, bComputeLightGrid, SortedLightSet);
|
||
}
|
||
``` |