The Complete Effect and HLSL Guide(六)
本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。
由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。
翻译:clayman
Blog:http://blog.youkuaiyun.com/soilwork
clayman_joe@yahoo.com.cn
第二章 HLSL着色语言
这一章我们将学习HLSL的大部分基本内容,包括丰富的变量类型,如何定义变量,和如何编写shader代码。你可能还想知道如何在shader中使用函数。虽然它们是使用HLSL编写shader的必须元素,但我还是决定把所有关于函数的内容作为单独一章来讲解。在第三章中,我们将详细讲解如何定义函数,以及HLSL为开发者所编写的内置函数。
在继续学习之前,需要进行一点点说明,读者在前一章学习HLSL语法时可能注意到了诸如techniques,渲染状态,pass之类的概念。虽然它们也是HLSL语言的一部分,但事实上它们只在effect文件中使用,而effect 文件则是HLSL的一个超集。
好了,闲谈到此为止,让我们直接进入本章主题,讨论在任何语言中都是最重要的元素,数据类型。
数据类型
数据类型是任何一门编程语言的核心。没有它们你将无法定义变量或者在函数之间传递数据。如果连呈现数据的方法都没有,又怎么能储存数据呢?和其他高级语言一样,HLSL有一系列内置定义类型,可以把它们分为以下几类:
l 标量类型
l 矢量类型
l 矩阵类型
l 对象类型
除了上面的内置类型外,HLSL同样允许自定义的复合类型,比如数组和结构。在介绍HLSL特定数据类型前,先来仔细看看大部分3D硬件上呈现数据的方式。当处理数据时,基本的选项是浮点值,根据硬件构架的不同,这些值可能为16或32位。记住,虽然可以让硬件同一时间只处理一个值,但这并不是最高效的方法。相反,如果硬件每次处理一个包含四个分量值的单元(或矢量),那么则可以同时对四个分量进行处理。当然,这就需要考虑硬件如何来保存非矢量的值。我稍后会讲解这一点。
除了浮点值以外,较新的硬件也内置支持整型和布尔值,但它们主要用于分支,循环,和条件测试语句。接下来的几页中,我将浏览每一种数据类型,并解释如何来使用它们。
标量类型
标量类型是由HLSL标准定义的,他们是最基本的类型。所有复杂类型,比如矢量,矩阵,和结构都由标量组成。表2-1列出了所有可用的标量类型以及它们所表示的值。
表 2 -1 HLSL标量类型
标量类型 值
bool true或false
int 32位有符号的整型
half 16位浮点数
float 32位浮点数
double 64位浮点数
需要注意并不是所有shader目标都天生支持整型,half和double值。如果要将shader编译为不支持指定类型数据的目标,那么将模拟处理float值的方式来处理它们。与使用原生(native)类型相比,结果可能不正确。在确定目标平台支持某个特定类型之前,为了保证一致性和可移植性,最好坚持使用标准浮点数。
注意
我们在上一章已经简要讨论过profile,它用来告诉HLSL编译器为哪种构架的shader产生代码。通常Profile的值直接对应于可用的顶点和像素着色器版本,但对于指令集没有改变的情况可能会有例外。
矢量和矩阵类型
矢量和矩阵是把标量组织为1维或2为数组的标准方式。它们通常用来表示3D数据,比如法线和变换矩阵。
矢量是HLSL标准所定义的,由特定标量类型组成的一维数组。默认情况下,一个矢量由4个浮点值组成。如表2-2所示,可以手动定义任何类型的矢量。
表 2 -2 HLSL矢量类型
矢量类型 值
vector 一个包含四个浮点分量的矢量
vector<type, size> 包含size个type类型的矢量
另外,为了简便,HLSL语言预定义了一组标准矢量类型,方便开发者使用。下面就是这些预定义的矢量类型
typedef vector <float, 4> VECTOR;
typedef vector <bool, #> bool# ;
typedef vector <int, #> int# ;
typedef vector <half, #> half# ;
typedef vector <float, #> float# ;
typedef vector <double, #> double# ;
(译注:“#”表示分量个数。)
你可能还记得我之前提到过图形硬件是基于矢量的。你看,这里所定义的矢量数据类型恰好与硬件相对应,编译器将把这些数据直接映射为矢量。当你使用少于四个分量的矢量时,编译器将在空闲分量中添加其他变量,以便压缩数据。
简要讨论了矢量之后,你可能想知道如何才能单独访问矢量中的某个分量。有许多方式允许我们单独访问矢量中的分量。下面列出了访问数组分量的几种不同方式。注意对多于四个分量的数组来说,额外的分量只能通过索引访问。
l 使用分量符访问:vector.x , vector.y , vector.z , vector.w
l 使用颜色符访问:vector.r , vector.g , vector.b , vector.a
l 使用索引访问:vector[0], vector[1], vector[2], vector[3]
接下来看看矩阵类型。矩阵是HLSL标准所定义的,由特定标量类型组成的二维数组。默认情况下
~~~~~~~~~~~未完待续~~~~~~~~~~~~~~~~