4.2 KiB
4.2 KiB
title, date, excerpt, tags, rating
| title | date | excerpt | tags | rating | ||||
|---|---|---|---|---|---|---|---|---|
| RED阴影系统 | 2026-05-03 00:00:00 | 动态/静态阴影分离着色系统,ARC 卡通渲染的核心阴影方案 |
|
⭐ |
RED 阴影系统
返回 Rendering
概述
RED 阴影系统是 ARC 引擎卡通渲染的核心机制。它将传统 Deferred Lighting 中的阴影处理替换为**阴影着色(Shadow Coloring)**方案——阴影区域不是简单地变暗,而是使用指定的"阴影颜色"进行着色,这是实现赛璐珞风格卡通渲染的关键技术。
核心思路
传统 PBR 阴影:最终颜色 = 光照颜色 × 阴影衰减
RED 阴影系统:最终颜色 = lerp(阴影颜色, 光照颜色, 阴影系数)
同时将动态阴影(Shadow Map)和静态阴影(Lightmap / Distance Field Shadow)分离处理,允许独立控制两种阴影的着色效果。
实现细节
1. 入口函数 REDDirectionalPixelMain
在 DeferredLightPixelShaders.usf 中新增独立的方向光入口:
// 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 中将阴影分解为动态和静态两个独立项:
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 中)作为阴影颜色:
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:
// ASW Change : 2020/01/14 20:19:00 Takeshi.N
ScreenSpaceData.GBuffer.DiffuseColor.rgb = ScreenSpaceData.GBuffer.CustomData.rgb;
C++ 端支持
在 LightRendering.cpp 中:
- 新增
REDDeferredLightPSPixel 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、点光排序 |