常量缓冲区 CBuffer
在 Unity 中,CBuffer 是通过 HLSL 中的CBUFFER_START和CBUFFER_END宏进行封装,背后在不同平台映射为常量缓冲区,其原理查看->[计算机图形学/HLSL/常量缓冲区 CBuffer](计算机图形学/HLSL/常量缓冲区 CBuffer)。
- 语法:
CBUFFER_START(缓冲区名称)
变量类型 _变量名;
CBUFFER_END各种常量缓冲区
Unity内置常量缓冲区
Unity预定义了一些内置常量缓冲区的名称,直接使用这些名称可以让Unity自动填充对应的全局变量:
UnityPerCamera:相机相关参数
_WorldSpaceCameraPos,_ProjectionParams等UnityPerDraw:物体变换矩阵
unity_ObjectToWorld,unity_WorldToObject等UnityPerFrame:全局渲染参数
_Time,_SinTime等UnityLighting:光照参数(旧版内置管线)UnityFog:雾效参数
// 示例:使用内置缓冲区名称
CBUFFER_START(UnityPerDraw)
float4x4 unity_ObjectToWorld;
float4x4 unity_WorldToObject;
CBUFFER_END自定义缓冲区:材质专属变量
在URP/HDRP管线中,为材质属性声明专用缓冲区时使用固定使用名称 UnityPerMaterial
这是Unity的约定,确保材质属性被正确分组优化。
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float4 _Color;
float _Glossiness;
CBUFFER_END完全自定义缓冲区
若无特殊需求,也可任意命名(仅限非材质属性):
CBUFFER_START(MyCustomBuffer)
float _CustomValue;
int _CustomID;
CBUFFER_END- 注意:
- 此类缓冲区需要手动更新数据(通过脚本或
MaterialPropertyBlock) - 不会享受SRP Batcher优化
- 此类缓冲区需要手动更新数据(通过脚本或
宏定义解析
在Unity中,声明CBuffer的宏有CBUFFER_START和CBUFFER_END,在文件Packages/com.unity.render-pipelines.core/ShaderLibrary/API/XXX.hlsl(XXX为图形API名称)中定义,具体定义如下:
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };可见在Unity中定义CBuffer实际上是与HLSL等效的:
cbuffer name {
变量类型 _变量名;
}不过值得注意的是在API GLES2中该宏定义为空,意味着在GLES2中使用该宏定义CBuffer会降级为普通的Uniform,即Built-In的写法。可见Unity之所以整出这两个宏,不过是为了兼容GLES2罢了。