ShaderX2翻译五 连载中
Type Modifiers
在HLSL中有一些可选的标识符你可能会在你的着色器中使用,最熟悉的是const类型标识符被用在指定在着色器代码中不会改变的变量上.如果使用这些变量放在等号左边时,会编译错误.row_major 和 col_major type类型标识符.能够指明希望矩阵存储在硬件的常量存储区.row_major类型指明矩阵中的行将会存储在常量寄存器中.同样的,col_major指明矩阵中的每列将会被存储在常量寄存器中.
Initializers
就如我们在先前的实例中显示的,我们能使用C的方式在声明的时候初始化变量
float2x2 fMat = {3.0f,5.0f, // row 1
2.0f,1.0f}; // row 2
float4 vPos = {3.0f,5.0f,2.0f,1.0f};
float fFactor =0.2f;
Working with Vedors
在HLSL中,我们可能要执行向量数学运算.很幸运,大多数算法都很直观.例如标准的2元操作被应用在每个要素中:
float4 vTone = vBrightness * vExposure;
假设vBrightness 和 vExposure都是float4类型的,上面等价于下面
float4 vTone;
vTone.x = vBrightness.x * vExposure.x;
vTone.y = vBrightness.y * vExposure.y;
vTone.z = vBrightness.z * vExposure.z;
vTone.w = vBrightness.w * vExposure.w;
注意这不是vBrightness 和 vExposure的点积.另外,使用这种方法的矩阵相乘不等于矩阵相乘.点积相乘和矩阵相乘被应用是通过内部函数mul(),我们将在章后面讨论
Construdors
另一个HLSL语言特性你经常遇到的是构造函数,像c++一样但是有些复杂类型需要处理.构造函数使用例子:
float3 vPos = float3(4.0f, 1.0f, 2.0f);
float fDiffuse = dot(vNormal, float3(1.0f, 0.0f, 0.0f));
float4 vPack = float4(vPos, fDiffuse);
构造函数通常在着色器编写者想临时定义内部变量时被使用(如上面的dot(vNormal, float3(1.0f, 0.0f, 0.0f)))或者着色器编写者想包装小的数据类型在一起(如上面的float4(vPos, fDiffuse)).在这个例子中,类型为float4的构造函数把类型为float3和float返回为float4.
Type Casting
为了帮助着色器编写高效率的代码,相似HLSL类型计算行为是很好的想法.类型转换经常发生在为了提高或降低变量来匹配等号另一边的变量.例如,在下面的例子中,float 0.0 在初始化vResult时被转换为一个float4 {0.0f , 0.0f , 0.0f , 0.0f }
float4 vResult = 0.0f;
相似类型转换能够发生当赋值的是高维数的数据类型比如matrix,被赋值的是一个低维数的数据类型.在这个例子中,额外的数据被有效的忽略,例如,我们可以写如下代码
float3 vLight;
float fFinal, fColor;
fFinal = vLight * fColor;
在这个例子中,vLight 只使用了第一个要素和标量float fColor相乘 结果被计算为float类型.在这个例子中,fFinal等价于vLight.x * fColor.
HLSL类型计算规则:
|
转换类型 |
转换行为 |
|
标量->标量 |
总是有效.当bool类型转换到int类型或float类型时,false被认为0,true被认为1.当int类型或float类型转换为bool类型时,0被认为false,非零被认为true.当float类型转换为int类型时,去除小数部分.这很像c的行为 |
|
标量-vectorr |
总是有效.拷贝标量来填充vector |
|
标量-矩阵 |
总是有效.拷贝标量来填充vector |
|
标量-结构体 |
拷贝标量来填充vector |
|
Vector-标量 |
总是有效.选择vector第一个要素 |
|
Vector-vector |
目标vector不能比源目标vector大. |
|
Vector-矩阵 |
两个大小必须相等 |
|
Vector –结构体 |
如果结构体不比vector大就有效 |
|
矩阵-标量 |
总是有效的,选择矩阵最左上的要素 |
|
矩阵-vector |
两个大小必须相等 |
|
矩阵-矩阵 |
在相同的维数下目标矩阵不能比源矩阵大. |
|
矩阵-结构体 |
两个大小必须相等 |
|
结构体-标量 |
结构体至少包含一个成员 |
|
结构体-vector |
结构体大小不比vector小 |
|
结构体-矩阵 |
结构体大小不比矩阵小. |
|
结构体-对象t |
结构体必须包含至少一个成员.成员的类型必须和对象相符 |
|
结构体-结构体 |
目标结构体不能比源结构体大. |
Strudures
就如我们在第一个着色器例子中显示的,很方便在HLSL着色器中定义结构体.例如一些着色器编写者将会在他们的顶点着色器代码中定义一个输出结构体并且使用结构体作为顶点着色器主函数的返回类型.(很少对像素着色器这样做,因为大多数顶点着色器值返回一个float4作为输出)一个结构体例子from NPR金属着色器,我们将会在稍后讨论
struct VS_OUTPUT
{
float4 Pos : POSITION;
float3 View : TEXCOORD0;
float3Normal: TEXCOORD1;
float3 Light1: TEXCOORD2;
float3 Light2: TEXCOORD3;
float3 Light3: TEXCOORD4;
};
在HLSL中使用结构体也遵行上面的类型转换规则
浙公网安备 33010602011771号