validate-urp-render-graph-renderer-feature

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Skill: Validate a Unity URP Render Graph Renderer Feature

技能:验证Unity URP Render Graph渲染器特性

Purpose

用途

Review a Unity 6+ URP Render Graph
ScriptableRendererFeature
and its associated pass implementation for correctness issues related to material binding, resource wiring, render graph texture creation, static render function structure, global resource exposure, and API/version usage.
审查Unity 6+ URP Render Graph的
ScriptableRendererFeature
及其关联Pass实现,检查与材质绑定、资源连接、Render Graph纹理创建、静态渲染函数结构、全局资源暴露以及API/版本使用相关的正确性问题。

When to Use

使用场景

Use this skill when:
  • reviewing AI-generated Unity URP Render Graph renderer feature code
  • validating a custom
    ScriptableRendererFeature
    before integrating it
  • checking for common Render Graph resource wiring and pass setup mistakes
  • diagnosing suspicious but plausible Render Graph pass implementations
  • reviewing whether a custom raster/blit/copy pass uses the most appropriate Render Graph helper APIs
在以下场景中使用本技能:
  • 审查AI生成的Unity URP Render Graph渲染器特性代码
  • 在集成前验证自定义
    ScriptableRendererFeature
  • 检查Render Graph常见的资源连接和Pass配置错误
  • 排查看似合理但存在疑点的Render Graph Pass实现
  • 审查自定义光栅/Blit/复制Pass是否使用了最合适的Render Graph辅助API

Inputs

输入

The skill should expect:
  • Unity version
  • URP version
  • Render Graph renderer feature code to review
    • ScriptableRendererFeature
    • associated pass code
    • or both
  • Intended behavior
  • Expected inputs/outputs, if known
  • Optional constraints
    • project conventions
    • required pass type
    • known resources
    • required material/shader properties
本技能预期接收以下输入:
  • Unity版本
  • URP版本
  • 待审查的Render Graph渲染器特性代码
    • ScriptableRendererFeature
      代码
    • 关联Pass代码
    • 或两者皆有
  • 预期行为
  • 预期输入/输出(如已知)
  • 可选约束条件
    • 项目约定
    • 要求的Pass类型
    • 已知资源
    • 必填材质/Shader属性

Output Format

输出格式

The skill must return results in the following structure:
本技能必须按照以下结构返回结果:

1. Validation Summary

1. 验证摘要

A short overall assessment of the implementation.
对实现方案的简短整体评估。

2. Confirmed Issues

2. 已确认问题

Concrete issues directly supported by the provided code.
由提供的代码直接佐证的具体问题。

3. Likely Issues / Risky Assumptions

3. 潜在问题/风险假设

Potential issues that depend on missing context or incomplete information.
依赖缺失上下文或不完整信息的潜在问题。

4. Recommended Fixes

4. 推荐修复方案

Minimal targeted fixes for each issue.
针对每个问题的最小化定向修复建议。

5. Corrected Snippets

5. 修正后的代码片段

Small corrected code snippets where useful.
必要时提供小型修正代码片段。

6. Missing Information

6. 缺失信息

Any information needed to validate the code with higher confidence.
为更有信心地验证代码所需的补充信息。

Validation Checklist

验证检查清单

1. Material Binding

1. 材质绑定

Check that:
  • materials are declared clearly
  • serialized materials are exposed correctly when needed
  • materials are passed into the pass correctly
  • null handling exists where required
  • declared materials are actually used
  • all required material inputs are bound before execution
  • the primary input texture is explicitly bound when the shader expects one
  • auxiliary textures and parameter textures are also bound explicitly
  • texture/property binding matches the shader’s expected property names
Flag as an issue when:
  • a material is declared or passed but not actually used
  • only secondary textures or parameters are bound while the main input texture is omitted
  • the pass binds a mask/noise/auxiliary texture but fails to bind the primary color/input texture
  • required shader properties are assumed to exist without being set
  • property names are inconsistent or ambiguous
  • the code relies on implicit main texture binding when explicit binding is required by the pass pattern
