docs(rendering): document color scale post-process API

This commit is contained in:
2026-04-10 18:25:06 +08:00
parent a990553ade
commit bb9a4d5ef4
24 changed files with 481 additions and 319 deletions

View File

@@ -6,35 +6,47 @@
**头文件**: `XCEngine/Rendering/Passes/BuiltinColorScalePostProcessPass.h`
**描述**: 基于 `RenderPassContext::sourceColorView`全屏颜色缩放后处理 pass当前由相机 post-process 栈通过 factory 按需创建。
**描述**: 基于 `RenderPassContext::sourceColorView` fullscreen 颜色缩放后处理 pass当前由相机 post-process 栈按需创建。
## 概
## 概
`BuiltinColorScalePostProcessPass` 是当前 post-process 路径里最简单的一类 fullscreen pass
`BuiltinColorScalePostProcessPass` 是当前 post-process 链路里最直接的一类 fullscreen pass
-`sourceColorView` 采样输入颜色
-`m_colorScale` 写入常量
- 输出到 `context.surface`
-`sourceColorView` 采样输入颜色
-`m_colorScale` 写入常量缓冲。
- 输出到 `context.surface` 的唯一颜色附件。
它通常不由调用方手工长期持有,而是通过 [BuildCameraPostProcessPassSequence](../../Planning/CameraPostProcessPassFactory/CameraPostProcessPassFactory.md) 根据 `CameraPostProcessStack` 临时组装。
## 当前公开能力
## 公开类型
- 构造时指定 `colorScale` 和可选 `shaderPath`
- `GetName()` / `Execute(...)` / `Shutdown()`
- `SetColorScale(...)` / `GetColorScale()`
- `SetShaderPath(...)` / `GetShaderPath()`
- [OwnedDescriptorSet](OwnedDescriptorSet.md)
## 公开方法
| 方法 | 说明 |
|------|------|
| [Constructor](Constructor.md) | 构造 post-process color-scale pass并可选指定自定义 shader 路径。 |
| [Destructor](Destructor.md) | 析构时释放内部 GPU 资源。 |
| [GetName](GetName.md) | 返回固定 pass 名称。 |
| [Execute](Execute.md) | 执行 fullscreen 颜色缩放绘制。 |
| [Shutdown](Shutdown.md) | 主动释放当前持有的 GPU 资源。 |
| [SetColorScale](SetColorScale.md) | 更新颜色缩放参数。 |
| [GetColorScale](GetColorScale.md) | 读取当前颜色缩放参数。 |
| [SetShaderPath](SetShaderPath.md) | 切换 post-process shader 路径,并使资源缓存失效。 |
| [GetShaderPath](GetShaderPath.md) | 读取当前 shader 路径。 |
## 当前实现边界
- 只处理单个全屏颜色缩放效果,不负责 tone mapping、output transfer 或 final compositing。
- 资源初始化按 `RenderContext` 后端和 render target format 惰性建立
- 输入颜色必须来自 `RenderPassContext::sourceColorView`;它不会自己分配中间表面
- 它只负责单一的颜色缩放效果,不承担 tone mapping、output transfer 或 final compositing。
- 当前实现要求 source surface 与 destination surface 都是“单颜色附件”形态;不支持 MRT也不使用深度附件
- 构造函数会在传入空路径时自动回退到 builtin color-scale shader但后续若显式调用 `SetShaderPath("")`,资源创建会因为空路径而失败,直到重新设置为非空路径
- GPU 资源缓存会随着 backend、目标格式、sample count、sample quality 和 shader path 变化而失效;[SetColorScale](SetColorScale.md) 本身只更新常量,不会重建 pipeline。
## 真实接入位置
- `SceneRenderer` 先根据相机 `postProcess` 描述构建 `CameraRenderRequest::postProcess`
- `BuildCameraPostProcessPassSequence(...)` 读取 [CameraPostProcessPassDesc](../../Planning/CameraPostProcessDesc/CameraPostProcessDesc.md) 并生成当前 pass。
- `SceneRenderer` 先根据相机 `postProcess` 描述构建 `CameraRenderRequest::postProcess`
- `BuildCameraPostProcessPassSequence(...)` 读取 [CameraPostProcessDesc](../../Planning/CameraPostProcessDesc/CameraPostProcessDesc.md) 并生成当前 pass。
- `CameraRenderer` 在主场景之后、final-output 之前执行这一阶段。
## 相关文档
@@ -43,3 +55,4 @@
- [CameraPostProcessDesc](../../Planning/CameraPostProcessDesc/CameraPostProcessDesc.md)
- [CameraPostProcessPassFactory](../../Planning/CameraPostProcessPassFactory/CameraPostProcessPassFactory.md)
- [BuiltinFinalColorPass](../BuiltinFinalColorPass/BuiltinFinalColorPass.md)
- [RenderPass](../../RenderPass/RenderPass.md)

View File

@@ -0,0 +1,26 @@
# BuiltinColorScalePostProcessPass::BuiltinColorScalePostProcessPass
构造 post-process color-scale pass并初始化颜色缩放参数与 shader 路径。
```cpp
explicit BuiltinColorScalePostProcessPass(
const Math::Vector4& colorScale = Math::Vector4(0.65f, 0.80f, 1.0f, 1.0f),
Containers::String shaderPath = {});
```
## 参数
- `colorScale` - 初始颜色缩放参数。
- `shaderPath` - 可选自定义 shader 路径;传空时会自动回退到 builtin color-scale shader。
## 当前语义
- 构造函数只保存 CPU 侧配置,不会立即创建 GPU 资源。
- 如果 `shaderPath.Empty()`,构造函数会改写成 `Resources::GetBuiltinColorScalePostProcessShaderPath()`
- 真正的 pipeline、sampler、descriptor set 与 shader 资源会在第一次 [Execute](Execute.md) 时按目标 surface 延迟创建。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [Execute](Execute.md)
- [SetShaderPath](SetShaderPath.md)
- [SetColorScale](SetColorScale.md)

View File

@@ -0,0 +1,21 @@
# BuiltinColorScalePostProcessPass::~BuiltinColorScalePostProcessPass
析构函数会兜底释放当前持有的 GPU 资源。
```cpp
~BuiltinColorScalePostProcessPass() override;
```
## 当前语义
- 实现直接调用 [Shutdown](Shutdown.md)。
- 因此即便调用方忘记手动 `Shutdown()`,析构时也会回收 pipeline、pipeline layout、sampler、descriptor pool / set 与 shader 句柄。
## 当前实现边界
- 析构只负责当前 pass 自己持有的 GPU 资源,不管理 source / destination surface 或外部传入的 `RenderPassContext` 资源。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [Shutdown](Shutdown.md)
- [OwnedDescriptorSet](OwnedDescriptorSet.md)

View File

@@ -0,0 +1,39 @@
# BuiltinColorScalePostProcessPass::Execute
执行一次 fullscreen 颜色缩放绘制。
```cpp
bool Execute(const RenderPassContext& context) override;
```
## 参数
- `context` - 当前渲染上下文、source surface / source color view以及目标 `RenderSurface` 的组合描述。
## 返回值
- 成功完成颜色缩放绘制返回 `true`;前置条件不满足或 GPU 资源初始化失败时返回 `false`
## 当前语义
- 要求 `context.renderContext` 有效,且 `context.sourceSurface``context.sourceColorView` 非空。
- 要求 source surface 与 destination surface 都是“恰好一个有效颜色附件”的形态。
- 会校验 destination `RenderSurface::GetRenderArea()` 的宽高必须大于 `0`
- 资源未就绪时会调用内部初始化逻辑;若 backend、目标格式、sample count、sample quality 或 shader path 发生变化,会先销毁旧资源再重建。
- 每次执行都会把 [GetColorScale](GetColorScale.md) 的结果写入常量缓冲source 纹理 descriptor 只有在 `sourceColorView` 变化时才会重新绑定。
- destination surface 开启自动状态切换时,会把目标颜色附件从 `GetColorStateBefore()` 切到 `RenderTarget`,绘制完成后再切回 `GetColorStateAfter()`
- source surface 开启自动状态切换时,会把 `sourceColorView``context.sourceColorState` 切到 `PixelShaderResource`,结束后再切回原状态;若 source 关闭自动切换,则 `context.sourceColorState` 必须已经是 `PixelShaderResource`
- 绘制路径会设置 render target、viewport、scissor、triangle-list 拓扑、pipeline state 和 3 组 descriptor set然后发出一次 `Draw(3, 1, 0, 0)`
## 当前实现边界
- 当前实现不使用深度附件,也不处理多颜色附件输出。
- 是否执行这个 post-process pass本身由上层 planning / factory 决定;这里不负责策略选择。
- 当前仓库里没有直接以 `BuiltinColorScalePostProcessPass` 命名的独立单元测试,更多约束来自 `SceneRenderer` 的 post-process 链路。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [Shutdown](Shutdown.md)
- [SetColorScale](SetColorScale.md)
- [RenderPass](../../RenderPass/RenderPass.md)
- [CameraPostProcessDesc](../../Planning/CameraPostProcessDesc/CameraPostProcessDesc.md)

