Chapter 106: Scriptable Render Pipelines
可编程渲染管线(Scriptable Render Pipeline,SRP)把一帧的渲染流程从固定黑盒改成可声明、可插拔、可调试的工程结构。读完本章后,读者应能定位一个自定义渲染效果进入哪一个 pass,追踪它读写哪些 texture / buffer,判断它受哪一级 quality tier 控制,并比较 Unity 与 Unreal 在 pass、resource 和 extension point 上的设计边界。
本章使用一个贯穿帧作为讲解对象:主摄像机渲染一座夜景工业城市,项目需要一个“选中物体轮廓 + debug normal view”的自定义效果。轮廓效果读取 camera color、depth 和 normal,写回当前 color target;debug normal view 在编辑器中替换最终颜色输出;低画质关闭轮廓,高画质启用法线重建和边缘膨胀。这个小需求覆盖 SRP 的核心问题:pass 顺序、资源声明、摄像机数据、画质开关、调试视图和工具证据。
SRP 的价值来自可控性。Unity 6.4 文档把 SRP 描述为一层薄 API,项目可以用脚本调度和配置渲染命令,再交给底层图形架构发送到图形 API;URP 和 HDRP 都建立在 SRP 之上,也可以基于 SRP 写自定义管线。对应到工程判断,SRP 解决的是“这一帧由哪些 pass 组成,每个 pass 使用哪些资源,哪些配置改变最终图像或性能结果”这一类问题。Unity 6.4 SRP fundamentals 给出了 Render Pipeline Asset、Render Pipeline Instance 和 ScriptableRenderContext 的基础边界。
本章讨论的 SRP 并限定在 Unity 命名体系内。Unreal 的 Render Dependency Graph(RDG)使用 C++ immediate-mode API 把渲染命令记录到图结构,再编译和执行;它强调 transient resource、barrier、pass culling、parallel command list recording 和 RDG Insights。两套系统的外观差异很大,核心工程问题一致:pass 必须声明输入输出,资源生命周期必须被图或管线追踪,扩展点必须接入工具和画质策略。Unreal Engine 5.7 RDG documentation 是本章比较 Unreal 侧机制的版本边界。
106.1 可编程渲染管线(SRP)概念与优势
SRP 的工作定义是:引擎把一帧拆成可由项目代码组织的 render pass 列表,每个 pass 声明输入资源、输出资源、执行条件和调试名称,管线再根据摄像机、平台、画质等级和资源依赖生成最终 GPU 命令。这里的“可编程”指项目可以改变 pass 组合与资源路径,并通过工具观察这些改变带来的图像和性能结果。
在贯穿帧中,默认渲染已经有 depth prepass、opaque pass、sky、transparent、post-processing 和 final blit。项目新增的轮廓效果放在 opaque 之后、透明物体之前,原因是轮廓需要稳定的深度与法线输入,同时希望透明物体覆盖在轮廓之上。debug normal view 则接近 final output,因为它用于替换最终颜色,服务编辑器诊断。
SRP 的第一个优势是 pass 组合可控。固定管线里,项目通常只能把后处理挂在少数固定点;SRP 中,项目可以把“选中物体 mask pass”“edge detect pass”“debug composite pass”拆成独立步骤,并给每一步设置清晰的资源读写关系。这个拆分让图像错误更容易定位:轮廓缺失时先看 mask 是否写入,再看 edge detect 是否读到了 mask 与 depth,最后看 composite 是否写回 color。
SRP 的第二个优势是资源声明可被工具使用。Unity URP 的 render graph 文档要求在 RecordRenderGraph 中声明 pass 的输入输出,使用 builder.UseTexture 表达只读输入,用 builder.SetRenderAttachment 表达颜色输出;Unreal RDG 使用 pass parameter struct 和 GraphBuilder.AddPass 表达资源依赖。资源声明把“代码里用了哪张纹理”变成工具可观察的图结构,从而支持 pass culling、资源别名、load / store action 分析和跨 pass 依赖检查。
SRP 的第三个优势是平台能力和画质等级可以集中治理。移动端 tile-based GPU 对 render target load / store、MSAA resolve 和中间纹理数量敏感;桌面端更常遇到带宽、后处理链和多 render target 的成本。SRP 可以把低、中、高画质的差异放在 pipeline asset 或 renderer settings 中,由同一帧图在不同 tier 下生成不同 pass 列表。贯穿帧中,低画质 tier 只保留单次 color edge,高画质 tier 增加 normal edge、depth dilation 和单独 debug target。
下面的图描述了贯穿帧在 SRP 中的主路径。图的边界是 CPU 侧管线组织到 GPU 命令生成;它说明 pipeline asset、camera data、pass list 和 resource graph 如何共同决定最终图像。
这条路径把 SRP 的判断顺序固定下来:先看当前 camera 使用哪套 pipeline asset,再看 quality tier 生成了哪些 pass,然后检查每个 pass 的资源声明,最后用工具确认 GPU 命令和最终输出。任何自定义效果都应沿这条路径定位,它把视觉结果和资源路径连成一条可复查链路。
106.2 引擎中 SRP 的实现模型
一个可维护的 SRP 实现模型通常由六类对象组成:pipeline asset、pipeline instance、render pass、renderer feature、camera data、resource graph。它们分别承担配置、运行、执行片段、扩展入口、视角输入和资源依赖追踪。把这些对象混在一个大型渲染函数里,会让自定义效果的开关、资源生命周期和工具命名失去稳定边界。
Pipeline asset 是项目级配置入口。它保存画质档位、默认 renderer、阴影策略、后处理开关、debug view 配置和平台 fallback。Unity 文档中,Render Pipeline Asset 负责存储使用哪一个 Render Pipeline Instance 以及如何配置它;Render Pipeline Instance 继承 RenderPipeline 并覆盖 Render() 方法。这个边界适合放长期配置,例如何时启用轮廓 pass、每个 tier 允许多少次中间 texture、debug normal view 是否出现在编辑器菜单中。
Render pass 是帧内最小执行单元。一个 pass 应说明三件事:它在帧中的注入点,读取和写入哪些资源,执行时记录哪些 GPU 命令。贯穿帧的 DebugOutlinePass 读取 CameraDepth、CameraNormals 和 SelectionMask,写入 CameraColor 或临时 OutlineColor。如果资源图能看到这些读写关系,工具就能回答“轮廓 pass 是否被剔除”“color target 是否发生多余 store”“normal texture 是否在当前 tier 被创建”。
Renderer feature 是扩展点。它把一组 pass 挂到某个 renderer 或 camera 类型上,并在每帧根据 camera data 决定是否 enqueue pass。Unity URP 文档说明 AddRenderPasses 会按 camera 调用,并可以根据 camera type 决定 feature 是否应用;这对应贯穿帧里的主摄像机和反射摄像机差异。Unity URP camera-specific renderer feature documentation 提醒 AddRenderPasses 至少每个 camera 每帧调用一次,因此该路径的逻辑应保持轻量。
Camera data 是每个视角的帧输入。它至少包含 camera 类型、分辨率、viewport、clear flags、projection、MSAA、HDR、是否为 scene view、是否为 reflection camera、camera stack 信息。贯穿帧中,主摄像机启用轮廓,反射摄像机关闭轮廓,scene view 可以启用 debug normal view。这个条件必须从 camera data 进入 pass 构建阶段,而非藏在 shader 分支里,因为 shader 分支仍会让 pass 占用资源路径。
Resource graph 是 pass 与资源之间的依赖模型。Unity 6.4 URP 的 render graph API 使用 RecordRenderGraph 声明输入输出,并提供 Render Graph Viewer 分析 pass、resource access、load / store 和 pass merge;Unreal RDG 在 setup timeline 构建图,在 execute timeline 执行 lambda,并将 transient / external resource 的生命周期放进图中。两者都把资源生命周期从“人为记住”转成“声明后由图检查”。Unity 6.4 URP render graph overview 与 Unity 6.4 write a render pass using render graph 说明了这条路径的 Unity 侧形态。
这六类对象的关系可以用同一组问题检查。下表把对象、输入、输出和贯穿帧中的证据对应起来。
| 对象 | 输入 | 输出 | 贯穿帧中的证据 |
|---|---|---|---|
| Pipeline asset | 平台、画质、默认 renderer | pass 策略与全局配置 | 低画质关闭 normal edge |
| Pipeline instance | 当前帧 camera 列表 | 每个 camera 的渲染调用 | 主摄像机与 scene view 分开渲染 |
| Renderer feature | camera data、feature settings | 注入的 pass 实例 | 只给 Game camera 注入轮廓 |
| Render pass | 资源句柄、shader、状态 | GPU 命令与目标写入 | DebugOutlinePass 读 depth / normal |
| Resource graph | pass 声明、resource handle | 依赖、生命周期、load / store | 工具显示 color 被读取并写回 |
| Editor tooling | pass name、debug flag、profile marker | 可视化证据 | Render Graph Viewer 或 RDG Insights 显示 pass |
实现 SRP 时,关键约束是对象职责稳定。Pipeline asset 决定“允许什么”,camera data 决定“当前帧需要什么”,renderer feature 决定“注入什么”,render pass 决定“读写什么”,resource graph 决定“依赖如何执行”。这个分层让同一个轮廓效果可以在不同 camera、tier 和平台下生成不同资源路径,同时保持调试命名和排查顺序一致。
106.3 构建自定义 Render Pipeline
构建自定义 Render Pipeline 的核心任务是设计 pass interface、render graph、resource declaration、camera stack 和 quality tier。它的目标是让项目新增效果时只声明自己的资源与注入点,主管线仍然能统一处理摄像机、平台能力、调试视图和性能证据。
一个 pass interface 至少需要四个能力:判断当前 frame 是否启用,声明资源,记录命令,提供调试名。下面是简化 C# 伪代码,用来表达接口边界。它强调“启用判断”和“资源声明”先于命令记录,因为 resource graph 需要在执行前知道依赖关系。
// 简化 C# 伪代码:表达自定义管线中 pass 的最小边界
public interface IFramePass
{
string Name { get; }
bool IsEnabled(in FrameContext context);
void DeclareResources(ResourceBuilder builder, in FrameContext context);
void Execute(CommandBuffer cmd, in FrameContext context);
}
这个接口不绑定某个具体 API。Unity URP 的实际路径会落到 ScriptableRenderPass.RecordRenderGraph、ScriptableRendererFeature.AddRenderPasses 和 RenderGraph builder;Unreal RDG 会落到 FRDGBuilder、pass parameter struct 和 GraphBuilder.AddPass。接口设计的关键是把判断拆成两层:CPU 构图阶段决定 pass 是否存在,GPU 执行阶段只记录当前 pass 的命令。
自定义 Render Pipeline 的第一步是固定 frame context。Frame context 需要包含 camera data、platform profile、quality tier、scene render list、shared textures、debug view 和 profiling sink。贯穿帧中,FrameContext 应能回答:当前 camera 是否是 Game camera,debug normal view 是否开启,当前 tier 是否允许 normal texture,selection mask 是否有对象需要渲染。这些答案决定 pass 列表,后续 shader 只消费已经确定的资源。
第二步是设计 render graph 资源声明。贯穿帧的轮廓效果可以拆成三段:SelectionMaskPass 写 SelectionMask,OutlineEdgePass 读 SelectionMask、CameraDepth、CameraNormals 并写 OutlineColor,OutlineCompositePass 读 OutlineColor 和 CameraColor 并写回 CameraColor。如果低画质关闭 normal edge,则 OutlineEdgePass 的资源声明只保留 CameraDepth 与 SelectionMask。这种声明方式让工具能显示少创建了哪张 texture,也能显示哪些 pass 被剔除。
第三步是处理 camera stack。一个 camera stack 可能包含 base camera、overlay camera、scene view camera 和 reflection camera。轮廓效果通常只服务主视角,因此 pass 注入条件应读取 camera type 与 stack role。overlay camera 如果覆盖 UI 或武器模型,需要单独判断它是否继承 base camera 的 depth / color;reflection camera 通常关闭轮廓,以保持反射纹理稳定。这个判断放在 AddRenderPasses 或自定义 pass scheduler 中,能减少无效 pass 和中间资源。
第四步是把 quality tier 映射到资源预算。资源预算应使用具体对象表达,例如 render target 数量、format、MSAA samples、是否创建 normal texture、是否启用 half resolution、是否允许 compute pass。贯穿帧可以使用三档:Low 使用 depth-only edge 且半分辨率,Medium 使用 depth + normal edge 且单临时 target,High 使用 full resolution normal edge、对象 mask 和可选 debug normal view。tier 改变后,pass graph 应出现可解释的差异。
下面的简化 URP 风格代码展示 render graph 写法的关键边界。它只用于说明资源声明和执行函数分离;真实项目还需要补齐材质、shader pass、profiling sampler、错误处理和平台判断。
// 简化 C# 伪代码:表达 URP Render Graph 中 pass 声明与执行分离
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameContext)
{
using var builder = renderGraph.AddRasterRenderPass<PassData>(
"DebugOutline", out var passData);
var resources = frameContext.Get<UniversalResourceData>();
passData.color = resources.activeColorTexture;
passData.depth = resources.activeDepthTexture;
builder.UseTexture(passData.depth);
builder.SetRenderAttachment(passData.color, 0);
builder.SetRenderFunc(static (PassData data, RasterGraphContext context) =>
{
// 这里记录绘制轮廓所需的命令
});
}
这段代码对应三条工程判断。第一,资源读取通过 UseTexture 声明,工具能把 depth 连接到当前 pass。第二,颜色输出通过 SetRenderAttachment 声明,工具能显示 load / store 与 pass merge 信息。第三,命令记录放在 SetRenderFunc 指向的执行函数中,构图阶段不直接写 command buffer。Unity 文档中 RecordRenderGraph 的说明也强调此阶段声明输入输出,命令在执行函数中生成。
第五步是接入 profiling 和 debug view。每个 pass 的名称应稳定,例如 SelectionMask、OutlineEdge、OutlineComposite、DebugNormals。工具里看到的 pass 名应能直接映射到源码或 feature 设置。debug view 应复用同一套资源声明,例如 debug normal view 读 CameraNormals 并输出到最终 color;这样调试视图验证的是管线里真实使用的资源,而非另一条临时调试路径。
一条可复用的构建顺序是:先定义 frame context,再定义 pass interface,然后建立资源命名规范,接着实现 pass scheduler,最后接入工具命名、debug view 和 tier 配置。这个顺序能把自定义效果固定在可复查结构中,后续新增 SSAO、SSR、custom decal 或 stylized post-processing 时,也沿同一套 pass / resource / camera / tier 关系扩展。
106.4 Editor Debug View Quality Tier and Pass Toggle Support
Editor debug view、quality tier 和 pass toggle 是 SRP 的工程控制面。它们的共同目标是让项目可以在编辑器中解释当前图像来源,并把“某个效果开关改变了哪些 pass 和资源”变成可观察证据。贯穿帧中的轮廓效果如果只提供一个布尔开关,调试时只能看到最终颜色差异;完善的控制面应显示它启用了哪些 pass、创建了哪些中间纹理、在哪个 camera 上生效。
Pass toggle 应分成三层。第一层是 feature 级开关,例如 DebugOutlineFeature.Enabled,用于决定整组 pass 是否注入。第二层是 pass 级开关,例如 SelectionMask、OutlineEdge、OutlineComposite,用于定位图像链路中断位置。第三层是 shader 分支或 keyword,例如 depth edge、normal edge、object id edge,用于改变 pass 内部算法。越靠前的开关越能减少 CPU 构图、资源创建和 GPU 执行成本;越靠后的开关越适合局部视觉调试。
Quality tier 应驱动具体资源路径,而非只驱动美术参数。Low tier 可以设置 half resolution outline、depth edge、single channel mask;Medium tier 使用 full resolution mask 和单临时 color;High tier 增加 normal edge、object id、temporal stabilization 或更高精度 format。tier 的验收标准应通过工具观察:pass 数是否变化,中间 texture format 是否变化,load / store action 是否减少,GPU marker 中的 pass 耗时是否移动到预期范围。
Editor debug view 应直接绑定 frame resource。debug normal view 读取当前帧真实的 normal texture,debug depth view 读取当前 depth,debug selection view 读取 selection mask。这样 debug view 可以回答“资源内容是否正确”,而非只证明 shader 能画出一张调试图。Unity Render Graph Viewer 能显示 render pass、resource access、pass culling、load / store action、pass merge 和 resource lifetime;这些信息适合用来验证 debug view 与 pass toggle 是否改变了同一张图结构。Unity 6.4 Render Graph Viewer reference 描述了这些观察项。
Hot reload 应集中处理 shader、material variant 和 pipeline state 的刷新边界。编辑器修改轮廓 shader 后,系统需要重新绑定 material pass、刷新 shader variant key、更新 pass 内缓存的资源引用,并保持上一帧可用配置作为回退。热更新路径的目标是缩短迭代反馈,同时让失败状态可见,例如显示 shader compile error、pass 被临时禁用、debug view 回到 fallback color。
Pass profiling 要把名称、范围和资源绑定在一起。Unity 侧可以让 pass name 与 Render Graph Viewer、Frame Debugger、Profiler marker 对齐;Unreal 侧可以使用 RDG event scope、GPU stat scope、CSV profiler scope 与 RDG Insights 对齐。Unreal RDG 文档说明 RDG 支持 profile scope,并能把 setup 与 execute timelines 分开计量。贯穿帧中,OutlineEdge 的耗时应对应 edge shader 与读 depth / normal 的采样成本,OutlineComposite 的耗时应对应全屏 blend 与 color 写回。
下表给出控制面的检查顺序。它把 UI 开关、图结构、资源证据和性能证据连在一起。
| 控制项 | 改变对象 | 工具中应看到的证据 | 失败症状 |
|---|---|---|---|
| Feature toggle | 整组 pass 注入 | pass 列表增减 | 开关关闭后仍有中间 texture |
| Pass toggle | 单个 pass | 对应 pass 被 cull 或移除 | 最终图变了但工具无 pass 差异 |
| Quality tier | format、分辨率、pass 数 | resource size / format 改变 | 低画质仍创建 full resolution texture |
| Debug view | 最终输出来源 | final pass 读取 debug resource | debug 图与真实资源路径分离 |
| Hot reload | shader variant、material pass | compile status 与 pass 刷新 | 修改 shader 后旧 variant 继续生效 |
| Profiling marker | pass 计时范围 | GPU marker 名称可定位 | 耗时只能归到匿名 full screen pass |
一个稳定的编辑器支持策略是:开关先影响 pass scheduler,tier 再影响 resource declaration,debug view 最后选择输出路径。这个顺序让用户在编辑器中看到的 UI 控件能映射到工具里的 pass 与 resource,而性能分析也能回到同一套名称体系。
106.5 Unity Unreal SRP Pass Resource and Extension Point Comparison
Unity 与 Unreal 都把现代渲染管线从手写命令序列推进到 pass / resource graph 模型,但扩展位置和语言边界不同。Unity SRP 更适合把渲染管线暴露为 C# asset、renderer feature 和 editor setting;Unreal RDG 更靠近 C++ renderer module、shader parameter struct 和 RHI command list。比较两者时,应使用同一组维度:pass declaration、resource lifetime、renderer feature、material variant 和 tool integration。
Pass declaration 的差异体现扩展层级。Unity URP 中,自定义 pass 常继承 ScriptableRenderPass,在 RecordRenderGraph 中声明资源与执行函数,再通过 ScriptableRendererFeature.AddRenderPasses 注入 renderer。Unreal RDG 中,pass 通常通过 FRDGBuilder::AddPass 添加,使用 ERDGPassFlags 标注 Compute、Raster、Copy 或 AsyncCompute,并通过 lambda 在 execute timeline 记录 RHI 命令。Unity 的优势是编辑器资产和 C# 工作流轻,Unreal 的优势是与底层 renderer、shader parameter 和 RHI 结合紧。
Resource lifetime 的差异体现图系统责任。Unity URP render graph 使用 TextureHandle、UniversalResourceData、builder.UseTexture、builder.SetRenderAttachment 等方式表达当前帧资源关系,并用 viewer 展示 pass / resource access。Unreal RDG 区分 transient 与 external resource,setup timeline 创建资源描述,execute timeline 延迟执行命令;RDG 还会处理资源 transition、unused pass culling、transient memory aliasing 和 validation。两者的共同判断是:资源只在声明过的 pass 中读写,生命周期交给图系统追踪。
Renderer feature 与 extension point 的差异体现用户入口。Unity 的 ScriptableRendererFeature 是项目层扩展点,适合美术工具、后处理、debug draw、camera-specific effect 和平台配置。Unreal 的扩展通常进入 renderer module、plugin、view extension、post process material 或 RDG pass 注入点,适合引擎级渲染功能、平台优化和 C++ shader 集成。贯穿帧中的轮廓效果在 Unity 里可以作为 renderer feature 分发;在 Unreal 里更可能作为 post process pass、mesh pass 或 view extension 接入。
Material variant 的差异体现 shader 组织方式。Unity 侧常通过 shader keyword、material property、URP renderer setting 和 pipeline asset 控制变体;SRP Batcher、shader variant stripping 和 render pass 注入点会影响最终绑定成本。Unreal 侧常通过 shader permutation、FShader、FParameters、uniform buffer 和 RDG pass parameter struct 控制资源绑定。两者都需要把 variant key 与 quality tier 对齐:Low tier 不生成 normal edge variant,High tier 才编译对象 id 与 temporal stabilization 相关路径。
Tool integration 的差异体现证据入口。Unity 中,Render Graph Viewer、Frame Debugger、Profiler 和 Rendering Debugger 可观察 pass 顺序、resource access、load / store、merge 和 debug view。Unreal 中,RDG Insights、RenderDoc、stat gpu、CSV profiler 和 RDG event scope 可观察 graph、resource lifetime、GPU scope 和 pass cost。工具证据应回答同一组问题:pass 是否存在,资源是否被创建,读写顺序是否正确,barrier 或 load / store 是否带来额外成本,final output 是否来自预期资源。
| 维度 | Unity SRP / URP | Unreal RDG | 迁移判断 |
|---|---|---|---|
| Pass declaration | ScriptableRenderPass + RecordRenderGraph | FRDGBuilder::AddPass + pass flags | 都需要显式声明 pass 名称和执行边界 |
| Resource lifetime | TextureHandle、frame resource、builder 声明 | transient / external RDG resource | 都把读写关系交给图系统追踪 |
| Extension point | ScriptableRendererFeature、pipeline asset、camera data | renderer module、view extension、post process、RDG pass | Unity 更偏项目资产,Unreal 更偏 C++ 渲染模块 |
| Material variant | shader keyword、material property、pipeline setting | shader permutation、parameter struct、uniform buffer | variant key 应跟 tier 和资源声明对齐 |
| Tool integration | Render Graph Viewer、Frame Debugger、Profiler | RDG Insights、RenderDoc、stat gpu、CSV profiler | 工具都应能映射到稳定 pass 名称 |
这张表的使用方式是:先比较扩展点,再比较资源声明,最后比较工具证据。只看 API 名称会误判迁移成本;真正决定迁移难度的是资源生命周期、shader variant key、camera 条件和工具可观察性。贯穿帧中的轮廓效果从 Unity 迁到 Unreal 时,视觉算法可以保持 edge detect 与 composite 思路,但 pass 注入点、资源句柄、shader 参数声明和 profiling scope 都需要按 Unreal RDG 重建。
最小自检任务
给定一个 SRP 项目:主摄像机渲染城市夜景,反射摄像机渲染水面反射,项目有一个 DebugOutlineFeature。该 feature 包含 SelectionMaskPass、OutlineEdgePass、OutlineCompositePass 和 DebugNormalsPass。Low tier 使用半分辨率 depth edge,High tier 使用 full resolution depth + normal edge。编辑器中打开 debug normal view 后,最终画面应显示当前帧 normal。请设计一套排查顺序,用来判断这个 feature 是否正确接入 SRP,并说明每一步观察什么证据。
答案要点
先检查 pipeline asset 与 quality tier。确认 Low tier 只生成半分辨率 depth edge 资源,High tier 生成 full resolution normal edge 相关资源;证据来自资源尺寸、format、pass 列表和 tier 设置。这个步骤回答“当前配置是否允许该效果存在”。
再检查 camera data 与 feature 注入条件。主摄像机应注入 SelectionMaskPass、OutlineEdgePass、OutlineCompositePass,反射摄像机应按项目策略关闭轮廓或使用单独配置;证据是每个 camera 的 pass 列表和 AddRenderPasses / pass scheduler 条件。这个步骤回答“该效果是否进了正确的 camera”。
接着检查资源声明。SelectionMaskPass 写 mask,OutlineEdgePass 读 mask、depth 和 High tier 的 normal,写 outline color,OutlineCompositePass 读 outline color 并写 final color。工具中应能看到这些读写关系、load / store action 和 pass 顺序。这个步骤回答“pass 是否使用了正确资源”。
然后检查 debug normal view。DebugNormalsPass 应读取当前帧真实 normal texture,并把 final color 输出切到 normal 可视化;如果工具显示它读取另一张临时调试纹理,debug view 就无法证明真实管线资源正确。这个步骤回答“调试视图是否验证了真实资源路径”。
最后检查 profiling 与热更新。pass 名称应稳定出现在 Profiler、Render Graph Viewer、RDG Insights 或其他工具里;修改 shader 后,应能看到 variant 刷新、pass 继续使用同一组资源声明。这个步骤回答“性能证据和迭代路径是否能回到同一套 pass 名称”。
本章知识点总结
- SRP 定义:SRP 把一帧拆成可由项目代码组织的 pass、资源声明、摄像机条件和画质策略。
- 贯穿帧:选中物体轮廓与 debug normal view 能覆盖 pass 顺序、资源读写、camera data、tier 和工具证据。
- Pass 组合:自定义效果应拆成 mask、edge、composite、debug 等可命名 pass,以便定位图像链路。
- 资源声明:pass 需要显式声明读取和写入的 texture / buffer,resource graph 才能追踪生命周期与依赖。
- Pipeline asset:pipeline asset 适合保存平台、画质、默认 renderer、debug view 和长期渲染策略。
- Camera data:camera data 决定当前视角是否注入 feature,以及 camera stack 如何共享或隔离资源。
- Renderer feature:renderer feature 是项目层扩展入口,负责按 camera 与设置把 pass 注入帧循环。
- Render graph:render graph 把 pass 与资源组成可分析图结构,支持 culling、merge、load / store 与 lifetime 观察。
- Quality tier:quality tier 应改变具体资源路径,例如分辨率、format、pass 数、normal texture 和 compute 路径。
- Debug view:debug view 应读取当前帧真实资源,才能验证资源内容和 pass 连接关系。
- Hot reload:热更新需要刷新 shader variant、material pass 和 pipeline state,并把失败状态暴露给编辑器。
- Profiling marker:稳定 pass 名称应贯穿源码、工具、GPU marker 和性能报告。
- Unity 边界:Unity SRP / URP 更偏 C# asset、renderer feature、camera data 和 editor tooling 工作流。
- Unreal 边界:Unreal RDG 更偏 C++ renderer module、shader parameter struct、RDG pass 和 RHI 资源路径。
- 迁移判断:跨引擎迁移自定义效果时,重点比较资源生命周期、pass 注入点、variant key 和工具证据。