Prefer patterns where:
  1. the material is created or assigned clearly
  2. the primary source texture is bound explicitly
  3. all auxiliary textures are bound explicitly
  4. property names are consistent and intentional
  5. null or missing-resource cases are handled or reported
检查以下内容:
  • 材质声明清晰
  • 序列化材质在需要时正确暴露
  • 材质正确传入Pass
  • 必要处存在空值处理逻辑
  • 声明的材质确实被使用
  • 所有必填材质输入在执行前完成绑定
  • 当Shader需要主输入纹理时,显式绑定该纹理
  • 辅助纹理和参数纹理也需显式绑定
  • 纹理/属性绑定与Shader预期的属性名称匹配
出现以下情况时标记为问题:
  • 声明或传入的材质未被实际使用
  • 仅绑定了辅助纹理或参数,却遗漏了主输入纹理
  • Pass绑定了遮罩/噪声/辅助纹理,但未绑定主颜色/输入纹理
  • 假设必填Shader属性存在但未设置
  • 属性名称不一致或模糊不清
  • 当Pass模式要求显式绑定时,代码依赖隐式主纹理绑定
优先采用以下模式:
  1. 材质的创建或分配清晰明确
  2. 显式绑定主源纹理
  3. 显式绑定所有辅助纹理
  4. 属性名称一致且明确
  5. 处理或报告空值或资源缺失情况

2. Texture Resource Wiring

2. 纹理资源连接

Check that:
  • sampled/read textures, write targets, and auxiliary textures are clearly distinguished
  • textures used with
    UseTexture(...)
    are appropriate for read access
  • textures used with
    SetRenderAttachment(...)
    are appropriate as write targets
  • source, destination, and auxiliary resources are not confused
  • all expected textures are explicitly wired
  • texture property names are explicit and consistent when materials are involved
  • the implementation does not invent texture availability
  • multi-texture resource usage is handled explicitly rather than implicitly
Flag as an issue when:
  • a texture intended as an input/read resource is instead used as a write target without justification
  • a destination/write target is confused with a sampled input
  • auxiliary textures are used without being clearly sourced or wired
  • a required texture resource is missing from the pass setup
  • read/write resource roles are ambiguous or inconsistent
检查以下内容:
  • 采样/读取纹理、写入目标和辅助纹理区分清晰
  • 使用
    UseTexture(...)
    的纹理适合读取访问
  • 使用
    SetRenderAttachment(...)
    的纹理适合作为写入目标
  • 源资源、目标资源和辅助资源未混淆
  • 所有预期纹理均显式连接
  • 涉及材质时,纹理属性名称明确且一致
  • 实现未凭空假设纹理可用
  • 多纹理资源使用通过显式方式处理而非隐式处理
出现以下情况时标记为问题:
  • 本应作为输入/读取资源的纹理被用作写入目标且无合理理由
  • 目标/写入目标与采样输入混淆
  • 使用辅助纹理但未明确来源或连接方式
  • Pass配置中缺失必填纹理资源
  • 读取/写入资源的角色模糊或不一致

3. Execution Structure / Static Render Function

3. 执行结构/静态渲染函数

Check that:
  • the render function is declared as
    static
  • the execution structure matches the target pass type and API style
  • pass data is wired correctly into execution
  • resources are accessed in the correct stage
  • execution logic is consistent with the intended render pass behavior
  • every
    PassData
    field used by the render function is explicitly assigned during pass setup for the current recording
  • the implementation does not rely on default values or previously assigned
    PassData
    state
  • resource handles stored in
    PassData
    are assigned fresh for the current frame/pass recording and are not left dangling from prior usage
Flag as an issue when:
  • the render function is not
    static
  • the implementation uses an instance method where the API pattern expects a static render function
  • pass data or required resources are accessed through instance state instead of the pass data/context provided to the static function
  • execution flow does not match the expected render graph or pass execution pattern
  • a
    PassData
    field is read in the render function but is not clearly assigned during pass setup
  • only some
    PassData
    fields are reassigned while others may retain stale values from previous pooled usage
  • a resource handle stored in
    PassData
    may survive from a previous frame or pass due to incomplete reassignment
  • the implementation risks using a dangling or stale handle because pass data is not fully initialized each time it is recorded
