第16章 HLSL入门

版权声明:转载请注明出处 https://blog.csdn.net/weixin_39918693/article/details/88724043

vertex shaderpixel shader是我们自行编写的一些规模较小的定制程序(custom programs),这些定制程序可取代固定功能流水线中某一功能模块,并可在显卡上执行

通过这种功能替换,我们便在实现各种图形效果时获得了巨大的灵活性

HLSL之于汇编语言有很大的优势

  • 1、编写和编译HLSL着色器程序
  • 2、应用程序与着色器程序之间的数据通信,通过常量表
  • 3、熟悉使用HLSL

1、HLSL着色器程序的编制

独立编写着色器代码,然后使用D3DXCompileShaderFromFile对着色器文件进行编译

在着色器源代码中有时是找不到一些全局变量的初始化代码的。这是因为有些全局变量的初始化应在应用程序源代码中进行而非着色器程序代码中。一定要是全局变量吗?????

顶点着色器的输入和输出结构定义了顶点的数据结构;像素着色器的输入和输出结构定义了像素的数据结构

很特别的冒号(colon)语法(syntax)表达了一种语义(semantic),用来指定变量的用途

语义层次的用法标识符(usage identifier)

从底层观点看,语义语法建立了着色器程序中的变量与硬件寄存器之间的联系

入口函数

在遵循函数命名规则的前提下,着色器的入口函数的命名可自由选择

入口函数必须有一个可接收输入结构的参数,该参数将用于把输入顶点传递给着色器;其还必须返回一个输出结构的实例,用来将经过处理的顶点从着色器中输出

实际上,输入和输出结构的使用并非是强制性的


2、HLSL着色器程序的编译

2.1、常量表

每个着色器程序都用常量表存储其变量

为了使应用程序能够访问着色器的常量表(Constant Table),D3DX库提供了接口ID3DXConstantTable。借助该接口,可以在应用程序代码中对着色器源代码中的变量进行设置

着色器代码和应用程序代码之际进行数据通信的通道是常量表,这种数据通信是必要的

接口ID3DXConstantTable是通过着色器代码编译函数得到的

获取变量的句柄

D3DXHANDLE ID3DXConstantTable::GetConstantByName(
	D3DXHANDLE hConstant,
	LPCSTR pName
);

变量的设置

HRESULT ID3DXConstantTable::SetXXX(
	LPDIRECT3DDEVICE9 pDevice,
	D3DXHANDLE hConstant,
	XXX value
);

对于bool、int、float,我们传入的是该值的一个副本;而对于向量、矩阵、结构体,我们传入的是指向该值的指针;如果要对数组进行设置,还需要传入数组的维度

可以通过接口ID3DXConstantTable进行设置的类型

设置变量的默认值

将变量设置为其默认值,该方法在应用程序的设置过程中,应调用一次

HRESULT ID3DXConstantTable::SetDefaults(
	LPDIRECT3DDEVICE9 pDevice
);

2.2、HLSL着色器程序的编译

在应用程序中通过D3DXCompileShaderFromFile函数来对着色器程序进行编译

一个编译实例
ID3DXConstantTable *TransformConstantTable = 0;
ID3DXBuffer *shader = 0;
ID3DX *errorBuffer = 0;

hr = D3DXCompileShaderFromFile(
	"transform.txt",
	0,
	0,
	"Main",
	"vs_2_0",
	D3DXSHADER_DEBUG,
	&shader,
	&errorBuffer,
	&TransformConstantTable
);

if(errorBuffer){
	MessageBox(0, (char *)errorBuffer->GetBufferPointer(), 0, 0);
	errorBuffer->Release();
}

if(!hr){
	MessageBox(0, "D3DXCompileShaderFromFile - FAILED", 0, 0);
	return false;
}

3、变量类型

3.1、标量类型

bool
int
half
float
double

3.2、向量类型

有很多细节

可以通过数组下标来访问向量中的每个元素;也可以通过已定义的分量名来访问

关于向量间的复制操作有很多特殊的用法

3.3、矩阵类型

有很多细节

通过双数组下标来访问时,下标不是从0开始的

3.4、数组

与C++一样

3.5、结构体

与C中的结构体类似,用法稍有不同

3.6、关键字typedef

与C++中的用法一样

3.7、变量的前缀

static:其修饰的全局变量在着色器程序外不可见;其修饰的局部变量与C++中的行为一致
uniform:表示该变量将在着色器之外进行初始化
extern:只能用于全局变量,表示该变量可在着色器程序之外进行访问
shared:只能用于全局变量,表示该变量可在多个效果框架之间共享
volatile:只能用于全局变量,提示效果框架该变量将经常被修改
const:与C++中的行为一致

4、关键字、语句及类型转换

4.1、基本程序流程

与C语言一致

4.2、类型转换

C语言的类型转换语法完全一致


5、运算符

与C++中的非常相似

%适用于整型和浮点型数据,且两操作数必须同号

很多运算都是在分量级别上进行的

在双目运算中的类型提升

  • 1、维度的提升
  • 2、精度的提升

6、用户自定义函数

HLSL中的函数:

  • 1、与C++中的函数语法类似
  • 2、参数总是按值传递
  • 3、不支持递归
  • 4、函数总是内联的

专门在函数参数列表中使用的关键字:

  • 1、int:可以不显式指定,因为默认状态下每个形参都是in类型的
  • 2、out
  • 3、inout

7、内置函数

大多数内置函数都经过了重载,以适应于所有内置类型

猜你喜欢

转载自blog.csdn.net/weixin_39918693/article/details/88724043