2026-05-03 20:37:58 +08:00
|
|
|
|
---
|
|
|
|
|
|
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 清除色等相关修改
|
|
|
|
|
|
|
2026-05-03 21:38:46 +08:00
|
|
|
|
## 完整代码解析
|
|
|
|
|
|
|
|
|
|
|
|
### 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.b(OutlineID)写入 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` |
|