Prefer:
  • explicitly assigning every
    PassData
    field used by the pass during each
    RecordRenderGraph(...)
    call
  • treating
    PassData
    as transient per-recording data, not persistent state
  • avoiding partial initialization of pooled pass data objects
检查以下内容:
  • 渲染函数声明为
    static
  • 执行结构匹配目标Pass类型和API风格
  • Pass数据正确连接到执行流程
  • 在正确阶段访问资源
  • 执行逻辑与预期渲染Pass行为一致
  • 渲染函数使用的每个
    PassData
    字段在当前录制的Pass配置期间均被显式赋值
  • 实现不依赖默认值或先前分配的
    PassData
    状态
  • PassData
    中存储的资源句柄为当前帧/Pass录制重新分配,未保留之前使用的悬空句柄
出现以下情况时标记为问题:
  • 渲染函数未声明为
    static
  • 在API模式预期使用静态渲染函数的场景中,实现使用了实例方法
  • 通过实例状态而非静态函数提供的Pass数据/上下文访问Pass数据或必填资源
  • 执行流程与预期的Render Graph或Pass执行模式不匹配
  • 渲染函数读取
    PassData
    字段,但该字段在Pass配置期间未被明确赋值
  • 仅重新分配部分
    PassData
    字段,其他字段可能保留之前池化使用的过期值
  • 由于未完全重新赋值,
    PassData
    中存储的资源句柄可能残留自之前的帧或Pass
  • 由于每次录制时Pass数据未完全初始化,实现存在使用悬空或过期句柄的风险
优先采用以下方式:
  • 在每次
    RecordRenderGraph(...)
    调用期间,显式赋值Pass使用的所有
    PassData
    字段
  • PassData
    视为每次录制的临时数据,而非持久化状态
  • 避免池化Pass数据对象的部分初始化

4. Render Graph Descriptor Validation

4. Render Graph描述符验证

Check that:
  • the implementation does not create a new
    TextureDesc
    by default when an appropriate graph-derived descriptor can be used directly
  • when a texture should match the active render target, the descriptor is sourced from the relevant render graph resource first, such as:
    • resourceData.activeColorTexture.GetDescriptor(renderGraph)
    • or another appropriate existing graph-backed resource
  • only the fields that actually need to differ are modified after sourcing the descriptor
  • descriptor fields such as name, depth bits, format, and MSAA are intentionally preserved or intentionally overridden
  • any manual reconstruction of descriptor data is justified by a specific requirement
Flag as an issue when:
  • the code creates a fresh
    TextureDesc
    without first attempting to reuse a graph-derived descriptor
  • width and height are manually copied into a new descriptor structure by default
  • cameraTargetDescriptor
    is used as the primary source when a render-graph-derived descriptor is available and more accurate
  • important properties such as MSAA, graphics format, or compatibility with the active render target are dropped accidentally
  • descriptor reconstruction is used as a convenience shortcut rather than a necessary divergence from the source resource
Preferred rule:
  • Do not create a new
    TextureDesc
    unless a graph-derived descriptor cannot be used directly or the texture must intentionally diverge from the source resource.
Preferred pattern:
  1. get the descriptor from the relevant render graph resource
  2. modify only the fields that must change
  3. create the texture from that derived descriptor whenever possible
Examples:
检查以下内容:
  • 当可直接使用图形派生的描述符时,实现默认创建新的
    TextureDesc
  • 当纹理需匹配活动渲染目标时,首先从相关Render Graph资源中获取描述符,例如:
    • resourceData.activeColorTexture.GetDescriptor(renderGraph)
    • 或其他合适的现有图形支持资源
  • 仅修改实际需要调整的字段
  • 描述符字段(如名称、深度位、格式、MSAA)被有意保留或覆盖
  • 任何手动重建描述符数据的行为均有特定需求作为依据