View File

@@ -0,0 +1,21 @@
# BuiltinColorScalePostProcessPass::GetColorScale
返回当前保存的颜色缩放参数。
```cpp
const Math::Vector4& GetColorScale() const;
```
## 返回值
- 返回内部保存的 `Math::Vector4` 引用。
## 当前语义
- 这里返回的是 CPU 侧配置快照,而不是 shader 常量缓冲的即时读回结果。
- 若调用方先执行了 [SetColorScale](SetColorScale.md) 但尚未调用 [Execute](Execute.md),这里已经能读到最新配置。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [SetColorScale](SetColorScale.md)
- [Execute](Execute.md)

View File

@@ -0,0 +1,20 @@
# BuiltinColorScalePostProcessPass::GetName
返回当前 pass 的固定名称。
```cpp
const char* GetName() const override;
```
## 返回值
- 固定返回字符串 `BuiltinColorScalePostProcessPass`
## 当前语义
- 返回值不依赖 `colorScale`、backend 或 shader 路径。
- 它主要用于调试、日志和统一的 pass 标识。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [Execute](Execute.md)

View File

@@ -0,0 +1,21 @@
# BuiltinColorScalePostProcessPass::GetShaderPath
返回当前保存的 post-process shader 路径。
```cpp
const Containers::String& GetShaderPath() const;
```
## 返回值
- 返回内部保存的 `shaderPath` 引用。
## 当前语义
- 构造函数若收到空路径,会先把它替换成 builtin color-scale shader 路径,因此默认情况下这里返回的是非空 builtin 路径。
- 如果调用方后续显式执行 [SetShaderPath](SetShaderPath.md) 并传入空字符串,这里也会如实返回空路径。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [SetShaderPath](SetShaderPath.md)
- [Constructor](Constructor.md)

View File

@@ -0,0 +1,26 @@
# BuiltinColorScalePostProcessPass::OwnedDescriptorSet
描述 `BuiltinColorScalePostProcessPass` 内部把“descriptor pool + descriptor set”作为一组资源一起持有的轻量结构。
```cpp
struct OwnedDescriptorSet {
RHI::RHIDescriptorPool* pool = nullptr;
RHI::RHIDescriptorSet* set = nullptr;
};
```
## 字段
- `pool` - 用来分配该 descriptor set 的 pool。
- `set` - 实际绑定到图形管线的 descriptor set。
## 当前语义
- `BuiltinColorScalePostProcessPass` 用它分别管理常量、纹理和采样器三组 descriptor 资源。
- 结构本身不提供独立生命周期函数;真正的释放逻辑由 pass 内部的 `DestroyOwnedDescriptorSet(...)` 和 [Shutdown](Shutdown.md) 统一处理。
- 这里暴露的是原始指针打包结果,不附带所有权转移语义。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [Shutdown](Shutdown.md)
- [Execute](Execute.md)

View File

@@ -0,0 +1,22 @@
# BuiltinColorScalePostProcessPass::SetColorScale
更新当前颜色缩放参数。
```cpp
void SetColorScale(const Math::Vector4& colorScale);
```
## 参数
- `colorScale` - 新的 RGBA 颜色缩放参数。
## 当前语义
- 这个 setter 只更新 `m_colorScale`,不会立即创建或重建 GPU 资源。
- 新配置会在下一次 [Execute](Execute.md) 时被写入常量缓冲并立即生效。
- 因为 pipeline 选择不依赖颜色缩放常量,这里不会触发资源失效。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [GetColorScale](GetColorScale.md)
- [Execute](Execute.md)

View File

@@ -0,0 +1,28 @@
# BuiltinColorScalePostProcessPass::SetShaderPath
切换当前 post-process shader 路径,并使已有资源缓存失效。
```cpp
void SetShaderPath(const Containers::String& shaderPath);
```
## 参数
- `shaderPath` - 新的 shader 资源路径。
## 当前语义
- 如果传入路径与当前 `m_shaderPath` 相同,函数直接返回,不做任何事。
- 路径发生变化时,会先销毁现有 GPU 资源,然后再保存新的路径字符串。
- 后续下一次 [Execute](Execute.md) 会按新的路径重新加载 shader 并创建 pipeline。
## 当前实现边界
- 与构造函数不同,这个 setter 不会在空字符串时自动回退到 builtin shader如果显式传入空路径后续资源创建会失败。
- 它只让资源缓存失效,不会立即触发重建。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [GetShaderPath](GetShaderPath.md)
- [Constructor](Constructor.md)
- [Execute](Execute.md)

View File

@@ -0,0 +1,24 @@
# BuiltinColorScalePostProcessPass::Shutdown
主动释放当前持有的 GPU 资源。
```cpp
void Shutdown() override;
```
## 当前语义
- 实现直接调用内部 `DestroyResources()`
- 会回收 pipeline state、pipeline layout、sampler以及常量/纹理/采样器三组 descriptor pool / set。
- 还会清空当前 shader 句柄、device/backend/format/sample 描述缓存与已绑定 source color view。
## 当前实现边界
- `Shutdown()` 不会重置 [GetColorScale](GetColorScale.md) 或 `shaderPath`;后续再次 [Execute](Execute.md) 时仍会基于现有配置重建资源。
- 析构函数也会调用它,因此可以把它视为幂等的显式清理入口。
## 相关文档
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass.md)
- [Destructor](Destructor.md)
- [Execute](Execute.md)
- [OwnedDescriptorSet](OwnedDescriptorSet.md)

View File

