HLSL高级着色语言简介

HLSL-High Level Shader Language

优点

用来书写Vertex Shader和Pixel Shader程序的代码,语法类似于C/C++,在DirectX 8.x的时代,Shader程序都是用低级Shader汇编语言编写的,姑且称之为LLSL吧,HLSL与之相比具有以下优点:

  • 更高的生产力,使用HLSL编程更快更容易,使我们有更多的时间关注与算法而不是编码
  • 更好的可读性,使用HLSH编写的程序更易读,易调试及维护
  • 编译器将生成更加高效的汇编代码
  • 可以将同一份代码编译成任何可用的Shader版本,但是用LLSL则必须按不同版本编写代码

如果你的显卡不支持Shader的话,那么可以使用REF Device模拟,这样可以得到正确的结果,但是速度非常慢

编写Shader代码

你可以将Shader代码写入到你的程序中,但是为了更方便,更模块化,通常将Shader程序放在单独的文件里,比如记事本,然后使用D3DXCompileShaderFromFile函数来编译它,使用记事本写Shader程序可能不太方便,以前微软提供编写Shader的工具,在DirectX SDK当中,但是现在不支持了,大家可以用AMD的RenderMonkey来编写。

一般的Shader程序包含以下几个部分

  • 全局变量-viewprojmatrix, color等
  • 输入结构和输出结构-VS_INPUT, VS_OUTPUT
  • 入口函数-Main, note the name is not mandatory, you can used any valid function name

常量表

每个Shader程序都有一个常量表来存储它的变量。可以用ID3DXConstantTable接口访问长量表,可以设置Shader程序中的全局变量值

实战-一个简单的Shader程序

下面我们就来看看如何编写一个Shader程序,我们还以茶壶为例,看看如何用Shader绘制一个蓝色的茶壶,学习如何用Shader处理颜色,这个例子简单的不能再简单,但是,它确实能反映如何使用Shader。首先用VS建立一个Win32工程,添加必要的框架代码,主要是创建窗口,简单的消息处理以及初始化D3D等,如下

Code

然后按照下面的步骤绘制一个茶壶

1.在程序头部添加茶壶对应的全局变量

1 ID3DXMesh*                g_pMesh                = NULL ;

2.在InitD3D函数尾部(返回语句之前)创建绘制茶壶的代码

1  D3DXCreateTeapot(g_pd3dDevice, &g_pMesh, NULL) ;
2 

3. 在Render函数中添加绘制茶壶的代码,位于BeginScene和EndScene之间

1 g_pMesh->DrawSubset(0) ;

4.在Cleanup函数中清除茶壶对应的mesh

1 if(g_pMesh != NULL)
2     g_pMesh->Release() ;
3 

下面编写Shader程序,打开记事本,输入如下代码,代码很简单-略加解释,ViewProjMatrix对应是view matrix和projection matrix的乘积,Blue是顶点颜色,input只包含一个信息,顶点位置,output包含两个信息,顶点的位置和颜色,在main函数中,将顶点的位置由local坐标系变换到投影空间,将颜色设置为蓝色,就这么简单。

Code

回到主程序中,添加全局变量g_pVertexShader用来保存创建的shader

1 IDirect3DVertexShader9*    g_pVertexShader        = NULL ;

添加全局变量g_pConstantTable用来保存Shader对应的常量表,有了常量表就可以存取和修改shader中的变量

1 ID3DXConstantTable*        g_pConstantTable    = NULL ;

添加一个变量句柄来存取shader中对应的ViewProjMatrix

1 D3DXHANDLE ViewProjMatrixHanle = 0 ;

添加函数PrepareShader,这个函数负责从文件编译shader,创建shader,设置shader中的变量等

Code

最后一行将shader中的变量ViewProjMatrix与ViewProjMatrixHandle相关联,这样接下来就可以用ViewProjMatrixHandle来存取和设置ViewProjMatrix了。注意,GetConstantByName函数的第二个参数是一个字符串,用来表示要获取的变量名字,这个名字必须与Shader文件中指定的名字一样才行,否则的话不起作用,也就是说Shader文件中一定有一个名为ViewProjectMatrix的变量。

添加函数SetupMatrix

这个函数负责设置view matrix, projection matrix, 并将二者的乘积赋值给shader中的ViewProjMatrix以便完成shader中的运算

Code

注意最后一行很重要,他是用来设置常量表中所有变量的默认值的,很多时候如果不加这一句,窗口中将看不到任何东西!还有要在InitD3D函数中禁用光照效果,因为我们是自己设置颜色

1 g_pd3dDevice->SetRenderState( D3DRS_LIGHTING , FALSE ); 

最后,也是最重要的,在Render函数中设置shader,只有这样,它才能生效

1 g_pd3dDevice->SetVertexShader(g_pVertexShader) ;

程序结束后,在Cleanup函数中清除常量表和shader

1 if(g_pConstantTable != NULL)
2     g_pConstantTable->Release() ;
3 
4 if(g_pVertexShader != NULL)
5     g_pVertexShader->Release() ;
6 

好了,大功告成,现在编译并运行这个程序,你将看到一个蓝色的茶壶!

完整源代码

Code

happy coding!

作者:zdd
出处:http://www.cnblogs.com/graphics/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
原文地址:https://www.cnblogs.com/graphics/p/1605435.html