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

4.2 KiB
Raw Blame History

title, date, excerpt, tags, rating
title date excerpt tags rating
RED阴影系统 2026-05-03 00:00:00 动态/静态阴影分离着色系统ARC 卡通渲染的核心阴影方案
ARC
Rendering
Shadow
Toon

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 中:

  • 新增 REDDeferredLightPS Pixel Shader 类,绑定 DynamicShadowShade 参数
  • 点光源通过 bPointLightRED 排序键控制渲染顺序(排在方向光之后)
  • RED_CUSTOM_LIGHTING 宏控制是否启用自定义光照路径

关联文档

修改文件列表

文件 修改类型
Shaders/Private/DeferredLightPixelShaders.usf 新增 REDDirectionalPixelMain
Shaders/Private/DeferredLightingCommon.ush 新增 REDGetShadowTermsREDGetShadowColor
Source/Runtime/Renderer/Private/LightRendering.cpp 新增 REDDeferredLightPS、点光排序