6.1 KiB
BuiltinForwardPipeline
命名空间: XCEngine::Rendering::Pipelines
类型: class
头文件: XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h
描述: 当前内建的前向主渲染管线实现。它会按 shader pass 的资源声明动态构建 PassResourceLayout、descriptor set 与 RHIPipelineState,并通过 RenderPassSequence 执行默认的 opaque pass。
概览
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_passSequence 注册一个 BuiltinForwardOpaquePass。因此当前仍是一条单 pass 的前向路径,但生命周期已经统一收口到 RenderPassSequence。
当前资源契约
BuiltinForwardPipeline 会优先读取 shader pass 自己声明的 resources。如果该列表为空,则回退到 BuildLegacyBuiltinForwardPassResourceBindings 返回的 legacy builtin forward 绑定:
set 1 binding 0->PerObject/CBVset 2 binding 0->Material/CBVset 3 binding 0->BaseColorTexture/Texture2Dset 4 binding 0->LinearClampSampler/Sampler
随后会通过 TryBuildBuiltinPassResourceBindingPlan 把显式资源声明或 legacy fallback 统一收口成 BuiltinPassResourceBindingPlan。
当前可识别的 forward 语义只有四个:
PerObject:必需,且必须是唯一的 constant buffer。Material:可选,且必须是唯一的 constant buffer。BaseColorTexture:可选,且必须是唯一的Texture2D或TextureCube。LinearClampSampler:可选,且必须是唯一的 sampler。
其中 Material 语义当前不是固定写死成某个历史布局。渲染时会先通过
ResolveSchemaMaterialConstantPayload(material) 取得
Material::GetConstantBufferData() 的字节视图;只有拿不到有效 payload 时,
才会回退到内部 FallbackPerMaterialConstants { baseColorFactor }。
binding-plan 解析之后,布局构建阶段还会继续拒绝以下情况:
- 未知语义。
- 非法 set index。
- 在同一个 set 中混用 sampler 与非 sampler 绑定。
- 在同一个 set 中出现重复 binding。
- 缺少
PerObject。
如果第一个实际绑定的 set 大于 0,并且 set 0 为空,实现还会补一个兼容用的 set 0,避免某些布局路径要求从 set 0 开始。
当前渲染流程
- Initialize 通过
m_passSequence.Initialize(context)进入 pass 生命周期。 - Render 把
RenderContext、RenderSurface和RenderSceneData打包成RenderPassContext,再交给m_passSequence.Execute(...)。 BuiltinForwardOpaquePass内部调用ExecuteForwardOpaquePass(),处理 render target 绑定、viewport/scissor、颜色与深度清理,以及前后自动状态切换。- 渲染阶段遍历
RenderSceneData::visibleItems,筛出BuiltinMaterialPass::ForwardLit物体。 - 每个物体都会按当前材质解析 shader/pass,获取或创建 pass layout、pipeline state、动态或静态 descriptor set,然后写入常量并发出 draw call。
当前实现细节
- BuildInputLayout 现在明确使用
POSITION=float3、NORMAL=float3、TEXCOORD=float2,与StaticMeshVertex对齐。 - 材质贴图解析通过
ResolveBuiltinBaseColorTexture(material)进入 builtin base-color 语义,不再依赖旧文档里的“按若干名字猜测纹理”说法。 - 逐物体常量来自
PerObjectConstants。 - 逐材质常量优先来自
ResolveSchemaMaterialConstantPayload(material)暴露的 schema-driven payload; 如果 view 无效,才回退到内部FallbackPerMaterialConstants { baseColorFactor }。 - 采样器和 1x1 白色 fallback 纹理在初始化后长期复用;具体
Texture和Mesh的 GPU 资源则由 RenderResourceCache 按需上传。
当前限制
- 目前只注册了
BuiltinForwardOpaquePass,没有透明排序、阴影、延迟渲染或后处理主路径。 - 资源语义是白名单模型,超出
PerObject / Material / BaseColorTexture / LinearClampSampler的声明不会被接受。 Render()层面不会因为单个物体DrawVisibleItem()失败而整体返回false;当前调用点仍然以“尽量继续绘制其余物体”为主。
公开方法
| 方法 | 说明 |
|---|---|
| Constructor | 创建管线对象,并注册默认的 opaque pass。 |
| Destructor | 析构时调用 Shutdown()。 |
| BuildInputLayout | 返回 builtin forward 使用的静态网格输入布局。 |
| Initialize | 初始化 pass sequence,并在需要时准备共享 GPU 资源。 |
| Shutdown | 关闭 pass sequence,释放 pass layout、descriptor set、pipeline state 与 fallback 资源。 |
| Render | 把 RenderSceneData 绘制到目标 RenderSurface。 |