• 3D流水线


    渲染流水线
            对于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)乘以以下变换矩阵:
     
     

    经过转换后,顶点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图像,将被显示在屏幕上。
     
     
  • 相关阅读:
    .Net Cache及(HttpRuntime.Cache与HttpContext.Current.Cache的区别)
    Autofac 属性注入的方式
    AutoFac创建实例的方法解析
    MongoDB 增删改查 CRUD 操作
    MongoDB 3.4版本在windows环境下的安装与配置
    Stack Overflow 2017 开发者调查报告
    使用SVN对GitHub进行版本管理
    MongoDB.Driver for C#
    Dapper.Net 轻量级的ORM 框架2
    Selenium webdriver 安装(一)
  • 原文地址:https://www.cnblogs.com/wonderKK/p/2246795.html
Copyright © 2020-2023  润新知