@@ -6,54 +6,44 @@
**头文件**: `XCEngine/Rendering/Passes/BuiltinFinalColorPass.h`
**描述**: final-color 阶段的 fullscreen pass负责把曝光、tone mapping、output transfer 与最终颜色缩放应用到最终输出颜色附件上。
**描述**: final-color 阶段的 fullscreen pass负责把 `ResolvedFinalColorPolicy` 应用到最终输出颜色上。
## 概
## 概
`BuiltinFinalColorPass` 处在 post-process 之后、最终回写目标表面之前。它当前统一承载:
`BuiltinFinalColorPass` 位于 post-process 之后、最终回写目标表面之前。它当前统一承载:
- output transfer
- exposure
- tone mapping
- final color scale
对应参数通过 [FinalColorSettings](../../Planning/FinalColorSettings/FinalColorSettings.md) 注入;真正的源颜色来自 `RenderPassContext::sourceColorView`,目标颜色来自 `context.surface` 的唯一颜色附件
对应参数通过 `FinalColorSettings``ResolvedFinalColorPolicy` 注入
## 公开类型
## 当前公开能力
- [OwnedDescriptorSet](OwnedDescriptorSet.md)
## 公开方法
| 方法 | 说明 |
|------|------|
| [Constructor](Constructor.md) | 构造 final-color pass并可选指定自定义 shader 路径。 |
| [Destructor](Destructor.md) | 析构时释放内部 GPU 资源。 |
| [GetName](GetName.md) | 返回固定 pass 名称。 |
| [Execute](Execute.md) | 执行 fullscreen final-color 绘制。 |
| [Shutdown](Shutdown.md) | 主动释放当前持有的 GPU 资源。 |
| [SetSettings](SetSettings.md) | 更新曝光、tone mapping 与颜色缩放配置。 |
| [GetSettings](GetSettings.md) | 读取当前配置。 |
| [SetShaderPath](SetShaderPath.md) | 切换 final-color shader 路径,并使资源缓存失效。 |
| [GetShaderPath](GetShaderPath.md) | 读取当前 shader 路径。 |
- 构造时指定 `FinalColorSettings` 和可选 `shaderPath`
- `GetName()` / `Execute(...)` / `Shutdown()`
- `SetSettings(...)` / `GetSettings()`
- `SetShaderPath(...)` / `GetShaderPath()`
## 当前实现边界
- 它只消费已经规划好的 [FinalColorSettings](../../Planning/FinalColorSettings/FinalColorSettings.md),不负责解析相机 override 或 pipeline 默认策略
- 当前实现要求 source surface 与 destination surface 都是“单颜色附件”形态;不支持 MRT也不使用深度附件
- 构造函数会在传入空路径时自动回退到 builtin final-color shader但后续若显式调用 `SetShaderPath("")`,资源创建会因为空路径而失败,直到重新设置为非空路径
- GPU 资源缓存会随着 backend、目标格式、sample count、sample quality 和 shader path 变化而失效;[SetSettings](SetSettings.md) 本身只更新常量,不会重建 pipeline
- 它只负责 final-color 阶段,不解析相机 override 或 pipeline 默认值;这些在 planning 阶段就已经被解出来
- 与其他 fullscreen pass 一样,它依赖 `RenderPassContext::sourceSurface``sourceColorView``sourceColorState`,不会自己管理中间表面生命周期
- 目标 surface 与 source surface 当前都要求“恰好一张有效颜色附件”
- 当 source surface 启用了自动状态切换时pass 会根据 `sourceColorState` 自动把输入切到 `PixelShaderResource` 再恢复;否则要求调用方保证输入已经可读
- GPU 资源缓存会跟随目标 surface 的 render target format、`sampleCount``sampleQuality` 一起变化。
## 真实接入位置
- `SceneRenderer` 先在 planning 阶段解析 `FinalColorSettings`
- `SceneRenderer::ResolveCameraFinalColorPolicies(...)` 先解析策略
- `BuildFinalColorPassSequence(...)` 根据策略决定是否创建当前 pass。
- `CameraRenderer``postProcess` 之后、`objectId` 之前执行 final-output 阶段。
## 相关文档
- [Passes](../Passes.md)
- [RenderPass](../../RenderPass/RenderPass.md)
- [FinalColorSettings](../../Planning/FinalColorSettings/FinalColorSettings.md)
- [FinalColorPassFactory](../../Planning/FinalColorPassFactory/FinalColorPassFactory.md)
- [BuiltinColorScalePostProcessPass](../BuiltinColorScalePostProcessPass/BuiltinColorScalePostProcessPass.md)
- [RenderPass](../../RenderPass/RenderPass.md)

View File

@@ -10,13 +10,13 @@
`Rendering::Passes` 不是用来替代 [RenderPipeline](../RenderPipeline/RenderPipeline.md) 的第二套主渲染框架,而是承载几类被 `CameraRenderer`、editor 视口流程和 builtin pipeline 复用的 builtin pass
- [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md) 把可见物体编码成 object-id 颜色,写到辅助渲染目标
- [BuiltinObjectIdOutlinePass](BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) 读取 object-id 纹理和选中对象列表,把轮廓或调试 mask 叠加回场景颜色
- [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md) 把可见物体编码成 object-id 颜色。
- [BuiltinObjectIdOutlinePass](BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) 读取 object-id 输入并把选中轮廓叠加回主颜色目标
- [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) 重绘当前选中对象,生成 selection mask。
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md) 读取 selection-mask 与 depth 纹理,在主颜色目标上合成轮廓。
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md) 读取 selection-mask 与 depth 输入,在主颜色目标上合成轮廓。
- [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) 给 Scene View 一类编辑器视口叠加无限网格。
- [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) 消费 `visibleVolumes` `VolumeField` GPU 资源,执行体渲染。
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass/BuiltinColorScalePostProcessPass.md) 执行基于 `sourceColorView` 的全屏颜色缩放后处理。
- [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) 消费 `visibleVolumes` 执行体渲染。
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass/BuiltinColorScalePostProcessPass.md) 执行依赖 `sourceSurface``sourceColorView``sourceColorState` 的全屏颜色缩放后处理。
- [BuiltinFinalColorPass](BuiltinFinalColorPass/BuiltinFinalColorPass.md) 执行 exposure、tone mapping、output transfer 和 final color scale 的最终输出阶段。
- [BuiltinDepthStylePassBase](BuiltinDepthStylePassBase/BuiltinDepthStylePassBase.md) 为深度风格场景重绘 pass 提供共享执行骨架。
- [BuiltinDepthOnlyPass](BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md) 是 `CameraRenderer` 默认 `depthOnly` request 的 builtin 实现。
@@ -29,21 +29,13 @@
当前 Scene View 相关链路大致是:
1. [CameraRenderer](../Execution/CameraRenderer/CameraRenderer.md) 先执行主 `RenderPipeline`
2. [CameraRenderRequest](../Planning/CameraRenderRequest/CameraRenderRequest.md) 请求了 `objectId.surface`,则额外执行 [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md)。
3. editor 侧的 `SceneViewportRenderPlan`构建 `postScenePasses``overlayPasses`
4. 其中 `SceneViewportGridPass` / `SceneViewportSelectionOutlinePass` 当前分别调用 [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) 与“[BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) + [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)”这组 selection outline 组合。
2. 如 [CameraRenderRequest](../Planning/CameraRenderRequest/CameraRenderRequest.md) 请求了 `objectId.surface`,则额外执行 [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md)。
3. editor 侧的 `SceneViewportRenderPlan`组装 `postScenePasses``overlayPasses`
4. 其中 `SceneViewportGridPass` / `SceneViewportSelectionOutlinePass` 分别调用 [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) 与“[BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) + [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)”这组 selection outline 组合。
### Fullscreen post-process / final-color
`SceneRenderer` 当前会先在 planning 阶段把:
- 相机 `postProcess` 描述栈
- pipeline 默认 final-color 设置
- 相机 final-color override
解析成 `CameraRenderRequest::postProcess``CameraRenderRequest::finalOutput`
随后 `CameraRenderer` 在主场景之后依次执行:
`SceneRenderer` 会先在 planning 阶段把相机 post-process 描述、pipeline 默认 final-color 设置和相机 final-color override 解析成 `CameraRenderRequest::postProcess``CameraRenderRequest::finalOutput`。随后 `CameraRenderer` 在主场景之后依次执行
1. `postProcess`
2. `finalOutput`
@@ -53,45 +45,19 @@
### Builtin volume scene pass
体渲染链路和前面两类流程不同,它不是 post-process而是 builtin scene pass
体渲染链路不是 post-process而是 builtin scene pass
1. `RenderSceneExtractor` 先把体对象提取到 `visibleVolumes`
1. `RenderSceneExtractor` 先把体对象提取到 `visibleVolumes`
2. [BuiltinForwardPipeline](../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md) 把 [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) 放进自己的 pass sequence。
3. `BuiltinVolumetricPass` 再按材质 shader pass、volume-field 绑定和 lighting 常量逐项绘制。
## 当前公开概念
| 类型 / 页面 | 角色 |
|------|------|
| [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md) | 生成 object-id 颜色缓冲。 |
| [BuiltinObjectIdOutlinePass](BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) | 在主颜色目标上合成选中轮廓。 |
| [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) | 为选中轮廓链路生成 selection mask。 |
| [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md) | 基于 selection-mask 与 depth 的全屏轮廓合成器。 |
| [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) | Scene View 网格覆盖层的底层执行 pass。 |
| [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) | builtin forward 链路中的体渲染 scene pass。 |
| [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass/BuiltinColorScalePostProcessPass.md) | 相机 post-process 栈当前的颜色缩放全屏 pass。 |
| [BuiltinFinalColorPass](BuiltinFinalColorPass/BuiltinFinalColorPass.md) | final-color 阶段的最终合成 / 输出变换 pass。 |
| [BuiltinDepthStylePassBase](BuiltinDepthStylePassBase/BuiltinDepthStylePassBase.md) | depth-only / shadow-caster 场景重绘共享的执行骨架。 |
| [BuiltinDepthOnlyPass](BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md) | `CameraRenderer` 默认的 depth-only scene pass。 |
| [BuiltinShadowCasterPass](BuiltinShadowCasterPass/BuiltinShadowCasterPass.md) | `CameraRenderer` 默认的 shadow-caster scene pass。 |
## 测试与真实调用点
- `tests/Rendering/unit/test_camera_scene_renderer.cpp` 验证了 `CameraRenderer` 里 object-id、post-process、final-output 与可选 pass sequence 的接入时机。
- `engine/src/Rendering/Execution/CameraRenderer.cpp` 当前把 [BuiltinShadowCasterPass](BuiltinShadowCasterPass/BuiltinShadowCasterPass.md) 与 [BuiltinDepthOnlyPass](BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md) 作为默认 scene pass 挂进 `shadowCaster` / `depthOnly` request。
- `engine/src/Rendering/Execution/SceneRenderer.cpp` 当前负责把 fullscreen 阶段写进 `CameraRenderRequest`
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h` 当前组合 [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) 与 [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)。
- `engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp` 当前把 [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) 挂进 builtin forward pass sequence。
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp` 验证了 `VolumeField` 资源语义与布局元数据。
- `tests/Editor/test_viewport_render_flow_utils.cpp` 验证了 Scene View render plan 如何组装 grid / selection outline / overlay pass。
## 当前实现边界
- 这一层目前是 builtin、轻量、偏 editor / 工具链导向的 pass 集合,还不是通用 render graph。
- object-id 相关流程依赖单独的辅助 render target / shader resource view而不是直接从主颜色结果反推。
- selection outline 当前已经拆成“mask 重绘 + fullscreen compositing”两层而不是单个对象列表后处理。
- volumetric pass 当前依赖 `visibleVolumes``VolumeField` 资源绑定和 builtin cube proxy不是独立 volume framework。
- fullscreen pass 依赖调用方准备 `sourceColorView` 和中间表面;单个 pass 本身不管理整条阶段链。
- fullscreen pass 依赖调用方准备 `sourceSurface``sourceColorView``sourceColorState` 和中间表面;单个 pass 本身不管理整条阶段链。
## 相关文档

