GPU概念以及D3D渲染流水线(管线)

来源:互联网 发布:移动网络经纪人登录 编辑:程序博客网 时间:2024/04/30 11:48

        当游戏的画面拟真度越来越高时,仅仅靠CPU来进行图形图像处理已经不能满足游戏的需要了。于是,人们开始尝试用硬件加速卡来协助CPU进行3D图像处理,此举在技术上和商业上都大获成功。早期比较出名的比如 Voodoo等。于是,大量的加速卡及GPU(Graphic Processing Unit)设计公司开始迅速推出自己的设计,如 ATI(刚被AMD收购),NVidia,PowerVR(市场萎缩,转向嵌入式系统的3D加速单元,参考PowerVR MBX及OpenGL ES)等开始展露头角。

GPU是计算机显卡的“心脏”,也就相当于CPU在电脑中的作用,它决定了该显卡的档次和大部分性能,同时也是2D显示卡和3D显示卡的区别依据。2D显示芯片在处理3D图像和特效时主要依赖CPU的处理能力,称为“软加速”。3D显示芯片是将三维图像和特效处理功能集中在显示芯片内,也即所谓的“硬件加速”功能。显示芯片通常是显示卡上最大的芯片(也是引脚最多的)。现在市场上的显卡大多采用NVIDIA和ATI两家公司的图形处理芯片。

GPU使显卡减少了对CPU的依赖,并进行部分原本CPU的工作,尤其是在3D图形处理时。GPU所采用的核心技术有硬体T&L、立方环境材质贴图和顶点混合、纹理压缩和凹凸映射贴图、双重纹理四像素256位渲染引擎等,而硬体T&L技术可以说是GPU的标志。

GPU能够从硬件上支持T&L(TransformandLighting,多边形转换与光源处理),T&L是3D渲染中的一个重要部分,其作用是计算多边形的3D位置和处理动态光线效果,也可以称为“几何处理”。一个好的T&L单元,可以提供细致的3D物体和高级的光线特效;

问题随之出现:每家公司可能都有自己的设计方案(产品),那么游戏和3D应用程序开发者所设计开发出来的软件就很难在不同的厂商之间的加速卡上运行,很难很好的使用这些加速卡的加速功能。也就是说,这类应用程序的移植性将会降低。
要解决移植性的问题,可以通过将加速卡功能抽象出来,统一定义接口的形式来实现。于是,人们采用了典型的分层模式,将一套应用程序分为3个层次:
                                                  应用程序层 -> 硬件抽象层 -> 硬件层
其中,应用层 就是游戏和应用软件开发人员的开发主体,他们调用统一的加速卡API来进行上层开发,而不用考虑移植性问题;
硬件抽象层 则抽象出硬件的加速功能,进行有利于应用层开发的封装,并向应用层开放API;
硬件层 将硬件驱动提供给抽象层,以实现抽象层加速功能的有效性。
这个结构有效的将游戏和应用程序 与 硬件加速卡隔离开,这就很好的提升了程序的移植能力。并且,还有一个好处就是,开发人员的知识复用率得到提高,从而降低了3D显示软件的开发门槛。

于是,众多的加速卡厂家就联合起来,形成一个组织,共同制定出了这个硬件抽象层的接口标准,这就是OpenGL。
而出于同样的目的,微软也定义了一套平行的类似于OpenGL的接口集合,就叫做 Direct 3D。
这就是OpenGL和D3D的起源。

不同的是,OpenGL只包含了3D加速接口,而DirectX除了D3D之外,还包含了声音接口Direct Sound,然后还有输入输出设备的接口,统称为DirectX。
不论OpenGL还是D3D,他们的工作流程其实是大同小异的。
下面以D3D为例,进行讨论。

3D加速卡的主要功能就是协助CPU,负责将内存中的矢量图像数据(顶点集合)进行变换、光照计算、裁剪等操作,最后经过光栅化将图像呈现给人眼。这个过程就叫做渲染,D3D把整个渲染分为9个步骤,叫做渲染流水线(管线)。

D3D的渲染管线(Rendering Pipeline):
局部坐标变换 -> 世界坐标变换 ->观察坐标变换->背面消除->光照->裁剪->投影->视口计算->光栅化

D3D里包含了倆种渲染流水线:固定管线 和 可编程管线。可编程管线就是说管线中的某些环节是可以被控制的。人们可以通过对GPU中的着色器进行编程的方式,来控制、管理加速卡的渲染效果。着色器分为 顶点着色器和像素着色器。 顶点着色器是在进行 坐标变换 和 光照计算时工作,像素着色器是在光栅化环节工作。人们对着色器进行自定义编程时,这个流水线就叫做 可编程管线。同时,D3D还提供默认的着色器程序,当游戏或应用程序完全使用默认着色器程序时,这个流水线就叫做 固定管线。

 

 局部坐标系:就是建模坐标系,它是在建模时由3DMAX之类的工具定义的。

 世界坐标系:用来统一场景中各个object的位置、尺寸等规格

 观察坐标系:也就是摄像机的坐标系。

 在固定管线中,坐标变换分成2个步骤:局部坐标系到世界坐标系 和 世界坐标系到观察坐标系。

 

 局部坐标系到世界坐标系变换:

         这个变换是为了把在不同建模工具或者有用不同规格的建模尺寸下设计的模型,都统一到一个通用的坐标系下面。在游戏设计时,由游戏工具(如:场景编辑器)来预先计算,并且为每个模型都计算出一个变换矩阵(即记录模型在游戏场景中的大小、朝向、位置),叫做世界坐标变换矩阵。在渲染时,实时的应用这些矩阵来参与运算写法:
            D3DXMATRIX worldMatrix;                                                               //这个矩阵就从文件中读进来
            Device->SetTransform(D3DTS_WORLD, &worldMatrix);                  //使用宏D3DTS_WORLD 
 
从世界坐标系到观察坐标系变换:
            这样变换之后,所有的顶点也就可以直接转换为向量,非常的便于某些计算。这个动作通常是,将摄像机平移到世界坐标系原点,再旋转摄像机,使它的光轴与世界坐标系z轴方向一致。与此同时,空间中的所有几何体都要随摄像机一同变换,以确保摄像机的视场不变。这个变换叫取景变换,变换后得到观察坐标系。写法如下:
            D3DXMATRIX    ViewMatrix;
            D3DXVECTOR3  position;                                                                                 //摄像机位置
            D3DXVECTOR3  targetPoint;                                                                            //摄像机的观察朝向
            D3DXVECTOR3  worldUp(0,1,0);                                                                      //摄像机的y朝向,也就是头的朝向
            D3DXMatrixLookAtLH(&ViewMatrix, &position,  &targetPoint,  &worldUp);
            Device->SetTransform(D3DTS_VIEW, &ViewMatrix);                                       //注意宏,D3DTS_VIEW
 其实,D3DXMatrixLookAtLH()函数只是类似功能函数中的一个,注意后缀 LH 这表示左手坐标系,对应的还有一个右手坐标系,它们的区别在于:左手系 其z轴向里为正;右手系向外为正。

 

投影:

         // 定义视图矩阵   

        D3DXMATRIXA16 matProj;  

         // 透视投影   

        D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );   

       g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );  

  

 


 


 

 

 

 

原创粉丝点击