渲染流水线

        对于Direct3D,上述过程通常被认为是一个渲染流水线。

        未经转换和照明的顶点从一端进入,在内部这些顶点将完成几个连续操作。然后,经过转换和照明处理的顶点从另一端出来。

 

        渲染流水线的大部分过程都是在进行坐标转换 ,将顶点从一个坐标系转换到别的坐标系。

 

        在使用Direct3D来进行转换时,用户只需要提供描述系统转换的完整转换矩阵,通过IDirect3DDevice->SetTransform方法来实现相应的变换。

HRESULT SetTransform(

           D3DTRANSFORMSTATETYPE State, //变换的类型

           CONST D3DMATRIX *pMatrix  //进行变换的变换矩阵);

 

世界变换

渲染流水线的第一步是将物体从本地坐标系转换到世界空间,这一过程称为世界变换。

       它的作用是:  把独立的物体放在一个统一的坐标系内,组合成一个完整的场景。在世界变换中主要完成的是对模型的转换,包括旋转、缩放、平移等。

       设置世界变换的函数如下:

g_pD3Ddevice->SetTransform(

                                 D3DTS_WORLD, &matWorld);

g_pD3DDevice为有效的Direct3D设备指针

matWorld代表一个变换矩阵。

 

视图变换

把物体转换到世界空间后,接下来就需要确定视图空间,这个过程称为视图变换。

 

      首先我们需要确定虚拟摄像机的属性。在Direct3D中,关于虚拟摄像机的属性主要包括:摄像机位置、摄像机的朝向和摄像机的正方向,分别用向量表示。可以从以下函数生成视图变换的矩阵。     

D3DXMATRIX *D3DXMatrixLookAtLH(         

          D3DXMATRIX *pOut,         //输出用于视图变换的矩阵

          CONST D3DXVECTOR3 *pEye,    //摄像机的位置

          CONST D3DXVECTOR3 *pAt,       //摄像机朝向的位置

          CONST D3DXVECTOR3 *pUp       //摄像机的正方向

      );

 

接下来,使用下面的函数来设置视图变换。

g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);

g_pD3DDevice为有效的Direct3D设备指针

matWorld代表一个视图变换矩阵

投影变换

把摄像机观察到的三维景像显示在二维的平面上,这种三维到二维的变换就是投影变换。实际应用中,主要的投影变换有两种类型:

Ø正交投影

Ø    透视投影

 

1.  正交投影

     

       在正交投影中,投影向量与观察平面垂直,物体坐标沿观察坐标系的z轴平行投影到观察平面上,观察点和观察平面的距离不影响物体的大小。    

可以使用下面的函数来得到正交投影的变换矩阵:

D3DXMATRIX *D3DXMatrixOrthoLH(         

         D3DXMATRIX *pOut, //输出用于正交投影的变换矩阵

         FLOAT w, //取景体宽度

         FLOAT h, //取景体高度

         FLOAT zn, //取景体离摄像机的最近距离

         FLOAT zf //取景体离摄像机的最远距离

      );

2.  透视投影

 

       透视投影的特点:是越远的物体在投影平面上的成像越小,这样生成的投影图更加具有纵深感。


      透视投影的观察范围是一个平截台体。平截台体是指一个去除了尖头的锥体。在计算机图形学中,观察平截面的概念是,锥体的尖头位于虚拟摄像机的位置,而摄像机指向该锥体的底部,将锥体的四个侧面向屏幕的四边投影,并切除远近裁剪平面位置的锥体的前后部分。得到的观察平截面代表摄影空间在渲染场景中的可见部分。实际应用中,如果我们要实现一个三维的场景,则我们通常使用透视投影。

下面的函数用于定义透视变换的矩阵:

D3DXMATRIX *D3DXMatrixPerspectiveFovLH(         
        D3DXMATRIX *pOut, //输出用于透视投影的变换矩阵
          FLOAT fovY, //摄像机镜头的夹角(在y轴上的成像角度)
          FLOAT Aspect, //平截台体的纵横比
          FLOAT zn, //近平截面的距离
          FLOAT zf //远平截面的距离
   );

顶点从均匀转化为非均匀:

 

Ø在顶点坐标信息里除顶点位置信息外再加一个W分量坐标,设定其初始值为1.0。

Ø在顶点通过T&L流水线中的多个矩阵传送时,w坐标将改变它的值。w值不为1.0的顶点是均匀的。当转换换结束时,就需要把顶点恢复为不均匀的形式,这是通过x、y和z坐标除以w完成的。w坐标的倒数也被存储起来。这个过程非常必要,因为光栅处理程序需要得到以非均匀x、y和z坐标以及均匀w的倒数值(reciprocal-of-homogeneous-w, RHW)表示的顶点。

 

视口变换

空间变换的最后一步是通过定义屏幕显示区域的实际宽、高等参数,将顶点从投影坐标转换为最终显示的以像素为单位的屏幕坐标。

在Direct3D中定义的视口结构:

typedef struct _D3DVIEWPORT9 {

          DWORD X; //视口区域的左上角x坐标

          DWORD Y; //视口区域的左上角y坐标

          DWORD Width; //视口区域的宽度

          DWORD Height; //视口区域的高度

          float MinZ;   //视口内景物的最小深度值,0-1.0之间,通常为0

          float MaxZ;   //视口内景物的最大深度值,0-1.0之间,通常为1

      } D3DVIEWPORT9;

通常情况下,参数MinZ和MaxZ被设为0和1.0f,即取景范围的最近和最远距离,表示在投影取景范围内,顶点只要满足了x∈(-1.0f , 1.0f)、y∈(-1.0f , 1.0f)和z∈(0.0f , 1.0f),就能通过裁剪,予以显示。

SetViewport()相当于把投影空间的顶点P(x,y,z)乘以以下变换矩阵:

 

kubernates 流水线_世界变换

 

经过转换后,顶点P的屏幕二维坐标x’,y’为:

x, = x × Width/2 + X + Width/2
      y, = y × Height/2 + Y + Height/2
      z’值为:
      z, = z × (MaxZ - MinZ) + MinZ

  

光栅化

经过视口变换,我们获得了一系列2D三角形。光栅化阶段被用于在描绘三角形时,计算每个像素的颜色值。

光栅化过程需要进行大量计算,并通常由特定的图像硬件来完成。光栅化的结果时一个2D图像,将被显示在屏幕上。