BlueRoseNote/03-UnrealEngine/Rendering/RenderingPipeline/Lighting/Lighting阶段的ShadowMap逻辑.md

65 lines
2.8 KiB
Markdown
Raw Normal View History

2023-06-29 11:55:02 +08:00
---
title: Lighting阶段的ShadowMap逻辑
date: 2023-04-10 14:45:45
excerpt:
tags:
rating: ⭐
---
## PS Parameter
`FDeferredLightPS::FParameters GetDeferredLightPSParameters()`
- LightAttenuationTexture = ShadowMaskTexture ? ShadowMaskTexture : WhiteDummy;
- One pass projection
- VirtualShadowMap = VirtualShadowMapUniformBuffer;
- VirtualShadowMapId = VirtualShadowMapId;
- ShadowMaskBits = ShadowMaskBits ? ShadowMaskBits : GSystemTextures.GetZeroUIntDummy(GraphBuilder);
最后输出
- SceneColorTexture
- SceneDepthTexture
## Lighting阶段中VSM 渲染函数
RenderDeferredShadowProjections(),输出`ScreenShadowMaskTexture`
## 问题所在
LightAttenuation
- x整个场景的方向光阴影。
- y整个场景的方向光SSS阴影。
- zLight function + per-object shadows
- wper-object SSS shadowing in w
zw用于非方向光或者移动端渲染路径。
```c++
if (LightData.bRadialLight || SHADING_PATH_MOBILE)
{
// Remapping the light attenuation buffer (see ShadowRendering.cpp)
Shadow.SurfaceShadow = LightAttenuation.z * StaticShadowing;
// SSS uses a separate shadowing term that allows light to penetrate the surface
//@todo - how to do static shadowing of SSS correctly? Shadow.TransmissionShadow = LightAttenuation.w * StaticShadowing;
Shadow.TransmissionThickness = LightAttenuation.w;
}
else
{
// Remapping the light attenuation buffer (see ShadowRendering.cpp)
// Also fix up the fade between dynamic and static shadows // to work with plane splits rather than spheres.
float DynamicShadowFraction = DistanceFromCameraFade(SceneDepth, LightData);
// For a directional light, fade between static shadowing and the whole scene dynamic shadowing based on distance + per object shadows
Shadow.SurfaceShadow = lerp(LightAttenuation.x, StaticShadowing, DynamicShadowFraction);
// Fade between SSS dynamic shadowing and static shadowing based on distance
Shadow.TransmissionShadow = min(lerp(LightAttenuation.y, StaticShadowing, DynamicShadowFraction), LightAttenuation.w);
Shadow.SurfaceShadow *= LightAttenuation.z;
Shadow.TransmissionShadow *= LightAttenuation.z;
// Need this min or backscattering will leak when in shadow which cast by non perobject shadow(Only for directional light)
Shadow.TransmissionThickness = min(LightAttenuation.y, LightAttenuation.w);
}
```
**DeferredLightingCommon.ush**与**DeferredLightPixelShaders.usf**中的**LightAttenuation**即为ShadowMap数据。具体可以参考**GetLightAttenuationFromShadow()**可以看得出EPIC之后打算通过抖动来消除VSM的阴影锯齿。
主要的阴影效果由**LightAttenuation**与ShadingModels.ush中的NoL提供。我们只需要调整自阴影也就是z通道其他的整个场景的阴影。