2026-05-03 20:37:58 +08:00
|
|
|
|
---
|
|
|
|
|
|
title: 自定义光照Pass
|
|
|
|
|
|
date: 2026-05-03 00:00:00
|
|
|
|
|
|
excerpt: REDDeferredLightPS 自定义光照 Pass、PointLight 排序和自定义光照路径
|
|
|
|
|
|
tags:
|
|
|
|
|
|
- ARC
|
|
|
|
|
|
- Rendering
|
|
|
|
|
|
- Lighting
|
|
|
|
|
|
rating: ⭐
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 自定义光照 Pass
|
|
|
|
|
|
|
|
|
|
|
|
返回 [[Rendering]]
|
|
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
|
|
|
|
|
ARC 引擎在 Deferred Lighting 阶段新增了自定义光照 Pass,通过 `REDDeferredLightPS` 替换标准光照 Pixel Shader,实现 [[RED阴影系统]] 的阴影着色逻辑。同时修改了点光源的渲染排序和数据传递方式。
|
|
|
|
|
|
|
|
|
|
|
|
## REDDeferredLightPS
|
|
|
|
|
|
|
|
|
|
|
|
在 `LightRendering.cpp` 中新增 Pixel Shader 类:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
class REDDeferredLightPS : public FDeferredLightPS
|
|
|
|
|
|
{
|
|
|
|
|
|
// 绑定 DynamicShadowShade uniform 参数
|
|
|
|
|
|
// 调用 REDDirectionalPixelMain 入口
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### DynamicShadowShade 参数
|
|
|
|
|
|
|
|
|
|
|
|
从 C++ 端传入的 uniform float,控制动态阴影区域的明暗程度:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
// 0.0 = 完全黑色的动态阴影
|
|
|
|
|
|
// 1.0 = 无动态阴影效果
|
|
|
|
|
|
SetShaderValue(RHICmdList, ShaderRHI,
|
|
|
|
|
|
DynamicShadowShadeParam, LightSceneInfo->DynamicShadowShade);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 点光源排序
|
|
|
|
|
|
|
|
|
|
|
|
点光源通过 `bPointLightRED` 排序键确保在方向光之后渲染:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
// 排序优先级:方向光 → 点光源(RED) → 其他
|
|
|
|
|
|
SortKey |= bPointLightRED ? (1 << PointLightSortBit) : 0;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
这确保方向光的阴影着色先完成,点光源再叠加贡献。
|
|
|
|
|
|
|
|
|
|
|
|
## 点光源 CustomData 覆写
|
|
|
|
|
|
|
|
|
|
|
|
渲染点光源时,GBufferD 的 CustomData 被重新解释为 DiffuseColor:
|
|
|
|
|
|
|
|
|
|
|
|
```hlsl
|
|
|
|
|
|
// DeferredLightPixelShaders.usf
|
|
|
|
|
|
#if USE_RED_CUSTOM_DATA_POINTLIGHT
|
|
|
|
|
|
ScreenSpaceData.GBuffer.DiffuseColor.rgb =
|
|
|
|
|
|
ScreenSpaceData.GBuffer.CustomData.rgb;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## RED_CUSTOM_LIGHTING 宏
|
|
|
|
|
|
|
|
|
|
|
|
通过 `RED_CUSTOM_LIGHTING` 定义控制是否启用整个自定义光照路径。关闭时回退到标准 UE4 Deferred Lighting。
|
|
|
|
|
|
|
|
|
|
|
|
## Decal Emissive 处理
|
|
|
|
|
|
|
|
|
|
|
|
贴花的 Emissive 被作为正常光照渲染(而非 Emissive 通道),因为在 RED 管线中 BaseColor 已被阴影颜色系统占用:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
// Decal Emissive → normal lighting contribution
|
|
|
|
|
|
// (BaseColor 在 RED 系统中用于 shadow color)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 关联文档
|
|
|
|
|
|
|
|
|
|
|
|
- [[RED阴影系统]] — 核心阴影着色逻辑
|
|
|
|
|
|
- [[RED自定义数据通道]] — 点光源 CustomData 的来源
|
|
|
|
|
|
|
2026-05-03 21:38:46 +08:00
|
|
|
|
## 完整代码解析
|
2026-05-03 20:37:58 +08:00
|
|
|
|
|
2026-05-03 21:38:46 +08:00
|
|
|
|
> Shader 侧的完整代码解析(`REDDirectionalPixelMain`、`REDGetShadowTerms`、`REDGetShadowColor`)请参见 [[RED阴影系统#完整代码解析]]。本节仅补充 C++ 端的结构说明。
|
|
|
|
|
|
|
|
|
|
|
|
### LightRendering.cpp — REDDeferredLightPS 类结构
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
// ASW Change : 2016/10/12 21:35:18 Takuro.K
|
|
|
|
|
|
// 继承自标准 FDeferredLightPS,新增 DynamicShadowShade 参数绑定
|
|
|
|
|
|
class REDDeferredLightPS : public FDeferredLightPS
|
|
|
|
|
|
{
|
|
|
|
|
|
DECLARE_SHADER_TYPE(REDDeferredLightPS, Global);
|
|
|
|
|
|
|
|
|
|
|
|
// Shader 参数声明
|
|
|
|
|
|
FShaderParameter DynamicShadowShadeParam;
|
|
|
|
|
|
|
|
|
|
|
|
// 构造函数中绑定参数
|
|
|
|
|
|
REDDeferredLightPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
|
|
|
|
|
|
: FDeferredLightPS(Initializer)
|
|
|
|
|
|
{
|
|
|
|
|
|
DynamicShadowShadeParam.Bind(
|
|
|
|
|
|
Initializer.ParameterMap, TEXT("DynamicShadowShade"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SetParameters 中传入光源的 DynamicShadowShade 值
|
|
|
|
|
|
void SetParameters(FRHICommandList& RHICmdList,
|
|
|
|
|
|
const FSceneView& View,
|
|
|
|
|
|
const FLightSceneInfo* LightSceneInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDeferredLightPS::SetParameters(RHICmdList, View, LightSceneInfo);
|
|
|
|
|
|
|
|
|
|
|
|
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();
|
|
|
|
|
|
// 从光源信息获取 DynamicShadowShade 值并设置到 GPU
|
|
|
|
|
|
SetShaderValue(RHICmdList, ShaderRHI,
|
|
|
|
|
|
DynamicShadowShadeParam,
|
|
|
|
|
|
LightSceneInfo->DynamicShadowShade);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### LightRendering.cpp — 点光源排序
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
// ASW Change : 2019/02/05 20:37:00 Takeshi.N
|
|
|
|
|
|
// 确保点光源在方向光之后渲染,让方向光阴影着色先完成
|
|
|
|
|
|
// bPointLightRED 标志位用于区分 RED 系统的点光源
|
|
|
|
|
|
uint32 SortKey = 0;
|
|
|
|
|
|
SortKey |= bDirectionalLight ? 0 : (1 << DirectionalLightSortBit);
|
|
|
|
|
|
SortKey |= bPointLightRED ? (1 << PointLightSortBit) : 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 排序结果:DirectionalLight(RED) → PointLight(RED) → 其他光源
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### LightRendering.cpp — RED_CUSTOM_LIGHTING 条件分派
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
// 根据 RED_CUSTOM_LIGHTING 宏决定使用标准光照还是 RED 光照
|
|
|
|
|
|
#if RED_CUSTOM_LIGHTING
|
|
|
|
|
|
if (bUseREDLighting)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 使用 REDDeferredLightPS 渲染方向光
|
|
|
|
|
|
TShaderMapRef<REDDeferredLightPS> PixelShader(View.ShaderMap);
|
|
|
|
|
|
// ...
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
#endif
|
|
|
|
|
|
{
|
|
|
|
|
|
// 标准 UE4 Deferred Light 路径
|
|
|
|
|
|
TShaderMapRef<FDeferredLightPS> PixelShader(View.ShaderMap);
|
|
|
|
|
|
// ...
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 代码修改情况
|
|
|
|
|
|
|
|
|
|
|
|
| 文件路径 | 行号 | 修改类型 | 修改内容 |
|
|
|
|
|
|
|---------|------|---------|---------|
|
|
|
|
|
|
| `Source/Runtime/Renderer/Private/LightRendering.cpp` | — | 新增 | `REDDeferredLightPS` 类(继承 `FDeferredLightPS`) |
|
|
|
|
|
|
| `Source/Runtime/Renderer/Private/LightRendering.cpp` | — | 新增 | `DynamicShadowShade` Shader 参数绑定 |
|
|
|
|
|
|
| `Source/Runtime/Renderer/Private/LightRendering.cpp` | — | 修改 | 点光源排序键 `bPointLightRED`(方向光后渲染) |
|
|
|
|
|
|
| `Source/Runtime/Renderer/Private/LightRendering.cpp` | — | 修改 | Decal Emissive → 正常光照贡献 |
|
|
|
|
|
|
| `Shaders/Private/DeferredLightPixelShaders.usf` | L109~L145 | 新增 | `REDDirectionalPixelMain` 入口(详见 [[RED阴影系统]]) |
|
|
|
|
|
|
| `Shaders/Private/DeferredLightPixelShaders.usf` | L236~L239 | 新增 | CustomData → DiffuseColor 覆写 |
|
|
|
|
|
|
| `Shaders/Private/DeferredLightingCommon.ush` | L457~L557 | 新增 | `REDGetShadowTerms` + `REDGetShadowColor`(详见 [[RED阴影系统]]) |
|