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

127 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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`、点光排序 |