出现以下情况时标记为问题:
  • 代码未先尝试复用图形派生的描述符,直接创建新的
    TextureDesc
  • 默认手动将宽度和高度复制到新的描述符结构中
  • 当Render Graph派生的描述符可用且更准确时,却使用
    cameraTargetDescriptor
    作为主要来源
  • 意外丢失MSAA、图形格式或与活动渲染目标兼容性等重要属性
  • 将描述符重建用作便捷捷径,而非基于源资源的必要差异
优先规则:
  • 除非无法直接使用图形派生的描述符,或纹理需有意偏离源资源,否则不要创建新的
    TextureDesc
优先模式:
  1. 从相关Render Graph资源中获取描述符
  2. 仅修改必须更改的字段
  3. 尽可能从该派生描述符创建纹理
示例:

Preferred

推荐写法

csharp
RenderTextureDescriptor desc = resourceData.activeColorTexture.GetDescriptor(renderGraph);
desc.depthBufferBits = 0;
desc.name = "New name";
// other desired paramters
passData.targetTexture = renderGraph.CreateTexture(desc);
csharp
RenderTextureDescriptor desc = resourceData.activeColorTexture.GetDescriptor(renderGraph);
desc.depthBufferBits = 0;
desc.name = "New name";
// other desired paramters
passData.targetTexture = renderGraph.CreateTexture(desc);

5. Manual Copy Pass Simplification

5. 手动复制Pass简化

Check that:
  • simple texture copy operations are not implemented as full custom raster passes when a built-in Render Graph helper is sufficient
  • passes that only read one texture and write it unchanged to another target are simplified where appropriate
  • the implementation prefers the most appropriate built-in helper for the target API/platform context
  • AddCopyPass(...)
    is not recommended by default if a more compatible
    AddBlitPass(...)
    overload should be preferred in the current environment
Flag as an issue when:
  • a raster pass exists only to copy one texture into another
  • the pass uses no material and no custom processing
  • the render function only performs a simple blit/copy equivalent
  • the implementation uses a full custom raster pass where a built-in copy/blit helper would express the same behavior more directly
Prefer:
  • the appropriate
    AddBlitPass(...)
    overload for straightforward copy-like operations when that is the recommended and more compatible path
  • AddCopyPass(...)
    only when it is explicitly appropriate and supported for the target API/platform context
  • a custom raster pass only when the copy requires additional logic or non-trivial behavior
检查以下内容:
  • 当内置Render Graph辅助工具足以实现时,简单的纹理复制操作未以完整自定义光栅Pass实现
  • 仅读取一个纹理并将其原封不动写入另一个目标的Pass在合适时被简化
  • 实现针对目标API/平台上下文选择最合适的内置辅助工具
  • 在当前环境中应优先选择更兼容的
    AddBlitPass(...)
    重载时,默认不推荐使用
    AddCopyPass(...)
出现以下情况时标记为问题:
  • 存在仅用于将一个纹理复制到另一个纹理的光栅Pass
  • Pass未使用材质且无自定义处理逻辑
  • 渲染函数仅执行简单的Blit/复制等效操作
  • 可使用内置复制/Blit辅助工具更直接地表达相同行为时,实现却使用了完整的自定义光栅Pass
优先采用以下方式:
  • 对于简单的类复制操作,使用合适的
    AddBlitPass(...)
    重载(这是推荐且兼容性更强的方式)
  • 仅当
    AddCopyPass(...)
    明确适用于目标API/平台上下文时才使用
  • 仅当复制操作需要额外逻辑或非平凡行为时,才使用自定义光栅Pass

6. Manual Blit Pass Simplification

6. 手动Blit Pass简化

Check that:
  • straightforward fullscreen material blits are not implemented as custom raster passes when
    renderGraph.AddBlitPass(...)
    would express the same behavior more directly
  • custom raster passes are only used for blits when additional logic or non-trivial behavior is actually required
  • simple source-to-destination material blits use the most direct render graph helper available
Flag as an issue when:
  • a raster pass reads one source texture and writes one destination texture
  • the pass uses a material but no additional custom pass logic
  • the render function only performs a simple fullscreen blit
  • renderGraph.AddBlitPass(...)
    would provide an equivalent result more clearly
