1.4怎么用HLSL着色器

1.4怎么用HLSL着色器

应用程序中对HLSL着色器的使用分为以下步骤:

1. 加载(称为编译更为妥当)着色器代码;

2. 创建(顶点/像素)着色器;

3. 对着色器中的变量进行赋值,完成应用程序和着色器之间的通信。

4. 把着色器设定到渲染管道中;

本例使用的着色器是一个顶点着色器,因此我们将通过顶点着色器的使用来讲解着色器的使用过程,像素着色器的使用过程与此大同小异,二者之间仅有些微差别。

1.4.1声明全局变量

IDirect3DVertexShader9* BasicShader = 0; //顶点着色器指针

ID3DXConstantTable* BasicConstTable = 0; //常量表指针

D3DXHANDLE WVPMatrixHandle = 0;

D3DXHANDLE ColorHandle = 0;

ID3DXMesh* Teapot = 0; //指向程序中D3D茶壶模型的指针

1.4.2编译着色器

通过D3DXCompileShaderFromFile函数从应用程序外部的文本文件BasicHLSL.txt中编译一个着色器:

//编译后的着色器代码将被放在一个buffer中,可以通过ID3DXBuffer接口对其进行访问,之后的着色器将从这里创建

ID3DXBuffer* shaderBuffer = 0;

//用于接受错误信息

ID3DXBuffer* errorBuffer = 0;

//编译着色器代码

D3DXCompileShaderFromFile("BasicHLSL.txt", //着色器代码文件名

0,

0,

"SetColor", //入口函数名称

"vs_1_1", //顶点着色器版本号

D3DXSHADER_DEBUG,// Debug模式编译

&shaderBuffer, //指向编译后的着色器代码的指针

&errorBuffer,

&BasicConstTable); //常量表指针

1.4.3创建着色器

应用程序通过CreateVertexShader创建一个顶点着色器,注意使用了上一步得到的shaderBuffer

g_pd3dDevice->CreateVertexShader((DWORD*)shaderBuffer->GetBufferPointer(), &BasicShader);

1.4.3对着色器中的变量进行赋值

1.3.4节说到着色器的全局变量在应用程序中赋值而在着色器程序中使用,这是应用程序和着色器通信的关键所在,这里就具体说明赋值过程。

着色器中的全局变量在编译后都被放在一个叫常量表的结构中,我们可以使用ID3DXConstantTable接口对其进行访问,参照1.4.1中编译着色器函数D3DXCompileShaderFromFile的最后一个参数,该参数即返回了指向常量表的指针。

对一个着色器中变量进行赋值的步骤如下:

1. 通过变量名称得到指向着色器变量的句柄;

还记得在BasicHLSL.x着色器文件中我们声明的两个全局变量吗:

matrix WVPMatrix;

vector color;

我们在应用程序中相应的声明两个句柄:

D3DXHANDLE WVPMatrixHandle = 0;

D3DXHANDLE ColorHandle = 0;

然后通过变量名得到分别得到对应的两个句柄:

WVPMatrixHandle = BasicConstTable->GetConstantByName(0, "WVPMatrix");

ColorHandle = BasicConstTable->GetConstantByName(0, "color");

2. 通过句柄对着色器变量进行赋值;

我们可以先设置各变量为默认值:

BasicConstTable->SetDefaults(g_pd3dDevice);

之后,可以使用ID3DXConstantTable::SetXXX函数对各个变量进行赋值:

HRESULT SetXXX(

LPDIRECT3DDEVICE9 pDevice,

D3DXHANDLE hConstant,

XXX value

);

其中XXX代表变量类型,例如Matrix类型的变量就要使用SetMatrix函数赋值,而Vector类型的则要使用SetVector来赋值。

1.4.4把着色器设定到渲染管道中

这里我们使用SetVertexShader方法把顶点着色器设定到渲染管道中:

g_pd3dDevice->SetVertexShader(BasicShader);

1.4.5整个渲染过程如下

在渲染过程中,我们设定顶点的变换坐标和颜色值,渲染代码如下:

g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,

D3DCOLOR_XRGB(153,153,153), 1.0f, 0 );

//开始渲染

g_pd3dDevice->BeginScene();

//得到世界矩阵、观察矩阵和投影矩阵

D3DXMATRIX matWorld, matView, matProj;

g_pd3dDevice->GetTransform(D3DTS_WORLD, &matWorld);

g_pd3dDevice->GetTransform(D3DTS_VIEW, &matView);

g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &matProj);

D3DXMATRIX matWVP = matWorld * matView * matProj;

//通过句柄对着色器中的WVPMatrix变量进行赋值

BasicConstTable->SetMatrix(g_pd3dDevice, WVPMatrixHandle, &matWVP);

D3DXVECTOR4 color(1.0f, 1.0f, 0.0f, 1.0f);

//通过句柄对着色器中的color变量进行赋值,这里我们赋值为黄色

BasicConstTable->SetVector(g_pd3dDevice, ColorHandle, &color);

//把顶点着色器设定到渲染管道中

g_pd3dDevice->SetVertexShader(BasicShader);

//绘制模型子集

Teapot->DrawSubset(0);

//渲染完毕

g_pd3dDevice->EndScene();

g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

编译运行程序,运行效果如图1.2所示,这里我们将顶点颜色设置为黄色,如果读者在渲染过程中不断变换对着色器变量color的赋值,你将会得到一个色彩不断变幻的D3D茶壶。

D3DXVECTOR4 color(1.0f, 1.0f, 0.0f, 1.0f); //读者可以尝试改变颜色值

BasicConstTable->SetVector(g_pd3dDevice, ColorHandle, &color);

1.4怎么用HLSL着色器

1.2 着色器效果