1.1 标量类型
1. bool: True or false .Note that the HLSL provides the true and false keywordslike in C++.
2. int: 32-bit signedinteger.
3. half: 16-bit-floatingpoint number.
4. float: 32-bit-floatingpoint number.
5. double: 64-bit-floatingpoint number.
1.2 向量类型
1.2.1 向量种类
1. float2: 2D vector, wherethe components are of type float.
2. float3: 3D vector, wherethe components are of type float.
3. float4: 4D vector, wherethe components are of type float.
除了float之外,我们也可以用其它基本类型来定义向量,如bool2,int3.总之向量的表达类型是TypeN,其中N属于(2,4).
1.2.2向量的初始化
float3 v = {1.0f, 2.0f, 3.0f};
float2 w = float2(x, y);
float4 u = float4(w, 3.0f, 4.0f); // u= (w.x, w.y, 3.0f, 4.0f)
1.2.3向量的访问
用数组语法:
如:vec[i] = 2.0f;
用字母语法,xyzw,rgba。
如:
vec.x = vec.r = 1.0f;
vec.y = vec.g = 2.0f;
vec.z = vec.b = 3.0f;
vec.w = vec.a = 4.0f;
1.2.4 向量的替换调配(swizzles)
为了避免向量赋值时的复杂,HLSL采取以Swizzles的方法,如下:
float4 u = {1.0f, 2.0f, 3.0f, 4.0f};
float4 v = {0.0f, 0.0f, 5.0f, 6.0f};
v = u.wyyx; // v = {4.0f, 2.0f, 2.0f,1.0f}
v = u.wzyx; // v = {4.0f, 3.0f, 2.0f,1.0f}
v.xy = u; // v = {1.0f, 2.0f, 5.0f,6.0f}
1.3 矩阵类型
1.3.1矩阵的定义语法
Typem×n xxx;如:
1. float2x2: 2 × 2 matrix, where theentries are of type float.
2. half3x3: 3 × 3 matrix, where theentries are of type half.
3. int4x4: 4 × 4 matrix, where theentries are of type int.
4. bool3x4: 3 × 4 matrix, where theentries are of type bool.
1.3.2 矩阵的访问
用数组语法:
M[i] [j] = value;
用成员变量语法:
M._11 = M._12 = M._13 = M._14 = 0.0f;
M._21 = M._22 = M._23 = M._24 = 0.0f;
M._31 = M._32 = M._33 = M._34 = 0.0f;
M._41 = M._42 = M._43 = M._44 = 0.0f;
或者
M._m00 = M._m01 = M._m02 = M._m03 =0.0f;
M._m10 = M._m11 = M._m12 = M._m13 =0.0f;
M._m20 = M._m21 = M._m22 = M._m23 =0.0f;
M._m30 = M._m31 = M._m32 = M._m33 =0.0f;
整行的访问:
float3 N = normalize(pIn.normalW);
float3 T = normalize(pIn.tangentW -dot(pIn.tangentW, N)*N);
float3 B = cross(N,T);
float3x3 TBN;
TBN[0] = T; // sets row 1
TBN[1] = B; // sets row 2
TBN[2] = N; // sets row 3
1.3.3 矩阵的初始化
float2x2 fxx =float2x2(1.0f,2.0f,3.0f,4.0f);
int2x2 ixx ={1,2,3,4};
1.3.4 数组向量的另类定义
vector u = {1.0f, 2.0f, 3.0f, 4.0f};
matrix M; // 4x4 matrix
1.4 数组
float M[4] [4] ;
half p[4] ;
float3 v[12] ; // 12 3D vectors
1.5 结构体
HLSL中的结构体类似C中的结构体,其不能含有函数成员,访问成员只需要根据下标即可。
struct SurfaceInfo
{
float3 pos;
float3 normal;
float4 diffuse;
float4 spec;
};
SurfaceInfo v;
litColor += v.diffuse;
dot(lightVec, v.normal);
float specPower = max(v.spec.a, 1.0f);
1.6 跟变量相关的关键字
typedef,static,uniform,extern,const
用法都和C++中的类似,当变量声明为static的时候说明该变量是内部变量,在着色器程序外不可见。非静态的全局变量默认都是extern的,即可以被着色器程序外的程序访问。
1.7 强制类型转化
HLSL中的类型转换非常的灵活,如下所示:
float f = 5.0f;
float4x4 m = (float4x4)f; // copy finto each entry of m.
float3 n = float3(...);
float3 v = 2.0f*n - 1.0f;
这里的1.0f其实被转换成了(1.0f,1.0f,1.0f);
2.1语法
2.1.1 return
return (expression);
2.1.2 if-else语句
if(condition)
{}
……………………………………
if(condition)
{}
else
{}
2.1.3 for循环
for(initial;condition;increament)
{}
2.14 while
while(condition)
{}
2.1.5do-while
do
{}while(condition);
2.2 函数
2.2.1 HLSL函数的特点
类似C++,参数按值传递(不支持引用和指针),不支持递归,函数总是内联
2.2.2 函数的例子
bool foo(in const bool b, out int r1,inout float r2)
{
if(b)// test input value
{
r1= 5; // output a value through r1
}
else
{
r1 = 1; // output a value through r1
}
//sincer2 is inout we can use it as an input value and also output a value through it
r2= r2 * r2 * r2;
returntrue;
}
这里需要说明的是关键字in,out,inout
in:默认的,可以不加。表示必须传递参数值的
out:表示该参数是函数的一个返回值,仅仅用做输出,不能用作输入
inout:既可以输入又可以输出
在定义HLSL不管是函数中输入的参数变量或者返回的变量的时候经常要用到诸如xxx:POSITION的形式,这里是HLSL中变量与众不同的一个地方。’:’后面的叫做叫做语义,它用来描述变量的一些信息,说到本质上语义是规定着色器变量与硬件之间的关系,例如POSITION指定这个变量是被用在位置相关的寄存器。
3.1 顶点着色器的语义
语义都有输入跟输出的部分,关于顶点的输入和输出的见下:
Input |
Description |
Type |
BINORMAL[n] |
Binormal |
float4 |
BLENDINDICES[n] |
Blend indices |
uint |
BLENDWEIGHT[n] |
Blend weights |
float |
COLOR[n] |
Diffuse and specular color |
float4 |
NORMAL[n] |
Normal vector |
float4 |
POSITION[n] |
Vertex position in object space. |
float4 |
POSITIONT |
Transformed vertex position. |
float4 |
PSIZE[n] |
Point size |
float |
TANGENT[n] |
Tangent |
float4 |
TEXCOORD[n] |
Texture coordinates |
float4 |
Output |
Description |
Type |
COLOR[n] |
Diffuse or specular color |
float4 |
FOG |
Vertex fog |
float |
POSITION[n] |
Position of a vertex in homogenous space. Compute position in screen-space by dividing (x,y,z) by w. Every vertex shader must write out a parameter with this semantic. |
float4 |
PSIZE |
Point size |
float |
TESSFACTOR[n] |
Tessellation factor |
float |
TEXCOORD[n] |
Texture coordinates |
float4 |
从上可以看出变量后面的语义不是随便乱加的,首先它指明了变量的用处,其次针对输入和输出都有专门限制的语义,我们不能把一个用作输入的语义来用作输出。
n是寄存器的索引值,最大值依赖于硬件的支持。如POSITION1.
3.2 像素着色器的语义
Input |
Description |
Type |
COLOR[n] |
Diffuse or specular color. |
float4 |
TEXCOORD[n] |
Texture coordinates |
float4 |
VFACE |
Floating-point scalar that indicates a back-facing primitive. A negative value faces backwards, while a positive value faces the camera. |
float |
VPOS |
The pixel location (x,y) in screen space. To convert a Direct3D 9 shader (that uses this semantic) to a Direct3D 10 shader, see Direct3D 9 VPOS and Direct3D 10 SV_Position) |
float2 |
Output |
Description |
Type |
COLOR[n] |
Output color |
float4 |
DEPTH[n] |
Output depth |
float |
3.3 例子
void SkyVS(float3posL : POSITION0,out float4 oPosH : POSITION0,out float3 oEnvTex : TEXCOORD0) { oPosH = mul(float4(posL, 1.0f),g_matWVP).xyww; oEnvTex = posL; }
/////////////////////////////////
struct OutputVS { float4 posH : POSITION0; float2 tex0 : TEXCOORD0; //D3D fills in for point sprites. float size : PSIZE; //In pixels. }; OutputVSSnowVS(float3 posL : POSITION0, float3 vel : TEXCOORD0, float size : TEXCOORD1, float initialT:TEXCOORD2, float lifeT :TEXCOORD3) { OutputVS outVS = (OutputVS)0; float t = g_Time - initialT; posL = posL + vel * t + 0.5f * g_Acc *t * t; outVS.posH = mul(float4(posL, 1.0f),g_matWVP); outVS.size = 0.0035f * g_ViewportHeight* size; return outVS; } float4 SnowPS(float2tex0 : TEXCOORD0) : COLOR { return tex2D(TexS, tex0); }
【1】Introduction to 3D Game Programming with DirectX11
【2】微软DirectX Sampler中的Semantics (DirectX HLSL)