2024-12-08 12:40:30 +08:00
|
|
|
|
---
|
|
|
|
|
title: Untitled
|
|
|
|
|
date: 2024-12-08 12:18:54
|
|
|
|
|
excerpt:
|
|
|
|
|
tags:
|
|
|
|
|
rating: ⭐
|
|
|
|
|
---
|
2024-12-17 17:06:38 +08:00
|
|
|
|
# 前言
|
|
|
|
|
阴影渲染笔记:[[Shadow]]
|
|
|
|
|
|
|
|
|
|
实现功能:
|
|
|
|
|
1. [ ] 控制深度偏移
|
|
|
|
|
2. [ ] CustomDepth制作头发阴影偏移效果哦 https://zhuanlan.zhihu.com/p/689578355
|
|
|
|
|
3. [ ] ContactShadow接触阴影实现衣服细节的DetailShadow
|
|
|
|
|
4. [ ] 半程阴影
|
2024-12-13 16:22:58 +08:00
|
|
|
|
# 半程阴影
|
|
|
|
|
由晨风&Neverwind提出:
|
|
|
|
|
- 【[UFSH2024]用虚幻引擎5为《幻塔》定制高品质动画流程风格化渲染管线 | 晨风 Neverwind 完美世界游戏】 【精准空降到 07:27】 https://www.bilibili.com/video/BV1rW2LYvEox/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e&t=447
|
|
|
|
|
|
|
|
|
|
**阴影Setup阶段**:
|
|
|
|
|
```c++
|
|
|
|
|
if 启用半程阴影:
|
|
|
|
|
{
|
|
|
|
|
额外进行一次CreatePerObjectProjectedShadow()
|
|
|
|
|
{
|
2024-12-16 10:18:10 +08:00
|
|
|
|
处理阴影光照Matrix //猜测:
|
|
|
|
|
//在ProjectedShadowInfo->SetupPerObjectProjection()中调整,FProjectedShadowInfo.TranslatedWorldToView。
|
|
|
|
|
//在LightSceneInfo->Proxy->GetPerObjectProjectedShadowInitializer(Bounds, ShadowInitializer)之后,修改WorldTolight。
|
|
|
|
|
向阴影信息写入IsHalfViewShadowFlag//猜测:在FProjectedShadowInfo中添加判断Flag并且写入。
|
|
|
|
|
用新的光源方向画Atlas //猜测:给带有对应Flog的DirectionLigh多创建一个对应的Atlas?
|
2024-12-13 16:22:58 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2024-12-16 10:18:10 +08:00
|
|
|
|
截图代码(半程阴影修改LightDirection逻辑):
|
2024-12-13 16:22:58 +08:00
|
|
|
|
```c++
|
|
|
|
|
if(PrimitiveSceneinfo->Proxy->IsToonDisableSelfShadow())
|
|
|
|
|
{
|
|
|
|
|
...
|
|
|
|
|
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
|
|
|
|
|
{
|
|
|
|
|
const FViewInfo& View = Views[ViewIndex];
|
|
|
|
|
const FMatrix& ViewMatrix = View.ShadowViewMatrices.GetViewMatrix()
|
|
|
|
|
FVector LightDirection = Lightsceneinfo->Proxy- GetDirection();
|
|
|
|
|
const FVector CameraDirection = ViewMatrix.GetColumn(2).GetSafeNonmal()
|
|
|
|
|
float LightViewBlendFactor = PrimitiveSceneinfo->Proxy->GetToonHalfVienShadowFactor();
|
|
|
|
|
Fvector HalfViewLightDir = (LightDirection + ( 1 - LightViewBlendFactor) + CameraDirection * LightViewBlendFactor).GetSafeNormal();
|
|
|
|
|
FMatrix FinalCombineMatrix = FNnverseRotationMatrix(HalfViewLightDir.Rotation())
|
|
|
|
|
ShadowInitializer.WorldTolight = FinalCombineMatrix;
|
|
|
|
|
}
|
|
|
|
|
...
|
|
|
|
|
}
|
2024-12-16 10:18:10 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
PS.很有可能需要创建2个Atlas。Atlas的创建位于***FSceneRenderer::AllocateCachedShadowDepthTargets()***。数据存储在***SortedShadowsForShadowDepthPass.ShadowMapAtlases***中。大致由FSceneRenderer::FinishInitDynamicShadows()调用。
|
|
|
|
|
|
|
|
|
|
**阴影Projection阶段**:
|
|
|
|
|
//此阶段需要屏蔽角色投射到自己的非半程阴影
|
|
|
|
|
//和角色投射到场景中会跟随视角移动的阴影
|
|
|
|
|
```c++
|
2024-12-16 22:25:20 +08:00
|
|
|
|
if(Toon材质,且没有半程阴影Flag的阴影
|
2024-12-16 10:18:10 +08:00
|
|
|
|
&&非Toon材质但有半程阴影Flag的阴影)
|
|
|
|
|
{
|
|
|
|
|
屏蔽此阴影
|
|
|
|
|
}
|
|
|
|
|
```
|
2024-12-16 22:25:20 +08:00
|
|
|
|
|
2024-12-19 12:49:37 +08:00
|
|
|
|
PS.很有可能在FProjectedShadowInfo::RenderProjection()阶段进行判断以此保证合成正确的**ScreenShadowMask**。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 实现方法
|
2024-12-19 16:34:02 +08:00
|
|
|
|
```c++
|
2024-12-19 12:49:37 +08:00
|
|
|
|
const FMaterialRenderProxy* MaterialRenderProxy = MeshBatch.MaterialRenderProxy;
|
|
|
|
|
bool bEnableToonMeshDrawOutline = MaterialRenderProxy->GetToonOutlineDataAssetRT()->Settings.bEnableToonMeshDrawOutline;
|
|
|
|
|
|
2024-12-19 16:34:02 +08:00
|
|
|
|
```
|
|
|
|
|
FProjectedShadowInfo->Scene
|
|
|
|
|
FPrimitiveSceneProxy
|
2024-12-19 12:49:37 +08:00
|
|
|
|
## 深度偏移
|
2024-12-19 14:10:21 +08:00
|
|
|
|
1. FProjectedShadowInfo添加变量。
|
|
|
|
|
|
|
|
|
|
FSceneRenderer::RenderShadowDepthMaps() => RenderShadowDepthMapAtlases() => ProjectedShadowInfo->RenderDepth()
|
2024-12-19 12:49:37 +08:00
|
|
|
|
|
|
|
|
|
## DirectionOffsetToViewShadow
|
2024-12-19 14:10:21 +08:00
|
|
|
|
1. 在FProjectedShadowInfo添加变量。
|
|
|
|
|
FSceneRenderer::CreateDynamicShadows() => SetupInteractionShadows(),在CreatePerObjectProjectedShadow()添加相关逻辑。
|