Merge remote-tracking branch 'origin/master'
# Conflicts: # .obsidian/plugins/various-complements/histories.json # 03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md
This commit is contained in:
commit
f4440d36e5
@ -1 +1 @@
|
||||
{"SequoiaCamShotEvalTemplate":{"SequoiaCamShotEvalTemplate":{"currentFile":{"count":1,"lastUpdated":1732609264076}}},"c++内存泄漏分析工具":{"c++内存泄漏分析工具":{"internalLink":{"count":1,"lastUpdated":1733137754779}}},"Lights":{"Lights":{"currentFile":{"count":1,"lastUpdated":1733637911876}}},"FShadowProjectionNoTransformVS(ShadowProjectionNoTransformVS)、FShadowVolumeBoundProjectionVS(ShadowVolumeBoundProjectionVS)":{"FShadowProjectionNoTransformVS(ShadowProjectionNoTransformVS)、FShadowVolumeBoundProjectionVS(ShadowVolumeBoundProjectionVS)":{"currentFile":{"count":1,"lastUpdated":1734345863513}}}}
|
||||
{"SequoiaCamShotEvalTemplate":{"SequoiaCamShotEvalTemplate":{"currentFile":{"count":1,"lastUpdated":1732609264076}}},"c++内存泄漏分析工具":{"c++内存泄漏分析工具":{"internalLink":{"count":1,"lastUpdated":1733137754779}}},"Lights":{"Lights":{"currentFile":{"count":1,"lastUpdated":1733637911876}}},"渲染屏幕空间阴影遮罩,并用于光照计算。":{"渲染屏幕空间阴影遮罩,并用于光照计算。":{"currentFile":{"count":1,"lastUpdated":1734354537396}}}}
|
@ -210,13 +210,17 @@ void FSceneRenderer::InitDynamicShadows(FRHICommandListImmediate& RHICmdList, FG
|
||||
1. UnbatchedLights
|
||||
1. ShadowProjectionOnOpaque
|
||||
# ShadowDepths
|
||||
渲染阴影深度贴图与图集。
|
||||
|
||||
- FSceneRenderer::RenderShadowDepthMaps():位于CustomDepth之前。
|
||||
- **RenderVirtualShadowMaps()**
|
||||
- RenderShadowDepthMapAtlases()
|
||||
- RenderVirtualShadowMaps()
|
||||
- ***RenderShadowDepthMapAtlases()***
|
||||
- SortedShadowsForShadowDepthPass.ShadowMapCubemaps循环。渲染点光源阴影立方体图
|
||||
- **FProjectedShadowInfo::RenderDepth()**
|
||||
- **FProjectedShadowInfo::RenderTranslucencyDepths**
|
||||
|
||||
RenderShadowDepthMapAtlases() 渲染的图集位于***FSceneRenderer::SortedShadowsForShadowDepthPass.ShadowMapAtlases*** (ShadowMapAtlases.RenderTargets.DepthTarget为深度,ShadowMapAtlases.Shadows 为FProjectedShadowInfo)
|
||||
|
||||
## RenderDepth
|
||||
MeshDrawProcessor为***FShadowDepthPassMeshProcessor***。渲染的Shader为***ShadowDepthPixelShader.usf***
|
||||
```c++
|
||||
@ -753,84 +757,10 @@ void Main(
|
||||
#endif
|
||||
}
|
||||
```
|
||||
# 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);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
# RenderLights
|
||||
渲染ScreenShadowMask,并用于光照计算。
|
||||
|
||||
FDeferredShadingSceneRenderer::RenderLights()
|
||||
=>
|
||||
RDG_EVENT_SCOPE(GraphBuilder, "UnbatchedLights");//batchedLights为没有LightFunction与没有阴影的灯光。
|
||||
@ -901,10 +831,14 @@ void FDeferredShadingSceneRenderer::RenderDeferredShadowProjections(
|
||||
RenderShadowProjections():
|
||||
1. 取得当前FVisibleLightInfo、FLightSceneProxy;创建FProjectedShadowInfoArray DistanceFieldShadows、NormalShadows。
|
||||
2. 遍历VisibleLightInfo.ShadowsToProject,按照阴影特征将每个FProjectedShadowInfo加入DistanceFieldShadows、NormalShadows。
|
||||
3. 调用Lambda RenderNormalShadows()来渲染ScreenShadowMaskTexture与ScreenShadowMaskSubPixelTexture。
|
||||
3. 调用Lamda来渲染ScreenShadowMaskTexture与ScreenShadowMaskSubPixelTexture。
|
||||
4. 遍历DistanceFieldShadows,调用FProjectedShadowInfo->RenderRayTracedDistanceFieldProjection()来渲染距离场阴影。
|
||||
|
||||
### FSceneRenderer::RenderShadowProjections()
|
||||
1. 初始化UniformStruct变量。
|
||||
2. 遍历传入的FProjectedShadowInfo数组,并调用**ProjectedShadowInfo->RenderProjection()** 将所有灯光的阴影Mask绘制到一张ScreenShadowMask上。
|
||||
1. 在TShadowProjectionPS中通过SetParameters() => ProjectionParameters.Set(),来设置ShadowDepthTextureValue。`ShadowDepthTextureValue = ShadowInfo->RenderTargets.DepthTarget->GetRHI();`
|
||||
|
||||
```c++
|
||||
void FSceneRenderer::RenderShadowProjections(
|
||||
FRDGBuilder& GraphBuilder,
|
||||
@ -986,8 +920,24 @@ void FSceneRenderer::RenderShadowProjections(
|
||||
- TShadowProjectionFromTranslucencyPS
|
||||
- TDirectionalPercentageCloserShadowProjectionPS
|
||||
- TModulatedShadowProjection
|
||||
- ShadowProjectionCommon.ush
|
||||
- ShadowDepthTexture
|
||||
- ShadowDepthCubeTexture
|
||||
|
||||
主要步骤:
|
||||
1. 将SceneDepth(ScreenSpace) =>(ShadowSpace)
|
||||
2. 根据过滤方式调用:
|
||||
1. 不过滤:`Shadow = LightSpacePixelDepthForOpaque < Texture2DSampleLevel(ShadowDepthTexture, ShadowDepthTextureSampler, ShadowPosition.xy, 0).r;`
|
||||
2. PCSS:初始化FPCSSSamplerSettings之后调用DirectionalPCSS()
|
||||
3. PCF:初始化FPCFSamplerSettings之后调用ManualPCF()
|
||||
3. 调整阴影数值。钳制、模糊、过滤。
|
||||
4. `OutColor = EncodeLightAttenuation(half4(FadedShadow, FadedSSSShadow, FadedShadow, FadedSSSShadow));`LinearSpace => sRGB 本质为sqrt(input),比pow(x, 1/2.2) 节约性能。
|
||||
|
||||
## 总结
|
||||
1. RenderDepth()渲染完深度贴图之后,经过GatherAndSortLights()、ComputeLightGrid()获取到经过剪裁的FSortedLightSetSceneInfo &SortedLightSet,之后传递给RenderLights()。
|
||||
2. BindShadowProjectionShaders() => BindShaderShaders() =>
|
||||
3. TShadowProjectionPS => ProjectionParameters.Bind(Initializer); => ShadowDepthTexture.Bind(ParameterMap,TEXT("ShadowDepthTexture"));
|
||||
|
||||
PS. 向往Blog: 以上可知,对ScreenShadowMaskTexture执行绘制时,是在屏幕空间进行的,并且ScreenShadowMask会被叠加多次(视光源的阴影实例个数而定),不同的通道存储了不同类型的阴影信息。
|
||||
|
||||
## RenderLight()
|
||||
```c++
|
||||
@ -1060,9 +1010,11 @@ PS.很有可能需要创建2个Atlas。Atlas的创建位于***FSceneRenderer::Al
|
||||
//此阶段需要屏蔽角色投射到自己的非半程阴影
|
||||
//和角色投射到场景中会跟随视角移动的阴影
|
||||
```c++
|
||||
if(Toon材质,且没有程阴影Flag的阴影
|
||||
if(Toon材质,且没有半程阴影Flag的阴影
|
||||
&&非Toon材质但有半程阴影Flag的阴影)
|
||||
{
|
||||
屏蔽此阴影
|
||||
}
|
||||
```
|
||||
|
||||
PS.很有可能在FProjectedShadowInfo::RenderProjection()阶段进行判断以此保证合成正确的**ScreenShadowMask**。
|
Loading…
x
Reference in New Issue
Block a user