Prefer:
  • renderGraph.AddBlitPass(...)
    for straightforward fullscreen material blits
  • a custom raster pass only when extra logic, multiple operations, conditional behavior, or special setup is actually required
检查以下内容:
  • renderGraph.AddBlitPass(...)
    可更直接地表达相同行为时,简单的全屏材质Blit未以自定义光栅Pass实现
  • 仅当确实需要额外逻辑或非平凡行为时,才使用自定义光栅Pass实现Blit
  • 简单的源到目标材质Blit使用可用的最直接Render Graph辅助工具
出现以下情况时标记为问题:
  • 光栅Pass读取一个源纹理并写入一个目标纹理
  • Pass使用材质但无额外自定义Pass逻辑
  • 渲染函数仅执行简单的全屏Blit
  • renderGraph.AddBlitPass(...)
    可更清晰地提供等效结果
优先采用以下方式:
  • 对于简单的全屏材质Blit,使用
    renderGraph.AddBlitPass(...)
  • 仅当确实需要额外逻辑、多步操作、条件行为或特殊配置时,才使用自定义光栅Pass

7. Global Resource Exposure

7. 全局资源暴露

Check that:
  • textures and buffers are not exposed globally unless explicitly requested or clearly required by a downstream consumer
  • when global exposure is required in a render graph pass, the implementation uses the appropriate render graph publication mechanism
  • direct command buffer global state mutation is not used as a substitute for render graph resource publication
  • global exposure is not extending resource lifetime unnecessarily or reducing aliasing opportunities without justification
Flag as an issue when:
  • SetGlobalTextureAfterPass
    is used without a clear consumer
  • context.cmd.SetGlobalTexture(...)
    is used inside a render graph pass where render graph resource publication is the appropriate mechanism
  • global exposure is used as a convenience shortcut instead of explicit pass-to-pass wiring
  • hidden coupling is introduced unnecessarily
  • a globally exposed texture may be kept alive longer than necessary due to downstream
    UseGlobalTexture(...)
    or
    UseAllGlobalTextures()
    usage, increasing memory pressure or reducing aliasing opportunities
Prefer:
  • no global exposure by default
  • explicit resource wiring where possible
  • builder.SetGlobalTextureAfterPass(...)
    only when global publication is truly required in render graph
  • resource lifetimes that remain as local and short-lived as possible
检查以下内容:
  • 纹理和缓冲区除非被明确请求或下游消费者明确需要,否则不全局暴露
  • 当Render Graph Pass中需要全局暴露时,实现使用合适的Render Graph发布机制
  • 不使用直接命令缓冲区全局状态突变替代Render Graph资源发布
  • 全局暴露不会无端延长资源生命周期或降低别名优化机会
出现以下情况时标记为问题:
  • 使用
    SetGlobalTextureAfterPass
    但无明确的消费者
  • 在Render Graph Pass中使用
    context.cmd.SetGlobalTexture(...)
    ,而合适的方式应为Render Graph资源发布
  • 将全局暴露用作便捷捷径而非显式的Pass间连接
  • 无端引入隐藏耦合
  • 全局暴露的纹理可能因下游
    UseGlobalTexture(...)
    UseAllGlobalTextures()
    的使用而被长时间保留,增加内存压力或降低别名优化机会
优先采用以下方式:
  • 默认不进行全局暴露
  • 尽可能使用显式资源连接
  • 仅当Render Graph中确实需要全局发布时,才使用
    builder.SetGlobalTextureAfterPass(...)
  • 资源生命周期尽可能保持局部化和短周期

8. Renderer Feature Input Declaration

8. 渲染器特性输入声明

Check that:
  • the
    ScriptableRendererFeature
    and its associated pass declare required pipeline inputs using
    ConfigureInput(...)
    when needed
  • the requested input flags match the feature’s intended behavior and visible resource usage
  • the pass does not rely on pipeline-provided inputs without declaring them when required by the target API pattern
  • unnecessary input requests are not declared by default, especially when they may introduce extra copies, intermediate resources, or avoidable pipeline work
