可编程流水线
Microsoft DirectX® 9.0中的Microsoft® Direct3D®使用了程序化的模块来指定顶点变换、光照流水线、像素/纹理混合流水线的行为。
使用基于程序化的模块来指定硬件的行为有许多好处。
首先,程序化的模型使得用更为通用的语句来指定常用的操作成为可能。与可编程API不同,固定功能API必须随着所支持操作的增长,定义新的模式,标志,等等。此外,随着硬件能力的加强——更多的颜色,更多的纹理,更多的顶点数据流,等等——由输入数据导致操作符空间的增长也变得复杂。另一方面,可编程模型能够以更为直接的方式进行甚至简单的操作,例如把适当的颜色和纹理放到光照模块中合适的地方。开发人员无需搜索所有可能的模式,只要学习计算机体系结构并指定想要执行的算法即可。
例如,可编程流水线可以支持以下众所周知的特性。
其次,程序化的模型为开发新的操作提供了一个简单的机制。当前API不支持许多开发人员需要的操作。大多数情况下,这并不是由于硬件能力的限制造成的,相反是由于API的限制造成的。一般情况下,比起试图超越设计者的意图,强制扩充固定功能API以实现相同功能来说,用程序化的模型执行这些操作会更简单,速度也更快。
开发人员普遍希望实现的新特性包括以下这些:
第三,程序化的模型提供了可扩充性和可发展性。硬件能力正在高速地发展,程序化的表示可以适应API,因为它们很容易扩充。通过以下手段,可以很容易地不断地添加新的特性和能力。
在对复杂事物的描述方法中,代码具有最好的扩充性。此外,对于添加到可编程着色器中的新特性,Direct3D内部所需改动的代码量也非常小。
第四,程序化的模型更容易被掌握。比起硬件,软件开发人员更理解编程。一个真正能够满足软件开发人员需要的API应该把硬件能力映射到代码的形式。
第五,程序化的模型跟随了具有照片真实感的渲染领域所经历的足迹。在具有照片真实感的高端渲染领域,使用可编程着色器的传统已经有许多年了。一般来说,这个领域不受性能的影响,因此对渲染技术而言,可编程着色器代表了无妥协的最终目标。
最后,程序化模型允许直接映射到硬件。当前大多数三维硬件,至少在顶点处理阶段,实际应该是可编程的。API提供的可编程性使用应用程序的指令可以直接映射到这部分硬件。这使用开发人员可以根据需要管理硬件资源。要用有限数量的寄存器和可以运行的指令,去实现一个能启用所有特性并且特性之间不相互影响的固定功能流水线是很难的。如果开发人员打开了太多特性,而这些特性需要共享同一资源,那么这些特性可能都会以意想不到的方式停止运作。通过让应用程序开发人员与硬件直接对话,从而使此类限制对API变得透明,可编程API消除了这个问题,这也遵循了DirectX的传统。
可编程顶点着色器在操作状态时会取代Microsoft® Direct3D®的几何流水线中的变换和光照模块。实际上,有关变换和光照的状态都被忽略。但是,如果禁用顶点着色器并重新使用固定功能处理,那么所有当前状态设置会起作用。
任何对high-order图元的tessellation操作必须在顶点着色器执行之前完成。对那些在着色器处理后执行表面tessellation的硬件实现来说,必须采用某种方式使之对应用程序不可见。因为在着色器之前一般来说没有提供语义信息,所以系统使用了一个特殊的token来确定输入流中的哪个成员表示基位置,所有其它成员都相对于该成员进行插值。Direct3D不支持无法插值的数据通道。
在输出时,顶点着色器必须产生齐次裁剪空间中的顶点位置。其它可以产生的数据包括纹理坐标,颜色,雾因子等等。
标准图形流水线会处理着色器输出的顶点,包括以下操作。
Microsoft DirectX® 9.0的顶点着色器和固定功能流水线的裁剪空间是相同的。更多细节,请参阅裁剪体。
可编程几何流水线是Direct3D应用程序编程接口(API)中的一种模式。当启用时,它会取代顶点流水线。当禁用时,API就切换回固定功能顶点处理。顶点着色器的执行不会影响Direct3D的内部状态,同样着色器也不能使用Direct3D的任何状态。
应该用IDirect3DDevice9::CreateVertexShader创建一个顶点着色器,并在进行绘制之前调用IDirect3DDevice9::SetVertexShader设置可编程着色器。
像素处理由像素着色器对每个像素单独执行。像素着色器可以单独工作,也可以和顶点着色器及数据流协同工作。开发人员不能凭空对像素着色器进行编程,它们要依赖于上游的数据成员。
下面是像素流水线中的操作顺序:
像素着色器的输入来自顶点着色器的输出。寄存器v0和v1包含了顶点颜色,它们来自顶点着色器的输出寄存器oD0和oD1。颜色层中的纹理由诸如tex t0之类的像素着色器指令引用,系统会根据顶点着色器的输出寄存器中对应的纹理坐标(如oT0)对纹理进行取样。像素着色器使用颜色和阿尔法混合指令以及纹理寻址指令对这些输入进行操控并计算出结果。像素着色器计算得到的结果是寄存器r0的内容或输出的像素颜色。着色器完成处理后会把处理结果送到雾处理阶段和渲染目标混合器做进一步的处理。顶点着色器的输出提供了像素着色器的输入。
ps_3_0着色器模型和ps_1_X/ps_2_0有些不同的概念。