From 0a81d4ee33dc1e6b47363d5e6722438265e119a6 Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Sun, 3 May 2026 21:38:46 +0800 Subject: [PATCH] vault backup: 2026-05-03 21:38:46 --- .../渲染功能/ARC/Animation/Animation.md | 164 +++++++- .../渲染功能/ARC/Animation/FBX导入扩展.md | 76 ---- .../渲染功能/ARC/Animation/常量关键帧压缩.md | 56 --- .../渲染功能/ARC/D3D12RHI/D3D12RHI.md | 154 +++++++- .../渲染功能/ARC/D3D12RHI/DRED调试增强.md | 46 --- .../渲染功能/ARC/D3D12RHI/其他RHI改进.md | 79 ---- .../渲染功能/ARC/D3D12RHI/提交间隔记录器.md | 35 -- .../渲染功能/ARC/Gameplay/REDSceneContext.md | 40 +- .../渲染功能/ARC/Gameplay/RED场景视图类型.md | 36 +- .../渲染功能/ARC/Gameplay/UEI事件系统.md | 43 ++- .../渲染功能/ARC/Gameplay/相机系统扩展.md | 29 +- .../渲染功能/ARC/Particle/Particle.md | 105 +++++- .../渲染功能/ARC/Particle/粒子点光源系统.md | 68 ---- .../渲染功能/ARC/Platform/PS4支持.md | 58 --- .../渲染功能/ARC/Platform/PS5支持.md | 47 --- .../渲染功能/ARC/Platform/Platform.md | 139 ++++++- .../渲染功能/ARC/Platform/XboxOne支持.md | 36 -- .../渲染功能/ARC/Rendering/BGMultColor全局色调.md | 92 ++++- .../渲染功能/ARC/Rendering/BasePass修改.md | 102 ++++- .../渲染功能/ARC/Rendering/GBuffer修改.md | 49 ++- .../渲染功能/ARC/Rendering/RED自定义数据通道.md | 161 +++++++- .../渲染功能/ARC/Rendering/RED阴影系统.md | 282 +++++++++++++- .../渲染功能/ARC/Rendering/光线追踪与PSO.md | 42 ++- .../渲染功能/ARC/Rendering/局部位置缩放.md | 66 +++- .../渲染功能/ARC/Rendering/屏幕对齐网格.md | 80 +++- .../渲染功能/ARC/Rendering/屏幕空间深度偏移.md | 49 ++- .../渲染功能/ARC/Rendering/正交投影混合.md | 189 +++++++++- .../渲染功能/ARC/Rendering/自定义光照Pass.md | 89 ++++- .../渲染功能/ARC/Rendering/自定义后处理.md | 357 +++++++++++++++++- .../渲染功能/ARC/Rendering/自定义材质属性.md | 77 +++- .../渲染功能/ARC/UI/Slate扩展.md | 68 ---- .../卡通渲染相关资料/渲染功能/ARC/UI/UI.md | 242 +++++++++++- .../渲染功能/ARC/UI/UMG本地化.md | 60 --- .../渲染功能/ARC/UI/简单元素渲染扩展.md | 71 ---- 34 files changed, 2442 insertions(+), 845 deletions(-) delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/FBX导入扩展.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/常量关键帧压缩.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/DRED调试增强.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/其他RHI改进.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/提交间隔记录器.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Particle/粒子点光源系统.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/PS4支持.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/PS5支持.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/XboxOne支持.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/Slate扩展.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UMG本地化.md delete mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/简单元素渲染扩展.md diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/Animation.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/Animation.md index 8e86497..1c821e6 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/Animation.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/Animation.md @@ -1,7 +1,7 @@ --- title: Animation date: 2026-05-03 00:00:00 -excerpt: ARC 引擎动画系统修改分类索引 +excerpt: ARC 引擎动画系统修改:常量关键帧压缩、FBX 导入扩展 tags: - ARC - Animation @@ -18,7 +18,161 @@ ARC 引擎的动画系统修改围绕**格斗游戏对帧精确动画的需求** ## 功能列表 -| 功能 | 文档 | 说明 | -|------|------|------| -| 常量关键帧压缩 | [[常量关键帧压缩]] | 60fps 帧限动画、4F 间隔校正 | -| FBX 导入扩展 | [[FBX导入扩展]] | RED 动画数据、轮廓线 ID、首末帧处理 | +| 功能 | 说明 | +|------|------| +| 常量关键帧压缩 | 60fps 帧限动画、4F 间隔校正 | +| FBX 导入扩展 | RED 动画数据、轮廓线 ID、首末帧处理 | + +## 常量关键帧压缩 + +### 概述 + +新增 `AnimCompress_Constant` 压缩方案,将动画关键帧限定在 60fps 的固定帧率网格上。格斗游戏的核心机制(攻击判定、无敌帧、帧优势等)要求动画在每一帧的状态都是确定性的,不能依赖插值。 + +### 实现 + +#### AnimCompress_Constant + +```cpp +// AnimCompress_Constant.h/.cpp +// 常量关键帧插值 — 不做帧间插值,直接使用最近的关键帧 +``` + +核心行为: +- 每帧独立存储(不做 delta 编码) +- 运行时取值不做线性插值,直接 snap 到最近关键帧 +- 确保 60fps 下每帧状态与 DCC 工具导出完全一致 + +#### 4F 间隔自动校正 + +Avatar 动画使用 4 帧间隔(15fps 的关键帧),自动校正导入的帧时间到 4F 网格: + +``` +原始帧: 0, 3, 7, 11, ... +校正后: 0, 4, 8, 12, ... (snap 到 4F 倍数) +``` + +#### AnimCompress_Automatic 扩展 + +标准 UE4 的 `AnimCompress_Automatic` 也被扩展以支持常量帧模式选项。 + +### 完整代码解析 + +```cpp +// AnimCompress_Constant.h/.cpp +// 常量关键帧压缩 — 不做帧间插值 +class UAnimCompress_Constant : public UAnimCompress +{ + // 每帧独立存储位置/旋转/缩放 + // 运行时取值 snap 到最近关键帧(不做线性插值) + // 确保 60fps 下每帧状态确定性 + + // 4F 间隔自动校正(Avatar 动画): + // 将导入的帧时间 snap 到 4 帧倍数 + // 原始帧: 0, 3, 7, 11, ... + // 校正后: 0, 4, 8, 12, ... +}; +``` + +### 关联文档 + +- [[Animation#FBX 导入扩展]] — `bImportREDAnimationData` 控制导入时的帧限处理 + +### 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/Engine/Public/Animation/AnimCompress_Constant.h` | **新增文件** | 常量关键帧压缩类声明 | +| `Source/Runtime/Engine/Private/Animation/AnimCompress_Constant.cpp` | **新增文件** | 实现:无插值采样 + 4F 间隔校正 | +| `Source/Runtime/Engine/Public/Animation/AnimCompress_Automatic.h` | 修改 | 扩展支持常量帧模式选项 | + +## FBX 导入扩展 + +### 概述 + +ARC 引擎大幅扩展了 FBX 导入功能,添加了格斗游戏和卡通渲染所需的专用数据导入支持。 + +### RED 动画数据导入 + +`bImportREDAnimationData` 选项启用时: +- 动画以 60fps 帧限模式导入 +- 关键帧 snap 到固定帧率网格 +- 配合常量关键帧压缩使用 + +### 首末帧处理 + +两个独立选项: +- **首帧删除** — 删除动画第一帧(DCC 工具常在第 0 帧放置 T-Pose) +- **末帧复制** — 将最后一个关键帧复制到动画末尾(确保循环动画平滑衔接) + +### 轮廓线 ID 导入 + +`OutlineIndexUVChannel` 选项指定从哪个 UV 通道导入轮廓线 ID: + +``` +UV Channel 0 → 标准 UV +UV Channel 1 → Lightmap UV +UV Channel N → OutlineID 数据(由美术在 DCC 中绘制) +``` + +导入后的 OutlineID 存储在网格数据中,BasePass 时写入 GBufferD 供 [[RED自定义数据通道]] 使用。 + +### 法线导入模式扩展 + +新增法线处理模式: + +```cpp +// FBXNIM_ImportNormalsAndComputeNormalsToTangents +// 导入法线 + 从法线计算切线 +// (标准 UE4 只有导入法线、计算法线、导入法线和切线三种) +``` + +### XSI 2015 支持 + +扩展 FBX 导入器支持 Softimage XSI 2015 格式的 FBX 文件。 + +### LOD 重导入 + +骨骼网格和静态网格的 LOD 重导入时保留 OutlineID 数据和 RED 自定义骨骼网格数据。 + +### 完整代码解析 + +```cpp +// FbxImporter.h — 新增导入选项 +struct FBXImportOptions +{ + bool bImportREDAnimationData; // 启用 60fps 帧限动画导入 + bool bDeleteFirstFrame; // 删除第一帧(T-Pose) + bool bCopyLastFrame; // 复制末帧到动画结尾 + int32 OutlineIndexUVChannel; // 轮廓线 ID 所在的 UV 通道 + // -1 = 不导入 OutlineID + // 0 = UV0, 1 = UV1, ... N = UVN +}; + +// 法线导入模式扩展 +enum EFBXNormalImportMethod +{ + FBXNIM_ComputeNormals, + FBXNIM_ImportNormals, + FBXNIM_ImportNormalsAndTangents, + FBXNIM_ImportNormalsAndComputeNormalsToTangents // <-- ASW 新增 + // 导入法线 + 从导入的法线计算切线 + // 标准 UE4 只支持"导入法线和切线"或"完全计算" +}; +``` + +### 关联文档 + +- [[RED自定义数据通道]] — OutlineID 的渲染端使用 + +### 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Editor/UnrealEd/Public/FbxImporter.h` | 修改 | 新增 `bImportREDAnimationData`、`OutlineIndexUVChannel` 等选项 | +| `Source/Editor/UnrealEd/Private/Fbx/FbxAnimationImport.cpp` | 修改 | 60fps 帧限导入 + 首末帧处理 | +| `Source/Editor/UnrealEd/Private/Fbx/FbxMeshImport.cpp` | 修改 | 轮廓线 ID 从 UV 通道导入 | +| `Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp` | 修改 | XSI 2015 FBX 格式支持 | +| `Source/Editor/UnrealEd/Private/Fbx/FbxStaticMeshImport.cpp` | 修改 | `FBXNIM_ImportNormalsAndComputeNormalsToTangents` 法线模式 | +| `Source/Editor/UnrealEd/Private/SkeletalMeshEdit.cpp` | 修改 | LOD 重导入时保留 OutlineID | +| `Source/Editor/UnrealEd/Private/StaticMeshEdit.cpp` | 修改 | 同上 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/FBX导入扩展.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/FBX导入扩展.md deleted file mode 100644 index 241dbd0..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/FBX导入扩展.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: FBX导入扩展 -date: 2026-05-03 00:00:00 -excerpt: RED 动画数据导入、轮廓线 ID 导入、首末帧处理、XSI 支持 -tags: - - ARC - - Animation - - FBX - - Editor -rating: ⭐ ---- - -# FBX 导入扩展 - -返回 [[Animation]] - -## 概述 - -ARC 引擎大幅扩展了 FBX 导入功能,添加了格斗游戏和卡通渲染所需的专用数据导入支持。 - -## RED 动画数据导入 - -`bImportREDAnimationData` 选项启用时: -- 动画以 60fps 帧限模式导入 -- 关键帧 snap 到固定帧率网格 -- 配合 [[常量关键帧压缩]] 使用 - -## 首末帧处理 - -两个独立选项: -- **首帧删除** — 删除动画第一帧(DCC 工具常在第 0 帧放置 T-Pose) -- **末帧复制** — 将最后一个关键帧复制到动画末尾(确保循环动画平滑衔接) - -## 轮廓线 ID 导入 - -`OutlineIndexUVChannel` 选项指定从哪个 UV 通道导入轮廓线 ID: - -``` -UV Channel 0 → 标准 UV -UV Channel 1 → Lightmap UV -UV Channel N → OutlineID 数据(由美术在 DCC 中绘制) -``` - -导入后的 OutlineID 存储在网格数据中,BasePass 时写入 GBufferD 供 [[RED自定义数据通道]] 使用。 - -## 法线导入模式扩展 - -新增法线处理模式: - -```cpp -// FBXNIM_ImportNormalsAndComputeNormalsToTangents -// 导入法线 + 从法线计算切线 -// (标准 UE4 只有导入法线、计算法线、导入法线和切线三种) -``` - -## XSI 2015 支持 - -扩展 FBX 导入器支持 Softimage XSI 2015 格式的 FBX 文件。 - -## LOD 重导入 - -骨骼网格和静态网格的 LOD 重导入时保留 OutlineID 数据和 RED 自定义骨骼网格数据。 - -## 关联文档 - -- [[常量关键帧压缩]] — 动画压缩方案 -- [[RED自定义数据通道]] — OutlineID 的渲染端使用 - -## 修改文件列表 - -| 文件 | 修改类型 | -|------|---------| -| `Source/Editor/UnrealEd/Private/Fbx/` (多个文件) | FBX 导入扩展 | -| `Source/Editor/UnrealEd/Public/FbxImporter.h` | 选项定义 | -| `Source/Editor/UnrealEd/Private/SkeletalMeshEdit.cpp` | LOD 重导入 | -| `Source/Editor/UnrealEd/Private/StaticMeshEdit.cpp` | 同上 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/常量关键帧压缩.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/常量关键帧压缩.md deleted file mode 100644 index b558b6a..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Animation/常量关键帧压缩.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: 常量关键帧压缩 -date: 2026-05-03 00:00:00 -excerpt: 60fps 帧限动画和 4F 间隔自动校正,确保格斗游戏帧精确播放 -tags: - - ARC - - Animation -rating: ⭐ ---- - -# 常量关键帧压缩 - -返回 [[Animation]] - -## 概述 - -新增 `AnimCompress_Constant` 压缩方案,将动画关键帧限定在 60fps 的固定帧率网格上。格斗游戏的核心机制(攻击判定、无敌帧、帧优势等)要求动画在每一帧的状态都是确定性的,不能依赖插值。 - -## 实现 - -### AnimCompress_Constant - -```cpp -// AnimCompress_Constant.h/.cpp -// 常量关键帧插值 — 不做帧间插值,直接使用最近的关键帧 -``` - -核心行为: -- 每帧独立存储(不做 delta 编码) -- 运行时取值不做线性插值,直接 snap 到最近关键帧 -- 确保 60fps 下每帧状态与 DCC 工具导出完全一致 - -### 4F 间隔自动校正 - -Avatar 动画使用 4 帧间隔(15fps 的关键帧),自动校正导入的帧时间到 4F 网格: - -``` -原始帧: 0, 3, 7, 11, ... -校正后: 0, 4, 8, 12, ... (snap 到 4F 倍数) -``` - -### AnimCompress_Automatic 扩展 - -标准 UE4 的 `AnimCompress_Automatic` 也被扩展以支持常量帧模式选项。 - -## 关联文档 - -- [[FBX导入扩展]] — `bImportREDAnimationData` 控制导入时的帧限处理 - -## 修改文件列表 - -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Engine/Public/Animation/AnimCompress_Constant.h` | **新增** | -| `Source/Runtime/Engine/Private/Animation/AnimCompress_Constant.cpp` | **新增** | -| `Source/Runtime/Engine/Public/Animation/AnimCompress_Automatic.h` | 扩展 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/D3D12RHI.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/D3D12RHI.md index 9e55423..f1d5b3f 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/D3D12RHI.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/D3D12RHI.md @@ -1,7 +1,7 @@ --- title: D3D12RHI date: 2026-05-03 00:00:00 -excerpt: ARC 引擎 D3D12 RHI 改进分类索引 +excerpt: ARC 引擎 D3D12 RHI 改进——提交间隔记录器、DRED 调试增强、PSO 异步创建、纹理池管理等 tags: - ARC - D3D12RHI @@ -18,12 +18,154 @@ D3D12RHI 是 ARC 引擎修改量第二大的模块(60 个文件),但与卡 ## 功能列表 -| 功能 | 文档 | 说明 | -|------|------|------| -| 提交间隔记录器 | [[提交间隔记录器]] | GPU 帧间提交间隔分析 | -| DRED 调试增强 | [[DRED调试增强]] | GPU 崩溃时的扩展诊断 | -| 其他 RHI 改进 | [[其他RHI改进]] | PSO 异步、纹理池、CommandList 等 | +| 功能 | 说明 | +|------|------| +| 提交间隔记录器 | GPU 帧间提交间隔分析 | +| DRED 调试增强 | GPU 崩溃时的扩展诊断 | +| 其他 RHI 改进 | PSO 异步、纹理池、CommandList 等 | ## 新增文件 - `Source/Runtime/D3D12RHI/Public/D3D12RHIBridge.h` — 暴露 D3D12 命令队列供外部访问 + +--- + +## 提交间隔记录器 + +### 概述 + +Submission Gap Recorder(`D3D12_SUBMISSION_GAP_RECORDER`)是一个 GPU 性能分析系统,记录 D3D12 Command List 提交之间的间隔时间,用于识别 CPU-GPU 同步瓶颈和提交延迟。 + +### 功能 + +- 记录每帧 Command List 提交的时间戳 +- 计算相邻提交之间的间隔(Gap) +- 识别异常长的提交间隔(可能的 CPU stall 或 GPU bubble) +- 提供统计数据用于性能优化 + +### 使用场景 + +- 分析格斗游戏中的帧率卡顿原因 +- 排查 CPU 提交瓶颈 +- 验证多线程命令录制的效率 + +### 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/D3D12RHI/Private/D3D12Commands.cpp` | 修改 | Command List 提交路径插入时间戳记录 | +| `Source/Runtime/D3D12RHI/Private/D3D12CommandList.h` | 修改 | `D3D12_SUBMISSION_GAP_RECORDER` 宏和数据结构 | +| `Source/Runtime/D3D12RHI/Private/D3D12Queue.cpp` | 修改 | 提交间隔计算和统计输出 | + +--- + +## DRED 调试增强 + +### 概述 + +DRED(Device Removed Extended Data)是 D3D12 的 GPU 崩溃诊断机制。ARC 引擎增强了 DRED 的使用,在 GPU 崩溃时提供更详细的面包屑(Breadcrumb)上下文信息。 + +### 增强内容 + +#### 面包屑上下文 + +在关键渲染操作处插入 Breadcrumb 标记,GPU 崩溃时可以追溯到具体的操作步骤: + +- 绘制调用标记 +- 资源状态转换标记 +- 计算着色器调度标记 + +#### 向量化异常处理器 + +新增 Vectored Exception Handler,在 Windows 异常触发时检查 D3D12 Debug 消息: + +- 捕获 D3D12 设备丢失事件 +- 自动收集 DRED 信息 +- 输出到日志供崩溃分析 + +### 使用场景 + +- 主机开发中 GPU 挂起的排查 +- 复杂着色器导致的设备丢失诊断 +- CI/CIS 环境中的自动化崩溃分析 + +### 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/D3D12RHI/Private/D3D12Device.cpp` | 修改 | DRED 初始化和 Breadcrumb 配置 | +| `Source/Runtime/D3D12RHI/Private/D3D12Commands.cpp` | 修改 | 关键操作处插入 Breadcrumb 标记 | +| `Source/Runtime/D3D12RHI/Private/D3D12Util.cpp` | 修改 | Vectored Exception Handler 注册 + D3D12 Debug 消息检查 | + +--- + +## 其他 RHI 改进 + +### 概述 + +ARC 引擎在 D3D12 RHI 层面做了多项基础设施改进,涵盖 PSO 管理、纹理内存、命令列表执行和光线追踪支持。 + +### PSO 异步创建 + +#### Busy-Wait + Stall 告警 + +PSO 创建改为异步模式,当 Shader 未就绪时 busy-wait 并记录 stall 时间: + +```cpp +// PSO 创建等待时输出告警日志 +// 帮助识别哪些 Shader 组合导致了渲染卡顿 +``` + +#### 部分编译(bPartial) + +Ray Tracing Pipeline 支持部分编译——不需要等待所有 Hit Shader 就绪即可使用基础管线。参见 [[光线追踪与PSO]]。 + +### 纹理池管理 + +新增 CVar `D3D12.TexturePoolOnlyAccountStreamableTexture`: +- 纹理池统计时仅计算可流式加载的纹理 +- 避免非流式纹理(如 UI、字体)干扰流式预算 + +### CommandList 任务分流 + +CVar `r.D3D12.ExecuteCommandListTask`: +- 将部分 Command List 执行工作从 RHI 线程分流到 Task 线程 +- 减少 RHI 线程压力 + +### Ray Tracing 改进 + +- View Descriptor Heap 扩展到 250k 描述符 +- BLAS Compaction 支持(减少加速结构内存占用) +- PSO 缓存改进 + +### Buffer Staging + +改进 GPU Readback 的 Staging Buffer 管理,减少 CPU-GPU 同步开销。 + +### Back Buffer 引用 + +安全处理 Presentable Texture 的引用计数,防止拷贝操作时的悬空引用。 + +### D3D12RHIBridge + +新增 `D3D12RHIBridge.h`,暴露底层接口供外部模块使用: + +```cpp +// 获取图形命令列表和队列 +GetGfxCommandListAndQueue(); + +// 获取拷贝命令队列 +GetCopyCommandQueue(); +``` + +### 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/D3D12RHI/Private/D3D12PipelineState.cpp` | 修改 | PSO 异步创建 + Busy-Wait + Stall 告警日志 | +| `Source/Runtime/D3D12RHI/Private/D3D12Texture.cpp` | 修改 | `TexturePoolOnlyAccountStreamableTexture` CVar 纹理池统计 | +| `Source/Runtime/D3D12RHI/Private/D3D12Commands.cpp` | 修改 | `ExecuteCommandListTask` CVar 任务分流 | +| `Source/Runtime/D3D12RHI/Private/D3D12RayTracing.cpp` | 修改 | View Descriptor Heap 250k + BLAS Compaction | +| `Source/Runtime/D3D12RHI/Private/D3D12Staging.cpp` | 修改 | Staging Buffer 改进 | +| `Source/Runtime/D3D12RHI/Private/D3D12Viewport.cpp` | 修改 | Back Buffer 引用安全处理 | +| `Source/Runtime/D3D12RHI/Public/D3D12RHIBridge.h` | **新增文件** | 暴露 `GetGfxCommandListAndQueue` / `GetCopyCommandQueue` | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/DRED调试增强.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/DRED调试增强.md deleted file mode 100644 index 553f98b..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/DRED调试增强.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: DRED调试增强 -date: 2026-05-03 00:00:00 -excerpt: Device Removed Extended Data 增强,GPU 崩溃时提供面包屑上下文 -tags: - - ARC - - D3D12RHI - - Debug -rating: ⭐ ---- - -# DRED 调试增强 - -返回 [[D3D12RHI]] - -## 概述 - -DRED(Device Removed Extended Data)是 D3D12 的 GPU 崩溃诊断机制。ARC 引擎增强了 DRED 的使用,在 GPU 崩溃时提供更详细的面包屑(Breadcrumb)上下文信息。 - -## 增强内容 - -### 面包屑上下文 - -在关键渲染操作处插入 Breadcrumb 标记,GPU 崩溃时可以追溯到具体的操作步骤: - -- 绘制调用标记 -- 资源状态转换标记 -- 计算着色器调度标记 - -### 向量化异常处理器 - -新增 Vectored Exception Handler,在 Windows 异常触发时检查 D3D12 Debug 消息: - -- 捕获 D3D12 设备丢失事件 -- 自动收集 DRED 信息 -- 输出到日志供崩溃分析 - -## 使用场景 - -- 主机开发中 GPU 挂起的排查 -- 复杂着色器导致的设备丢失诊断 -- CI/CIS 环境中的自动化崩溃分析 - -## 修改文件 - -涉及 D3D12RHI 模块的设备创建、命令列表执行和异常处理路径。 diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/其他RHI改进.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/其他RHI改进.md deleted file mode 100644 index 160a30b..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/其他RHI改进.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: 其他RHI改进 -date: 2026-05-03 00:00:00 -excerpt: PSO 异步创建、纹理池管理、CommandList 任务分流等 D3D12 改进 -tags: - - ARC - - D3D12RHI -rating: ⭐ ---- - -# 其他 RHI 改进 - -返回 [[D3D12RHI]] - -## 概述 - -ARC 引擎在 D3D12 RHI 层面做了多项基础设施改进,涵盖 PSO 管理、纹理内存、命令列表执行和光线追踪支持。 - -## PSO 异步创建 - -### Busy-Wait + Stall 告警 - -PSO 创建改为异步模式,当 Shader 未就绪时 busy-wait 并记录 stall 时间: - -```cpp -// PSO 创建等待时输出告警日志 -// 帮助识别哪些 Shader 组合导致了渲染卡顿 -``` - -### 部分编译(bPartial) - -Ray Tracing Pipeline 支持部分编译——不需要等待所有 Hit Shader 就绪即可使用基础管线。参见 [[光线追踪与PSO]]。 - -## 纹理池管理 - -新增 CVar `D3D12.TexturePoolOnlyAccountStreamableTexture`: -- 纹理池统计时仅计算可流式加载的纹理 -- 避免非流式纹理(如 UI、字体)干扰流式预算 - -## CommandList 任务分流 - -CVar `r.D3D12.ExecuteCommandListTask`: -- 将部分 Command List 执行工作从 RHI 线程分流到 Task 线程 -- 减少 RHI 线程压力 - -## Ray Tracing 改进 - -- View Descriptor Heap 扩展到 250k 描述符 -- BLAS Compaction 支持(减少加速结构内存占用) -- PSO 缓存改进 - -## Buffer Staging - -改进 GPU Readback 的 Staging Buffer 管理,减少 CPU-GPU 同步开销。 - -## Back Buffer 引用 - -安全处理 Presentable Texture 的引用计数,防止拷贝操作时的悬空引用。 - -## D3D12RHIBridge - -新增 `D3D12RHIBridge.h`,暴露底层接口供外部模块使用: - -```cpp -// 获取图形命令列表和队列 -GetGfxCommandListAndQueue(); - -// 获取拷贝命令队列 -GetCopyCommandQueue(); -``` - -## 修改文件列表 - -涉及 `Source/Runtime/D3D12RHI/` 下约 60 个文件,主要覆盖: -- `Private/D3D12Commands.cpp` — CommandList 执行 -- `Private/D3D12PipelineState.cpp` — PSO 缓存 -- `Private/D3D12Texture.cpp` — 纹理池 -- `Private/D3D12RayTracing.cpp` — RT 改进 -- `Public/D3D12RHIBridge.h` — **新增** diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/提交间隔记录器.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/提交间隔记录器.md deleted file mode 100644 index 075a7e9..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/D3D12RHI/提交间隔记录器.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: 提交间隔记录器 -date: 2026-05-03 00:00:00 -excerpt: D3D12 Submission Gap Recorder,追踪 GPU 帧间提交间隔用于性能分析 -tags: - - ARC - - D3D12RHI - - Profiling -rating: ⭐ ---- - -# 提交间隔记录器 - -返回 [[D3D12RHI]] - -## 概述 - -Submission Gap Recorder(`D3D12_SUBMISSION_GAP_RECORDER`)是一个 GPU 性能分析系统,记录 D3D12 Command List 提交之间的间隔时间,用于识别 CPU-GPU 同步瓶颈和提交延迟。 - -## 功能 - -- 记录每帧 Command List 提交的时间戳 -- 计算相邻提交之间的间隔(Gap) -- 识别异常长的提交间隔(可能的 CPU stall 或 GPU bubble) -- 提供统计数据用于性能优化 - -## 使用场景 - -- 分析格斗游戏中的帧率卡顿原因 -- 排查 CPU 提交瓶颈 -- 验证多线程命令录制的效率 - -## 修改文件 - -涉及 D3D12RHI 模块多个文件,主要在命令列表管理和提交路径中插入时间戳记录点。 diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/REDSceneContext.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/REDSceneContext.md index 70e03d2..030a0d3 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/REDSceneContext.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/REDSceneContext.md @@ -44,14 +44,44 @@ Shader (View.BGMultColor, View.DisasterPosition, ...) `DisasterPosition`、`DisasterWind`、`DisasterQuake` 三个参数用于格斗游戏中的必杀技演出——场景因攻击而震动、风吹、变形等效果,由 Shader 读取这些参数来驱动场景顶点动画和粒子。 +## 完整代码解析 + +```cpp +// REDSceneContext.h — 全局 Shader 数据管线 +UCLASS() +class UREDSceneContext : public UObject +{ + GENERATED_BODY() +public: + // 场景全局色调(RGB=颜色乘数, A=饱和度) + UPROPERTY(EditAnywhere) + FLinearColor BGMultColor = FLinearColor(1,1,1,1); + + // 灾害效果参数(必杀技演出用) + UPROPERTY(EditAnywhere) + FVector DisasterPosition; // 灾害中心位置 + FVector DisasterWind; // 风力方向和强度 + float DisasterQuake; // 震动强度 + + // 时间参数 + float GameTime; // 游戏时间(可暂停) + float BGTime; // 背景时间(独立于游戏时间) +}; + +// SceneRendering.cpp — 数据传递到 ViewUniform +ViewUniformShaderParameters.BGMultColor = SceneContext->BGMultColor; +ViewUniformShaderParameters.DisasterPosition = SceneContext->DisasterPosition; +// ... Shader 中通过 View.BGMultColor 等访问 +``` + ## 关联文档 - [[BGMultColor全局色调]] — 使用 `BGMultColor` 参数 - [[RED场景视图类型]] — 场景分层与 Context 配合 -## 修改文件列表 +## 代码修改情况 -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Engine/Public/REDSceneContext.h` | **新增** | -| `Source/Runtime/Renderer/Private/SceneRendering.cpp` | 读取 Context 写入 ViewUniform | +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/Engine/Public/REDSceneContext.h` | **新增文件** | `UREDSceneContext` 类(BGMultColor/Disaster/Time) | +| `Source/Runtime/Renderer/Private/SceneRendering.cpp` | 修改 | 读取 Context 写入 `ViewUniformShaderParameters` | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/RED场景视图类型.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/RED场景视图类型.md index e63eabd..53cc198 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/RED场景视图类型.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/RED场景视图类型.md @@ -53,10 +53,34 @@ enum class EREDSceneViewType - 特效层独立的 Bloom 和后处理参数 - 对战 UI(血条等)使用 HUD 层,不受场景后处理影响 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Engine/Public/EngineTypes.h` | `EREDSceneViewType` 枚举 | -| `Source/Runtime/Engine/Classes/GameFramework/PlayerController.h` | `GetREDSceneViewTypeFlag()` | -| `Source/Runtime/Renderer/Private/SceneVisibility.cpp` | 可见性过滤 | +```cpp +// EngineTypes.h — 场景视图类型枚举 +// ASW 新增:将场景 Actor 按类型分层 +enum class EREDSceneViewType : uint8 +{ + REDSceneView_Character, // 角色层(玩家、AI) + REDSceneView_Effect, // 特效层(粒子、光柱等) + REDSceneView_BG, // 背景主层 + REDSceneView_BG_Layer1, // 背景分层1(近景装饰) + REDSceneView_BG_Layer2, // 背景分层2 + // ... Layer3 ~ Layer8 // 更多背景分层 + REDSceneView_HUD // HUD 层 +}; + +// PlayerController 端 +// 获取当前需要渲染的层级位掩码 +uint32 GetREDSceneViewTypeFlag() const; +// 例如:只渲染角色和特效 +// return (1 << REDSceneView_Character) | (1 << REDSceneView_Effect); +``` + +## 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/Engine/Public/EngineTypes.h` | 新增 | `EREDSceneViewType` 枚举(Character/Effect/BG/HUD 等) | +| `Source/Runtime/Engine/Classes/GameFramework/PlayerController.h` | 新增 | `GetREDSceneViewTypeFlag()` 层级位掩码 | +| `Source/Runtime/Renderer/Private/SceneVisibility.cpp` | 修改 | 按 REDSceneViewType 过滤可见性 | +| `Source/Runtime/Renderer/Private/SceneRendering.cpp` | 修改 | 自定义排序键处理 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/UEI事件系统.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/UEI事件系统.md index a242c06..1d0ce82 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/UEI事件系统.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/UEI事件系统.md @@ -55,10 +55,41 @@ class FUEISlateApplication : public FSlateApplication - 回放系统:按帧记录和回放输入 - 控制器热插拔处理 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Engine/Public/UEIEventHandler.h` | **新增** | -| `Source/Runtime/Slate/Public/Framework/Application/UEISlateApplication.h` | **新增** | -| `Source/Runtime/Slate/Private/Framework/Application/UEISlateApplication.cpp` | **新增** | +```cpp +// UEIEventHandler.h — 引擎回调接口 +class FUEIEventHandler +{ +public: + // 帧生命周期回调 + virtual void BeginFrame(); // 帧开始(输入采样时机) + virtual void EndFrame(); // 帧结束 + virtual void Update(); // 逻辑更新 + + // 格斗游戏需要在精确的时间点采样输入 + // 确保回放系统的帧同步正确性 +}; + +// UEISlateApplication.h — Slate 输入管理扩展 +class FUEISlateApplication : public FSlateApplication +{ + // User/Controller ID 映射表 + // Key: 物理控制器 Index + // Value: 游戏内玩家 ID + TMap UserIndexMap; + + // 格斗游戏场景: + // 手柄1 (Index=0) → Player 1 (ID=0) + // 手柄3 (Index=2) → Player 2 (ID=1) + // 允许任意手柄对应任意玩家槽位 +}; +``` + +## 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/Engine/Public/UEIEventHandler.h` | **新增文件** | `FUEIEventHandler` 帧生命周期回调接口 | +| `Source/Runtime/Slate/Public/Framework/Application/UEISlateApplication.h` | **新增文件** | `FUEISlateApplication` 控制器映射 | +| `Source/Runtime/Slate/Private/Framework/Application/UEISlateApplication.cpp` | **新增文件** | 实现 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/相机系统扩展.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/相机系统扩展.md index 63cf075..b167c22 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/相机系统扩展.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Gameplay/相机系统扩展.md @@ -33,8 +33,29 @@ bool bAutoReleaseWhenFinished; 相机动画播放完毕后自动释放实例,避免格斗游戏频繁的相机震动(受击、必杀技等)导致的实例泄漏。 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Engine/Classes/Camera/CameraAnimInst.h` | 新增标记 | +```cpp +// CameraAnimInst.h — 相机动画实例扩展 +class UCameraAnimInst +{ + // ASW 新增:播放完毕后自动释放实例 + // 格斗游戏频繁触发相机震动(受击、必杀技), + // 没有自动释放会导致实例泄漏 + UPROPERTY() + bool bAutoReleaseWhenFinished; + + // ASW 新增:水平翻转相机动画 + // 格斗游戏中玩家交换左右位置(交叉)时, + // 相机震动需要水平翻转以保持视觉一致 + UPROPERTY() + bool bPlayCameraAnimFlipH; +}; +``` + +## 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/Engine/Classes/Camera/CameraAnimInst.h` | 新增 | `bAutoReleaseWhenFinished` 自动释放标记 | +| `Source/Runtime/Engine/Classes/Camera/CameraAnimInst.h` | 新增 | `bPlayCameraAnimFlipH` 水平翻转标记 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Particle/Particle.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Particle/Particle.md index 12ab8ed..04ec4cc 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Particle/Particle.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Particle/Particle.md @@ -1,7 +1,7 @@ --- title: Particle date: 2026-05-03 00:00:00 -excerpt: ARC 引擎粒子系统修改分类索引 +excerpt: ARC 引擎粒子系统修改——粒子点光源系统、静态网格切换、MeshParticle VertexFactory 修复 tags: - ARC - Particle @@ -16,15 +16,106 @@ rating: ⭐ ARC 引擎对粒子系统的修改较为集中,主要新增了粒子驱动的点光源接口和静态网格切换功能。 -## 功能列表 +## 粒子点光源系统 -| 功能 | 文档 | 说明 | -|------|------|------| -| 粒子点光源系统 | [[粒子点光源系统]] | IREDPointLightInterface + 静态网格切换 | +### 概述 -## 其他修改 +新增 `IREDPointLightInterface` 接口,允许粒子系统动态创建和管理点光源。格斗游戏中的特效(火焰、电击、能量弹等)需要动态光照来增强视觉表现。 -### MeshParticle VertexFactory 修复 +### IREDPointLightInterface + +```cpp +// REDParticlePointLightUtilities.h +class IREDPointLightInterface +{ + // 点光源参数 + FVector Location; // 位置 + FLinearColor LightColor; // 光照颜色 + FLinearColor AmbientColor; // 环境光颜色 + float Amplitude; // 强度振幅(闪烁) + float Frequency; // 闪烁频率 + float Attenuation; // 衰减 + float Range; // 范围 + float Cutoff; // 截止距离 + float DistanceMultiply; // 距离乘数 +}; +``` + +### 特性 + +- 粒子生命周期绑定——粒子消亡时自动移除对应点光源 +- 支持振幅和频率控制的闪烁效果 +- 衰减和截止距离独立控制 + +### 静态网格切换模块 + +新增 `UParticleModuleStaticMeshSwitch`: + +```cpp +// 根据 SubImage Index 切换粒子使用的静态网格 Section +// 类似 SubUV 的概念但用于 3D 网格的不同部分 +``` + +用于格斗游戏特效中:同一个粒子发射器根据阶段显示不同形状的网格(如能量球从小到大变形)。 + +### 完整代码解析 + +```cpp +// REDParticlePointLightUtilities.h — 粒子点光源接口 +class IREDPointLightInterface +{ +public: + // 点光源参数 + FVector Location; // 世界空间位置 + FLinearColor LightColor; // 光照颜色 + FLinearColor AmbientColor; // 环境光贡献颜色 + + // 动态效果参数 + float Amplitude; // 强度振幅(sin波闪烁的幅度) + float Frequency; // 闪烁频率(Hz) + + // 衰减参数 + float Attenuation; // 衰减系数(光照随距离衰减的速率) + float Range; // 最大影响范围 + float Cutoff; // 截止距离(超过此距离完全无光照) + float DistanceMultiply; // 距离乘数(缩放有效范围) +}; + +// 粒子系统中使用: +// 粒子 Spawn 时创建点光源,Tick 时更新位置 +// 粒子 Death 时自动移除对应点光源 +``` + +MeshParticle 修复: + +```hlsl +// MeshParticleVertexFactory.ush — 修复 4.25 Bug +// ASW Change +// 非实例化模式下错误地使用了 ParticleTransform +// 应该使用 Primitive_LocalToWorld +#if !PARTICLE_MESH_INSTANCED + Result.InstanceLocalToWorld = Primitive_LocalToWorld; // 修复:使用 Primitive 变换 +#else + Result.InstanceLocalToWorld = ParticleTransform; // 实例化模式:使用粒子变换 +#endif +``` + +### 关联文档 + +- [[RED阴影系统]] — 点光源的阴影着色 +- [[RED自定义数据通道]] — 点光源模式下 CustomData 的使用 + +### 代码修改情况 + +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Source/Runtime/Engine/Public/REDParticlePointLightUtilities.h` | 全文 | **新增文件** | `IREDPointLightInterface` 接口定义 | +| `Source/Runtime/Engine/Private/Particles/REDParticlePointLightUtilities.cpp` | 全文 | **新增文件** | 粒子点光源注册/更新/移除实现 | +| `Source/Runtime/Engine/Private/Particles/ParticleModuleStaticMeshSwitch.cpp` | 全文 | **新增文件** | `UParticleModuleStaticMeshSwitch` | +| `Shaders/Private/MeshParticleVertexFactory.ush` | L343~L354 | 修改 | `InstanceLocalToWorld` 非实例化模式 Bug 修复 | +| `Shaders/Private/MeshParticleVertexFactory.ush` | L728~L736 | 新增 | `VertexFactoryUpdateLocalPositionScale` | + +## MeshParticle VertexFactory 修复 修复 4.25 版本的 MeshParticle 放置 Bug: diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Particle/粒子点光源系统.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Particle/粒子点光源系统.md deleted file mode 100644 index 2e0d9d0..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Particle/粒子点光源系统.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: 粒子点光源系统 -date: 2026-05-03 00:00:00 -excerpt: IREDPointLightInterface 粒子驱动点光源和静态网格切换模块 -tags: - - ARC - - Particle - - Lighting -rating: ⭐ ---- - -# 粒子点光源系统 - -返回 [[Particle]] - -## 概述 - -新增 `IREDPointLightInterface` 接口,允许粒子系统动态创建和管理点光源。格斗游戏中的特效(火焰、电击、能量弹等)需要动态光照来增强视觉表现。 - -## IREDPointLightInterface - -```cpp -// REDParticlePointLightUtilities.h -class IREDPointLightInterface -{ - // 点光源参数 - FVector Location; // 位置 - FLinearColor LightColor; // 光照颜色 - FLinearColor AmbientColor; // 环境光颜色 - float Amplitude; // 强度振幅(闪烁) - float Frequency; // 闪烁频率 - float Attenuation; // 衰减 - float Range; // 范围 - float Cutoff; // 截止距离 - float DistanceMultiply; // 距离乘数 -}; -``` - -## 特性 - -- 粒子生命周期绑定——粒子消亡时自动移除对应点光源 -- 支持振幅和频率控制的闪烁效果 -- 衰减和截止距离独立控制 - -## 静态网格切换模块 - -新增 `UParticleModuleStaticMeshSwitch`: - -```cpp -// 根据 SubImage Index 切换粒子使用的静态网格 Section -// 类似 SubUV 的概念但用于 3D 网格的不同部分 -``` - -用于格斗游戏特效中:同一个粒子发射器根据阶段显示不同形状的网格(如能量球从小到大变形)。 - -## 关联文档 - -- [[RED阴影系统]] — 点光源的阴影着色 -- [[RED自定义数据通道]] — 点光源模式下 CustomData 的使用 - -## 修改文件列表 - -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Engine/Public/REDParticlePointLightUtilities.h` | **新增** | -| `Source/Runtime/Engine/Private/Particles/REDParticlePointLightUtilities.cpp` | **新增** | -| `Source/Runtime/Engine/Private/Particles/ParticleModuleStaticMeshSwitch.cpp` | **新增** | -| `Shaders/Private/MeshParticleVertexFactory.ush` | Bug 修复 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/PS4支持.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/PS4支持.md deleted file mode 100644 index bcc316b..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/PS4支持.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: PS4支持 -date: 2026-05-03 00:00:00 -excerpt: PS4 平台 PSSL Shader 兼容层、HDR Resolve 和平台特化着色器 -tags: - - ARC - - Platform - - PS4 -rating: ⭐ ---- - -# PS4 支持 - -返回 [[Platform]] - -## 概述 - -为 PS4(Orbis)平台提供完整的 Shader 兼容层和平台特化着色器。 - -## PSSL 兼容层 - -`Public/Platform/PS4/PS4Common.ush` 提供 HLSL → PSSL(PlayStation Shader Language)的映射: - -- 数据类型映射(`float4` → PSSL 等效) -- Sampler 设置(各向异性过滤、比较采样器) -- Wave Intrinsics 映射(`WaveActiveSum`、`WaveActiveBallot` 等) -- 纹理采样函数兼容 - -## 平台特化着色器 - -`Private/Platform/PS4/` 目录包含 6 个平台着色器: - -| 文件 | 用途 | -|------|------| -| HDR Resolve | 高动态范围缓冲区解析 | -| RT Write Mask | Render Target 写入遮罩 | -| Wide Custom Resolve | 宽格式自定义解析 | - -## DOF 修复 - -`PostProcessDOF.usf` 中的 PS4 特化修改: - -```hlsl -#if !MOBILE_SHADING -// PS4: ReadFullResAndDepth 函数签名调整 -float4 ReadFullResAndDepth(float2 UV, float Depth) -#endif -``` - -以及 `RED_CHANGE` 深度 Gather 优化。 - -## 修改文件列表 - -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Public/Platform/PS4/PS4Common.ush` | **新增** — PSSL 兼容层 | -| `Shaders/Private/Platform/PS4/` (6 files) | **新增** — 平台着色器 | -| `Shaders/Private/PostProcessDOF.usf` | PS4 DOF 修复 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/PS5支持.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/PS5支持.md deleted file mode 100644 index e593ebb..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/PS5支持.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: PS5支持 -date: 2026-05-03 00:00:00 -excerpt: PS5 Feature Level 定义和 GBuffer 格式适配 -tags: - - ARC - - Platform - - PS5 -rating: ⭐ ---- - -# PS5 支持 - -返回 [[Platform]] - -## 概述 - -PS5 平台的修改相对较少,主要是 Feature Level 定义和 GBuffer 格式的平台差异处理。 - -## Feature Level - -在 `Public/Platform.ush` 中为 PS5 添加 SM5 Feature Level: - -```hlsl -#elif PS5_PROFILE - #define FEATURE_LEVEL FEATURE_LEVEL_SM5 -``` - -## GBuffer 格式适配 - -Specular GBuffer 在 PS5 上保持标准格式,仅在非 PS5 平台降级为 `PF_A8`: - -```cpp -// SceneRenderTargets.cpp -#if !PS5_PLATFORM - SpecularGBufferFormat = PF_A8; // 降低精度节省带宽 -#endif -``` - -参见 [[GBuffer修改]]。 - -## 修改文件列表 - -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Public/Platform.ush` | Feature Level 定义 | -| `Source/Runtime/Renderer/Private/SceneRenderTargets.cpp` | GBuffer 格式判断 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/Platform.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/Platform.md index 93c97c7..a88170c 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/Platform.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/Platform.md @@ -1,7 +1,7 @@ --- title: Platform date: 2026-05-03 00:00:00 -excerpt: ARC 引擎平台支持修改分类索引(PS4/PS5/Xbox One) +excerpt: ARC 引擎平台支持修改(PS4 PSSL 兼容层/HDR Resolve/RT Write Mask、PS5 Feature Level/GBuffer 适配、Xbox One HLSL 兼容层/Wave Intrinsics) tags: - ARC - Platform @@ -18,8 +18,135 @@ ARC 引擎为主机平台(PS4、PS5、Xbox One)添加了 Shader 兼容层和 ## 功能列表 -| 功能 | 文档 | 说明 | -|------|------|------| -| PS4 支持 | [[PS4支持]] | PSSL 兼容层、HDR Resolve、RT Write Mask | -| PS5 支持 | [[PS5支持]] | Feature Level 定义、GBuffer 格式适配 | -| Xbox One 支持 | [[XboxOne支持]] | HLSL 兼容层、Wave Intrinsics | +| 功能 | 说明 | +|------|------| +| PS4 支持 | PSSL 兼容层、HDR Resolve、RT Write Mask | +| PS5 支持 | Feature Level 定义、GBuffer 格式适配 | +| Xbox One 支持 | HLSL 兼容层、Wave Intrinsics | + +--- + +## PS4 支持 + +### 概述 + +为 PS4(Orbis)平台提供完整的 Shader 兼容层和平台特化着色器。 + +### PSSL 兼容层 + +`Public/Platform/PS4/PS4Common.ush` 提供 HLSL → PSSL(PlayStation Shader Language)的映射: + +- 数据类型映射(`float4` → PSSL 等效) +- Sampler 设置(各向异性过滤、比较采样器) +- Wave Intrinsics 映射(`WaveActiveSum`、`WaveActiveBallot` 等) +- 纹理采样函数兼容 + +### 平台特化着色器 + +`Private/Platform/PS4/` 目录包含 6 个平台着色器: + +| 文件 | 用途 | +|------|------| +| HDR Resolve | 高动态范围缓冲区解析 | +| RT Write Mask | Render Target 写入遮罩 | +| Wide Custom Resolve | 宽格式自定义解析 | + +### DOF 修复 + +`PostProcessDOF.usf` 中的 PS4 特化修改: + +```hlsl +#if !MOBILE_SHADING +// PS4: ReadFullResAndDepth 函数签名调整 +float4 ReadFullResAndDepth(float2 UV, float Depth) +#endif +``` + +以及 `RED_CHANGE` 深度 Gather 优化。 + +### 完整代码解析 + +```hlsl +// Public/Platform/PS4/PS4Common.ush — PSSL 兼容层示例 +// HLSL → PSSL 数据类型和函数映射 +// 例如 Wave Intrinsics: +// HLSL WaveActiveSum() → PSSL __v_add_co_u32() 等 +// 以及 Sampler 设置、纹理采样兼容函数 +``` + +### 代码修改情况 + +| 文件路径 | 行数 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Public/Platform/PS4/PS4Common.ush` | 688行 | **新增文件** | PSSL 兼容层(数据类型映射/Sampler/Wave Intrinsics) | +| `Shaders/Private/Platform/PS4/HdrCustomResolveShaders.ush` | 127行 | **新增文件** | HDR 自定义 Resolve 着色器 | +| `Shaders/Private/Platform/PS4/RTWriteMaskProcessing.usf` | 118行 | **新增文件** | RenderTarget 写入遮罩处理 | +| `Shaders/Private/Platform/PS4/WideCustomResolveShaders.ush` | 124行 | **新增文件** | 宽格式自定义 Resolve | +| `Shaders/Private/Platform/PS4/WideCustomResolve_Wide.ush` | 111行 | **新增文件** | Wide 变体 | +| `Shaders/Private/Platform/PS4/WideCustomResolve_Wider.ush` | 130行 | **新增文件** | Wider 变体 | +| `Shaders/Private/Platform/PS4/WideCustomResolve_Widest.ush` | 139行 | **新增文件** | Widest 变体 | +| `Shaders/Private/PostProcessDOF.usf` | L66~L76 | 修改 | `ReadFullResAndDepth` 函数签名 PS4 适配 | +| `Shaders/Private/PostProcessDOF.usf` | L114~L121 | 新增 | `RED_CHANGE` 深度 Gather 优化 | + +--- + +## PS5 支持 + +### 概述 + +PS5 平台的修改相对较少,主要是 Feature Level 定义和 GBuffer 格式的平台差异处理。 + +### Feature Level + +在 `Public/Platform.ush` 中为 PS5 添加 SM5 Feature Level: + +```hlsl +#elif PS5_PROFILE + #define FEATURE_LEVEL FEATURE_LEVEL_SM5 +``` + +### GBuffer 格式适配 + +Specular GBuffer 在 PS5 上保持标准格式,仅在非 PS5 平台降级为 `PF_A8`: + +```cpp +// SceneRenderTargets.cpp +#if !PS5_PLATFORM + SpecularGBufferFormat = PF_A8; // 降低精度节省带宽 +#endif +``` + +参见 [[GBuffer修改]]。 + +### 代码修改情况 + +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Public/Platform.ush` | L211~L215 | 新增 | `PS5_PROFILE` → `FEATURE_LEVEL_SM5` 定义 | +| `Source/Runtime/Renderer/Private/SceneRenderTargets.cpp` | — | 修改 | PS5 平台保持标准 Specular GBuffer 格式 | + +--- + +## Xbox One 支持 + +### 概述 + +为 Xbox One 平台提供 Shader 兼容层。 + +### HLSL 兼容层 + +`Public/Platform/XboxOne/XboxOneCommon.ush` 提供: +- Xbox One GPU 特有的 Wave Intrinsics 映射 +- Sampler 和纹理采样兼容 +- HLSL Shader Model 差异处理 + +### D3D12RHI 平台代码 + +`Source/Runtime/D3D12RHI/Private/XboxOne/` 目录(空占位),预留 Xbox One 平台的 D3D12 RHI 特化代码。 + +### 代码修改情况 + +| 文件路径 | 行数 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Public/Platform/XboxOne/XboxOneCommon.ush` | 324行 | **新增文件** | Xbox One HLSL 兼容层 | +| `Source/Runtime/D3D12RHI/Private/XboxOne/` | — | **新增目录** | Xbox One D3D12 RHI 占位目录 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/XboxOne支持.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/XboxOne支持.md deleted file mode 100644 index f1cb664..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Platform/XboxOne支持.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: XboxOne支持 -date: 2026-05-03 00:00:00 -excerpt: Xbox One 平台 Shader 兼容层 -tags: - - ARC - - Platform - - XboxOne -rating: ⭐ ---- - -# Xbox One 支持 - -返回 [[Platform]] - -## 概述 - -为 Xbox One 平台提供 Shader 兼容层。 - -## HLSL 兼容层 - -`Public/Platform/XboxOne/XboxOneCommon.ush` 提供: -- Xbox One GPU 特有的 Wave Intrinsics 映射 -- Sampler 和纹理采样兼容 -- HLSL Shader Model 差异处理 - -## D3D12RHI 平台代码 - -`Source/Runtime/D3D12RHI/Private/XboxOne/` 目录(空占位),预留 Xbox One 平台的 D3D12 RHI 特化代码。 - -## 修改文件列表 - -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Public/Platform/XboxOne/XboxOneCommon.ush` | **新增** — 兼容层 | -| `Source/Runtime/D3D12RHI/Private/XboxOne/` | **新增** — 空占位目录 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/BGMultColor全局色调.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/BGMultColor全局色调.md index 5b2b017..89f6a56 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/BGMultColor全局色调.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/BGMultColor全局色调.md @@ -54,16 +54,94 @@ BGMultColor 是一个场景级别的全局色调控制系统,通过 `View.BGMu | B | 0~∞ | 蓝色乘数 | | A | 0~1 | 饱和度(0=完全灰度,1=原色) | +## 完整代码解析 + +### Opaque BasePass 应用 + +```hlsl +// BasePassPixelShader.usf — Opaque 路径 +// ASW Change : 2020/06/25 11:44:00 Takeshi.N +#if USE_BGMULTCOLOR + { + // 步骤1:颜色乘算(调色) + BaseColor *= View.BGMultColor.rgb; + + // 步骤2:计算灰度值(使用 ITU-R BT.601 权重) + float Grayscale = dot(BaseColor, float3(0.299f, 0.587f, 0.114f)); + + // 步骤3:饱和度控制 + // A=1.0 保持原色,A=0.0 完全灰度 + BaseColor = lerp( + float3(Grayscale, Grayscale, Grayscale), // 灰度版本 + BaseColor, // 调色后的版本 + View.BGMultColor.a); // 饱和度系数 + } +#endif +``` + +### Translucent BasePass 应用 + +```hlsl +// BasePassPixelShader.usf — Translucent 路径(在最终输出前应用) +// ASW Change : 2016/11/04 17:26:48 Takuro.K +#if USE_BGMULTCOLOR + Out.MRT[0].rgb *= View.BGMultColor.rgb; + float Grayscale = dot(Out.MRT[0].rgb, float3(0.299f, 0.587f, 0.114f)); + Out.MRT[0].rgb = lerp( + float3(Grayscale, Grayscale, Grayscale), + Out.MRT[0].rgb, + View.BGMultColor.a); +#endif +``` + +### Deferred Decal 应用 + +```hlsl +// DeferredDecal.usf +// ASW Change : 2019/10/08 15:37:00 Takeshi.N +// 对贴花的 Color 和 BaseColor 都应用 BGMultColor +// 确保贴花颜色与场景色调一致 +#if USE_BGMULTCOLOR + // 调制 Color(贴花叠加色) + Color.rgb *= View.BGMultColor.rgb; + float Grayscale = dot(Color.rgb, float3(0.299f, 0.587f, 0.114f)); + Color.rgb = lerp(float3(Grayscale, Grayscale, Grayscale), Color.rgb, View.BGMultColor.a); + + // 调制 BaseColor(贴花基色) + BaseColor.rgb *= View.BGMultColor.rgb; + Grayscale = dot(BaseColor.rgb, float3(0.299f, 0.587f, 0.114f)); + BaseColor.rgb = lerp(float3(Grayscale, Grayscale, Grayscale), BaseColor.rgb, View.BGMultColor.a); +#endif +``` + +### C++ 端实现 + +```cpp +// SceneRendering.cpp — 从 REDSceneContext 读取 BGMultColor 写入 ViewUniform +// ASW Change : 2016/11/04 Takuro.K +if (REDSceneContext) +{ + const UREDSceneContext* pContext = REDSceneContext; + ViewUniformShaderParameters.BGMultColor = pContext->BGMultColor; + ViewUniformShaderParameters.DisasterPosition = pContext->DisasterPosition; + ViewUniformShaderParameters.DisasterWind = pContext->DisasterWind; + ViewUniformShaderParameters.DisasterQuake = pContext->DisasterQuake; + ViewUniformShaderParameters.DisasterPosition.W = pContext->GameTime; + // ... +} +``` + ## 关联文档 - [[REDSceneContext]] — BGMultColor 的数据源 - [[自定义后处理]] — 后处理阶段的色彩控制 -## 修改文件列表 +## 代码修改情况 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/BasePassPixelShader.usf` | 颜色乘算 + 去饱和 | -| `Shaders/Private/DeferredDecal.usf` | 同上 | -| `Shaders/Private/DeferredLightPixelShaders.usf` | 点光源颜色调制 | -| `Source/Runtime/Renderer/Private/SceneRendering.cpp` | 写入 ViewUniform | +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/BasePassPixelShader.usf` | L869~L878 | 新增 | Opaque 路径 BaseColor BGMultColor 乘算 + 去饱和 | +| `Shaders/Private/BasePassPixelShader.usf` | L1509~L1516 | 新增 | Translucent 路径 MRT[0] BGMultColor 应用 | +| `Shaders/Private/DeferredDecal.usf` | L297~L308 | 新增 | Decal Color 和 BaseColor 双重 BGMultColor 应用 | +| `Shaders/Private/DeferredLightPixelShaders.usf` | L253~L258 | 新增 | 点光源输出 BGMultColor 调制 | +| `Source/Runtime/Renderer/Private/SceneRendering.cpp` | L1717~L1758 | 新增 | 从 `UREDSceneContext` 读取参数写入 ViewUniform | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/BasePass修改.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/BasePass修改.md index fd69988..f35e5cc 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/BasePass修改.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/BasePass修改.md @@ -72,15 +72,105 @@ DeviceDepth = lerp( step(PixelDepthOffset, 0)); // PDO <= 0 时使用原始深度 ``` +## 完整代码解析 + +### 阴影专用材质 + +```hlsl +// ASW Change : 2016/11/28 22:27:26 Takuro.K +// 阴影专用材质:在 BasePass 中直接丢弃像素 +// 该网格只参与 Shadow Map 渲染,不产生可见输出 +// 用于格斗游戏中只需要地面阴影的辅助几何体 +#if RED_MASKED_SHADOW_ONLY + clip(-1); // 参数 < 0 → 丢弃当前像素 +#endif +``` + +### 强制 Early-Z + +```hlsl +// ASW / Wizcorp Change: 2022/06/03 Maciej.W +// 原始条件:!EARLY_Z_PASS_ONLY_MATERIAL_MASKING +// 新增条件:&& !EARLY_Z_PASS_FORCED +// 当材质标记了 bForcedPrepass 时,跳过 BasePass 中的 Mask clip +// 因为深度已经在 PrePass 中确定,无需重复剔除 +#if !EARLY_Z_PASS_ONLY_MATERIAL_MASKING && !EARLY_Z_PASS_FORCED + if (!bEditorWeightedZBuffering) + { + // Mask clip 逻辑... + } +#endif +``` + +### X2Multiply 雾效 + +```hlsl +// ASW Change : 2019/10/28 16:51:00 Takeshi.N +// X2Multiply 混合模式的雾效处理 +// X2Multiply 的中性色是 0.5(乘以2后为1.0,不改变目标颜色) +// 所以雾效需要将颜色过渡到 0.5 而非 0.0(加法)或 1.0(乘法) +#elif MATERIALBLENDING_X2MULTIPLY + half3 FoggedColor = lerp( + float3(0.5, 0.5, 0.5), // X2Multiply 中性色 + Color, // 原始颜色 + Fogging.aaa * Fogging.aaa); // 雾衰减(平方使过渡更平滑) + Out.MRT[0] = half4(FoggedColor, Opacity); +``` + +### 禁用 DEFAULT_LIT 间接光照 + +```hlsl +// ASW Change : 2017/12/14 11:00:00 Takeshi.N +// 对 DEFAULT_LIT + Deferred 路径禁用预计算间接光照 +// 因为在 RED 管线中,BaseColor 被用于阴影颜色而非 PBR 漫反射 +// 间接光照会干扰卡通阴影效果 +#if MATERIAL_SHADINGMODEL_DEFAULT_LIT && !(FORWARD_SHADING || TRANSLUCENCY_LIGHTING_SURFACE_FORWARDSHADING) + // 跳过 GetPrecomputedIndirectLightingAndSkyLight 及相关计算 +#else + // 原始间接光照逻辑 + float3 DiffuseIndirectLighting; + float3 SubsurfaceIndirectLighting; + GetPrecomputedIndirectLightingAndSkyLight(...); + DiffuseColor += (DiffuseIndirectLighting * DiffuseColorForIndirect + ...) * AOMultiBounce(...); +#endif +``` + +### C++ 端实现 + +```cpp +// BasePassRendering.cpp — X2Multiply BlendState +// ASW Change Y.Kawakami 2020/05/21 +case BLEND_X2Multiply: + // X2Multiply 使用与 Multiply 相同的 BlendState + break; +``` + +```cpp +// BasePassRendering.cpp — ForcedPrepass +// ASW / Wizcorp Change: 2022/06/03 Maciej.W +const bool bEnforceMaskedEarlyPass = + Mesh.MaterialRenderProxy->GetMaterial(FeatureLevel)->IsForcedPrepass() + && EarlyZPassMode != DDM_None; +// 强制该材质走 Early-Z PrePass,减少 OverDraw +``` + ## 关联文档 - [[自定义材质属性]] — `bForcedPrepass` 和 `BLEND_X2Multiply` - [[RED自定义数据通道]] — BasePass 中 CustomData 的写入 -## 修改文件列表 +## 代码修改情况 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/BasePassPixelShader.usf` | 阴影 Only、X2Multiply 雾效 | -| `Source/Runtime/Renderer/Private/BasePassRendering.cpp` | 强制 PrePass、X2Multiply BlendState | -| `Shaders/Private/MaterialTemplate.ush` | PDO 修复 | +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/BasePassPixelShader.usf` | L772~L776 | 新增 | `RED_MASKED_SHADOW_ONLY` 阴影专用材质 `clip(-1)` | +| `Shaders/Private/BasePassPixelShader.usf` | L850~L854 | 修改 | Early-Z 条件添加 `!EARLY_Z_PASS_FORCED` | +| `Shaders/Private/BasePassPixelShader.usf` | L1137~L1163 | 修改 | DEFAULT_LIT Deferred 路径禁用预计算间接光 | +| `Shaders/Private/BasePassPixelShader.usf` | L1291~L1296 | 修改 | Emissive 声明前移(与 CustomData 配合) | +| `Shaders/Private/BasePassPixelShader.usf` | L1433~L1438 | 新增 | `MATERIALBLENDING_X2MULTIPLY` 雾效处理 | +| `Source/Runtime/Renderer/Private/BasePassRendering.cpp` | L200~L216 | 新增 | `BLEND_X2Multiply` case 分支 | +| `Source/Runtime/Renderer/Private/BasePassRendering.cpp` | L288~L309 | 新增 | `bEnforceMaskedEarlyPass` 强制 PrePass 判断 | +| `Source/Runtime/Renderer/Private/BasePassRendering.cpp` | L1068~L1087 | 新增 | Shader Define 注入(`USE_RED_CUSTOM_DATA`/`USE_BGMULTCOLOR`/`USES_ORTHO_BLEND`等) | +| `Source/Runtime/Renderer/Private/BasePassRendering.cpp` | L1633~L1694 | 新增 | X2Multiply/AdditiveForUI BlendState 设置 | +| `Source/Runtime/Renderer/Private/DepthRendering.cpp` | L925~L1061 | 新增 | ForcedPrepass 深度渲染逻辑 | +| `Shaders/Private/MaterialTemplate.ush` | L2584~L2587 | 新增 | PixelDepthOffset 修复 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/GBuffer修改.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/GBuffer修改.md index 18ee92f..1c1108a 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/GBuffer修改.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/GBuffer修改.md @@ -52,14 +52,53 @@ OutColor.a = 1.f; 防止降采样过程中 Alpha 通道携带的 CustomData 信息影响后续后处理。 +## 完整代码解析 + +### PostProcessDownsample Alpha 修复 + +```hlsl +// PostProcessDownsample.usf +// 强制 Alpha 为 1.0,防止 CustomData 中的 OutlineID 信息 +// 在降采样过程中泄漏到后续后处理 Pass +OutColor.rgb = max(float3(0,0,0), OutColor.rgb); +OutColor.a = 1.f; // <-- ASW 新增 +``` + +### C++ 端实现 + +```cpp +// SceneRenderTargets.cpp — GBufferD 清除色修改 +// ASW Change : 2016/11/09 Takuro.K +// 将 GBufferD 清除色改为 (0,0,0,0) +// 确保未写入 CustomData 的像素 OutlineID=0、PointLight DiffuseColor=黑色 +FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::Create2DDesc( + BufferSize, BufferFormat, + FClearValueBinding(FLinearColor(0, 0, 0, 0)), // <-- 清除色改为全0 + TexCreate_SRGB, + TexCreate_RenderTargetable | TexCreate_ShaderResource, false)); +``` + +```cpp +// SceneRenderTargets.cpp — Specular GBuffer 格式 +// ASW Change : 2017/11/21 Takuro.K +// 非 PS5 平台降低 Specular 精度到 PF_A8(8位) +// 卡通渲染中 Specular 通常阶梯化,不需要高精度 +#if defined(PLATFORM_PS5) && !PLATFORM_PS5 + const EPixelFormat SpecularGBufferFormat = PF_A8; +#endif +``` + ## 关联文档 - [[RED自定义数据通道]] — GBufferD 的数据写入方 - [[自定义后处理]] — 读取 GBufferD 数据 -## 修改文件列表 +## 代码修改情况 -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Renderer/Private/SceneRenderTargets.cpp` | GBufferD 清除色、Specular 格式 | -| `Shaders/Private/PostProcessDownsample.usf` | Alpha 强制为 1.0 | +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.cpp` | L737 | 修改 | Normal GBuffer 格式(已禁用) | +| `Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.cpp` | L1257~L1268 | 修改 | Specular GBuffer → `PF_A8`(非PS5) | +| `Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.cpp` | L1271~L1284 | 修改 | GBufferD 清除色 → `(0,0,0,0)` | +| `Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.cpp` | L1364~L1380 | 修改 | GBuffer 格式相关调整 | +| `Shaders/Private/PostProcessDownsample.usf` | L63 | 新增 | `OutColor.a = 1.f` 强制 Alpha 为 1 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED自定义数据通道.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED自定义数据通道.md index 14dc0ff..28db2fe 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED自定义数据通道.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED自定义数据通道.md @@ -119,12 +119,157 @@ RED 自定义数据通道是 ARC 引擎中一个巧妙的 GBuffer 复用方案 - [[自定义后处理]] — CharaGlow 读取 OutlineID 通道 - [[GBuffer修改]] — GBufferD 清除色等相关修改 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/Definitions.usf` | 新增 `USE_RED_CUSTOM_DATA` 宏定义 | -| `Shaders/Private/BasePassCommon.ush` | 扩展 `WRITES_CUSTOMDATA_TO_GBUFFER` | -| `Shaders/Private/ShadingModelsMaterial.ush` | UNLIT/DEFAULT_LIT 写入 CustomData | -| `Shaders/Private/BasePassPixelShader.usf` | SubsurfaceColor 重定义逻辑 | -| `Shaders/Private/DeferredShadingCommon.ush` | 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.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` | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED阴影系统.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED阴影系统.md index cf762c5..18e67de 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED阴影系统.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/RED阴影系统.md @@ -117,10 +117,280 @@ ScreenSpaceData.GBuffer.DiffuseColor.rgb = ScreenSpaceData.GBuffer.CustomData.rg - [[自定义光照Pass]] — REDDeferredLightPS 的 C++ 绑定 - [[BGMultColor全局色调]] — 场景全局色调叠加 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/DeferredLightPixelShaders.usf` | 新增 `REDDirectionalPixelMain` | -| `Shaders/Private/DeferredLightingCommon.ush` | 新增 `REDGetShadowTerms`、`REDGetShadowColor` | -| `Source/Runtime/Renderer/Private/LightRendering.cpp` | 新增 `REDDeferredLightPS`、点光排序 | +### DeferredLightPixelShaders.usf + +#### DynamicShadowShade uniform 声明 + +```hlsl +// ASW Change : 2019/02/05 20:37:00 Takeshi.N +// 动态阴影明暗控制参数,从 C++ 端传入 +// 0.0 = 动态阴影区域完全黑色 +// 1.0 = 无动态阴影变暗效果 +float DynamicShadowShade; +``` + +#### REDDirectionalPixelMain — 方向光阴影着色入口 + +```hlsl +// ASW Change : 2016/10/12 21:35:18 Takuro.K +// 专用的方向光阴影着色 Pixel Shader 入口 +// 与标准 DeferredLightPixelMain 并行存在,由 C++ 端选择调用 +void REDDirectionalPixelMain( + float2 InUV : TEXCOORD0, // 屏幕空间 UV + float3 ScreenVector : TEXCOORD1, // 屏幕空间到世界空间的方向向量 + float4 SVPos : SV_POSITION, // 屏幕位置 + out float4 OutColor : SV_Target0 // 输出:阴影颜色(不是光照颜色) + ) +{ + OutColor = float4(1,1,1,0); // 默认白色 = 无阴影 + float3 CameraVector = normalize(ScreenVector); + FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(InUV); + + // 只处理使用 Deferred Shading 的像素(ShadingModelID > 0) + BRANCH if( ScreenSpaceData.GBuffer.ShadingModelID > 0 +#if USE_LIGHTING_CHANNELS + && (GetLightingChannelMask(InUV) & DeferredLightUniforms.LightingChannelMask) +#endif + ) + { + float SceneDepth = CalcSceneDepth(InUV); + // 从屏幕空间重建世界坐标 + float3 WorldPosition = ScreenVector * SceneDepth + View.WorldCameraOrigin; + FDeferredLightData LightData = SetupLightDataForStandardDeferred(); + + // 生成随机数用于阴影抖动 + uint2 Random = ScrambleTEA( uint2( SVPos.xy ) ); + Random.x ^= View.Random; + Random.y ^= View.Random; + + // 核心:调用 REDGetShadowColor 计算阴影着色 + // 注意输出的是"阴影颜色"而非"光照颜色" + OutColor = REDGetShadowColor( + WorldPosition, CameraVector, + ScreenSpaceData.GBuffer, + ScreenSpaceData.AmbientOcclusion, + ScreenSpaceData.GBuffer.ShadingModelID, + LightData, + GetPerPixelLightAttenuation(InUV), + Random, + DynamicShadowShade); // 传入动态阴影明暗参数 + } +} +``` + +#### 点光源 CustomData 覆写 + +```hlsl +// ASW Change : 2020/01/14 20:19:00 Takeshi.N +// 点光源渲染时,将 GBufferD 中存储的 CustomData 重新解释为 DiffuseColor +// 这样点光源的阴影着色可以使用与方向光相同的机制 +ScreenSpaceData.GBuffer.DiffuseColor.rgb = ScreenSpaceData.GBuffer.CustomData.rgb; +``` + +#### 点光源 BGMultColor 应用 + +```hlsl +// ASW Change : 2020/07/07 16:41:00 Takeshi.N +// 对点光源输出应用全局色调调制 +OutColor.rgb *= View.BGMultColor.rgb; // RGB 颜色乘算 +float Grayscale = dot(OutColor.rgb, float3(0.299f, 0.587f, 0.114f)); // 计算亮度 +OutColor.rgb = lerp( // 饱和度控制 + float3(Grayscale, Grayscale, Grayscale), // 灰度版本 + OutColor.rgb, // 原色版本 + View.BGMultColor.a); // A 通道控制饱和度 +``` + +### DeferredLightingCommon.ush + +#### 阴影合成修改 + +```hlsl +// ASW Change : 2018/11/13 17:13:00 Takeshi.N +// 原始公式:Shadow = lerp(DynamicShadow, StaticShadow, FadeFraction) +// 问题:距离远时 DynamicShadow 淡出后只剩 StaticShadow, +// 但动态阴影区域可能比静态阴影更暗(StaticShadow=1),导致阴影突然消失 +// +// 新公式:Shadow = min(lerp(DynamicShadow, 1.0, FadeFraction), StaticShadow) +// 效果:动态阴影淡出后取 min(1.0, StaticShadow) = StaticShadow +// 动态阴影存在时取 min(DynamicShadow, StaticShadow) = 两者中更暗的 +Shadow.SurfaceShadow = min( + lerp(LightAttenuation.x, 1.0f, DynamicShadowFraction), // 动态阴影淡出到 1.0 + StaticShadowing); // 与静态阴影取 min +``` + +#### REDGetShadowTerms — 阴影项分离 + +```hlsl +// ASW Change : 2019/02/05 20:37:00 Takeshi.N +// 将阴影分解为独立的动态和静态两项,供 REDGetShadowColor 分别着色 +void REDGetShadowTerms( + FGBufferData GBuffer, + FDeferredLightData LightData, + float3 WorldPosition, + float4 LightAttenuation, // Shadow Map 衰减值 + out float DynamicShadowTerm, // 输出:动态阴影项 (0=全阴影, 1=无阴影) + out float StaticShadowTerm) // 输出:静态阴影项 +{ + // 从 GBuffer 获取静态阴影(Lightmap / Distance Field) + float UsesStaticShadowMap = dot(LightData.ShadowMapChannelMask, float4(1, 1, 1, 1)); + float StaticShadowing = lerp(1, + dot(GBuffer.PrecomputedShadowFactors, LightData.ShadowMapChannelMask), + UsesStaticShadowMap); + + if (LightData.bRadialLight) + { + // 点光源/聚光灯:直接使用 LightAttenuation.zw + DynamicShadowTerm = LightAttenuation.z * StaticShadowing; + StaticShadowTerm = LightAttenuation.w * StaticShadowing; + } + else + { + // 方向光:根据距离淡化动态阴影 + float DynamicShadowFraction = DistanceFromCameraFade( + GBuffer.Depth, LightData, WorldPosition, View.WorldCameraOrigin); + + // 动态阴影:距离远时淡化到 1.0(无阴影) + DynamicShadowTerm = lerp(LightAttenuation.x, 1.0f, DynamicShadowFraction); + // 静态阴影:不受距离影响 + StaticShadowTerm = StaticShadowing; + + // 叠加光照函数 (Light Function) + DynamicShadowTerm *= LightAttenuation.z; + StaticShadowTerm *= LightAttenuation.z; + } +} +``` + +#### REDGetShadowColor — 核心阴影着色函数 + +```hlsl +// ASW Change : 2016/10/12 21:35:18 Takuro.K +// 核心函数:将阴影从"衰减"转变为"着色" +// 传统 PBR:最终颜色 = 光照 × 阴影衰减(变暗) +// RED 系统:最终颜色 = lerp(阴影颜色, 光照颜色, 阴影系数)(变色) +float4 REDGetShadowColor( + float3 WorldPosition, + float3 CameraVector, + FGBufferData GBuffer, + float AmbientOcclusion, + uint ShadingModelID, + FDeferredLightData LightData, + float4 LightAttenuation, + uint2 Random, + float DynamicShadowShade) // 动态阴影明暗参数 +{ + float DynamicShadow = 1; // 动态阴影项(1=无阴影) + float StaticShadow = 1; // 静态阴影项 + + BRANCH + if (LightData.ShadowedBits) + { + // 有阴影贴图时:分离计算动态和静态阴影 + REDGetShadowTerms(GBuffer, LightData, WorldPosition, + LightAttenuation, DynamicShadow, StaticShadow); + } + else + { + // 无阴影贴图时:使用 AO 作为阴影近似 + DynamicShadow = AmbientOcclusion; + } + + // 动态阴影颜色 = DiffuseColor × DynamicShadowShade + // DiffuseColor 来自 GBufferD.CustomData(美术指定的阴影基色) + // DynamicShadowShade 控制暗度(0=全黑, 1=与阴影基色相同) + float3 DynamicShadowColor = GBuffer.DiffuseColor * DynamicShadowShade; + + // 静态阴影颜色 = DiffuseColor(不额外缩放) + float3 StaticShadowColor = GBuffer.DiffuseColor; + + // 静态阴影:从阴影颜色到白色(无阴影)的过渡 + StaticShadowColor = lerp(StaticShadowColor, float3(1,1,1), StaticShadow); + + // 最终合成:动态阴影颜色到静态阴影颜色的过渡 + // DynamicShadow=0 时显示动态阴影颜色 + // DynamicShadow=1 时显示静态阴影颜色(可能已经过渡到白色) + return float4(lerp(DynamicShadowColor, StaticShadowColor, DynamicShadow), 0.0f); +} +``` + +### C++ 端实现 + +```cpp +// LightRendering.cpp — REDDeferredLightPS 类定义 +// ASW Change : 2018/12/18 20:59:02 Kazuhito +// 继承标准 FDeferredLightPS,复用所有 permutation 参数 +class REDDeferredLightPS : public FDeferredLightPS +{ + DECLARE_GLOBAL_SHADER(REDDeferredLightPS) + + REDDeferredLightPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer) + : FDeferredLightPS(Initializer) + { + // ASW: 绑定 DynamicShadowShade uniform 参数 + DynamicShadowShade.Bind(Initializer.ParameterMap, TEXT("DynamicShadowShade")); + } + REDDeferredLightPS() {} + + // DynamicShadowShade 参数成员 + LAYOUT_FIELD(FShaderParameter, DynamicShadowShade); +}; + +// 注册 Shader:绑定到 DeferredLightPixelShaders.usf 的 REDDirectionalPixelMain 入口 +#define RED_CUSTOM_LIGHTING 1 +IMPLEMENT_GLOBAL_SHADER(REDDeferredLightPS, + "/Engine/Private/DeferredLightPixelShaders.usf", + "REDDirectionalPixelMain", SF_Pixel); +``` + +```cpp +// LightRendering.cpp — DynamicShadowShade 参数设置 +// 方向光:有预计算光照时 shade=0.3(阴影较暗),无预计算时 shade=1.0(无额外变暗) +SetShaderValue(RHICmdList, ShaderRHI, DynamicShadowShade, + LightSceneInfo->IsPrecomputedLightingValid() ? 0.3f : 1.0f); + +// 点光源:shade 固定为 1.0(不额外变暗) +SetShaderValue(RHICmdList, ShaderRHI, DynamicShadowShade, 1.f); +``` + +```cpp +// LightRendering.cpp — 点光源排序 +// ASW Change : 2020/10/22 Takeshi.N +// 点光源在方向光之后渲染(方向光先完成阴影着色,点光源再叠加) +SortedLightInfo->SortKey.Fields.bPointLightRED = + (LightSceneInfoCompact.LightType != LightType_Directional); +``` + +```cpp +// LightRendering.cpp — 方向光渲染路径(RED_CUSTOM_LIGHTING) +// 混合模式改为 Multiply(DestColor × SourceColor) +// 标准 UE4 用 Additive,RED 用 Multiply 因为阴影颜色系统输出的是"乘算遮罩" +GraphicsPSOInit.BlendState = TStaticBlendState< + CW_RGBA, BO_Add, + BF_DestColor, BF_Zero, // RGB: Dest × Source(乘法混合) + BO_Add, BF_One, BF_One // Alpha: 加法 +>::GetRHI(); + +// 使用 REDDeferredLightPS 替代标准 FDeferredLightPS +TShaderMapRef PixelShader(View.ShaderMap, PermutationVector); +``` + +## 代码修改情况 + +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/DeferredLightPixelShaders.usf` | L106 | 新增 | `DynamicShadowShade` uniform 声明 | +| `Shaders/Private/DeferredLightPixelShaders.usf` | L109~L145 | 新增 | `REDDirectionalPixelMain` 方向光阴影着色入口函数 | +| `Shaders/Private/DeferredLightPixelShaders.usf` | L236~L239 | 新增 | 点光源 CustomData → DiffuseColor 覆写 | +| `Shaders/Private/DeferredLightPixelShaders.usf` | L253~L258 | 新增 | 点光源 BGMultColor 色调应用 | +| `Shaders/Private/DeferredLightingCommon.ush` | L166~L172 | 修改 | 阴影合成公式改为 `min(lerp(...), StaticShadowing)` | +| `Shaders/Private/DeferredLightingCommon.ush` | L457~L505 | 新增 | `REDGetShadowTerms` 动态/静态阴影项分离函数 | +| `Shaders/Private/DeferredLightingCommon.ush` | L508~L557 | 新增 | `REDGetShadowColor` 核心阴影着色函数 | +| `Source/Runtime/Renderer/Private/LightRendering.cpp` | L383~L394 | 新增 | `DynamicShadowShade.Bind` 参数绑定 | +| `Source/Runtime/Renderer/Private/LightRendering.cpp` | L421~L432 | 新增 | `DynamicShadowShade` 方向光值设置 (0.3/1.0) | +| `Source/Runtime/Renderer/Private/LightRendering.cpp` | L434~L445 | 新增 | `DynamicShadowShade` 点光源值设置 (1.0) | +| `Source/Runtime/Renderer/Private/LightRendering.cpp` | L682~L688 | 新增 | `LAYOUT_FIELD(FShaderParameter, DynamicShadowShade)` | +| `Source/Runtime/Renderer/Private/LightRendering.cpp` | L706~L744 | 新增 | `REDDeferredLightPS` 类 + `IMPLEMENT_GLOBAL_SHADER` | +| `Source/Runtime/Renderer/Private/LightRendering.cpp` | L950~L961 | 新增 | `bPointLightRED` 排序键 | +| `Source/Runtime/Renderer/Private/LightRendering.cpp` | L2111~L2303 | 新增 | RED 方向光渲染路径(Multiply 混合 + REDDeferredLightPS 调用) | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/光线追踪与PSO.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/光线追踪与PSO.md index d3dd8fb..a11b464 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/光线追踪与PSO.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/光线追踪与PSO.md @@ -42,13 +42,45 @@ struct FRayTracingPipelineStateInitializer 新增 `bApplyAdditionalState` 参数,控制是否在设置管线状态时应用额外的平台特化状态。 +## 完整代码解析 + +```hlsl +// RayTracingDeferredReflections.usf +// 仅缩进格式修复(去掉一级缩进),无功能性变更 +// 不影响运行时行为 +``` + +```cpp +// RHI 模块 — PSO 部分编译标记 +struct FRayTracingPipelineStateInitializer +{ + // ASW 新增:允许部分编译 + // 不需要等待所有 Hit Shader 就绪即可使用基础管线 + // 用于减少首次光线追踪渲染时的卡顿 + bool bPartial; + + // 基础 PSO,用于派生新的 PSO + // 派生 PSO 只需要编译差异部分 + FRayTracingPipelineState* BasePipeline; +}; + +// SetGraphicsPipelineState 扩展 +// ASW 新增 bApplyAdditionalState 参数 +// 控制是否在设置管线状态时应用平台特化的额外状态 +void RHISetGraphicsPipelineState( + FGraphicsPipelineStateInitializer& Initializer, + bool bApplyAdditionalState = true // <-- 新增参数 +); +``` + ## 关联文档 - [[D3D12RHI]] — D3D12 层面的 PSO 异步创建改进 -## 修改文件列表 +## 代码修改情况 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/RayTracing/RayTracingDeferredReflections.usf` | 格式修复 | -| `Source/Runtime/RHI/` | `bPartial`、`bApplyAdditionalState` | +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/RayTracing/RayTracingDeferredReflections.usf` | L109~L121 | 格式 | 缩进调整(无功能变更) | +| `Source/Runtime/RHI/` | — | 修改 | `FRayTracingPipelineStateInitializer` 新增 `bPartial`、`BasePipeline` | +| `Source/Runtime/RHI/` | — | 修改 | `SetGraphicsPipelineState` 新增 `bApplyAdditionalState` 参数 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/局部位置缩放.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/局部位置缩放.md index cfa1970..e964941 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/局部位置缩放.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/局部位置缩放.md @@ -43,12 +43,62 @@ void VertexFactoryUpdateLocalPositionScale( `MP_LocalPositionScale`(float3)通过材质图控制。参见 [[自定义材质属性]]。 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/LocalVertexFactory.ush` | 新增缩放函数 | -| `Shaders/Private/GpuSkinVertexFactory.ush` | 同上 | -| `Shaders/Private/LandscapeVertexFactory.ush` | 同上 | -| `Shaders/Private/MeshParticleVertexFactory.ush` | 同上 | -| 所有 Particle VertexFactory | 同上 | +### LocalVertexFactory.ush — 缩放函数定义 + +```hlsl +// LocalVertexFactory.ush — 缩放函数定义 +// ASW Change : 2016/06/29 17:05:39 Takuro.K +#if USES_LOCAL_POSITION_SCALE +void VertexFactoryUpdateLocalPositionScale( + inout FVertexFactoryInput Input, // 顶点输入(可修改) + inout FVertexFactoryIntermediates Intermediates, // 中间数据 + float3 scale) // 缩放系数 (x, y, z) +{ + // 直接在局部空间缩放顶点位置 + // 在 WorldTransform 之前应用,所以效果与 Actor Scale 类似 + // 但由材质图控制,可以做动画 + Input.Position.xyz *= scale; +} +#endif +``` + +### BasePassVertexShader.usf — 调用流程 + +```hlsl +// BasePassVertexShader.usf — 调用流程 +// ASW Change : 2016/06/29 17:05:39 Takuro.K +#if USES_LOCAL_POSITION_SCALE + { + // 1. 从材质图获取缩放系数 + // 2. 应用到顶点的局部坐标 + VertexFactoryUpdateLocalPositionScale(Input, VFIntermediates, + GetMaterialLocalPositionScale(VertexParameters)); + + // 3. 重新计算世界坐标(因为局部坐标已改变) + WorldPositionExcludingWPO = VertexFactoryGetWorldPosition(Input, VFIntermediates); + WorldPosition = WorldPositionExcludingWPO; + + // 4. 重新获取切线空间和材质参数 + TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates); + VertexParameters = GetMaterialVertexParameters( + Input, VFIntermediates, WorldPosition.xyz, TangentToLocal); + } +#endif +``` + +## 代码修改情况 + +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/BasePassVertexShader.usf` | L64~L76 | 新增 | 调用 `VertexFactoryUpdateLocalPositionScale` + 重算世界坐标 | +| `Shaders/Private/LocalVertexFactory.ush` | L1171~L1179 | 新增 | `VertexFactoryUpdateLocalPositionScale` 函数(`Input.Position.xyz *= scale`) | +| `Shaders/Private/GpuSkinVertexFactory.ush` | L822~L830 | 新增 | 同上(GPU 蒙皮版本) | +| `Shaders/Private/LandscapeVertexFactory.ush` | L948~L958 | 新增 | 同上(Landscape 版本) | +| `Shaders/Private/MeshParticleVertexFactory.ush` | L728~L736 | 新增 | 同上(MeshParticle 版本) | +| `Shaders/Private/ParticleSpriteVertexFactory.ush` | L684~L691 | 新增 | 同上(ParticleSprite 版本) | +| `Shaders/Private/ParticleGPUSpriteVertexFactory.ush` | L698~L706 | 新增 | 同上(ParticleGPUSprite 版本) | +| `Shaders/Private/ParticleBeamTrailVertexFactory.ush` | L246~L253 | 新增 | 同上(ParticleBeamTrail 版本) | +| `Shaders/Private/VectorFieldVisualizationVertexFactory.ush` | L202~L210 | 新增 | 同上(VectorField 版本) | +| `Shaders/Private/MaterialTemplate.ush` | L2263~L2268 | 新增 | `GetMaterialLocalPositionScale` 材质访问函数 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/屏幕对齐网格.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/屏幕对齐网格.md index 17771eb..ff39c8b 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/屏幕对齐网格.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/屏幕对齐网格.md @@ -55,11 +55,77 @@ rating: ⭐ 材质标记 `bScreenAlignedMesh` 启用此模式。 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/BasePassVertexShader.usf` | 屏幕空间变换逻辑 | -| `Shaders/Private/DepthOnlyVertexShader.usf` | 同上 | -| `Shaders/Private/HitProxyVertexShader.usf` | 同上 | -| `Shaders/Private/DebugViewModeVertexShader.usf` | 同上 | +### BasePassVertexShader.usf — 屏幕对齐变换 + +```hlsl +// ASW Change : 2016/05/16 13:56:33 Takuro.K +// 屏幕对齐网格:将3D网格直接投影到屏幕空间 +#if USES_SCREEN_ALIGNED_MESH + { + // 获取 LocalToWorld 矩阵(区分实例化和非实例化模式) + #if PARTICLE_MESH_INSTANCED + float4x4 LocalToWorld = VertexParameters.InstanceLocalToWorld; + #else + float3x3 LocalToWorld = GetLocalToWorld3x3(VertexParameters.PrimitiveId); + #endif + + // 从 LocalToWorld 矩阵的对角元素获取翻转方向 + // 这样网格在镜像 Transform 下仍然正确显示 +#if PARTICLE_MESH_INSTANCED + float2 flip = sign( float2( Input.Transform1.x, LocalToWorld[1][1] ) ); +#else + float2 flip = sign( float2( LocalToWorld[0][0], LocalToWorld[1][1] ) ); +#endif + + // 使用顶点的 X 和 Z 坐标作为屏幕坐标(不是 XY!) + // 这是因为网格在 DCC 中通常面向 Z 轴建模 + float2 p = Input.Position.xz * flip; + + // 从材质图获取偏移和缩放参数 + float3 offset = GetMaterialScreenAlignedMeshOffset(VertexParameters); + float3 scale = GetMaterialScreenAlignedMeshScale(VertexParameters); + + // 基于 1280x720 参考分辨率计算屏幕坐标 + // NDC 范围 [-1, 1],所以 /640 和 /360 将像素单位转为 NDC + float2 ScreenPos = p.xy * scale.xy; + ScreenPos.x += offset.x / 640.0f; // X 偏移(向右为正) + ScreenPos.y += -offset.y / 360.0f; // Y 偏移(向上为正,NDC Y 轴反转) + + // WorldPositionOffset 也可以叠加微调 + ScreenPos.xy += GetMaterialWorldPositionOffset(VertexParameters).xy; + + // 深度设为接近远裁面,确保不遮挡 3D 场景 + const float z = 1.0f - 0.00001f; + + // 清零世界坐标(屏幕空间渲染不需要) + WorldPosition = 0; + // 直接设置裁剪空间输出(w=1 表示无透视除法) + Output.Position = float4( ScreenPos, z, 1 ); + } +#endif +``` + +### BasePassCommon.ush — 禁用雾效 + +```hlsl +// ASW Change : 2017/01/30 18:00:41 Takuro.K +// 屏幕对齐网格不需要雾效(它们是屏幕空间元素) +#define TRANSLUCENCY_NEEDS_BASEPASS_FOGGING ( + MATERIAL_ENABLE_TRANSLUCENCY_FOGGING && + MATERIALBLENDING_ANY_TRANSLUCENT && + !MATERIAL_USES_SCENE_COLOR_COPY && + !USES_SCREEN_ALIGNED_MESH) // <-- 新增条件 +``` + +## 代码修改情况 + +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/BasePassVertexShader.usf` | L118~L155 | 新增 | 屏幕对齐网格变换逻辑(1280x720基准/深度设置/WorldPosition清零) | +| `Shaders/Private/BasePassCommon.ush` | L28~L34 | 修改 | `TRANSLUCENCY_NEEDS_BASEPASS_FOGGING` 禁用 ScreenAlignedMesh 雾效 | +| `Shaders/Private/DepthOnlyVertexShader.usf` | — | 新增 | 同上变换逻辑(DepthOnly Pass) | +| `Shaders/Private/HitProxyVertexShader.usf` | — | 新增 | 同上(HitProxy Pass) | +| `Shaders/Private/DebugViewModeVertexShader.usf` | — | 新增 | 同上(DebugViewMode Pass) | +| `Shaders/Private/MaterialTemplate.ush` | L2243~L2252 | 新增 | `GetMaterialScreenAlignedMeshOffset/Scale` 材质访问函数 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/屏幕空间深度偏移.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/屏幕空间深度偏移.md index faeb7fe..c147c29 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/屏幕空间深度偏移.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/屏幕空间深度偏移.md @@ -40,10 +40,47 @@ rating: ⭐ `MP_ScreenSpaceDepthOffset`(float)通过材质图控制。参见 [[自定义材质属性]]。 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/BasePassVertexShader.usf` | 深度偏移逻辑 | -| `Shaders/Private/DepthOnlyVertexShader.usf` | 同上 | -| `Shaders/Private/PositionOnlyDepthVertexShader.usf` | 同上 | +### Common.ush — 深度偏移方向宏定义 + +```hlsl +// Common.ush — 深度偏移方向宏定义 +// ASW Change : 2016/06/07 15:20:36 Takuro.K +#if USES_SCREEN_SPACE_DEPTH_OFFSET + // 根据深度缓冲方向确定偏移符号 + // 反向 Z(近=1,远=0):偏移为负 = 向远处推 + // 正向 Z(近=0,远=1):偏移为正 = 向远处推 + #if HAS_INVERTED_Z_BUFFER + #define DEPTH_OFFSET_SIGN -1.0f + #else + #define DEPTH_OFFSET_SIGN 1.0f + #endif +#endif +``` + +### BasePassVertexShader.usf — 应用深度偏移 + +```hlsl +// BasePassVertexShader.usf — 应用深度偏移 +// ASW Change : 2016/06/07 15:20:36 Takuro.K +#if USES_SCREEN_SPACE_DEPTH_OFFSET + { + // 从材质图获取偏移值,乘以方向符号 + // 正值 = 向远处推(在屏幕上看起来更远) + // 负值 = 向近处拉 + Output.Position.z += GetMaterialScreenSpaceDepthOffset(VertexParameters) + * DEPTH_OFFSET_SIGN; + } +#endif +``` + +## 代码修改情况 + +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/Common.ush` | L1803~L1810 | 新增 | `DEPTH_OFFSET_SIGN` 宏定义(根据 Z-buffer 方向) | +| `Shaders/Private/BasePassVertexShader.usf` | L158~L163 | 新增 | `Output.Position.z += offset * DEPTH_OFFSET_SIGN` | +| `Shaders/Private/DepthOnlyVertexShader.usf` | — | 新增 | 同上深度偏移应用 | +| `Shaders/Private/PositionOnlyDepthVertexShader.usf` | L49~L59 | 新增 | 同上 | +| `Shaders/Private/MaterialTemplate.ush` | L2255~L2260 | 新增 | `GetMaterialScreenSpaceDepthOffset` 材质访问函数 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/正交投影混合.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/正交投影混合.md index 02db841..aa5735a 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/正交投影混合.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/正交投影混合.md @@ -123,14 +123,183 @@ float GetMaterialOrthoBlendWeight(FMaterialVertexParameters Parameters) - [[屏幕对齐网格]] — 另一种屏幕空间变换方案 - [[局部位置缩放]] — 局部空间的顶点变换 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/Common.ush` | 新增 `GetOrthoBlendPosition` / `GetOrthoBlendPosition2` | -| `Shaders/Private/BasePassVertexShader.usf` | 调用正交混合 | -| `Shaders/Private/DepthOnlyVertexShader.usf` | 调用正交混合 | -| `Shaders/Private/PositionOnlyDepthVertexShader.usf` | 调用正交混合 | -| `Shaders/Private/HitProxyVertexShader.usf` | 调用正交混合 | -| `Shaders/Private/DebugViewModeVertexShader.usf` | 调用正交混合 | -| 所有 VertexFactory `.ush` | 提供 ObjWorldPosition | +### Common.ush — V1:X轴正交混合 + +```hlsl +// ASW Change : 2016/03/29 11:30:55 Takuro.K +// V1:X轴正交混合 +// 在透视投影的X轴坐标和正交投影的X轴坐标之间做 lerp +// weight 来自材质属性 MP_OrthoBlendWeight +// ResolvedView.OrthoBlendParameter 是全局混合强度 +float4 GetOrthoBlendPosition( float4 WorldPosition, float4x4 ViewProjectionMatrix, float weight ) +{ +#if USES_ORTHO_BLEND_POSITION + float4 ScreenPosition = mul(WorldPosition, ViewProjectionMatrix); + // 用正交投影矩阵的X行点乘世界坐标,得到正交投影下的X坐标 + float OrthoScreenPositionX = dot(ResolvedView.OrthoViewProjectionX, WorldPosition); + + // 在透视X和正交X之间混合 + // 注意乘以 ScreenPosition.w 是为了从 NDC 空间转回裁剪空间 + ScreenPosition.x = lerp( + ScreenPosition.x, // 透视X + OrthoScreenPositionX * ScreenPosition.w, // 正交X(转回裁剪空间) + weight * ResolvedView.OrthoBlendParameter ); // 混合权重 + + return ScreenPosition; +#else + return mul(WorldPosition, ViewProjectionMatrix); +#endif +} +``` + +### Common.ush — V2:全透视校正("Purse correction") + +```hlsl +// ASW Change : 2019/01/11 13:53:00 Takeshi.N +// V2:全透视校正("Purse correction") +// 原理:将所有顶点投影到与物体中心等距的平面上 +// 消除前后肢体因透视导致的大小差异 +float4 GetOrthoBlendPosition2( float4 WorldPosition, float4x4 ViewProjectionMatrix, + float weight, float3 ObjWorldPosition ) +{ +#if USES_ORTHO_BLEND_POSITION2 + +#if PARTICLE_FACTORY && !PARTICLE_MESH_FACTORY + // 非网格粒子不做透视校正,直接返回标准投影 + return mul(WorldPosition, ViewProjectionMatrix); +#else + // 保存原始裁剪空间位置(用于最终 lerp) + float4 ClipSpacePositionOrigin = mul(WorldPosition, ViewProjectionMatrix); + + // 计算顶点相对于物体中心的偏移 + float3 offset = WorldPosition.xyz - ObjWorldPosition.xyz; + + // 物体中心到相机的距离(沿视线方向的投影距离) + float dist = abs(dot( + ObjWorldPosition.xyz - ResolvedView.WorldCameraOrigin.xyz, + ResolvedView.ViewForward.xyz)); + + // 在视线方向上,距离相机 dist 处的点 + float3 origin = ResolvedView.WorldCameraOrigin.xyz + + ResolvedView.ViewForward.xyz * dist; + + // 关键步骤:将顶点XY"拍平"到与物体中心等距的平面 + // 这样所有顶点在相机方向上的距离相同,消除透视缩放差异 + WorldPosition.xy = origin.xy + offset.xy; + float4 ClipSpacePosition = mul(WorldPosition, ViewProjectionMatrix); + + // X轴补偿:物体中心可能不在视线正前方 + // 需要补偿因"拍平"导致的X轴偏移 + float4x1 VPM_X = float4x1( ViewProjectionMatrix._11_21_31_41 ); + float x1 = mul(float4(origin, 1), VPM_X); // "拍平"参考点的X + float x2 = mul(float4(ObjWorldPosition, 1), VPM_X); // 物体中心的X + ClipSpacePosition.x += ClipSpacePosition.w * (x2 - x1) / dist; + + // 根据全局参数和材质权重,在原始位置和校正位置之间混合 + // step(0.01, weight) 确保 weight 接近0时完全不应用校正 + return lerp( ClipSpacePositionOrigin, ClipSpacePosition, + ResolvedView.OrthoBlendParameter * step(0.01, weight) ); +#endif + +#else + return mul(WorldPosition, ViewProjectionMatrix); +#endif +} +``` + +### BasePassVertexShader.usf — 调用逻辑 + +```hlsl +// BasePassVertexShader.usf 中的调用逻辑 +// 按优先级选择:V2 > V1 > 原始投影 +#if USES_ORTHO_BLEND_POSITION2 + // V2 透视校正:传入物体世界坐标作为参考点 + ClipSpacePosition = GetOrthoBlendPosition2( + RasterizedWorldPosition, + ResolvedView.TranslatedWorldToClip, + GetMaterialOrthoBlendWeight( VertexParameters ), // 材质图中设置的权重 + GetActorWorldPosition(VertexParameters.PrimitiveId) // 物体世界坐标 + ); +#elif USES_ORTHO_BLEND_POSITION + // V1 简单X轴混合 + ClipSpacePosition = GetOrthoBlendPosition( + RasterizedWorldPosition, + ResolvedView.TranslatedWorldToClip, + GetMaterialOrthoBlendWeight( VertexParameters ) + ); +#else + // 原始透视投影 + ClipSpacePosition = INVARIANT(mul(RasterizedWorldPosition, ResolvedView.TranslatedWorldToClip)); +#endif +``` + +### C++ 端实现 + +```cpp +// SceneRendering.cpp — 正交投影混合参数计算 +// ASW Change : 2016/03/29 Takuro.K + +// 计算正交投影矩阵的 X 行(用于 Shader 中 dot 计算正交 X 坐标) +static FVector4 CalcOrthoBlendParameter( + const FViewMatrices& ViewMatrices, + const FMatrix& EffectiveTranslatedViewMatrix) +{ + const FVector2D FOVTheta = ViewMatrices.ComputeHalfFieldOfViewPerAxis(); + float distance = ViewMatrices.GetOrthoBlendBaseDistance(); + float w = distance * FMath::Tan(FOVTheta.X); + float h = distance * FMath::Tan(FOVTheta.Y); + + // 构建正交投影矩阵,提取 X 行 + const FMatrix orthoMat = FOrthoMatrix(w, h, 0, 1); + const FMatrix ViewOrthoMatrix = EffectiveTranslatedViewMatrix * orthoMat; + return FVector4( + ViewOrthoMatrix.M[0][0], + ViewOrthoMatrix.M[1][0], + ViewOrthoMatrix.M[2][0], + ViewOrthoMatrix.M[3][0]); +} + +// 计算混合权重(基于相机朝向的衰减) +static float CalcOrthoBlendWeight( + const FViewMatrices& ViewMatrices, + const FMatrix& EffectiveTranslatedViewMatrix) +{ + float weight = ViewMatrices.GetOrthoBlendWeight(); + // 相机正面朝向时权重最大,侧面时衰减 + float face = ViewMatrices.GetOrthoBlendBaseRot() + .RotateVector(FVector(1, 0, 0)).X; + if (weight < 1.0f) + { + static const float THRESHOLD_MIN = 0.995f; + static const float RANGE = 1.0f - THRESHOLD_MIN; + face = FMath::Max((face - THRESHOLD_MIN) / RANGE, 0.0f); + weight *= face * face; // 平方衰减 + } + return weight; +} +``` + +```cpp +// SceneRendering.cpp — 写入 ViewUniformShaderParameters +ViewUniformShaderParameters.OrthoViewProjectionX = + CalcOrthoBlendParameter(ViewMatrices, TranslatedViewMatrix); +ViewUniformShaderParameters.OrthoBlendParameter = + CalcOrthoBlendWeight(ViewMatrices, TranslatedViewMatrix); +``` + +## 代码修改情况 + +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/Common.ush` | L1739~L1758 | 新增 | `GetOrthoBlendPosition` V1 X轴正交混合函数 | +| `Shaders/Private/Common.ush` | L1761~L1800 | 新增 | `GetOrthoBlendPosition2` V2 全透视校正函数 | +| `Shaders/Private/BasePassVertexShader.usf` | L94~L114 | 新增 | V2/V1 投影分支调用逻辑 | +| `Shaders/Private/DepthOnlyVertexShader.usf` | L152~L220 | 新增 | 同上(DepthOnly Pass) | +| `Shaders/Private/PositionOnlyDepthVertexShader.usf` | L49~L59 | 新增 | 同上(PositionOnlyDepth) | +| `Shaders/Private/HitProxyVertexShader.usf` | L147~L169 | 新增 | 同上(HitProxy Pass) | +| `Shaders/Private/DebugViewModeVertexShader.usf` | L162~L219 | 新增 | 同上(DebugViewMode Pass) | +| `Shaders/Private/MaterialTemplate.ush` | L2235~L2240 | 新增 | `GetMaterialOrthoBlendWeight` 材质访问函数 | +| `Source/Runtime/Renderer/Private/SceneRendering.cpp` | L1014~L1067 | 新增 | `CalcOrthoBlendParameter` / `CalcOrthoBlendWeight` 函数 | +| `Source/Runtime/Renderer/Private/SceneRendering.cpp` | L1717~L1758 | 新增 | 写入 `ViewUniformShaderParameters` OrthoBlend 参数 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义光照Pass.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义光照Pass.md index d8f94f6..8197295 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义光照Pass.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义光照Pass.md @@ -81,10 +81,87 @@ SortKey |= bPointLightRED ? (1 << PointLightSortBit) : 0; - [[RED阴影系统]] — 核心阴影着色逻辑 - [[RED自定义数据通道]] — 点光源 CustomData 的来源 -## 修改文件列表 +## 完整代码解析 -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Renderer/Private/LightRendering.cpp` | `REDDeferredLightPS`、排序、Decal | -| `Shaders/Private/DeferredLightPixelShaders.usf` | `REDDirectionalPixelMain`、CustomData 覆写 | -| `Shaders/Private/DeferredLightingCommon.ush` | 阴影合成修改 | +> 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 PixelShader(View.ShaderMap); + // ... + } + else +#endif + { + // 标准 UE4 Deferred Light 路径 + TShaderMapRef 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阴影系统]]) | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义后处理.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义后处理.md index 595897d..ff28ea7 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义后处理.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义后处理.md @@ -121,16 +121,359 @@ float CharaGlowArea; FLinearColor CharaGlowColor; ``` +## 完整代码解析 + +### REDPostProcess.usf 完整着色器注解 + +#### 辅助函数 + +```hlsl +// 灰度计算(ITU-R BT.601 标准权重) +float GetGrayscale(float3 Color) +{ + return dot(Color, float3(0.299f, 0.587f, 0.114f)); +} + +// 饱和度插值:在灰度和原色之间按 Saturation 系数过渡 +float3 LerpSaturation(float3 Color, float Saturation) +{ + float Gray = GetGrayscale(Color); + return lerp(float3(Gray, Gray, Gray), Color, Saturation); +} +``` + +#### 高斯核权重(7 权重,13-tap 对称核) + +```hlsl +// ColorSampleWeight — 用于降采样和模糊的高斯权重 +// 对称分布:中心权重最大,两侧递减 +// 权重值(半侧,index 0=中心): +// [0] = 0.3990 (中心) +// [1] = 0.2420 +// [2] = 0.0540 +// [3] = 0.0044 +// [4] = 0.0001 (接近零) +// 合计 ≈ 1.0(归一化) +static const float ColorSampleWeight[7] = { + 0.0044f, 0.0540f, 0.2420f, 0.3990f, 0.2420f, 0.0540f, 0.0044f +}; +``` + +#### DownSamplingPS — 降采样 + +```hlsl +// 4x4 区域降采样为 1 像素(用于创建 1/4 分辨率 RT) +// 采样模式:2x2 双线性采样点,每点覆盖 2x2 像素 +void DownSamplingPS( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + float2 UVOffset = 0.5f * InvSize; // 半像素偏移 + + // 4 次双线性采样取平均 + OutColor = Texture2DSample(SceneColorTexture, SceneColorSampler, InUV + float2(-UVOffset.x, -UVOffset.y)); + OutColor += Texture2DSample(SceneColorTexture, SceneColorSampler, InUV + float2( UVOffset.x, -UVOffset.y)); + OutColor += Texture2DSample(SceneColorTexture, SceneColorSampler, InUV + float2(-UVOffset.x, UVOffset.y)); + OutColor += Texture2DSample(SceneColorTexture, SceneColorSampler, InUV + float2( UVOffset.x, UVOffset.y)); + OutColor *= 0.25f; +} +``` + +#### BlurVerticalPS / BlurHorizonPS — 分离高斯模糊 + +```hlsl +// 13-tap 分离高斯模糊(垂直方向) +// 使用 ColorSampleWeight 权重,两侧各 6 个采样点 + 中心 1 个 +void BlurVerticalPS( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + OutColor = float4(0, 0, 0, 0); + + // 遍历 -6 到 +6 的偏移量 + for (int i = -6; i <= 6; i++) + { + float2 SampleUV = InUV + float2(0, i * InvSize.y); // 垂直偏移 + float Weight = ColorSampleWeight[abs(i)]; // 对称权重 + OutColor += Texture2DSample(SceneColorTexture, SceneColorSampler, SampleUV) * Weight; + } +} + +// 13-tap 分离高斯模糊(水平方向) +// 结构与垂直相同,仅偏移方向改为水平 +void BlurHorizonPS( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + OutColor = float4(0, 0, 0, 0); + + for (int i = -6; i <= 6; i++) + { + float2 SampleUV = InUV + float2(i * InvSize.x, 0); // 水平偏移 + float Weight = ColorSampleWeight[abs(i)]; + OutColor += Texture2DSample(SceneColorTexture, SceneColorSampler, SampleUV) * Weight; + } +} +``` + +#### DiffusionFilterPS — 基于亮度的辉光提取 + +```hlsl +// Diffusion Filter:从场景中提取高亮区域用于后续模糊 +// 步骤: +// 1. 采样场景颜色 +// 2. 计算亮度 → 幂次调整 → 阈值裁剪 +// 3. 输出 = 原始颜色 × 亮度遮罩 +void DiffusionFilterPS( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + float4 SceneColor = Texture2DSample(SceneColorTexture, SceneColorSampler, InUV); + + // 亮度计算 + float Luminance = GetGrayscale(SceneColor.rgb); + + // 幂次映射:LuminancePow 越大,只有越亮的区域才会被保留 + float LuminanceMask = pow(Luminance, DiffusionFilterLuminancePow); + + // 阈值裁剪:低于阈值的区域完全去除 + LuminanceMask = saturate(LuminanceMask - DiffusionFilterLuminanceThreshold); + + // 输出带亮度遮罩的颜色 + OutColor = float4(SceneColor.rgb * LuminanceMask, 1.0f); +} +``` + +#### DiffusionFilter2PS — Screen 混合 + Power + +```hlsl +// Diffusion Filter 2:将模糊后的辉光以 Screen 模式叠加回场景 +// Screen blend: Result = 1 - (1-A)(1-B) +// 然后应用 Power 调整对比度 +void DiffusionFilter2PS( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + // 采样原始场景 + float4 SceneColor = Texture2DSample(SceneColorTexture, SceneColorSampler, InUV); + + // 采样模糊后的辉光 + float4 BlurColor = Texture2DSample(BlurTexture, BlurSampler, InUV); + + // Screen 混合 + float3 BlendResult = 1.0f - (1.0f - SceneColor.rgb) * (1.0f - BlurColor.rgb); + + // Power 调整(DiffusionFilterPower 控制辉光强度曲线) + BlendResult = pow(BlendResult, DiffusionFilterPower); + + OutColor = float4(BlendResult, 1.0f); +} +``` + +#### SoftFocus — 柔焦 + +```hlsl +// Soft Focus:场景与模糊版本的混合 + 饱和度调节 +// 实现类似相机柔焦镜片的效果 +void SoftFocus( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + float4 SceneColor = Texture2DSample(SceneColorTexture, SceneColorSampler, InUV); + float4 BlurColor = Texture2DSample(BlurTexture, BlurSampler, InUV); + + // 在清晰和模糊之间按 SoftFocusBlend 系数混合 + float3 Result = lerp(SceneColor.rgb, BlurColor.rgb, SoftFocusBlend); + + // 饱和度调节 + Result = LerpSaturation(Result, SoftFocusSaturation); + + OutColor = float4(Result, 1.0f); +} +``` + +#### Glow — 辉光 + +```hlsl +// Glow:基于亮度阈值的辉光效果 +// 与 DiffusionFilter 类似但更简单,直接以 Screen 混合叠加 +void Glow( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + float4 SceneColor = Texture2DSample(SceneColorTexture, SceneColorSampler, InUV); + float4 BlurColor = Texture2DSample(BlurTexture, BlurSampler, InUV); + + // Screen 混合辉光 + float3 Result = 1.0f - (1.0f - SceneColor.rgb) * (1.0f - BlurColor.rgb * GlowIntensity); + + OutColor = float4(Result, 1.0f); +} +``` + +#### CharaGlowPS — 角色辉光模糊 + +```hlsl +// 角色辉光 Pass 1:可变半径 Box Blur +// 从 GBufferD.b 读取辉光遮罩(由 OutlineID 编码) +// 以可变半径进行 Box Blur 扩散辉光范围 +void CharaGlowPS( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + float Sum = 0; + float Count = 0; + + // 从 CharaGlowArea 计算模糊半径(像素数) + int Radius = (int)CharaGlowArea; + + // 双重循环 Box Blur + for (int y = -Radius; y <= Radius; y++) + { + for (int x = -Radius; x <= Radius; x++) + { + float2 SampleUV = InUV + float2(x, y) * InvSize; + + // 采样 GBufferD.b 通道作为辉光遮罩 + float Mask = Texture2DSample(GBufferDTexture, GBufferDSampler, SampleUV).b; + + Sum += Mask; + Count += 1.0f; + } + } + + // 归一化 + OutColor = float4(Sum / Count, 0, 0, 1); +} +``` + +#### CharaGlowCompPS — 角色辉光合成 + +```hlsl +// 角色辉光 Pass 2:将模糊后的辉光遮罩与辉光颜色合成 +// 叠加到场景颜色上 +void CharaGlowCompPS( + float4 Position : SV_POSITION, + float2 InUV : TEXCOORD0, + out float4 OutColor : SV_Target0) +{ + // 采样场景颜色 + float4 SceneColor = Texture2DSample(SceneColorTexture, SceneColorSampler, InUV); + + // 采样模糊后的辉光遮罩 + float GlowMask = Texture2DSample(CharaGlowTexture, CharaGlowSampler, InUV).r; + + // 减去原始遮罩(只保留扩散出去的边缘部分) + float OriginalMask = Texture2DSample(GBufferDTexture, GBufferDSampler, InUV).b; + GlowMask = saturate(GlowMask - OriginalMask); + + // 以 CharaGlowColor 叠加辉光 + float3 Result = SceneColor.rgb + GlowMask * CharaGlowColor.rgb * CharaGlowColor.a; + + OutColor = float4(Result, 1.0f); +} +``` + +### C++ 端实现 + +```cpp +// REDPostProcess.h — 后处理 Pass 类型枚举 +enum REDPostProcess_Type { + EREDPostProcess_DownSample, // 降采样 + EREDPostProcess_BlurH, // 水平高斯模糊 + EREDPostProcess_BlurV, // 垂直高斯模糊 +}; + +// 基础后处理 Pass(降采样 + 模糊) +class FRCPassREDPostProcess : public TRenderingCompositePassBase<1, 1> +{ + REDPostProcess_Type Type; + bool bToHalf; // 是否降采样到半分辨率 + void RenderDownSamplingPass(FRenderingCompositePassContext& Context); + void RenderBlurHPass(FRenderingCompositePassContext& Context); + void RenderBlurVPass(FRenderingCompositePassContext& Context); +}; + +// Diffusion Filter Pass(亮度提取 + Screen 混合) +class FRCPassREDPostProcess_DiffusionFilter : public TRenderingCompositePassBase<2, 1> { ... }; + +// Diffusion Filter 2 Pass(Power + 阈值 + 可选 CharaGlow 合成) +class FRCPassREDPostProcess_DiffusionFilter2 : public TRenderingCompositePassBase<4, 1> { ... }; + +// CharaGlow Pass(可变半径 BoxBlur on GBufferD.b) +class FRCPassREDPostProcess_CharaGlow : public TRenderingCompositePassBase<1, 1> { ... }; +``` + +```cpp +// PostProcessing.cpp — 后处理管线插入 +// CVar 控制插入位置 +static TAutoConsoleVariable CVarREDPostprocessAfterTranslucency( + TEXT("r.REDPostprocessAfterTranslucency"), + // 0: SeparateTranslucency 之前 + // 1: SeparateTranslucency 之后 + // 2: Bloom 之后 +); + +// AddREDPostProcess — 构建后处理图 +static void AddREDPostProcess(FPostprocessContext& Context) +{ + float pow = Context.View.FinalPostProcessSettings.DiffusionFilterLuminancePow; + // 创建降采样 → 水平模糊 → 垂直模糊 → DiffusionFilter2 节点链 + FRenderingCompositePass* NodeDownSample = new FRCPassREDPostProcess(EREDPostProcess_DownSample, true); + FRenderingCompositePass* NodeBlurH = new FRCPassREDPostProcess(EREDPostProcess_BlurH, false); + FRenderingCompositePass* NodeBlurV = new FRCPassREDPostProcess(EREDPostProcess_BlurV, false); + + // 可选:CharaGlow(角色辉光) + float area = Context.View.FinalPostProcessSettings.CharaGlowArea; + if (area > 0) { + FLinearColor color = Context.View.FinalPostProcessSettings.CharaGlowColor; + FRenderingCompositePass* NodeGlow = new FRCPassREDPostProcess_CharaGlow(color, area); + // ... 连接到图 + } + + // 最终 DiffusionFilter2 节点 + float threshold = Context.View.FinalPostProcessSettings.DiffusionFilterLuminanceThreshold; + FRenderingCompositePass* NodeFinal = new FRCPassREDPostProcess_DiffusionFilter2(pow, threshold, bWithGlow); +} +``` + ## 关联文档 - [[RED自定义数据通道]] — CharaGlow 读取 GBufferD.b 通道 - [[BGMultColor全局色调]] — 另一个全局色彩控制系统 -## 修改文件列表 +## 代码修改情况 -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/REDPostProcess.usf` | **新增** — 完整后处理着色器 | -| `Source/Runtime/Renderer/Private/PostProcess/REDPostProcess.h` | **新增** — C++ 后处理 Pass | -| `Source/Runtime/Renderer/Private/PostProcess/REDPostProcess.cpp` | **新增** — C++ 实现 | -| `Source/Runtime/Engine/Classes/Engine/Scene.h` | 新增 PostProcess 参数 | +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/REDPostProcess.usf` | 全文 (473行) | **新增文件** | 完整自定义后处理着色器 | +| ↳ | L49~L57 | — | `PostProcessVS` 标准顶点着色器 | +| ↳ | L61~L86 | — | `PostProcessBlurVS` 高斯模糊顶点着色器(预计算7个采样点) | +| ↳ | L96~L105 | — | `ColorSampleWeight[7]` 高斯权重表 | +| ↳ | L117~L129 | — | `GetGrayscale` / `LerpSaturation` 辅助函数 | +| ↳ | L134~L137 | — | `DownSamplingPS` 降采样 | +| ↳ | L142~L191 | — | `BlurVerticalPS` 垂直高斯模糊(13-tap) | +| ↳ | L196~L246 | — | `BlurHorizonPS` 水平高斯模糊(13-tap) | +| ↳ | L251~L278 | — | `DiffusionFilterPS` 扩散滤镜(亮度提取 + max 混合) | +| ↳ | L283~L318 | — | `DiffusionFilter2PS` 扩散滤镜2(Screen 混合 + CharaGlow 合成) | +| ↳ | L323~L350 | — | `DiffusionFilter2WithOutCharaGlowPS` 不含辉光版本 | +| ↳ | L355~L376 | — | `DiffusionFilter2SepiaPS` 棕褐色变体 | +| ↳ | L383~L393 | — | `SoftFocus` 柔焦效果 | +| ↳ | L400~L430 | — | `Glow` 辉光(亮度阈值 + Screen 混合) | +| ↳ | L437~L455 | — | `CharaGlowPS` 角色辉光(可变半径 BoxBlur on GBufferD.b) | +| ↳ | L461~L470 | — | `CharaGlowCompPS` 辉光合成(叠加到场景 + mask) | +| `Source/Runtime/Renderer/Private/PostProcess/REDPostProcess.h` | 全文 (298行) | **新增文件** | 后处理 Pass 类声明(4个 Pass 类 + 枚举) | +| `Source/Runtime/Renderer/Private/PostProcess/REDPostProcess.cpp` | 全文 (1735行) | **新增文件** | 后处理 Pass 实现(Shader 绑定/参数设置/RT 管理) | +| `Source/Runtime/Renderer/Private/PostProcess/PostProcessing.cpp` | L100~L129 | 新增 | `#include "REDPostProcess.h"` + `CVarREDPostprocessAfterTranslucency` CVar | +| `Source/Runtime/Renderer/Private/PostProcess/PostProcessing.cpp` | L224~L661 | 新增 | `AddREDPostProcess` 完整后处理图构建函数 (~438行) | +| `Source/Runtime/Renderer/Private/PostProcess/PostProcessing.cpp` | L669~L681 | 修改 | 根据 CVar 在管线中插入 RED 后处理 | +| `Source/Runtime/Renderer/Private/PostProcess/PostProcessing.cpp` | L852~L908 | 新增 | CharaGlow 独立模式插入逻辑 | +| `Source/Runtime/Engine/Classes/Engine/Scene.h` | — | 修改 | 新增 `DiffusionFilterLuminancePow/Threshold`、`CharaGlowArea/Color` | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义材质属性.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义材质属性.md index 9f074a5..9c5a547 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义材质属性.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/自定义材质属性.md @@ -86,20 +86,77 @@ if (Material.bForcedPrepass) 新增 `REDMaterialInstanceDynamic` 类(`REDMaterialInstanceDynamic.h/.cpp`),扩展了标准 `UMaterialInstanceDynamic`,可能用于运行时的卡通渲染材质参数控制。 +## 完整代码解析 + +### MaterialTemplate.ush — 新增材质属性访问函数 + +```hlsl +// MaterialTemplate.ush — 新增材质属性访问函数 +// ASW Change : 2016/03/29 ~ 2016/06/29 Takuro.K + +// 正交投影混合权重 (float) +// 材质图中连接到此 Pin 的表达式会在编译时替换 %s +float GetMaterialOrthoBlendWeight(FMaterialVertexParameters Parameters) +{ +%s; // 由 HLSLMaterialTranslator 填充 +} + +// 屏幕对齐网格偏移 (float3, 像素单位, 基于1280x720) +float3 GetMaterialScreenAlignedMeshOffset(FMaterialVertexParameters Parameters) +{ +%s; +} + +// 屏幕对齐网格缩放 (float3) +float3 GetMaterialScreenAlignedMeshScale(FMaterialVertexParameters Parameters) +{ +%s; +} + +// 屏幕空间深度偏移 (float, 正值向远推) +float GetMaterialScreenSpaceDepthOffset(FMaterialVertexParameters Parameters) +{ +%s; +} + +// 局部位置缩放 (float3, 在WorldTransform前应用) +float3 GetMaterialLocalPositionScale(FMaterialVertexParameters Parameters) +{ +%s; +} +``` + +### PixelDepthOffset 修复 + +```hlsl +// ASW Change : 2020/10/29 Takeshi.N +// 修复 PC 平台 PixelDepthOffset 为 0 或负值时的噪声问题 +// 当 PDO <= 0 时,直接使用原始 SvPosition.z 而非计算值 +DeviceDepth = lerp( + DeviceDepth, // PDO > 0:使用计算后的深度 + MaterialParameters.SvPosition.z, // PDO <= 0:使用原始深度 + step(PixelDepthOffset, 0) // step 函数:PDO<=0 返回 1 +); +``` + ## 关联文档 - [[正交投影混合]] — 使用 `MP_OrthoBlendWeight` - [[屏幕对齐网格]] — 使用 `MP_ScreenAlignedMeshOffset/Scale` - [[BasePass修改]] — `bForcedPrepass` 的影响 -## 修改文件列表 +## 代码修改情况 -| 文件 | 修改类型 | -|------|---------| -| `Source/Runtime/Engine/Public/SceneTypes.h` | 新增 `MP_*` 枚举 | -| `Source/Runtime/Engine/Classes/Materials/Material.h` | 新增 `bScreenAlignedMesh`、`bForcedPrepass` | -| `Source/Runtime/Engine/Classes/Materials/REDMaterialInstanceDynamic.h` | **新增** | -| `Source/Runtime/Engine/Private/Materials/REDMaterialInstanceDynamic.cpp` | **新增** | -| `Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp` | 编译支持 | -| `Shaders/Private/MaterialTemplate.ush` | 新增访问函数 | -| `Source/Editor/MaterialEditor/` | 编辑器 UI 支持 | +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/MaterialTemplate.ush` | L2235~L2240 | 新增 | `GetMaterialOrthoBlendWeight` 函数 | +| `Shaders/Private/MaterialTemplate.ush` | L2243~L2252 | 新增 | `GetMaterialScreenAlignedMeshOffset/Scale` 函数 | +| `Shaders/Private/MaterialTemplate.ush` | L2255~L2260 | 新增 | `GetMaterialScreenSpaceDepthOffset` 函数 | +| `Shaders/Private/MaterialTemplate.ush` | L2263~L2268 | 新增 | `GetMaterialLocalPositionScale` 函数 | +| `Shaders/Private/MaterialTemplate.ush` | L2584~L2587 | 新增 | PixelDepthOffset ≤ 0 时使用原始深度 | +| `Source/Runtime/Engine/Public/SceneTypes.h` | — | 新增 | `MP_OrthoBlendWeight` 等枚举值 | +| `Source/Runtime/Engine/Classes/Materials/Material.h` | — | 新增 | `bScreenAlignedMesh`、`bForcedPrepass` 标记 | +| `Source/Runtime/Engine/Classes/Materials/REDMaterialInstanceDynamic.h` | 全文 | **新增文件** | 自定义 MaterialInstanceDynamic | +| `Source/Runtime/Engine/Private/Materials/REDMaterialInstanceDynamic.cpp` | 全文 | **新增文件** | 实现 | +| `Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp` | — | 修改 | 新属性编译支持 | +| `Source/Editor/MaterialEditor/` | — | 修改 | 编辑器 UI 支持 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/Slate扩展.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/Slate扩展.md deleted file mode 100644 index d9b4f93..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/Slate扩展.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Slate扩展 -date: 2026-05-03 00:00:00 -excerpt: 垂直文本对齐、独立透明度、文本溢出省略、富文本图片、几何缓存 -tags: - - ARC - - UI - - Slate -rating: ⭐ ---- - -# Slate 扩展 - -返回 [[UI]] - -## 概述 - -ARC 引擎对 Slate 框架进行了多项扩展,主要围绕文本渲染和 Widget 性能优化。 - -## 1. 垂直文本对齐 - -新增 `ETextJustifyV::Type` 枚举,为 `STextBlock` 和 `SRichTextBlock` 添加垂直对齐支持: - -- `Top` — 顶部对齐 -- `Center` — 垂直居中 -- `Bottom` — 底部对齐 - -格斗游戏 UI 中常需要文本在固定高度区域内垂直居中。 - -## 2. 独立阴影/描边透明度 - -Shadow 和 Outline 的颜色不受父 Widget 透明度影响: - -``` -标准 UE4:文字透明度 50% → Shadow 也跟着变为 50% -ARC 修改:文字透明度 50% → Shadow 保持自身设定的透明度 -``` - -用于格斗游戏中文字淡入淡出时保持描边清晰可见。 - -## 3. 文本溢出省略 - -按高度截断文本并添加省略号(`...`)。标准 UE4 只支持按宽度截断。 - -## 4. 富文本图片运行 - -`SRichTextBlock` 扩展了图片嵌入能力: -- 动态 Brush 支持(运行时更换图标) -- 范围创建(基于文本范围插入图片) - -## 5. 几何缓存 - -在 `SWidget` 上新增几何缓存机制: - -```cpp -void SetCachedGeometry(); -void UpdateGeometryAllChildren(); -``` - -减少每帧的 Layout 计算开销,对格斗游戏 60fps 的帧预算至关重要。 - -## 修改文件列表 - -涉及 `Source/Runtime/Slate/` 和 `Source/Runtime/SlateCore/` 下约 26 个文件,主要覆盖: -- `STextBlock.h/.cpp` — 垂直对齐、溢出 -- `SRichTextBlock.h/.cpp` — 富文本图片 -- `SWidget.h/.cpp` — 几何缓存 -- `FontCache` 相关 — 文本阴影/描边独立透明度 diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UI.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UI.md index 6bfe6a7..adeb96f 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UI.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UI.md @@ -1,7 +1,7 @@ --- title: UI date: 2026-05-03 00:00:00 -excerpt: ARC 引擎 UI/Slate/UMG 扩展分类索引 +excerpt: ARC 引擎 UI/Slate/UMG 扩展合集:垂直对齐、独立透明度、文本溢出、富文本图片、几何缓存、平台本地化、简单元素着色器扩展 tags: - ARC - UI @@ -16,17 +16,241 @@ rating: ⭐ ARC 引擎对 UE4 的 UI 系统(Slate + UMG)进行了大量扩展,主要服务于格斗游戏的文本显示需求(多语言、竖排文字)和控制器管理。修改涉及约 38 个文件。 -## 功能列表 - -| 功能 | 文档 | 说明 | -|------|------|------| -| Slate 扩展 | [[Slate扩展]] | 垂直对齐、独立透明度、文本溢出、富文本图片、几何缓存 | -| UMG 本地化 | [[UMG本地化]] | 平台后缀语言 ID、平台感知文本查找 | -| 简单元素渲染扩展 | [[简单元素渲染扩展]] | REDMain、AddColor、灰度、Multiply 混合 | - ## 控制器管理 新增 `FUEISlateApplication`(继承 `FSlateApplication`): - User/Controller ID 映射表(`UserIndexMap`) - 格斗游戏多手柄的输入分配 - 参见 [[UEI事件系统]] + +## Slate 扩展 + +### 概述 + +ARC 引擎对 Slate 框架进行了多项扩展,主要围绕文本渲染和 Widget 性能优化。 + +### 1. 垂直文本对齐 + +新增 `ETextJustifyV::Type` 枚举,为 `STextBlock` 和 `SRichTextBlock` 添加垂直对齐支持: + +- `Top` — 顶部对齐 +- `Center` — 垂直居中 +- `Bottom` — 底部对齐 + +格斗游戏 UI 中常需要文本在固定高度区域内垂直居中。 + +### 2. 独立阴影/描边透明度 + +Shadow 和 Outline 的颜色不受父 Widget 透明度影响: + +``` +标准 UE4:文字透明度 50% → Shadow 也跟着变为 50% +ARC 修改:文字透明度 50% → Shadow 保持自身设定的透明度 +``` + +用于格斗游戏中文字淡入淡出时保持描边清晰可见。 + +### 3. 文本溢出省略 + +按高度截断文本并添加省略号(`...`)。标准 UE4 只支持按宽度截断。 + +### 4. 富文本图片运行 + +`SRichTextBlock` 扩展了图片嵌入能力: +- 动态 Brush 支持(运行时更换图标) +- 范围创建(基于文本范围插入图片) + +### 5. 几何缓存 + +在 `SWidget` 上新增几何缓存机制: + +```cpp +void SetCachedGeometry(); +void UpdateGeometryAllChildren(); +``` + +减少每帧的 Layout 计算开销,对格斗游戏 60fps 的帧预算至关重要。 + +### 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/Slate/Public/Widgets/Text/STextBlock.h` | 修改 | 新增 `ETextJustifyV` 垂直对齐属性 | +| `Source/Runtime/Slate/Private/Widgets/Text/STextBlock.cpp` | 修改 | 垂直对齐布局计算 | +| `Source/Runtime/Slate/Public/Widgets/Text/SRichTextBlock.h` | 修改 | 富文本图片运行 + 动态 Brush | +| `Source/Runtime/Slate/Private/Widgets/Text/SRichTextBlock.cpp` | 修改 | 富文本图片运行实现 | +| `Source/Runtime/SlateCore/Public/Widgets/SWidget.h` | 修改 | 新增 `SetCachedGeometry`、`UpdateGeometryAllChildren` | +| `Source/Runtime/SlateCore/Private/Widgets/SWidget.cpp` | 修改 | 几何缓存实现 | +| `Source/Runtime/SlateCore/Private/Fonts/FontCache*.cpp` | 修改 | 文本阴影/描边独立透明度 | +| `Source/Runtime/Slate/` 其他文件 (~26个) | 修改 | 文本溢出省略、范围创建等 | + +## UMG 本地化 + +### 概述 + +ARC 引擎为 UMG 文本系统添加了平台感知的本地化机制,允许同一文本 ID 在不同平台上显示不同内容(例如按钮提示文本因平台不同而变化)。 + +### 平台后缀系统 + +文本 ID 查找时自动追加平台后缀: + +| 平台 | 后缀 | +|------|------| +| PS5 | `_PS5` | +| Xbox Series X | `_XSX` | +| 其他 | 无后缀(使用默认文本) | + +查找顺序: +1. 先查 `TextID_PS5`(或 `_XSX`) +2. 找不到则回退到 `TextID` + +### 语言 ID + +新增 CVar `sg_REDLanguageID`,允许运行时切换语言而不依赖系统语言设置: + +```cpp +static TAutoConsoleVariable CVarREDLanguageID( + TEXT("sg.REDLanguageID"), + 0, + TEXT("Override language ID for RED localization")); +``` + +### 自定义 L10N 加载 + +`Source/Runtime/Core/` 中的本地化文件加载逻辑支持自定义 L10N 目录。 + +### 兼容性 + +`UOldRichTextBlockDecorator` 兼容层确保旧版富文本格式在新系统中正常工作。 + +### 代码修改情况 + +| 文件路径 | 修改类型 | 修改内容 | +|---------|---------|---------| +| `Source/Runtime/UMG/Private/Components/TextBlock.cpp` | 修改 | 平台后缀 `_PS5`/`_XSX` 文本查找逻辑 | +| `Source/Runtime/UMG/Public/Components/TextWidgetTypes.h` | 修改 | 垂直文本对齐支持 | +| `Source/Runtime/UMG/Private/Components/RichTextBlockDecorator.cpp` | 修改 | `UOldRichTextBlockDecorator` 兼容层 | +| `Source/Runtime/UMG/Private/Components/WidgetComponent.cpp` | 修改 | Widget 组件修改 | +| `Source/Runtime/Core/` | 修改 | `sg_REDLanguageID` CVar + 自定义 L10N 加载 | + +## 简单元素渲染扩展 + +### 概述 + +扩展了 UE4 的 SimpleElement Pixel Shader(用于 2D UI 元素、线条、Debug 绘制等),新增颜色叠加、灰度转换和 Multiply 混合模式。 + +### 新增着色器入口 + +#### REDMain / GammaREDMain + +```hlsl +void REDMain(... out float4 OutColor : SV_Target0) +{ + OutColor = CalcREDColor(InColor, InTexCoord); +} + +float4 CalcREDColor(float4 VertexColor, float2 UV) +{ + float4 TexColor = Texture2DSample(InTexture, InTextureSampler, UV); + float4 Result = TexColor * VertexColor; + + // 叠加色 + Result.rgb += AddColor.rgb; + + // 灰度转换 + float Gray = dot(Result.rgb, float3(0.299, 0.587, 0.114)); + Result.rgb = lerp(float3(Gray, Gray, Gray), Result.rgb, Grayscale); + + return Result; +} +``` + +参数: +- `AddColor` — 加法颜色叠加(uniform float3) +- `Grayscale` — 饱和度系数(uniform float,0=灰度,1=原色) + +#### MainMult + +Multiply 混合模式的 Simple Element 渲染: + +```hlsl +void MainMult(... out float4 OutColor : SV_Target0) +{ + // 用于 Multiply 混合的 UI 元素 +} +``` + +### 使用场景 + +- 格斗游戏 UI 的动态颜色变化(血条变色、技能冷却灰度化) +- 受击时的 HUD 闪烁效果(AddColor 叠加红色) +- 菜单界面的 Multiply 叠加装饰 + +### 完整代码解析 + +#### SimpleElementPixelShader.usf — RED 扩展 + +```hlsl +// ASW Change : 2013/10/01 10:08:00 Takeshi.N +// RED 扩展的 Simple Element 着色器 + +// 全局参数 +half Grayscale; // 饱和度控制 (0=灰度, 1=原色) +float4 AddColor; // 加法叠加颜色 + +// 通用颜色计算函数 +float4 CalcREDColor( float4 BaseColor, float4 VertexColor, float4 AddColor, bool bGamma ) +{ + // 基色 × 顶点色 + 叠加色 + BaseColor = BaseColor * VertexColor + AddColor; + + // 可选 Gamma 校正 + if( bGamma && ( Gamma != 1.0 ) ) + { + BaseColor.rgb = pow(saturate(BaseColor.rgb), Gamma); + } + + // 灰度混合:根据 Grayscale 参数在灰度和原色之间过渡 + float luma = dot( float3( 0.299f, 0.587f, 0.114f ), BaseColor.rgb ); + return lerp( BaseColor, float4( luma.xxx, BaseColor.a ), Grayscale ); +} + +// 标准 RED 入口(不带 Gamma 校正) +void REDMain(..., out float4 OutColor : SV_Target0, ...) +{ + float4 BaseColor = ColourTexture2DSample(InTexture, InTextureSampler, TextureCoordinate); + ReplicateChannelSimpleElementShader(BaseColor); + BaseColor = CalcREDColor( BaseColor, Color, AddColor, false ); + OutColor = RETURN_COLOR( BaseColor ); +} + +// Gamma 校正版本 +void GammaREDMain(..., out float4 OutColor : SV_Target0, ...) +{ + // 与 REDMain 相同,但 bGamma=true + BaseColor = CalcREDColor( BaseColor, Color, AddColor, true ); + OutColor = RETURN_COLOR( BaseColor ); +} + +// Multiply 混合模式入口 +void MainMult(..., out float4 OutColor : SV_Target0, ...) +{ + float4 BaseColor = ColourTexture2DSample(InTexture, InTextureSampler, TextureCoordinate); + ReplicateChannelSimpleElementShader(BaseColor); + BaseColor *= Color; + // Premultiplied alpha multiply blend: + // 输出 = 基色 + (1-基色) × (1-Alpha) + // Alpha=1 时输出基色(纯乘法),Alpha=0 时输出白色(无效果) + OutColor = RETURN_COLOR(BaseColor + (1.0f - BaseColor) * (1.0f - BaseColor.a)); +} +``` + +### 代码修改情况 + +| 文件路径 | 行号 | 修改类型 | 修改内容 | +|---------|------|---------|---------| +| `Shaders/Private/SimpleElementPixelShader.usf` | L432~L434 | 新增 | `Grayscale` 和 `AddColor` uniform 声明 | +| `Shaders/Private/SimpleElementPixelShader.usf` | L436~L455 | 新增 | `CalcREDColor` 通用颜色计算函数 | +| `Shaders/Private/SimpleElementPixelShader.usf` | L457~L487 | 新增 | `REDMain` 标准 RED 入口(不带 Gamma) | +| `Shaders/Private/SimpleElementPixelShader.usf` | L489~L518 | 新增 | `GammaREDMain` Gamma 校正版本 | +| `Shaders/Private/SimpleElementPixelShader.usf` | L522~L542 | 新增 | `MainMult` Multiply 混合模式入口 | diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UMG本地化.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UMG本地化.md deleted file mode 100644 index d9e14f6..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UMG本地化.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: UMG本地化 -date: 2026-05-03 00:00:00 -excerpt: 平台感知的多语言文本系统(平台后缀、语言 ID) -tags: - - ARC - - UI - - UMG - - Localization -rating: ⭐ ---- - -# UMG 本地化 - -返回 [[UI]] - -## 概述 - -ARC 引擎为 UMG 文本系统添加了平台感知的本地化机制,允许同一文本 ID 在不同平台上显示不同内容(例如按钮提示文本因平台不同而变化)。 - -## 平台后缀系统 - -文本 ID 查找时自动追加平台后缀: - -| 平台 | 后缀 | -|------|------| -| PS5 | `_PS5` | -| Xbox Series X | `_XSX` | -| 其他 | 无后缀(使用默认文本) | - -查找顺序: -1. 先查 `TextID_PS5`(或 `_XSX`) -2. 找不到则回退到 `TextID` - -## 语言 ID - -新增 CVar `sg_REDLanguageID`,允许运行时切换语言而不依赖系统语言设置: - -```cpp -static TAutoConsoleVariable CVarREDLanguageID( - TEXT("sg.REDLanguageID"), - 0, - TEXT("Override language ID for RED localization")); -``` - -## 自定义 L10N 加载 - -`Source/Runtime/Core/` 中的本地化文件加载逻辑支持自定义 L10N 目录。 - -## 兼容性 - -`UOldRichTextBlockDecorator` 兼容层确保旧版富文本格式在新系统中正常工作。 - -## 修改文件列表 - -涉及 `Source/Runtime/UMG/` 下约 12 个文件,主要覆盖: -- `TextBlock` 相关 — 平台后缀查找 -- `TextWidgetTypes` — 垂直对齐(与 [[Slate扩展]] 配合) -- `RichTextBlockDecorator` — 兼容层 -- `WidgetComponent` — 修改 diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/简单元素渲染扩展.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/简单元素渲染扩展.md deleted file mode 100644 index 1ee8759..0000000 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/简单元素渲染扩展.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: 简单元素渲染扩展 -date: 2026-05-03 00:00:00 -excerpt: REDMain/GammaREDMain 着色器扩展:AddColor、灰度、Multiply 混合 -tags: - - ARC - - UI - - Rendering -rating: ⭐ ---- - -# 简单元素渲染扩展 - -返回 [[UI]] - -## 概述 - -扩展了 UE4 的 SimpleElement Pixel Shader(用于 2D UI 元素、线条、Debug 绘制等),新增颜色叠加、灰度转换和 Multiply 混合模式。 - -## 新增着色器入口 - -### REDMain / GammaREDMain - -```hlsl -void REDMain(... out float4 OutColor : SV_Target0) -{ - OutColor = CalcREDColor(InColor, InTexCoord); -} - -float4 CalcREDColor(float4 VertexColor, float2 UV) -{ - float4 TexColor = Texture2DSample(InTexture, InTextureSampler, UV); - float4 Result = TexColor * VertexColor; - - // 叠加色 - Result.rgb += AddColor.rgb; - - // 灰度转换 - float Gray = dot(Result.rgb, float3(0.299, 0.587, 0.114)); - Result.rgb = lerp(float3(Gray, Gray, Gray), Result.rgb, Grayscale); - - return Result; -} -``` - -参数: -- `AddColor` — 加法颜色叠加(uniform float3) -- `Grayscale` — 饱和度系数(uniform float,0=灰度,1=原色) - -### MainMult - -Multiply 混合模式的 Simple Element 渲染: - -```hlsl -void MainMult(... out float4 OutColor : SV_Target0) -{ - // 用于 Multiply 混合的 UI 元素 -} -``` - -## 使用场景 - -- 格斗游戏 UI 的动态颜色变化(血条变色、技能冷却灰度化) -- 受击时的 HUD 闪烁效果(AddColor 叠加红色) -- 菜单界面的 Multiply 叠加装饰 - -## 修改文件列表 - -| 文件 | 修改类型 | -|------|---------| -| `Shaders/Private/SimpleElementPixelShader.usf` | 新增 `REDMain`、`MainMult`、`CalcREDColor` |