UPL9-17-b——数据类型
UPL9-17-b——数据类型
Compute Shader 中的数据类型
Compute Shader 的数据类型和普通 HLSL(即 Unity Shader)非常接近,
但由于它不走渲染管线,它的重点在于 通用计算与内存访问,因此在类型体系上有一些专门针对 数据并行 和 存储 的扩展
主要分为:
- 标量类型
- 向量类型
- 矩阵类型
- 复合类型
- 纹理类型
- 常量缓冲区
注意:这里只强调常用的类型
标量类型
-
bool:布尔类型 -
uint:32位无符号整形 -
int:32位整形 -
float:32位浮点数,符号:f -
double:64位浮点数 -
half:16位浮点数,符号:h
注意:虽然支持
half,但是由于对齐问题和平台支持问题以及和 C# 数据交互问题(C# 没有half类型),不建议在 ComputeShader 中使用
1 | bool b; // 1byte |
向量类型
内置的向量类型是基于基础数据类型声明的
向量的最大维度不超过 4 维,数据类型可以是任意数值类型(也就是基础数据类型的数值类型)
基本构成:
-
数据类型2 = 数据类型2(n1,n2) -
数据类型3 = 数据类型3(n1,n2,n3) -
数据类型4 = 数据类型4(n1,n2,n3,n4)
1 | float2 f2; float3 f3; float4 f4; |
1 | //二维向量 |
矩阵类型
矩阵类型属于 CG 语言的内置数据类型
矩阵的最大行列不大于 4,不小于 1,数据类型可以是任意数值类型
基本构成:
-
数据类型'n'x'm' = {n1m1, n1m2, n1m3.....} -
数据类型2x2 -
数据类型3x3 -
数据类型4x4
1 | float2x2 |
1 | //矩阵声明示例(以2x3,3x3为例) |
复合类型
结构体
1 | struct 结构体名 |
1 | struct Test |
缓冲区
-
结构体数组
-
只读结构体数组(只读)
StructuredBuffer<T>1
2
3
4
5
6
7
8struct Test
{
float3 position;
float3 velocity;
float lifetime;
};
StructuredBuffer<Test> buffer; -
可读写结构体数组(读写)
1
2
3
4
5
6
7
8struct Test
{
float3 position;
float3 velocity;
float lifetime;
};
RWStructuredBuffer<Test> buffer2;
-
-
字节访问数组
-
低级字节访问数组(只读)
1
ByteAddressBuffer buffer3;
-
可读写字节访问数组(读写)
1
RWByteAddressBuffer buffer4;
-
-
动态追加元素缓冲区(队列式)
适合一开始不知道输出元素个数的场景,可以动态想其中添加内容,只能通过
Append()添加1
AppendStructuredBuffer<float> buffer5;
-
动态消耗元素缓冲区(队列式)
动态从中移除对象,只能通过
Consume()移除1
ConsumeStructuredBuffer<float> buffer6;
纹理类型
1 | Texture1D, Texture2D, Texture3D // 只读普通采样纹理 |
其中,纹理类型后面可以接 <T>,代表该纹理中的像素有多少数据,它由图片的格式和作用决定
例如,对于一张 RGBA 通道格式的贴图,对应的纹理类型就是 RWTexture2D<float4>,
对于一张法线图,只有 RGB 三个通道,对应的纹理类型就是 RWTexture2D<float3>,
如果是一张高度图,只有一个通道数值,则对应的纹理类型就是 RWTexture2D<float>
常量缓冲区
用于将一组常量打包在一起传给 ComputeShader,按块上传数据更高效,驱动可以批量上传并放进高效缓存
1 | cbuffer 自定义常量区名(常用 Params): register(b[寄存器索引]) // ": register(b[寄存器索引])" 部分可省略 |
注意:
后面的寄存器索引相关 :register(b[寄存器索引]) 可省略,省略后Unity会自动分配
如果要写,所以必须是b0 到b13,代表14个常量缓冲区
在编写 Compute Shader 时,应当尽量使用较少的 cbuffer,并注意每个平台的最大常量缓冲区数量
1 | cbuffer Params : register(b0) |
