关于 validate-urp-render-graph-renderer-feature
这项审查技能面向 Unity 6+ URP Render Graph 渲染器功能及其 Pass,帮助开发者发现实现问题,并给出针对性修复、代码片段和缺失信息。
主要功能
- 01检查材质与纹理绑定
- 02审查 Render Graph 资源连接
- 03验证静态渲染函数结构
- 04检查纹理描述符选择
- 05评估复制与 Blit 辅助方法
- 06审查全局资源与输入声明
适用场景
- 01审查 AI 生成的渲染器功能代码
- 02集成前验证自定义功能
- 03诊断 Pass 设置与资源连接
- 04检查复制或 Blit 的实现选择
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ unity-technologies/ skills --skill validate-urp-render-graph-renderer-feature安装后在 Claude Code 中输入/validate-urp-render-graph-renderer-feature确认已加载。
详细介绍
技能:验证 Unity URP Render Graph Renderer Feature
目的
检查 Unity 6+ URP Render Graph ScriptableRendererFeature 及其关联 Pass 实现,确认是否存在与材质绑定、资源连接、Render Graph 纹理创建、静态渲染函数结构、全局资源公开以及 API/版本使用相关的正确性问题。
使用时机
在以下情况下使用此技能:
- 检查 AI 生成的 Unity URP Render Graph Renderer Feature 代码
- 集成自定义
ScriptableRendererFeature前进行验证 - 检查常见的 Render Graph 资源连接和 Pass 设置错误
- 诊断看似合理但可疑的 Render Graph Pass 实现
- 检查自定义光栅化/Blit/复制 Pass 是否使用了最合适的 Render Graph 辅助 API
输入
此技能应接收:
- Unity 版本
- URP 版本
- 待检查的 Render Graph Renderer Feature 代码
ScriptableRendererFeature- 关联的 Pass 代码
- 或两者
- 预期行为
- 预期输入/输出(如已知)
- 可选约束
- 项目约定
- 必需的 Pass 类型
- 已知资源
- 必需的材质/着色器属性
输出格式
此技能必须按以下结构返回结果:
1. 验证摘要
对实现进行简短的整体评估。
2. 已确认的问题
有提供的代码直接支持的具体问题。
3. 可能的问题 / 风险假设
取决于缺失上下文或信息不完整的潜在问题。
4. 建议的修复方案
针对每个问题提供精简且有针对性的修复方案。
5. 修正后的代码片段
适用时提供简短的修正代码片段。
6. 缺失信息
为提高代码验证的可信度所需的任何信息。
验证清单
1. 材质绑定
检查以下内容:
- 材质声明清晰
- 需要时正确公开序列化材质
- 材质正确传递给 Pass
- 在需要时处理空值
- 声明的材质确实得到使用
- 执行前已绑定所有必需的材质输入
- 着色器需要主输入纹理时,已显式绑定该纹理
- 辅助纹理和参数纹理也已显式绑定
- 纹理/属性绑定与着色器预期的属性名称一致
在以下情况下标记为问题:
- 声明或传入了材质,但实际并未使用
- 只绑定了次要纹理或参数,却遗漏了主输入纹理
- Pass 绑定了遮罩/噪声/辅助纹理,却未绑定主颜色/输入纹理
- 假定必需的着色器属性存在,却未对其进行设置
- 属性名称不一致或含义模糊
- Pass 模式要求显式绑定,但代码依赖隐式主纹理绑定
优先采用以下模式:
- 清晰地创建或指定材质
- 显式绑定主源纹理
- 显式绑定所有辅助纹理
- 属性名称保持一致且明确
- 处理或报告空值或缺失资源的情况
2. 纹理资源连线
检查以下内容:
- 采样/读取纹理、写入目标和辅助纹理是否明确区分
- 与
UseTexture(...)搭配使用的纹理是否适合读取 - 与
SetRenderAttachment(...)搭配使用的纹理是否适合作为写入目标 - 是否混淆源、目标和辅助资源
- 是否显式连线所有预期使用的纹理
- 涉及材质时,纹理属性名称是否明确且一致
- 实现是否虚构了纹理可用性
- 是否显式处理多纹理资源的使用,而非隐式处理
在以下情况下,标记为问题:
- 原本用于输入/读取的纹理被用作写入目标,且没有合理说明
- 混淆了目标/写入纹理和采样输入
- 使用了辅助纹理,却未明确说明其来源或如何连线
- 通道设置中缺少必需的纹理资源
- 读写资源的角色不明确或不一致
3. 执行结构/静态渲染函数
检查以下内容:
- 渲染函数是否声明为
static - 执行结构是否符合目标通道类型和 API 风格
- 通道数据是否正确传入执行逻辑
- 是否在正确的阶段访问资源
- 执行逻辑是否符合预期的渲染通道行为
- 渲染函数使用的每个
PassData字段,是否都在当前录制的通道设置过程中被显式赋值 - 实现是否依赖默认值或先前赋值的
PassData状态 - 存储在
PassData中的资源句柄,是否针对当前帧/通道录制重新赋值,而不是沿用之前的值
在以下情况下,标记为问题:
- 渲染函数不是
static - API 模式要求静态渲染函数,但实现使用了实例方法
- 通过实例状态而非静态函数提供的通道数据/上下文访问通道数据或必需资源
- 执行流程不符合预期的渲染图或通道执行模式
- 渲染函数读取了某个
PassData字段,但该字段在通道设置期间没有得到明确赋值 - 只重新赋值了部分
PassData字段,其他字段可能保留此前复用对象中的过期值 PassData中存储的资源句柄可能因未完整重新赋值而沿用上一帧或上一通道的值- 每次录制时未完整初始化通道数据,导致可能使用已失效或过期的句柄
建议:
- 在每次
RecordRenderGraph(...)调用期间,显式赋值该通道使用的每个PassData字段 - 将
PassData视为每次录制的临时数据,而非持久状态 - 避免只初始化部分字段的池化通道数据对象
4. 渲染图描述符验证
检查以下事项:
- 当可以直接使用适当的图派生描述符时,实现不会默认创建新的
TextureDesc - 当纹理应与当前活动渲染目标匹配时,描述符会优先从相关渲染图资源获取,例如:
resourceData.activeColorTexture.GetDescriptor(renderGraph)- 或其他适当的现有图支持资源
- 从源获取描述符后,只修改确实需要不同的字段
- 有意保留或覆盖名称、深度位数、格式和 MSAA 等描述符字段
- 任何手动重建描述符数据的做法都有具体需求作为依据
出现以下情况时,请标记为问题:
- 代码未先尝试重用图派生描述符,就创建新的
TextureDesc - 默认情况下,将宽度和高度手动复制到新的描述符结构中
- 有可用且更准确的渲染图派生描述符时,仍将
cameraTargetDescriptor用作主要来源 - 意外丢弃 MSAA、图形格式或与当前活动渲染目标兼容性等重要属性
- 将重建描述符作为方便的捷径,而非与源资源存在必要差异的做法
首选规则:
- 除非无法直接使用图派生描述符,或纹理必须有意与源资源不同,否则不要创建新的
TextureDesc。
首选模式:
- 从相关渲染图资源获取描述符
- 只修改必须更改的字段
- 尽可能根据派生描述符创建纹理
示例:
首选
RenderTextureDescriptor desc = resourceData.activeColorTexture.GetDescriptor(renderGraph);
desc.depthBufferBits = 0;
desc.name = "New name";
// other desired paramters
passData.targetTexture = renderGraph.CreateTexture(desc);
5. 简化手动复制通道
检查以下事项:
- 当内置 Render Graph 辅助方法足以胜任时,不会将简单的纹理复制操作实现为完整的自定义光栅通道
- 仅从一个纹理读取并原样写入另一个目标的通道,会在适当情况下予以简化
- 实现会根据目标 API/平台环境,优先使用最合适的内置辅助方法
- 如果当前环境应优先使用兼容性更好的
AddBlitPass(...)重载,则默认不会推荐AddCopyPass(...)
出现以下情况时,请标记为问题:
- 光栅通道的唯一作用是将一个纹理复制到另一个纹理
- 通道不使用材质,也不执行自定义处理
- 渲染函数仅执行简单的 Blit/复制操作
- 使用完整的自定义光栅通道,而内置复制/Blit 辅助方法可以更直接地表达相同行为
优先使用:
- 对于简单的类复制操作,在这是推荐且兼容性更好的路径时,使用适当的
AddBlitPass(...)重载 - 仅当
AddCopyPass(...)明确适用于目标 API/平台环境且受其支持时,才使用它 - 仅当复制需要额外逻辑或非简单行为时,才使用自定义光栅通道
6. 简化手动 Blit 通道
检查以下事项:
- 如果
renderGraph.AddBlitPass(...)能更直接地表达相同行为,就不会将简单的全屏材质 Blit 实现为自定义光栅通道 - 只有在确实需要额外逻辑或非简单行为时,才会使用自定义光栅通道执行 Blit
- 简单的源到目标材质 Blit 会使用最直接的可用渲染图辅助方法
出现以下情况时,请标记为问题:
- 光栅通道读取一个源纹理并写入一个目标纹理
- 通道使用材质,但没有额外的自定义通道逻辑
- 渲染函数仅执行简单的全屏 Blit
renderGraph.AddBlitPass(...)可以更清晰地实现等效结果
优先使用:
- 对于简单的全屏材质 Blit,使用
renderGraph.AddBlitPass(...) - 仅当确实需要额外逻辑、多项操作、条件行为或特殊设置时,才使用自定义光栅通道
7. 全局资源公开
检查以下内容:
- 除非明确要求,或下游使用方显然需要,否则不要全局公开纹理和缓冲区
- 如果渲染图通道需要全局公开资源,实现应使用适当的渲染图发布机制
- 不要用直接修改命令缓冲区全局状态的方式,替代渲染图资源发布
- 不要在没有充分理由的情况下,通过全局公开不必要地延长资源生命周期或减少别名机会
以下情况应标记为问题:
- 使用了
SetGlobalTextureAfterPass,但没有明确的使用方 - 在渲染图通道中使用了
context.cmd.SetGlobalTexture(...),而适当的机制应是渲染图资源发布 - 将全局公开作为便利捷径,而不是显式连接通道间的资源
- 不必要地引入了隐式耦合
- 由于下游使用
UseGlobalTexture(...)或UseAllGlobalTextures(),全局公开的纹理可能会比必要时间更长地保持存活,从而增加内存压力或减少别名机会
优先采用:
- 默认不进行全局公开
- 尽可能显式连接资源
- 仅在渲染图确实需要全局发布时使用
builder.SetGlobalTextureAfterPass(...) - 尽可能保持资源生命周期局部且短暂
8. Renderer Feature 输入声明
检查以下内容:
ScriptableRendererFeature及其关联通道在需要时,使用ConfigureInput(...)声明所需的管线输入- 请求的输入标志与该 Feature 的预期行为和可见资源使用情况相符
- 当目标 API 模式要求声明时,通道不会依赖管线提供的输入却不作声明
- 默认情况下不声明不必要的输入,尤其是那些可能引入额外复制、中间资源或可避免的管线工作量的输入
以下情况应标记为问题:
- Feature 的通道使用或显然打算使用管线提供的输入,却没有通过
ConfigureInput(...)声明 ConfigureInput(...)请求了 Feature/通道似乎并未使用的输入- 声明的输入标志与预期的效果行为不符
- 效果说明、代码和已声明的输入暗示了相互冲突的需求
- 不必要的输入声明可能导致额外复制、额外通道工作或其他可避免的性能开销
分类指导:
- 当代码清楚表明使用了必需输入,但未声明该输入时,标记为已确认的问题
- 当预期效果意味着需要某项输入,但可见代码无法完全证实着色器/资源的使用情况时,标记为可能的问题
- 如果不必要的输入声明可能引入额外复制或其他可测量的运行时开销,应将其视为更严重的问题
约束
此技能必须:
- 避免臆造无依据的 API
- 区分已确认的问题与可能的问题
- 优先采用最小化、针对性的修复,而不是大范围重写
- 解释每个问题的重要性
- 标记隐式耦合和不必要的全局状态
- 在所提供的代码不足以完全确定时明确说明
非目标
- 保证运行时正确性
- 除非确有必要,否则不重写整个 Renderer Feature
- 验证无关的游戏逻辑
- 除非与通道连接或绑定直接相关,否则不验证着色器内部逻辑
评估标准
成功的验证应当:
- 发现实际的连接和 API 问题
- 找出可疑但合理的错误
- 提供可执行的修复建议
- 避免表达不切实际的确定性
- 提升对生成的渲染通道代码的信任
未来扩展注意事项
发现新的常见问题后,请扩展此检查清单,添加以下规则:
- 验证通道顺序/注入点
- 检查资源生命周期和清理
- 检测读写冲突
- 检查不必要的复制或分配
- 验证相机深度/颜色依赖
- 验证多通道依赖
- 检查替代材质是否正确
- 通道配置
评论
支持 Markdown