View File

@@ -6,85 +6,62 @@
**头文件**: `XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h`
**描述**: 当前内建的前向主渲染管线实现。它会按 shader pass 的资源声明动态构建 `PassResourceLayout`、descriptor set 与 `RHIPipelineState`,并通过 `RenderPassSequence` 顺序执行 opaque、skybox、volumetric 和 transparent 阶段
**描述**: 当前内建的前向主渲染管线实现。它会按 shader pass 的资源声明动态构建 `PassResourceLayout`、descriptor set 与 `RHIPipelineState`,并通过 `RenderPassSequence` 顺序执行 builtin scene pass
## 概览
`BuiltinForwardPipeline` 已经不是“固定几套 descriptor set + 单一 pipeline layout”的旧模型。当前实现有三条关键缓存链路
`BuiltinForwardPipeline` 已经不是“固定几套 descriptor set + 单一 pipeline layout”的旧模型。当前实现有三条关键缓存链路
- `m_passResourceLayouts`:以 `(shader*, passName)` 为 key缓存每个 shader pass 的资源布局、pipeline layout、静态 descriptor set 和语义位置。
- `m_pipelineStates`:以 `(shader*, passName, material render state)` 为 key缓存真正的图形 pipeline state。
- `m_dynamicDescriptorSets`:以 `(passLayout, setIndex, objectId, material)` 为 key缓存逐物体或逐材质的 descriptor set。
- `m_passResourceLayouts`:以 `(shader*, passName)` 为 key缓存每个 shader pass 的资源布局、pipeline layout、静态 descriptor set 和语义位置信息
- `m_pipelineStates`:以 `(shader*, passName, material render state, surface properties)` 为 key缓存真正的图形 pipeline state。
- `m_dynamicDescriptorSets`:以 `(passLayout, setIndex, objectId, material)` 为 key缓存逐对象或逐材质的 descriptor set。
当前构造函数会向 `m_passSequence` 依次注册:
构造函数当前会向 `m_passSequence` 顺序注册:
- `BuiltinForwardOpaquePass`
- `BuiltinForwardSkyboxPass`
- [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
- `BuiltinForwardTransparentPass`
因此它已经不再是“单 opaque pass”的过渡版前向路径而是一条正式的多阶段 builtin forward sequence。
## 当前资源契约
`BuiltinForwardPipeline` 当前要求 resolved shader pass 显式声明 `resources`
`BuiltinForwardPipeline` 当前要求 resolved shader pass 显式声明 `resources`随后会通过 [TryBuildBuiltinPassResourceBindingPlan](../../RenderMaterialUtility/TryBuildBuiltinPassResourceBindingPlan.md) 把资源声明收口成 [BuiltinPassResourceBindingPlan](../../RenderMaterialUtility/BuiltinPassResourceBindingPlan.md)。
如果 `resources.Empty()`,实现会直接报错,而不是自动生成 legacy fallback binding plan。
当前可识别的 forward 语义主要包括:
随后会通过 [TryBuildBuiltinPassResourceBindingPlan](../../RenderMaterialUtility/TryBuildBuiltinPassResourceBindingPlan.md)
把显式资源声明收口成
[BuiltinPassResourceBindingPlan](../../RenderMaterialUtility/BuiltinPassResourceBindingPlan.md)。
- `PerObject`
- `Material`
- `BaseColorTexture`
- `LinearClampSampler`
当前可识别的 forward 语义只有四个:
- `PerObject`:必需,且必须是唯一的 constant buffer。
- `Material`:可选,且必须是唯一的 constant buffer。
- `BaseColorTexture`:可选,且必须是唯一的 `Texture2D``TextureCube`
- `LinearClampSampler`:可选,且必须是唯一的 sampler。
其中 `Material` 语义当前不是固定写死成某个历史布局。渲染时会先通过
`ResolveSchemaMaterialConstantPayload(material)` 取得
`Material::GetConstantBufferData()` 的字节视图;只有拿不到有效 payload 时,
才会回退到内部 `FallbackPerMaterialConstants { baseColorFactor, alphaCutoffParams }`
binding-plan 解析之后,布局构建阶段还会继续拒绝以下情况:
- 未知语义。
- 非法 set index。
- 在同一个 set 中混用 sampler 与非 sampler 绑定。
- 在同一个 set 中出现重复 binding。
- 缺少 `PerObject`
超出这组约定的资源声明不会被当前 builtin forward 路径接受。
## 当前渲染流程
1. [Initialize](Initialize.md) 通过 `m_passSequence.Initialize(context)` 进入 pass 生命周期。
2. [Render](Render.md) 把 `RenderContext``RenderSurface``RenderSceneData` 打包成 `RenderPassContext`,再交给 `m_passSequence.Execute(...)`
2. [Render](Render.md) 把 `RenderContext``RenderSurface``RenderSceneData` 打包成不带上游输入的 `RenderPassContext`,再交给 `m_passSequence.Execute(...)`
3. `BuiltinForwardOpaquePass` 处理主场景 opaque 物体。
4. `BuiltinForwardSkyboxPass` 在环境允许时绘制天空盒。
5. [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md) 遍历 `RenderSceneData::visibleVolumes`,绘制当前已接入的体对象
5. [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md) 遍历 `RenderSceneData::visibleVolumes` 并执行体渲染
6. `BuiltinForwardTransparentPass` 再处理透明阶段。
## 当前实现细节
- [BuildInputLayout](BuildInputLayout.md) 现在明确使用 `POSITION=float3``NORMAL=float3``TEXCOORD=float2`,与 `StaticMeshVertex` 对齐
- 材质贴图解析通过 `ResolveBuiltinBaseColorTexture(material)` 进入 builtin base-color 语义,不再依赖旧文档里的“按若干名字猜测纹理”说法
- 逐物体常量来自 `PerObjectConstants`
- 逐材质常量优先来自 `ResolveSchemaMaterialConstantPayload(material)` 暴露的 schema-driven payload
如果 view 无效,才回退到内部 `FallbackPerMaterialConstants { baseColorFactor, alphaCutoffParams }`
- 采样器和 1x1 白色 fallback 纹理在初始化后长期复用;具体 `Texture``Mesh` 的 GPU 资源则由 [RenderResourceCache](../../Caches/RenderResourceCache/RenderResourceCache.md) 按需上传。
- 体对象阶段当前已经正式接入 [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md),因此 `RenderSceneData` 不再只有 `visibleItems` 一条几何主链。
- pipeline state 缓存已经会跟随目标 surface 的 render target format、depth format、sample count 和 sample quality 一起变化
- 材质常量优先来自 schema-driven payload只有拿不到有效 payload 时才会回退到 builtin fallback 常量
- 采样器和 fallback 纹理可长期复用;具体 mesh / texture / volume 资源由 [RenderResourceCache](../../Caches/RenderResourceCache/RenderResourceCache.md) 按需上传
## 当前限制
- 当前虽然已经有 opaque / skybox / volumetric / transparent 四段 sequence但仍不是延迟渲染、RenderGraph 或更通用的多管线框架。
- 资源语义是白名单模型,超出 `PerObject / Material / BaseColorTexture / LinearClampSampler` 的声明不会被接受
- `Render()` 层面不会因为单个物体 `DrawVisibleItem()` 失败整体返回 `false`;当前调用点仍然以“尽量继续绘制其余物体”为主
- 这仍然不是 deferred、render graph 或更通用的多管线框架。
- 资源语义是白名单模型,不接受任意自定义 binding plan
- `Render()` 层面不会因为单个对象 draw 失败整体返回 `false`,更偏向“尽量继续绘制其余对象”
## 公开方法
| 方法 | 说明 |
|------|------|
| [Constructor](Constructor.md) | 创建管线对象,并注册默认的 opaque pass。 |
| [Constructor](Constructor.md) | 创建管线对象,并注册默认 builtin scene pass。 |
| [Destructor](Destructor.md) | 析构时调用 `Shutdown()`。 |
| [BuildInputLayout](BuildInputLayout.md) | 返回 builtin forward 使用的静态网格输入布局。 |
| [Initialize](Initialize.md) | 初始化 pass sequence并在需要时准备共享 GPU 资源。 |

View File

@@ -12,54 +12,35 @@ bool Render(
当前 `Render()` 本身很薄,只做两件事:
1. 调用 `Initialize(context)`,确保 pass sequence 与共享资源已经可用。
2. 组装 `RenderPassContext { context, surface, sceneData }`,再执行 `m_passSequence.Execute(passContext)`
2. 组装 `RenderPassContext { context, surface, sceneData, nullptr, nullptr, RHI::ResourceStates::Common }`,再执行 `m_passSequence.Execute(passContext)`
由于当前 sequence 里只包含 `BuiltinForwardOpaquePass`,真正的绘制逻辑发生在 `ExecuteForwardOpaquePass()`
由于 forward scene pass 没有上游 fullscreen 输入,所以这里会显式把 `sourceSurface` / `sourceColorView` 置空,并把 `sourceColorState` 置为 `Common`
## 当前 opaque pass 流程
## 当前 opaque / scene pass 流程
1. 校验 `surface.GetColorAttachments()` 非空
2. 如启用了自动状态切换,把颜色附件从 `surface.GetColorStateBefore()` 转成 `RenderTarget`
3. 绑定 render target、depth attachment、viewport scissor。
4. `RenderSurface` clear-color override `sceneData.cameraData.clearFlags` 决定是否清颜色/深度
5. 设置 `TriangleList` 拓扑
6. 遍历 `RenderSceneData::visibleItems`,只处理匹配 `BuiltinMaterialPass::ForwardLit` 的可见项
7. 对每个物体复用或创建匹配的 pipeline state并调用内部 `DrawVisibleItem(...)`
8. 结束时如启用了自动状态切换,再把颜色附件从 `RenderTarget` 切回 `surface.GetColorStateAfter()`
## `DrawVisibleItem()` 当前行为
单个可见项的绘制链路为:
1. 通过 `RenderResourceCache` 取得 mesh 的 GPU 缓存。
2. 写入 `PerObjectConstants`,其中包含投影矩阵、视图矩阵、`localToWorld`、逆矩阵和主方向光数据。
3. 基于材质解析实际要使用的 shader/pass。
4. 获取或创建该 `(shader*, passName)` 对应的 `PassResourceLayout`
5. 先解析逐材质常量 payload
- 优先用 `ResolveSchemaMaterialConstantPayload(material)` 取得 schema-driven 字节视图。
- 若 view 无效,则用 `BuildBuiltinForwardMaterialData(material)` 构造仅含 `baseColorFactor` 的 fallback 常量。
- base-color 纹理视图仍单独通过 `ResolveBuiltinBaseColorTexture(material)` 解析。
6. 逐 set 绑定 descriptor
-`PerObject / Material / Texture` 的 set 走动态 descriptor set 缓存。
- 只含 sampler 的 set 走静态 descriptor set 缓存。
7. 调用 `SetGraphicsDescriptorSets(...)`,并按 section 或整 mesh 发出 `DrawIndexed` / `Draw`
1. 校验 `surface`、render area 与必要附件
2. 按需执行自动状态切换。
3. 绑定 render target、depth attachment、viewport scissor。
4. 根据 clear-color override 与相机 clear flags 决定是否清
5. 顺序执行 builtin forward 的 scene-pass sequence
6. 如启用了自动状态切换,在结束阶段把资源恢复到 `surface` 约定的 after state
## 参数
- `context` - 当前渲染上下文。
- `surface` - 当前输出目标。
- `sceneData` - `RenderSceneExtractor` 产出的相机、光照与 `visibleItems` 数据。
- `sceneData` - `RenderSceneExtractor` 产出的相机、光照与可见对象数据。
## 返回值
- 整个 pass sequence 成功执行时返回 `true`
- 初始化失败、缺少颜色附件、render area 非法,或 pass sequence 中某个 pass 明确失败时返回 `false`
- 初始化失败、缺少必要附件、render area 非法,或 sequence 中某个 pass 明确失败时返回 `false`
## 当前限制
- 当前 sequence 只有一个 opaque pass还没有透明排序、shadow pass 或 deferred path
- 调用点目前不会把单个 `DrawVisibleItem()` 失败汇总成整体失败;它更偏向“跳过当前物体,继续绘制其余物体”
- `Render()` 只处理一个 `RenderSurface` 和一份 `RenderSceneData`,不是 render graph。
- `Render()` 只负责把 `RenderSceneData` 交给 builtin forward 的 scene-pass sequence不直接处理 fullscreen 输入链
- 单个 `DrawVisibleItem()` 失败通常只会跳过当前对象,而不是把整帧渲染整体判定为失败
- 这里仍是单 `RenderSurface` + 单 `RenderSceneData` 的线性入口,不是 render graph。
## 相关文档

View File

@@ -10,31 +10,36 @@
## 概览
`RenderPass.h` 是当前渲染基础设施里最通用的一层 pass 协议。
它统一回答三件事:
`RenderPass.h` 是当前渲染基础设施里最通用的一层 pass 协议。它统一回答三件事:
- pass 执行时能拿到什么上下文
- 一个 pass 少需要实现哪些生命周期函数
- 一个 pass 少需要实现哪些生命周期函数
- 多个 pass 如何按顺序组成一个小型执行序列
## 当前定义
### `RenderPassContext`
`RenderPassContext` 只是三个引用的聚合
`RenderPassContext` 当前包含 6 个字段
- `renderContext`
- `surface`
- `sceneData`
| 字段 | 说明 |
|------|------|
| `renderContext` | 当前后端、设备与命令列表。 |
| `surface` | 当前 pass 的输出目标 surface。 |
| `sceneData` | 本帧已提取的场景数据。 |
| `sourceSurface` | fullscreen / chained pass 的输入 surface无上游输入时可为空。 |
| `sourceColorView` | 上游传入的颜色输入视图;无上游输入时可为空。 |
| `sourceColorState` | `sourceColorView` 当前约定的资源状态,供自动切换或校验使用。 |
前向场景 pass 往往只使用 `renderContext``surface``sceneData`fullscreen post-process / final-output 链路则会继续消费 `sourceSurface``sourceColorView``sourceColorState`
### `RenderPass`
抽象基类包含个核心成员:
抽象基类包含 4 个核心成员:
| 成员 | 当前语义 |
|------|------|
| `GetName()` | 返回 pass 的人类可读名称。 |
| `GetName()` | 返回 pass 的可读名称。 |
| `Initialize()` | 默认返回 `true`,需要时准备一次性资源。 |
| `Execute()` | 纯虚函数,执行真正的 pass 逻辑。 |
| `Shutdown()` | 默认空实现,释放 pass 资源。 |
@@ -45,21 +50,21 @@
当前行为是:
- `AddPass()` 会忽略空指针
- `GetPassCount()` 返回当前持有的 pass 数
- `Initialize()` 按插入顺序调用每个 pass 的 `Initialize()`
- `Execute()` 按插入顺序调用每个 pass 的 `Execute()`
- `Shutdown()` 按逆序调用每个 pass 的 `Shutdown()`
- `AddPass()` 会忽略空指针
- `GetPassCount()` 返回当前持有的 pass 数量。
- `Initialize()` 按插入顺序调用每个 pass 的 `Initialize()`
- `Execute()` 按插入顺序调用每个 pass 的 `Execute()`
- `Shutdown()` 按逆序调用每个 pass 的 `Shutdown()`
## 失败与回滚语义
- `Initialize()` 遇到失败会立返回 `false`
- `Execute()` 遇到失败也会立停止后续 pass
- `RenderPassSequence` 自身不会在 `Initialize()` 失败时自动回滚已经初始化过的 pass
- `Initialize()` 遇到失败会立返回 `false`
- `Execute()` 遇到失败也会立停止后续 pass
- `RenderPassSequence` 自身不会在 `Initialize()` 失败时自动回滚已经初始化过的 pass
当前更高层调用方,例如 `CameraRenderer`,会额外包一层 helper sequence 初始化失败,就主动执行一次 `Shutdown()` 回滚。
更高层调用方,例如 `CameraRenderer`,会 sequence 初始化失败时显式再做一次 `Shutdown()` 回滚。
## 测试验证的真实行为
## 测试真实行为
`tests/Rendering/unit/test_render_pass.cpp` 已覆盖:
@@ -71,7 +76,7 @@
- 这套协议仍然是线性顺序执行,不是 render graph也没有显式资源依赖建模。
- `RenderPassSequence` 只管理 pass 对象,不管理共享资源或跨 pass 的状态同步。
- `RenderPassContext` 暂时只暴露一个目标表面和一份 `RenderSceneData`不适合表达更复杂的多目标或多阶段图结构。
- `RenderPassContext` 虽然现在已经能表达“一个输出 surface + 一路可选上游颜色输入”,但仍不适合描述更复杂的多目标或多阶段图结构。
## 相关文档

View File

@@ -1,29 +1,24 @@
# RenderSurface::GetDepthStateAfter
返回深度附件在本次渲染结束后预期应处于的状态。
返回深度附件在本次渲染结束后期望落到的状态。
```cpp
RHI::ResourceStates GetDepthStateAfter() const;
```
## 返回值
- 返回内部保存的深度附件“结束状态”;默认值是 `DepthWrite`
- 返回内部保存的深度附件“结束状态”;默认值是 `RHI::ResourceStates::DepthWrite`
## 当前语义
- 这个返回值描述的是阶段性契约,不是对 GPU 实际状态的即时查询
- 当 [IsAutoTransitionEnabled](IsAutoTransitionEnabled.md) 为 `true` 时,多个 builtin 渲染路径会在结束 render pass 后把深度附件切回这个状态
- `SceneRenderer` 在派生 fullscreen surface 时会继续保留这份深度 after 状态,使后续阶段仍能沿用同一份资源状态约定。
- 某些支持自动 depth barrier 的路径会把它当作从 `DepthWrite` 或其他中间状态恢复出去的目标
- 它常与 [GetDepthStateBefore](GetDepthStateBefore.md) 共同描述一次渲染阶段对深度附件的进入/退出约定
## 调用方影响
## 当前实现边界
- 如果后续 pass 依赖深度纹理以 `PixelShaderResource` 等状态被采样,调用方应显式把这个返回值对应的 setter 配置成匹配状态
- 默认值 `DepthWrite` 适合“本阶段前后都继续作为深度写入目标”的简单场景
## 测试覆盖
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
- 这里返回的是 surface 记录值,不是对真实资源状态的反查
- 不同 pass 是否消费它并不完全一致
## 相关文档

View File

@@ -1,29 +1,24 @@
# RenderSurface::GetDepthStateBefore
返回深度附件进入本次渲染前预期所处的状态。
返回深度附件本次渲染开始前期望处于的状态。
```cpp
RHI::ResourceStates GetDepthStateBefore() const;
```
## 返回值
- 返回内部保存的深度附件“始状态”;默认值是 `DepthWrite`
- 返回内部保存的深度附件“始状态”;默认值是 `RHI::ResourceStates::DepthWrite`
## 当前语义
- 这不是逐资源的真实状态查询,而是 `RenderSurface` 暴露给调用方和 builtin pass 的契约值
- 当 [IsAutoTransitionEnabled](IsAutoTransitionEnabled.md) 为 `true`主场景、depth-style 与 object-id 这些路径会把它作为深度附件进入本次 pass 前的 barrier 来源状态
- `SceneRenderer` 在复用深度附件构造 fullscreen 阶段 surface 时,也会保留这个值。
- 当消费方启用了基于 `RenderSurface` 的自动 depth barrier 时,这个值会被当作过渡到 `DepthWrite` 或其他目标状态的起点
- 即使当前 `surface` 没有深度附件,这个字段也仍然可以被预先设置和保留
## 调用方影响
## 当前实现边界
- 如果调用方关闭自动状态切换,就必须自己保证深度附件真的处于这里声明的状态
- 这个值通常和 [GetDepthStateAfter](GetDepthStateAfter.md) 配对出现,用来描述同一块深度资源在本阶段前后的状态约定
## 测试覆盖
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
- 该返回值只反映 `RenderSurface` 当前记录的约定,不保证 GPU 资源真实状态与之完全一致
- 并非所有 renderer / pass 都会读取这个字段
## 相关文档

View File

@@ -1,28 +1,27 @@
# RenderSurface::GetSampleCount
返回当前 surface 的 sample count
返回当前记录的采样数
```cpp
uint32_t GetSampleCount() const;
```
## 返回值
- 返回内部保存的采样数;默认值是 `1`
- 返回 `RenderSurface` 当前保存的 `sampleCount`;默认值是 `1`
## 当前语义
- 这个值会被 `RenderSurfacePipelineUtils` 消费并写入图形管线描述
- `SceneRenderer` 也会用它判断主场景输出是否仍满足 fullscreen post-process / final-output 所要求的单采样约束
- 如果调用方此前通过 [SetSampleDesc](SetSampleDesc.md) 传入了 `0`,这里返回的仍会是规范化后的 `1`
- 这个值来自 [SetSampleDesc](SetSampleDesc.md)
- 一些 scene pass、fullscreen pass 和 request planning 逻辑会把它用于 pipeline 兼容性判断或中间 surface 规划
## 测试覆盖
## 当前实现边界
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
- 该值不保证当前绑定的附件真实具备相同 sample count。
- `1` 表示非 MSAA 目标,不代表调用方显式调用过 `SetSampleDesc(1, 0)`
## 相关文档
- [RenderSurface](RenderSurface.md)
- [SetSampleDesc](SetSampleDesc.md)
- [GetSampleQuality](GetSampleQuality.md)
- [CameraRenderRequest](../Planning/CameraRenderRequest/CameraRenderRequest.md)

View File

@@ -1,33 +1,28 @@
# RenderSurface::GetSampleQuality
返回当前 surface 的 sample quality
返回当前记录的采样质量
```cpp
uint32_t GetSampleQuality() const;
```
## 返回值
- 返回内部保存的 quality;默认值是 `0`
- 返回 `RenderSurface` 当前保存的 `sampleQuality`;默认值是 `0`
## 当前语义
- 这个值会被 `RenderSurfacePipelineUtils` 继续写入 `GraphicsPipelineDesc.sampleQuality`
-前实现保证单采样 surface 的 quality 总是 `0`;只有多采样时这里才可能返回调用方显式设置的非零值
- `CameraRenderRequest` 的 surface 合法性检查也依赖“单采样时 quality 必须为 `0`”这条约束
- 该值来自 [SetSampleDesc](SetSampleDesc.md)
-有效 `sampleCount <= 1` 时,当前实现会保证这里返回 `0`
- 某些后端或 pipeline 构建路径会把它作为 sample quality 维度继续传递
## 调用方影响
## 当前实现边界
- 如果后端只识别 `sampleCount`,调用方仍可以保留统一的 `RenderSurface` 描述,而把 `sampleQuality` 当作由具体 RHI 选择性消费的附加信息
- 对 fullscreen post-process / final-output 链路而言,`sampleCount == 1 && sampleQuality == 0` 才是当前允许的输入形态
## 测试覆盖
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
- 这只是目标 surface 的元数据,不代表附件或后端一定真正使用该 quality
- 如果调用方把 surface 切回 1x 采样,这个值会被重置为 `0`
## 相关文档
- [RenderSurface](RenderSurface.md)
- [SetSampleDesc](SetSampleDesc.md)
- [GetSampleCount](GetSampleCount.md)
- [CameraRenderRequest](../Planning/CameraRenderRequest/CameraRenderRequest.md)

View File

@@ -6,82 +6,79 @@
**头文件**: `XCEngine/Rendering/RenderSurface.h`
**描述**: 描述当前渲染目标表面,包括尺寸、颜色/深度附件、自定义渲染区域、清屏覆、自动状态切换,以及与管线创建对齐的 sample 描述。
**描述**: 描述一次渲染输出使用的目标表面,包括颜色/深度附件、render area、清屏覆、自动状态切换约定以及采样描述。
## 概
## 概
`RenderSurface` 把“这一次渲染要写到哪里、写之前/写之后资源期处于什么状态”从具体 swap chain、framebuffer 和缓存分配逻辑里抽离出来,变成 `Planning``Execution`、builtin pass 与 editor overlay 都能复用的统一协议对象。
`RenderSurface` 把“这一阶段渲染到哪里、渲染前后资源期处于什么状态、目标表面采用什么采样描述”集中到一个轻量对象里。当前它负责承载:
当前它负责描述:
- 输出尺寸
- 颜色附件数组与深度附件
- 可选自定义 render area
- 可选 clear color override
- 颜色附件前后状态
- 深度附件前后状态
- 是否启用自动状态切换
- `sampleCount` / `sampleQuality`
- 宽高
- 一组颜色附件。
- 一个可选深度附件。
- 一个可选自定义 render area。
- 一个可选清屏颜色覆盖。
- 颜色附件共享的 before / after 状态。
- 深度附件共享的 before / after 状态。
- 是否由渲染路径自动执行颜色/深度附件状态切换。
- 当前 surface 的 MSAA `sampleCount` / `sampleQuality`
`RenderSurface` 自己不拥有 GPU 资源,也不验证附件尺寸、资源类型或 sample 描述是否真实匹配;它只是把这组约束交给调用方和具体渲染路径消费。
`SceneRenderer``CameraRenderer`、builtin scene pass 和 fullscreen pass 会把这些约定继续传递到 request、pipeline desc 与 barrier 逻辑里
## 当前实现边界
- 颜色附件仍只有一组统一的 `colorStateBefore` / `colorStateAfter`,深度附件也只有一组统一的 `depthStateBefore` / `depthStateAfter`;它不是逐 attachment 的精细状态表
- 当 [IsAutoTransitionEnabled](IsAutoTransitionEnabled.md) 为 `true` 时,`BuiltinForwardPipeline``BuiltinDepthStylePassBase``BuiltinObjectIdPass``BuiltinInfiniteGridPass` 等路径都会消费这些 before / after 状态;关闭自动切换后,`RenderSurface` 只保留契约信息,不会主动纠正真实 GPU 状态
- [SetSampleDesc](SetSampleDesc.md) 会把 `sampleCount == 0` 规范化为单采样 `1, 0`;只有 `sampleCount > 1` `sampleQuality` 才保留调用方传入值
- `SceneRenderer` 当前要求 fullscreen post-process / final-output 链路的主场景 surface 为单采样,因此多重采样主表面不会进入这两段 fullscreen 阶段
- 当前没有 load/store action、resolve target、mip slice、array slice 等更细粒度 surface 配置
- 状态仍是“整组颜色附件一份 before/after深度附件一份 before/after”不是每个 attachment 独立配置
- `SetSampleDesc()` 只记录采样描述,不会验证附件或后端是否真的支持该 MSAA 配置
- `SetSampleDesc(0, quality)` 会把 `sampleCount` 归一化为 `1`;当有效 `sampleCount <= 1``sampleQuality` 会被压成 `0`
- render area 仍会在设置和读取时 clamp 到当前 surface 尺寸内
- 没有 load/store action、resolve attachment、mip slice、array slice 等更细粒度 surface 描述
## 公开方法
| 方法 | 说明 |
|------|------|
| [Constructor](Constructor.md) | 构造渲染表面。 |
| [GetWidth](GetWidth.md) | 获取宽度。 |
| [GetHeight](GetHeight.md) | 获取高度。 |
| [SetSize](SetSize.md) | 设置宽高。 |
| [Constructor](Constructor.md) | 构造空的 render surface。 |
| [GetWidth](GetWidth.md) | 获取 surface 宽度。 |
| [GetHeight](GetHeight.md) | 获取 surface 高度。 |
| [SetSize](SetSize.md) | 更新 surface 尺寸。 |
| [SetColorAttachment](SetColorAttachment.md) | 设置单个颜色附件。 |
| [SetColorAttachments](SetColorAttachments.md) | 设置多个颜色附件。 |
| [GetColorAttachments](GetColorAttachments.md) | 获取颜色附件数组。 |
| [SetColorAttachments](SetColorAttachments.md) | 设置颜色附件数组。 |
| [GetColorAttachments](GetColorAttachments.md) | 读取当前颜色附件数组。 |
| [SetDepthAttachment](SetDepthAttachment.md) | 设置深度附件。 |
| [GetDepthAttachment](GetDepthAttachment.md) | 获取深度附件。 |
| [SetRenderArea](SetRenderArea.md) | 设置自定义渲染区域。 |
| [ResetRenderArea](ResetRenderArea.md) | 清除自定义渲染区域。 |
| [HasCustomRenderArea](HasCustomRenderArea.md) | 判断是否启用了自定义渲染区域。 |
| [GetRenderArea](GetRenderArea.md) | 获取当前实际生效的渲染区域。 |
| [GetRenderAreaWidth](GetRenderAreaWidth.md) | 获取当前渲染区域宽度。 |
| [GetRenderAreaHeight](GetRenderAreaHeight.md) | 获取当前渲染区域高度。 |
| [SetClearColorOverride](SetClearColorOverride.md) | 设置清屏颜色覆盖。 |
| [ClearClearColorOverride](ClearClearColorOverride.md) | 清除清屏颜色覆盖。 |
| [HasClearColorOverride](HasClearColorOverride.md) | 判断是否启用了清屏颜色覆盖。 |
| [GetClearColorOverride](GetClearColorOverride.md) | 获取清屏颜色覆盖值。 |
| [SetAutoTransitionEnabled](SetAutoTransitionEnabled.md) | 设置是否自动切换附件状态。 |
| [IsAutoTransitionEnabled](IsAutoTransitionEnabled.md) | 查询是否自动切换附件状态。 |
| [SetColorStateBefore](SetColorStateBefore.md) | 设置渲染前颜色附件状态。 |
| [GetColorStateBefore](GetColorStateBefore.md) | 获取渲染前颜色附件状态。 |
| [SetColorStateAfter](SetColorStateAfter.md) | 设置渲染后颜色附件状态。 |
| [GetColorStateAfter](GetColorStateAfter.md) | 获取渲染后颜色附件状态。 |
| [SetDepthStateBefore](SetDepthStateBefore.md) | 设置渲染前深度附件状态。 |
| [GetDepthStateBefore](GetDepthStateBefore.md) | 获取渲染前深度附件状态。 |
| [SetDepthStateAfter](SetDepthStateAfter.md) | 设置渲染后深度附件状态。 |
| [GetDepthStateAfter](GetDepthStateAfter.md) | 获取渲染后深度附件状态。 |
| [SetSampleDesc](SetSampleDesc.md) | 设置 sample count / quality。 |
| [GetSampleCount](GetSampleCount.md) | 获取 sample count。 |
| [GetSampleQuality](GetSampleQuality.md) | 获取 sample quality。 |
| [GetDepthAttachment](GetDepthAttachment.md) | 读取当前深度附件。 |
| [SetRenderArea](SetRenderArea.md) | 设置自定义 render area。 |
| [ResetRenderArea](ResetRenderArea.md) | 清除自定义 render area。 |
| [HasCustomRenderArea](HasCustomRenderArea.md) | 判断是否启用了自定义 render area。 |
| [GetRenderArea](GetRenderArea.md) | 获取当前实际生效的 render area。 |
| [GetRenderAreaWidth](GetRenderAreaWidth.md) | 获取 render area 宽度。 |
| [GetRenderAreaHeight](GetRenderAreaHeight.md) | 获取 render area 高度。 |
| [SetClearColorOverride](SetClearColorOverride.md) | 设置 clear color override。 |
| [ClearClearColorOverride](ClearClearColorOverride.md) | 清除 clear color override。 |
| [HasClearColorOverride](HasClearColorOverride.md) | 判断是否存在 clear color override。 |
| [GetClearColorOverride](GetClearColorOverride.md) | 读取 clear color override。 |
| [SetAutoTransitionEnabled](SetAutoTransitionEnabled.md) | 开关自动状态切换约定。 |
| [IsAutoTransitionEnabled](IsAutoTransitionEnabled.md) | 查询是否启用自动状态切换。 |
| [SetColorStateBefore](SetColorStateBefore.md) | 设置颜色附件渲染前状态。 |
| [GetColorStateBefore](GetColorStateBefore.md) | 读取颜色附件渲染前状态。 |
| [SetColorStateAfter](SetColorStateAfter.md) | 设置颜色附件渲染后状态。 |
| [GetColorStateAfter](GetColorStateAfter.md) | 读取颜色附件渲染后状态。 |
| [SetDepthStateBefore](SetDepthStateBefore.md) | 设置深度附件渲染前状态。 |
| [GetDepthStateBefore](GetDepthStateBefore.md) | 读取深度附件渲染前状态。 |
| [SetDepthStateAfter](SetDepthStateAfter.md) | 设置深度附件渲染后状态。 |
| [GetDepthStateAfter](GetDepthStateAfter.md) | 读取深度附件渲染后状态。 |
| [SetSampleDesc](SetSampleDesc.md) | 设置 surface 的采样数和采样质量。 |
| [GetSampleCount](GetSampleCount.md) | 读取当前采样数。 |
| [GetSampleQuality](GetSampleQuality.md) | 读取当前采样质量。 |
## 设计说明
`RenderSurface` 做成独立对象的价值在当前重构后的渲染链路里更直接
surface 做成独立对象,而不是让 pipeline 直接吃裸 `RHIResourceView*`,好处是
- `SceneRenderer` 可以在构造 post-process / final-output request 时复制颜色/深度附件约束、sample 描述和 render area而不必重新展开 swap chain 细节
- `BuiltinForwardPipeline` 与多个 builtin pass 可以从同一份 surface 描述中同时解析附件格式、状态切换与 sample 描述,避免每个调用点重复拼装 `GraphicsPipelineDesc` 前置条件
- Editor overlay、selection outline、object-id 等附加阶段可以复用主场景输出的深度/颜色状态约定,而不需要各自发明一套 surface 协议
- 目标尺寸和附件集合可以一起传递
- 清屏策略、资源状态约定和采样描述可以挂在目标表面上,而不是散落在调用点
- 同一条渲染链更容易复用到 back buffer、离屏纹理、intermediate post-process surface 和 editor preview surface。
## 相关文档
- [当前模块](../Rendering.md)
- [RenderContext](../RenderContext/RenderContext.md)
- [CameraRenderRequest](../Planning/CameraRenderRequest/CameraRenderRequest.md)
- [RenderPass](../RenderPass/RenderPass.md)
- [BuiltinForwardPipeline](../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md)

View File

@@ -1,24 +1,25 @@
# RenderSurface::SetDepthStateAfter
设置深度附件在本次渲染结束后预期应回到的统一状态。
设置深度附件在本次渲染结束后期望落到的状态。
```cpp
void SetDepthStateAfter(RHI::ResourceStates state);
```
## 参数
- `state` - 调用方希望深度附件在本阶段结束后处于的资源状态。
- `state` - 调用方约定的深度附件结束资源状态。
## 当前语义
- 这个值只写入 `RenderSurface` 内部,不会主动触发过渡
- [IsAutoTransitionEnabled](IsAutoTransitionEnabled.md) 为 `true` 时,`BuiltinForwardPipeline``BuiltinDepthStylePassBase``BuiltinObjectIdPass` 等路径会在绘制结束后把深度附件从 `DepthWrite` 切回这里声明的状态。
- 一些 post-scene / overlay 路径会把它当作“主场景阶段结束后的深度基线状态”继续消费
- 默认值是 `RHI::ResourceStates::DepthWrite`
-某些 pass / renderer 在结束阶段恢复深度资源状态时,会把这里当作目标状态。
- `RenderSurface` 本身不会执行 barrier也不会检查调用方是否声明正确
## 测试覆盖
## 当前实现边界
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
- 这是约定性元数据,不是后端状态跟踪器。
- 是否会在渲染结束后真正切回该状态,取决于具体消费该 `surface` 的路径。
## 相关文档

View File

@@ -1,24 +1,25 @@
# RenderSurface::SetDepthStateBefore
设置深度附件在本次渲染开始前预期所处的统一状态。
设置深度附件在本次渲染开始前期望处于的状态。
```cpp
void SetDepthStateBefore(RHI::ResourceStates state);
```
## 参数
- `state` - 调用方认为当前深度附件进入本次 pass 前所处的资源状态。
- `state` - 调用方约定的深度附件起始资源状态。
## 当前语义
- 这个值只写入 `RenderSurface` 自身,不会立即发出 barrier
- 当 [IsAutoTransitionEnabled](IsAutoTransitionEnabled.md) 为 `true` 时,`BuiltinForwardPipeline``BuiltinDepthStylePassBase``BuiltinObjectIdPass` 等路径会把它作为深度附件进入 `DepthWrite` 前的来源状态。
- `SceneRenderer` 在为 post-process / final-output 构造派生 `RenderSurface` 时,会继续复制这份深度 before 状态
- 默认值是 `RHI::ResourceStates::DepthWrite`
- `RenderSurface` 只保存该状态,不会验证深度附件是否真的已经处于这个状态。
- 支持 depth barrier 的 pass 或 renderer 可在 [IsAutoTransitionEnabled](IsAutoTransitionEnabled.md) 为 `true` 时把它作为自动切换的起点
## 测试覆盖
## 当前实现边界
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
- 这不是 depth attachment 的真实状态查询接口,只是调用方与消费方之间的约定。
- 是否真正消费这个字段,取决于具体 pass / renderer 的实现。
## 相关文档

View File

@@ -1,30 +1,29 @@
# RenderSurface::SetSampleDesc
设置当前 surface 的 sample count 和 sample quality
设置目标表面的采样数和采样质量
```cpp
void SetSampleDesc(uint32_t sampleCount, uint32_t sampleQuality = 0);
```
## 参数
- `sampleCount` - 期望的采样数;传入 `0`当前实现会规范化成单采样
- `sampleQuality` - `sampleCount > 1` 时保留的 quality 值;单采样时会被重置成 `0`
- `sampleCount` - 期望的采样数;传入 `0`会被归一化为 `1`
- `sampleQuality` - 采样质量;仅当有效 `sampleCount > 1`才会被保留。
## 当前语义
- 实现会把 `sampleCount == 0` 规范化为 `1`
- 只有 `sampleCount > 1` 时,`sampleQuality` 才保留调用方传入值;否则内部强制存成 `0`
- `RenderSurfacePipelineUtils` 会把这组值写入 `GraphicsPipelineDesc.sampleCount` / `sampleQuality`
- `SceneRenderer` 当前要求 fullscreen post-process / final-output 链路的主场景输出为单采样,因此多采样主 surface 会跳过这两段 fullscreen 阶段。
- 当前实现会把 `sampleCount` 归一化到至少 `1`
- 当有效 `sampleCount <= 1` 时,内部会把 `sampleQuality` 强制置为 `0`
- 该描述会被一些 pipeline 构建路径读取,用于让图形 pipeline 与目标 surface 的 MSAA 配置保持一致
## 测试覆盖
## 当前实现边界
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
- 这不会自动创建 MSAA 附件,也不会验证当前 color / depth attachment 是否真的匹配该采样描述。
- 该接口只描述目标 surface 的采样元数据,不涉及 resolve 行为。
## 相关文档
- [RenderSurface](RenderSurface.md)
- [GetSampleCount](GetSampleCount.md)
- [GetSampleQuality](GetSampleQuality.md)
- [CameraRenderRequest](../Planning/CameraRenderRequest/CameraRenderRequest.md)