高级着色器语言参考
高级着色器语言(High-Level Shading Language, HLSL)是DirectX平台上用于编写图形着色器程序的专用编程语言。熟练掌握HLSL对于充分利用现代GPU硬件能力、实现高质量的视觉效果至关重要。本附录提供了HLSL的语法和功能参考,帮助开发者编写高效的着色器程序。
B.1 变量类型
HLSL提供了多种数据类型,用于处理着色器中的不同数据。这些类型包括基本标量类型、向量类型、矩阵类型以及特殊的纹理和采样器类型。
B.1.1 标量类型
标量类型表示单一的数值,是HLSL中最基本的数据类型:
类型 | 描述 | 大小(字节) |
---|---|---|
bool | 布尔值 (true 或 false) | 4 |
int | 32位有符号整数 | 4 |
uint | 32位无符号整数 | 4 |
dword | 32位无符号整数 (uint的别名) | 4 |
half | 16位浮点数 (GPU支持时使用) | 2 |
float | 32位浮点数 | 4 |
double | 64位浮点数 (GPU支持时使用) | 8 |
示例:
hlsl
// 标量类型定义示例
bool isVisible = true;
int count = 42;
uint index = 0xFFFFFFFF;
float alpha = 0.5f;
double preciseValue = 3.14159265359;
B.1.2 向量类型
向量类型表示由多个同类型元素组成的数组。HLSL中向量可以有1到4个元素,最常用的是2、3、4元素向量:
类型 | 描述 |
---|---|
bool1, bool2, bool3, bool4 | 1D, 2D, 3D, 4D布尔向量 |
int1, int2, int3, int4 | 1D, 2D, 3D, 4D整数向量 |
uint1, uint2, uint3, uint4 | 1D, 2D, 3D, 4D无符号整数向量 |
float1, float2, float3, float4 | 1D, 2D, 3D, 4D浮点向量 |
double1, double2, double3, double4 | 1D, 2D, 3D, 4D双精度浮点向量 |
HLSL还提供了一些常用向量类型的别名:
别名 | 等价类型 | 常见用途 |
---|---|---|
float2 | float2 | 2D坐标、纹理坐标 |
float3 | float3 | 3D位置、法线、颜色(RGB) |
float4 | float4 | 齐次坐标、颜色(RGBA) |
vector | float4 | 通用4D向量 |
向量可以通过多种方式进行初始化和访问:
hlsl
// 向量定义和初始化
float4 color = float4(1.0f, 0.5f, 0.3f, 1.0f);
float3 position = float3(0.0f, 1.0f, 0.0f);
float2 texCoord = float2(0.5f, 0.5f);
// 向量分量访问 - 使用索引
float red = color[0];
float height = position[1];
// 向量分量访问 - 使用分量名称
float r = color.r; // color.x 也可以
float g = color.g; // color.y 也可以
float b = color.b; // color.z 也可以
float a = color.a; // color.w 也可以
// 向量分量访问 - 使用掩码提取部分向量
float2 rg = color.rg; // 等价于 float2(color.r, color.g)
float3 bgr = color.bgr; // 等价于 float3(color.b, color.g, color.r)
B.1.3 矩阵类型
矩阵类型表示由行和列组成的二维数组。HLSL支持1x1到4x4的各种矩阵尺寸:
类型 | 描述 |
---|---|
bool1x1 到 bool4x4 | 布尔值矩阵 |
int1x1 到 int4x4 | 整数矩阵 |
float1x1 到 float4x4 | 浮点数矩阵 |
double1x1 到 double4x4 | 双精度浮点数矩阵 |
常用的矩阵类型别名:
别名 | 等价类型 | 常见用途 |
---|---|---|
matrix | float4x4 | 通用矩阵 |
float3x3 | float3x3 | 旋转变换、法线变换 |
float4x4 | float4x4 | 模型视图投影变换 |
矩阵的定义和使用:
hlsl
// 矩阵定义和初始化
float4x4 modelMatrix = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
// 或者使用单一值初始化对角矩阵
float4x4 identity = float4x4(1.0f);
// 矩阵元素访问
float m00 = modelMatrix[0][0]; // 第一行第一列
float m12 = modelMatrix[1][2]; // 第二行第三列
// 矩阵行访问
float4 firstRow = modelMatrix[0];
// 矩阵乘法
float4x4 viewMatrix = GetViewMatrix();
float4x4 viewModelMatrix = mul(modelMatrix, viewMatrix); // 注意乘法顺序
// 向量与矩阵乘法
float4 worldPosition = float4(position, 1.0f);
float4 viewPosition = mul(worldPosition, viewMatrix);
HLSL中的矩阵默认是行优先的,这一点与数学上常用的列优先表示有所不同。在涉及矩阵乘法时需要特别注意顺序。
B.1.4 数组
HLSL支持一维和多维数组,用于存储同类型的多个元素:
hlsl
// 一维数组定义
float4 colors[3] = {
float4(1.0f, 0.0f, 0.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 1.0f),
float4(0.0f, 0.0f, 1.0f, 1.0f)
};
// 多维数组定义
float heights[2][3] = {
{ 0.0f, 1.0f, 2.0f },
{ 3.0f, 4.0f, 5.0f }
};
// 数组元素访问
float4 redColor = colors[0];
float heightValue = heights[1][2]; // 值为5.0f
在着色器常量缓冲区中,数组的大小必须在编译时确定,但DirectX 11.1及以上版本支持动态索引数组元素,这在某些应用场景中非常有用。
B.1.5 结构体
结构体允许将不同类型的变量组合成一个单一的复合类型: