Files
BlueRoseNote/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED自定义数据通道.md

276 lines
12 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: 复用 GBuffer CustomData 通道存储轮廓线 ID 和点光源 DiffuseColor
tags:
- ARC
- Rendering
- GBuffer
- Toon
rating: ⭐
---
# RED 自定义数据通道
返回 [[Rendering]]
## 概述
RED 自定义数据通道是 ARC 引擎中一个巧妙的 GBuffer 复用方案。它将 UE4 原有的 **Subsurface Scattering** 数据通道GBufferD CustomData重新用于存储卡通渲染所需的**轮廓线 ID** 和**点光源 DiffuseColor**,避免了新增 GBuffer 通道带来的带宽开销。
## 控制宏
```hlsl
// Definitions.usf
#ifndef USE_RED_CUSTOM_DATA_POINTLIGHT
#define USE_RED_CUSTOM_DATA_POINTLIGHT 0
#endif
#ifndef USE_RED_CUSTOM_DATA
#define USE_RED_CUSTOM_DATA USE_RED_CUSTOM_DATA_POINTLIGHT
#endif
```
两个模式:
- `USE_RED_CUSTOM_DATA` — 基础模式,存储轮廓线 ID从 SubsurfaceData.b 通道读取)
- `USE_RED_CUSTOM_DATA_POINTLIGHT` — 点光源模式,存储 Emissive 作为 DiffuseColor
## 数据写入流程
### 1. 启用 CustomData 写入
`BasePassCommon.ush` 中,将 `USE_RED_CUSTOM_DATA` 加入 `WRITES_CUSTOMDATA_TO_GBUFFER` 条件:
```hlsl
#define WRITES_CUSTOMDATA_TO_GBUFFER (USES_GBUFFER && (
MATERIAL_SHADINGMODEL_SUBSURFACE ||
MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE ||
... ||
USE_RED_CUSTOM_DATA ))
```
### 2. 填充 CustomData
`ShadingModelsMaterial.ush` 中,为 `UNLIT``DEFAULT_LIT` 两个 ShadingModel 注入自定义数据:
```hlsl
#if MATERIAL_SHADINGMODEL_UNLIT
GBuffer.ShadingModelID = SHADINGMODELID_UNLIT;
#if USE_RED_CUSTOM_DATA
GBuffer.CustomData = float4(SubsurfaceColor, SubsurfaceProfile);
#endif
#elif MATERIAL_SHADINGMODEL_DEFAULT_LIT
GBuffer.ShadingModelID = SHADINGMODELID_DEFAULT_LIT;
#if USE_RED_CUSTOM_DATA
GBuffer.CustomData = float4(SubsurfaceColor, SubsurfaceProfile);
#endif
#endif
```
### 3. SubsurfaceColor 的实际含义
`BasePassPixelShader.usf`SubsurfaceColor 被重新赋值:
```hlsl
#if USE_RED_CUSTOM_DATA
{
#if USE_RED_CUSTOM_DATA_POINTLIGHT
// 点光源模式Emissive 作为 DiffuseColor
SubsurfaceColor = Emissive;
SubsurfaceProfile = 0.0;
#else
// 基础模式B 通道存储 OutlineID
float4 SubsurfaceData = GetMaterialSubsurfaceData(PixelMaterialInputs);
SubsurfaceColor = float3(0, 0, 0);
SubsurfaceProfile = SubsurfaceData.b; // OutlineID
#endif
}
#endif
```
### 4. 写入 GBufferD
`DeferredShadingCommon.ush` 中:
```hlsl
#if USE_RED_CUSTOM_DATA
OutGBufferD = GBuffer.CustomData;
#endif
```
## 数据读取
- **轮廓线渲染**:从 GBufferD.b 读取 OutlineID用于区分不同物体的轮廓线参数
- **点光源着色**:从 GBufferD.rgb 读取 DiffuseColor用于 [[RED阴影系统]] 的阴影着色
- **角色辉光**[[自定义后处理]] 中的 CharaGlow 读取 GBufferD.b 作为辉光遮罩
## 设计权衡
| 优点 | 缺点 |
|------|------|
| 零额外 GBuffer 带宽开销 | 无法同时使用 SSS 材质 |
| 复用已有的 CustomData 管线 | UNLIT/DEFAULT_LIT 的 SubsurfaceColor 被占用 |
| 对渲染管线入侵性小 | 两种模式(基础/点光源)互斥 |
## 关联文档
- [[RED阴影系统]] — 点光源模式下 DiffuseColor 的使用方
- [[自定义后处理]] — CharaGlow 读取 OutlineID 通道
- [[GBuffer修改]] — GBufferD 清除色等相关修改
## 完整代码解析
### Definitions.usf — 宏定义
```hlsl
// ASW Change : 2020/01/14 20:19:00 Takeshi.N
// 点光源自定义数据宏:启用时将 Emissive 写入 GBufferD 作为点光源 DiffuseColor
#ifndef USE_RED_CUSTOM_DATA_POINTLIGHT
#define USE_RED_CUSTOM_DATA_POINTLIGHT 0
#endif
// ASW Change : 2018/06/20 14:00:00 Takeshi.N
// 基础自定义数据宏:启用时将 SubsurfaceData.bOutlineID写入 GBufferD
// 默认值跟随点光源模式,即点光源模式开启时基础模式也自动开启
#ifndef USE_RED_CUSTOM_DATA
#define USE_RED_CUSTOM_DATA USE_RED_CUSTOM_DATA_POINTLIGHT
#endif
```
### BasePassCommon.ush — WRITES_CUSTOMDATA_TO_GBUFFER 扩展
```hlsl
// ASW Change : 2018/06/20 14:00:00 Takeshi.N
// 将 USE_RED_CUSTOM_DATA 加入 CustomData 写入条件
// 原始条件仅包含 SSS 相关 ShadingModel现在 RED 自定义数据也可触发 GBufferD 写入
#define WRITES_CUSTOMDATA_TO_GBUFFER (USES_GBUFFER && ( \
MATERIAL_SHADINGMODEL_SUBSURFACE || \
MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || \
MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || \
MATERIAL_SHADINGMODEL_CLEAR_COAT || \
MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || \
MATERIAL_SHADINGMODEL_HAIR || \
MATERIAL_SHADINGMODEL_CLOTH || \
MATERIAL_SHADINGMODEL_EYE || \
USE_RED_CUSTOM_DATA )) // ← 新增条件
```
### ShadingModelsMaterial.ush — UNLIT/DEFAULT_LIT CustomData 填充
```hlsl
// ASW Change : 2018/06/20 14:00:00 Takeshi.N
// 为 UNLIT 着色模型注入自定义数据
// 正常情况下 UNLIT 不写入 GBufferD但 RED 系统需要存储轮廓线 ID
#if MATERIAL_SHADINGMODEL_UNLIT
GBuffer.ShadingModelID = SHADINGMODELID_UNLIT;
#if USE_RED_CUSTOM_DATA
// SubsurfaceColor.rgb = 阴影基色或清零(取决于模式)
// SubsurfaceProfile = OutlineID 或 0.0
GBuffer.CustomData = float4(SubsurfaceColor, SubsurfaceProfile);
#endif
// ASW Change : 2018/06/20 14:00:00 Takeshi.N
// 为 DEFAULT_LIT 着色模型注入自定义数据
// DEFAULT_LIT 原本也不写入 CustomData现在复用该通道
#elif MATERIAL_SHADINGMODEL_DEFAULT_LIT
GBuffer.ShadingModelID = SHADINGMODELID_DEFAULT_LIT;
#if USE_RED_CUSTOM_DATA
GBuffer.CustomData = float4(SubsurfaceColor, SubsurfaceProfile);
#endif
#endif
```
### BasePassPixelShader.usf — SubsurfaceColor 重定义
```hlsl
// ASW Change : 2020/01/14 20:19:00 Takeshi.N (点光源模式)
// ASW Change : 2018/06/20 14:00:00 Takeshi.N (基础模式)
// 在 Base Pass 中重新定义 SubsurfaceColor 的含义
// 这段代码在正式写入 GBuffer 之前执行,覆写材质系统原本的 SubsurfaceColor
#if USE_RED_CUSTOM_DATA
{
#if USE_RED_CUSTOM_DATA_POINTLIGHT
// 点光源模式:
// 将材质的 Emissive 输出作为点光源的 DiffuseColor阴影基色
// 这意味着美术可以在材质编辑器中通过 Emissive 通道控制点光源阴影颜色
SubsurfaceColor = Emissive; // Emissive → DiffuseColor
SubsurfaceProfile = 0.0; // 点光源模式不使用 OutlineID
// 注意:此处覆写后原始 Emissive 功能失效
// 如需自发光效果需通过其他方式实现
#else
// 基础模式:
// 从材质的 SubsurfaceData 读取数据B 通道存储 OutlineID
// OutlineID 用于后续轮廓线渲染中区分不同物体的轮廓线参数
float4 SubsurfaceData = GetMaterialSubsurfaceData(PixelMaterialInputs);
SubsurfaceColor = float3(0, 0, 0); // RGB 清零(基础模式不存储颜色)
SubsurfaceProfile = SubsurfaceData.b; // B 通道 = OutlineID
#endif
}
#endif
```
### DeferredShadingCommon.ush — GBufferD 写入
```hlsl
// ASW Change : 2018/06/20 14:00:00 Takeshi.N
// 在 EncodeGBuffer 函数中,将 CustomData 直接写入 GBufferD
// 原始逻辑中只有 SSS 相关 ShadingModel 才会写入 GBufferD
// 现在通过 USE_RED_CUSTOM_DATA 宏UNLIT 和 DEFAULT_LIT 也可以写入
// 原始代码根据 ShadingModelID 分支写入:
// case SHADINGMODELID_SUBSURFACE: OutGBufferD = ...
// case SHADINGMODELID_SUBSURFACE_PROFILE: OutGBufferD = ...
// RED 修改:在所有分支之后追加无条件覆写
#if USE_RED_CUSTOM_DATA
// 无论 ShadingModelID 是什么,都将 CustomData 写入 GBufferD
// 这确保了 UNLIT/DEFAULT_LIT 材质的数据也能正确输出
OutGBufferD = GBuffer.CustomData;
#endif
// 注意:这个覆写意味着如果同时启用了 RED_CUSTOM_DATA 和 SSS 材质,
// SSS 的 CustomData 也会被覆写为 RED 的数据
// 这是设计上的权衡——RED 系统下不支持 SSS 材质
```
### 数据流总结
```
┌─────────────────────────────────────────────────────────────────┐
│ 材质编辑器 │
│ 基础模式SubsurfaceData.b → OutlineID │
│ 点光源模式Emissive → DiffuseColor │
└─────────────────┬───────────────────────────────────────────────┘
│ BasePassPixelShader.usf
┌─────────────────────────────────────────────────────────────────┐
│ SubsurfaceColor / SubsurfaceProfile 重新赋值 │
│ 点光源模式SubsurfaceColor = Emissive │
│ 基础模式SubsurfaceProfile = SubsurfaceData.b │
└─────────────────┬───────────────────────────────────────────────┘
│ ShadingModelsMaterial.ush
┌─────────────────────────────────────────────────────────────────┐
│ GBuffer.CustomData = float4(SubsurfaceColor, SubsurfaceProfile) │
└─────────────────┬───────────────────────────────────────────────┘
│ DeferredShadingCommon.ush
┌─────────────────────────────────────────────────────────────────┐
│ OutGBufferD = GBuffer.CustomData │
│ → GBufferD.rgb = DiffuseColor点光源阴影基色
│ → GBufferD.b = OutlineID轮廓线 ID
└─────────────────────────────────────────────────────────────────┘
```
## 代码修改情况
| 文件路径 | 行号 | 修改类型 | 修改内容 |
|---------|------|---------|---------|
| `Shaders/Private/Definitions.usf` | L65~L76 | 新增 | `USE_RED_CUSTOM_DATA_POINTLIGHT``USE_RED_CUSTOM_DATA` 宏定义 |
| `Shaders/Private/BasePassCommon.ush` | L28~L34 | 修改 | `TRANSLUCENCY_NEEDS_BASEPASS_FOGGING` 添加 `!USES_SCREEN_ALIGNED_MESH` |
| `Shaders/Private/BasePassCommon.ush` | L51~L57 | 修改 | `WRITES_CUSTOMDATA_TO_GBUFFER` 添加 `USE_RED_CUSTOM_DATA` 条件 |
| `Shaders/Private/ShadingModelsMaterial.ush` | L35~L53 | 新增 | `UNLIT``DEFAULT_LIT` 的 CustomData 写入逻辑 |
| `Shaders/Private/BasePassPixelShader.usf` | L928~L943 | 新增 | SubsurfaceColor 重定义OutlineID / PointLight DiffuseColor |
| `Shaders/Private/DeferredShadingCommon.ush` | L403~L409 | 修改 | Unlit 路径 GBufferD 写入 `GBuffer.CustomData` |