Files
BlueRoseNote/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED阴影系统.md

127 lines
4.2 KiB
Markdown
Raw Normal View History

2026-05-03 20:37:58 +08:00
---
title: RED阴影系统
date: 2026-05-03 00:00:00
excerpt: 动态/静态阴影分离着色系统ARC 卡通渲染的核心阴影方案
tags:
- ARC
- Rendering
- Shadow
- Toon
rating: ⭐
---
# RED 阴影系统
返回 [[Rendering]]
## 概述
RED 阴影系统是 ARC 引擎卡通渲染的核心机制。它将传统 Deferred Lighting 中的阴影处理替换为**阴影着色Shadow Coloring**方案——阴影区域不是简单地变暗,而是使用指定的"阴影颜色"进行着色,这是实现赛璐珞风格卡通渲染的关键技术。
## 核心思路
传统 PBR 阴影:`最终颜色 = 光照颜色 × 阴影衰减`
RED 阴影系统:`最终颜色 = lerp(阴影颜色, 光照颜色, 阴影系数)`
同时将**动态阴影**Shadow Map和**静态阴影**Lightmap / Distance Field Shadow分离处理允许独立控制两种阴影的着色效果。
## 实现细节
### 1. 入口函数 REDDirectionalPixelMain
`DeferredLightPixelShaders.usf` 中新增独立的方向光入口:
```hlsl
// ASW Change : 2016/10/12 21:35:18 Takuro.K
void REDDirectionalPixelMain(
float2 InUV : TEXCOORD0,
float3 ScreenVector : TEXCOORD1,
float4 SVPos : SV_POSITION,
out float4 OutColor : SV_Target0 )
{
// ... 读取 GBuffer、计算光照衰减 ...
OutColor = REDGetShadowColor(
WorldPosition, CameraVector, ScreenSpaceData.GBuffer,
ScreenSpaceData.AmbientOcclusion,
ScreenSpaceData.GBuffer.ShadingModelID,
LightData, GetPerPixelLightAttenuation(InUV),
Random, DynamicShadowShade);
}
```
`DynamicShadowShade` 是一个 uniform 参数,控制动态阴影的明暗程度。
### 2. 阴影项分离 REDGetShadowTerms
`DeferredLightingCommon.ush` 中将阴影分解为动态和静态两个独立项:
```hlsl
void REDGetShadowTerms(
FGBufferData GBuffer, FDeferredLightData LightData,
float3 WorldPosition, float4 LightAttenuation,
out float DynamicShadowTerm, out float StaticShadowTerm)
{
// 动态阴影:来自 Shadow Map
float DynamicShadowFraction = DistanceFromCameraFade(...);
DynamicShadowTerm = min(
lerp(LightAttenuation.x, 1.0f, DynamicShadowFraction),
StaticShadowing);
// 静态阴影:来自 Lightmap / Distance Field
StaticShadowTerm = StaticShadowing;
}
```
### 3. 阴影着色 REDGetShadowColor
核心函数——使用 `DiffuseColor`(存储在 GBufferD 的 CustomData 中)作为阴影颜色:
```hlsl
float4 REDGetShadowColor(...)
{
float DynamicShadow, StaticShadow;
REDGetShadowTerms(GBuffer, LightData, WorldPosition,
LightAttenuation, DynamicShadow, StaticShadow);
// 动态阴影颜色 = DiffuseColor × DynamicShadowShade
float3 DynamicShadowColor = GBuffer.DiffuseColor * DynamicShadowShade;
// 静态阴影颜色 = DiffuseColor不额外缩放
float3 StaticShadowColor = GBuffer.DiffuseColor;
StaticShadowColor = lerp(StaticShadowColor, float3(1,1,1), StaticShadow);
return float4(
lerp(DynamicShadowColor, StaticShadowColor, DynamicShadow), 0.0f);
}
```
### 4. PointLight 的 CustomData 使用
点光源渲染时,将 CustomData原本存储轮廓线 ID 等数据)重新解释为 DiffuseColor
```hlsl
// ASW Change : 2020/01/14 20:19:00 Takeshi.N
ScreenSpaceData.GBuffer.DiffuseColor.rgb = ScreenSpaceData.GBuffer.CustomData.rgb;
```
## C++ 端支持
`LightRendering.cpp` 中:
- 新增 `REDDeferredLightPS` Pixel Shader 类,绑定 `DynamicShadowShade` 参数
- 点光源通过 `bPointLightRED` 排序键控制渲染顺序(排在方向光之后)
- `RED_CUSTOM_LIGHTING` 宏控制是否启用自定义光照路径
## 关联文档
- [[RED自定义数据通道]] — DiffuseColor 如何写入 GBufferD
- [[自定义光照Pass]] — REDDeferredLightPS 的 C++ 绑定
- [[BGMultColor全局色调]] — 场景全局色调叠加
## 修改文件列表
| 文件 | 修改类型 |
|------|---------|
| `Shaders/Private/DeferredLightPixelShaders.usf` | 新增 `REDDirectionalPixelMain` |
| `Shaders/Private/DeferredLightingCommon.ush` | 新增 `REDGetShadowTerms``REDGetShadowColor` |
| `Source/Runtime/Renderer/Private/LightRendering.cpp` | 新增 `REDDeferredLightPS`、点光排序 |