Flag as an issue when:
  • the feature’s pass uses or is clearly intended to use a pipeline-provided input but does not declare it with
    ConfigureInput(...)
  • ConfigureInput(...)
    requests inputs that the feature/pass does not appear to use
  • the declared input flags do not match the intended effect behavior
  • the effect description, code, and declared inputs imply conflicting requirements
  • unnecessary declared inputs may force extra copies, extra pass work, or other avoidable performance costs
Classification guidance:
  • mark as a confirmed issue when the code clearly shows a required input is used but not declared
  • mark as a likely issue when the intended effect implies a required input but the visible code does not fully prove shader/resource usage
  • treat unnecessary input declarations as higher severity when they are likely to introduce additional copies or other measurable runtime cost
检查以下内容:
  • ScriptableRendererFeature
    及其关联Pass在需要时使用
    ConfigureInput(...)
    声明必填管线输入
  • 请求的输入标志与特性的预期行为和可见资源使用匹配
  • 当目标API模式要求时,Pass不依赖管线提供的输入却不声明
  • 默认不声明不必要的输入请求,尤其是可能引入额外复制、中间资源或可避免管线工作的请求
出现以下情况时标记为问题:
  • 特性的Pass使用或明确意图使用管线提供的输入,但未通过
    ConfigureInput(...)
    声明
  • ConfigureInput(...)
    请求了特性/Pass未使用的输入
  • 声明的输入标志与预期效果行为不匹配
  • 效果描述、代码和声明的输入隐含冲突需求
  • 不必要的输入声明可能强制额外复制、额外Pass工作或其他可避免的性能开销
分类指导:
  • 当代码明确显示使用了必填输入但未声明时,标记为已确认问题
  • 当预期效果暗示需要必填输入,但可见代码无法完全证明Shader/资源使用时,标记为潜在问题
  • 当不必要的输入声明可能引入额外复制或其他可测量的运行时成本时,视为更高严重程度

Guardrails

约束规则

The skill must:
  • avoid inventing unsupported APIs
  • distinguish confirmed issues from likely issues
  • prefer minimal targeted fixes over broad rewrites
  • explain why each issue matters
  • flag hidden coupling and unnecessary global state
  • state when the provided code is insufficient for full certainty
本技能必须:
  • 避免编造未被支持的API
  • 区分已确认问题与潜在问题
  • 优先采用最小化定向修复而非大范围重写
  • 解释每个问题的影响原因
  • 标记隐藏耦合和不必要的全局状态
  • 说明提供的代码不足以完全确定情况的场景

Non-Goals

非目标

  • guarantee runtime correctness
  • rewrite the entire renderer feature unless necessary
  • validate unrelated gameplay logic
  • validate shader internals unless directly relevant to pass wiring or binding
  • 保证运行时正确性
  • 重写整个渲染器特性(除非必要)
  • 验证无关的游戏逻辑
  • 验证Shader内部实现(除非与Pass连接或绑定直接相关)

Evaluation Criteria

评估标准

A successful validation should:
  • catch real wiring and API issues
  • identify suspicious but plausible mistakes
  • provide actionable fixes
  • avoid false certainty
  • improve trust in generated render pass code
成功的验证应:
  • 发现真实的连接和API问题
  • 识别看似合理但存在错误的问题
  • 提供可操作的修复方案
  • 避免错误的确定性
  • 提升对生成的渲染Pass代码的信任度

Notes for Future Expansion

未来扩展说明

As new recurring issues are discovered, extend this checklist with additional rules such as:
  • pass ordering / injection point validation
  • resource lifetime and cleanup checks
  • read/write hazard detection
  • unnecessary copies or allocations
  • camera depth/color dependency validation
  • multi-pass dependency validation
  • override material correctness
  • pass configuration
随着发现新的常见问题,可通过添加以下规则扩展检查清单:
  • Pass排序/注入点验证
  • 资源生命周期和清理检查
  • 读取/写入风险检测
  • 不必要的复制或分配
  • 相机深度/颜色依赖验证
  • 多Pass依赖验证
  • 覆盖材质正确性
  • Pass配置