转自http://blog.csdn.net/soilwork/archive/2006/11/23/1408299.aspx
The Complete Effect and HLSL Guide(二)
一点点历史
….
从
1995
年,
3Dfx
发布第一块消费级的
3D
硬件加速图形卡开始,计算机图形技术和相关的硬件技术都取得了重大进展。虽然这类图形卡在渲染功能上有诸多限制,但为开发者打开了一片新的天地,终结了只能依靠软件解决方案进行渲染的时代。其结果是让实时
3D
图形和游戏都变得更加真实。
此后,接下来的几代硬件都在性能和功能方面有了重大突破。但是,由于受到硬件固定管线构架(
fixed-pipeline architecture
)的限制,仍然有很多约束,开发者被强制只能通过使用和改变渲染状态来控制渲染过程,获得最终的输出图形。
固定管线构架功能上的局限性,限制了开发者创建所需效果的能力。总的来说,它所产生的图形都不够真实。另一方面,用于电影
CG
渲染的高端软件渲染构架则发明了一些让渲染更加逼真的方法。
Pixar Animation Studios
开发了一门称为
RenderMan
的着色语言。它的目的是让艺术家和开发者使用一门简单但强大的编程语言来完全控制渲染过程。
RenderMan
可以创建出高质量的图形,从照片级的真实效果,到卡通风格的非真实渲染效果都可以实现。被广泛用于当今的电影中,包括著名的动画
Toy Story
和
A Bug’s Life
。
随着处理器芯片制造技术的革新,和处理能力的增强,
RenderMan
的思想逐渐影响并延伸到了消费级图形硬件。
DirectX 8
的发布引入了顶点(
vertex
)和像素着色器(
pixel shader
)
1.0
以及
1.1
版本。虽然这两个版本的着色模型灵活性不高,同时缺乏流程控制等一些功能。但是,这第一步,给予了艺术家和开发者长久以来所梦想的,创造夺目的、真实的图形的能力。消费级图形卡所生产的图形终于能和好莱坞电影工作室所渲染出的图形相比了。
接下来的几年间,图像硬件和
3D API
无论在功能和性能上都取得了巨大飞跃,甚至打破了摩尔定律中的技术进步速率。随着
DirectX 9.0 SDK
以及最新的一代图形卡的发布,比如
Nvidia
的
Geforce FX
系列和
ATI
的
Radeon 9800
系列,顶点和像素着色器发展到了
2.0
和
2.x
版本。以及随后的
3.x
版本。
注意
:
摩尔定律是1965年,由
戈登摩尔(Gordon Moore)——intel的创建者之一,通过统计得出的结论:集成电路上可容纳的晶体管数目,约每隔一年便会增加一倍。他还预测在以后的几十年中仍然将是这样。至今为止,这条理论依然很正确。另外,由于晶体管数量与集成电路的性能有关,因此,摩尔定律也是硬件性能增长的预测的依据。
这些新的着色模型为实时图像程序开发者带来了前所未有的灵活性。然而,大部分
shader
都通过一种低级的,类似于汇编的语言来编写的。这意味着作为一名开发人员,你必须像多年前使用汇编语言的时代那样,自己管理寄存器,分配变量以及优化。此外,
shader model 2.0
和
3.0
增加的复杂性让开发人员更加头疼,因为不同的图形卡寄存器数量不一样,甚至同样的指令执行结果也不一样。
为了简化
shader
开发,同时,给予硬件开发者更多的自由优化性能,微软在
DirectX 9.0
中引入了
High-Level Shading Language
(
HLSL
)。这门语言和其他高级语言,比如
C
或
C++
很类似,这样,开发者就能把注意力集中在
shader
所要实现的功能上,而不是把精力放在如何使用寄存器,或对某种硬件如何组合指令才能最优化之类的琐碎问题上。
在讲解
HLSL
能做什么,以及如何来使用它之前,先来看看不同的
shader
版本可以提供哪些功能。需要说明的是,在编写
shader
之前,需要知道硬件都有哪些功能(
capable
)。使用
HLSL
并不能消除特定硬件平台上的限制,但却可以把这些限制隐藏起来。
顶点和像素着色器管线以及
Capabilities
与随
DirectX 8.0
发布的顶点和像素着色器
1.0
和
1.1
版本相比,
shader model 2.0
对语言进行了许多重要改进。由于最新的
DirectX 9.0
所使用的顶点和像素着色器版本为
2.0
,同时,已经有大量支持
vertex
和
pixel 2.0
的显卡,所以本书主要讨论基于这一技术的
shader
。
注意:
虽然在编写本书时,支持
shader model 3.0
的图形卡已经开始上市,但尚未普及。我们会讨论一些
shader model 3.0
的特性,但大部分例子都是基于
2.0
或更低版本的
shader
技术。
假设你已经有一定的
3D
和
shader
基础知识,我们来看看第二代着色语言和上一代技术相比有哪些比较重要的改变。
顶点着色器
2.0
和
2.x
相对于
1.x
的版本有如下改进:
l
支持整数和布尔数据类型,并分别有相应的设置指令。
l
增加了临时和常量寄存器的数量。
l
对程序所能包含的最大指令数进行了增加,给开发者以更多灵活性(标准所要求的最小指令数从
128
增加到了
256
,某些硬件还能支持更多指令)。
l
添加了许多支持复杂运算的宏指令,比如
sine/cosine
,
absolute
,以及
power
等。
l
支持流程控制语句,比如循环和条件测试。
下面列出的则是像素着色器
2.0
和
2.x
相对于
1.x
版本的改进:
l
支持扩展
32-bit
精度的浮点运算。
l
支持对寄存器元素的任意重组(
swizzling
)和遮罩(
masking
)。
l
增加了常量和临时寄存器的可用数量。
l
标准所允许的最小指令卡有明显增加。算术指令从
8
条增加到
64
条,同时还允许使用
32
条纹理指令。像素着色器
2.x
默认情况下甚至支持更多指令,允许硬件支持比标准最小要求多的指令数。
l
支持整数和布尔常量,循环计数器以及断言寄存器(
predicate register
)。
l
支持动态流程控制,包括循环和分支。
l
Gradient instrctions allowing a shader to discover the dervate of any input register
通过这一系列强大的改进,如今,开发者可以自由发挥想象力,创造出令人吃惊的效果。到这里,我们应该学习一下两种着色器的构架,以便更好的了解数据是怎样在图形硬件上流动。
当渲染
3D
图形时,几何体信息通过
Direct3D
之类的渲染
API
传递给图形硬件。硬件一旦接收到这些信息,就为
mesh
中的每一个顶点调用顶点程序。图
1.1
描绘了顶点和像素着色器
2.0
标准实现的原理图。
从图
1.1
中可以看到,开发者通过
3D
渲染
API
,以数据流的形式,为顶点着色器提供顶点数据。数据流中包含了正确渲染几何体所需的所有信息,包括顶点位置,颜色和纹理坐标等等。当这些信息传递进来时,将分别放到合适的输入寄存器
v0
到
v15
中,以便顶点着色程序使用。顶点程序还需要访问许多其他的寄存器,才能完成自己的工作。常量寄存器都是只读的,通常用来为
shader
储存静态数据,因此,必须预先设置好它们的值。顶点着色器
2.0
标准下,常量寄存器储存的都是矢量,可以保存浮点数,整数,以及布尔类型的值。需要注意,顶点着色器中所有的寄存器都把数据储存为包含
4
个分量的矢量,可以并行访问所有分量,也可以使用重组或遮罩分别访问某个分量。
在图
1.1
的右边部分,是临时寄存器,用来储存顶点着色器计算出的中间结果。显然,由于它们是临时性的,因此,可以对这些寄存器进行写入和读取操作。注意名称为
a0
到
aL
的寄存器,它们是循环时用来索引地址和追踪循环所用的计数寄存器(
counter register
)。记住,由于
HLSL
是一门高级的着色语言,你不需要关心寄存器是如何分配的。对开发者来说这个过程应该是透明的,并且只有在
shader
被最终编译为机器代码时才发生。
在访问了输入寄存器,临时寄存器和常量寄存器之后,顶点着色器程序才开始以开发者所希望的方式来处理和控制输入的顶点。处理过程结束之后,结果立即被输送到最终的输出寄存器中。其中
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~