GameTech/URP 渲染实战

案例 2.6兼容与不兼容 SRP Batcher 的 Shader入门

目标:对比两个功能完全相同的 Shader,一个兼容 SRP Batcher,一个不兼容,并学会检查兼容性。

Assets/Cookbook/Ch02/SrpBatcherCompatible.shader(节选:cbuffer)
// 纹理对象本身不进 CBUFFER,但它的 _ST(缩放平移)是数值,要进
TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
    float4 _BaseMap_ST;
    half4  _BaseColor;
CBUFFER_END
// 纹理对象本身不进 CBUFFER,但它的 _ST(缩放平移)是数值,要进
uniform sampler2D _BaseMap;
// CBUFFER_START(UnityPerMaterial)
uniform vec4 _BaseMap_ST;
uniform vec4 _BaseColor;
// CBUFFER_END
Assets/Cookbook/Ch02/SrpBatcherBroken.shader(节选:broken)
TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
float4 _BaseMap_ST;     // ✗ 不在 UnityPerMaterial 里
half4  _BaseColor;      // ✗ 不在 UnityPerMaterial 里
uniform sampler2D _BaseMap;
uniform vec4 _BaseMap_ST;     // ✗ 不在 UnityPerMaterial 里
uniform vec4 _BaseColor;      // ✗ 不在 UnityPerMaterial 里

两个 Shader 都能正常编译、正常显示,区别只在声明位置。选中 Shader 资产,Inspector 里会显示 “SRP Batcher: compatible” 或 “not compatible” 以及原因。本书在批处理模式下读取了同一个检查结果(Shader Inspector 背后的接口),得到的原因原文是:

SrpBatcherCompatible : OK
SrpBatcherBroken     : Material property is found in another cbuffer than "UnityPerMaterial" (_BaseColor)
LightModeDemo        : OK   (三个 Pass 共用同一个 UnityPerMaterial)

常见的不兼容原因:

验证是否真正生效:打开 Frame Debugger,选中某个绘制事件,右侧会显示它是否属于一个 SRP Batch,以及“为什么没有和上一个合批”的原因(例如 “Node use different shader keywords”——不同的关键字组合是不同的 Shader 变体,无法合进同一个 SRP Batch)。第 29 章会系统地讨论 SRP Batcher、GPU Instancing 与静态合批的取舍。