渲染流程

(注:【D3D11游戏编程】学习笔记系列由CSDN作者BonChoix所写,转载请注明出处:http://blog.csdn.net/BonChoix,谢谢~)

 

       3D图形学研究的基本内容,即给定场景的描述,包括各个物体的材质、纹理、坐标等,照相机的位置及朝向,光源等信息,计算其最终在二维的光栅化显示器上对应的显示结果。从最初的场景描述到最终的显示结果,这整个过程就是在3D渲染管线中完成的。
       这里的“管线”即我们通常意义上的流水线,与工业上的生产流水线,或者是CPU指令执行的流水线具有相似的意义。如果对“流水线”概念有所了解,就会明白其直接目的就是提高执行的效率。假如没有流水线,所有的处理都放到单独一个阶段执行,那么一个顶点从开始被处理到最终处理完毕的过程中,后面的顶点只能处于等待状态。假设整个处理过程时间为T,那么系统的吞吐量就相当于1/T。 如果把整个处理过程合理地分成不同的阶段,我们假设平均分成了5个阶段(P1,P2,P3,P4,P5,且每个阶段执行时间为T/5),各个阶段可以互不影响地独立工作,即一个顶点在执行完P1进入P2阶段后下一个顶点马上可以进入P1阶段开始执行。这种情况下在任意时刻,五个阶段就可以同时工作,效率自然会大大提高。此时的吞吐量为5/T这个事实就是证明。当然,真正的管线不同的阶段执行时间一般不可能完全一样的,这时整个管线的效率瓶颈取决于时间最长的那个,假设为Tmax,则整个管线的吞吐量为1/Tmax。
 在D3D11中,整个渲染管线可以分成如下几个主要阶段:

       从最开始的Input Assembler阶段到最终的Output Merger阶段,每个阶段处理完的输出,传递给下一个阶段,作为其输入。
       下面针对各个阶段逐个进行介绍:
1. Input Assembler Stage
       这个阶段的主要目的是根据用户提供的顶点及索引信息,构建多边形,主要有点、线段、三角形。给定顶点和索引,构建多边形的方法取决于所使用的基本图元的拓扑类型(Primitive Topology)。D3D11中常见的拓扑类型有以下几种:
   1. Point List:定义的每一个顶点作为一个单独的点进行绘制,如图:
  

  2. Line Strip:所有的顶点按顺序逐个连接成线段,如图:
 
   3. Line List:所有的顶点按顺序两两配对连接成线段,如图:
 
   4. Triangle Strip:所有的顶点按顺序组成三角形,前三个顶点为第一个三角形,从第四个开始每个顶点与位于其前面的两个顶点组成一个三角形,如图:
 
   5. Triangle List:类似于Line List,按顺序三三配对组成三角形,如图:
 
        举个例子,对于下图,9个顶点及拓扑类型Triangle List,对应索引:[0,1,2, 0,2,3, 0,3,4, 0,4,5, 0,5,6, 0,6,7, 0,7,8]。
 
        Input Assembler会三个三个地读取索引组成三角形,形成图中的七个三角形。
        对于另一个图,4个顶点及拓扑类型Triangle Strip,对应索引:[1,2,0,3]。
 
        此时,GPU读取[1,2,0]组成第一个三角形,[0,2,3]组成第二个三角形。
      【注意】:从上面可以看出,对于奇数序号三角形和偶数序号三角形,读取索引顺序是不一样的。偶数三角形三个顶点索引顺序跟用户指定的一致([1,2,0]),奇数三角形前两个索引顺序与用户指定的相反([0,2,3]中的0和2与用户指定索引2,0反序)。这是由GPU自动完成的,以保证所有的三角形顶点顺序一致地按照顺时针(或逆时针)排列。
        此外,三角形的奇、偶是以0为基准的。

        除此之外还有Control Point PatchList类型,由于其主要用于Tessellation阶段作为控制点使用,这里不多作介绍,在后面学习到曲面细分技术时再来了解它。

2. Vertex Shader Stage
        这是一个完全可编程的阶段,即完全由程序员自己来实现。该阶段的核心为模型顶点的各种空间变化。3D图形学定义了以下几种坐标系空间:
        1. 模型空间:Model Space,也叫Local Space
        直观的讲,这个坐标系一般以模型中心为原点,所有的模型在建模的时候给定的模型顶点坐标都以这个坐标系为基准,用户最开始所指定的顶点坐标也是位于该空间。
        给出模型空间的好处在于方便建模,以及单个模型的重重利用。因为一个物体可被放置到场景的多个地方,这时每个物体的顶点坐标显然是不一样的,但可以共享同一个模型。
        2. 世界空间:World Space
        这个坐标系即3D场景给各个物体指定坐标的基准。场景有不同的物体具有不同的世界坐标。
        3. 视角空间:View Space
        这个坐标是以照相机为基准的,以照相机位置为原点,照相机朝向z轴正方向,右边为x轴正方向,上边为y轴正方向。之所以设置这个坐标系,主要是为了主便接下来的投影及裁剪操作。如果直接在世界空间下进行,由于照相机位置、朝向灵活多变,计算将会十分复杂。有了视角空间,一切计算以原点为基准,会大大方便计算。
        4. 投影、裁剪空间:Projection Clip Space
        这个空间即世界空间的物体被投影到相应的投影面上之后,继而进行裁剪操作所在的空间。

        用户指定的所有顶点都是基于模型空间的,在Vertex Shader阶段,每个顶点要依次经历所有这些空间,最终转换为屏幕上对应的二维坐标,不同空间之间的切换称为“空间变换”,实现空间变换的基本工作即矩阵。
        I. 模型、世界空间变换
        从模型空间到世界的变换主要包括:缩放、旋转和平移。缩放和旋转操作通过3X3矩阵及可实现,为了实现平移操作,则需要4X4型矩阵,因此所有的空间变换统一采用4X4矩阵,且顶点坐标也采用相应的[x,y,z,w]型。大多数情况下,w=1,[x,y,z]与顶点本身坐标保持一致。此外,多出的w在投影变换中发挥了至关重要的作用。
        II. 世界、视角空间变换
        从世界空间到视角空间通过相应的“视角矩阵”实现。为了更好的理解视角矩阵的作用,可以这样理解:

       在任意时刻,相机在世界空间都有一个位置坐标[Px,Py,Pz],同时也有相应的朝向,我们可以用三个坐标轴来确定其朝向,即U,V,W,U指向相机右侧,V指定相机上侧,W为相机注视方向。那么视角矩阵的作用,即把相机位置移回到世界坐标系原点,且三个坐标轴U,V,W与世界坐标系的X,Y,Z分别重合。这就是视角矩阵的目的!理解这一点对于自己来实现灵活的照相机非常重要,因为实现照相机最重要的一点即根据任意时刻相机的位置、朝向来计算其视角矩阵。
        III. 视角、投影空间变换
        从视角空间到投影、裁剪空间依靠“投影矩阵”来实现。投影有两种:正交投影和透明投影,大多数情况下,比如游戏中,用到的投影为透视投影,因为这种投影方式与人观察物体的方式是一样的。
 要计算投影矩阵,首先要确定照相机的几项基本参数:近、远平面(n,f),投影平面的宽、高比(r),以及上、下视野角度大小(a)。近、远平面规定照相机能看到的最近和最远的距离。有了这些参数,所有能投影到屏幕上的点组成了如下所示的多面体:
 
        即一个被切掉顶部的金字塔。
        投影变换的效果即把这个多面体转换成长方体,长、宽分别位于[-1,1]之间,z位于[0,1]之间。真正的裁剪操作就是在这个长方体中进行的,因此将大大简化裁剪的计算。
        关于投影变换,要注意一点的是,很多人误以为投影即把三维顶点投影到二维平面 上,投影变换后顶点的z坐标即被抛弃,只剩下x,y坐标用于后面的屏幕变换。实际上,投影变换后z坐标并没有消失,位于[0,1]之间。屏幕坐标的变换不再使用z坐标,但z坐标在后面的Output Merger阶段用于深度比较时发挥的关键作用。

       整个顶点着色阶段到此结束。

3. Hull Shader Stage、Tessellation Stage、Domain Shader Stage
        这三个阶段其实共属于Tessellation Stage,即曲面细分阶段,可选阶段。这个是D3D11中刚加入的一个高级特性,主要用于如LOD(Level of Detail)技术中。
        该阶段主要的好处即在运行期可利用显卡动态的增加模型多边形的细节。例如在地形渲染中,根据距离照相机距离的远近程序采用不同的细节等级,近距离的部分采用高精度的多边形,远距离的部分采用低精度的多边形,以同时满足视觉上的要求又优化了渲染。 另一个利用曲面细分的典型例子是Displacement Mapping,这个在后面学习法线映射时会介绍。

4. Geometry Shader Stage
        这个也是D3D11中加入的新特性,为可选阶段。在这个阶段中,输入为一个完整的多边形,点、线段或三角形。这个阶段直接对输入的多边形进行操作,可以把其消灭,不再往下一个阶段传输;也可以衍生出新的多边形出来。总之,该阶段操作的对象是完整的多边形,相比于顶点着色阶段,其操作的对象是单个的顶点。

5. Rasterizer Stage
        这个阶段属于不可编程阶段,即完全由硬件实现,主要包括:
        1. 视口变换
        即把投影变换后得到的顶点的x,y坐标,根据用户设定的视口参数,变换到屏幕上对应的坐标。
        2. 隐藏面消除(Backface Culling)
        即使经过了裁剪操作,对于每一个物体,照相机只能看到其正对着相机的一面,对背对着相机的一面是看不到的。这一步的任务即是把看不到的这一面消除掉,以免继续对其进行处理影响效率。
        为了确定一个多边形是正对着相机还是背对着相机,就要用到我们在Input Assembler Stage指定多边形(三角形)时的顶点顺序了。默认情况下,D3D规定按顺时针顺序指定的三角形属于正面,逆时针为背面。如果V0,V1,V2按顺时针排序,则该三角形为正面,将通过这一步的检测,如果为逆时针,则被抛弃。
        确定顺时针还是逆时针,可以用如下方法:
        给出两个向量:E0 = V1-V0 E1 = V2-V0对E0和E1进行叉乘操作N = E0 X E1。如果N指向相机,则为正面,否则为背面。
        3. 顶点属性的插值计算
        在Input Assembler Stage中,用户指定的仅仅是一系列的多边形,以三角形为合例,每个三角形由三个顶点组成,每个顶点包含一系列的属性,如坐标、法线、纹理坐标等等。在经过顶点着色阶段、视口变换后,这三个顶点在屏幕上都有对应的坐标。但为了显示该三角形,仅仅三个顶点显然是不够的,为了计算该三角形所覆盖的屏幕上每个像素处的属性,要进行正确的插值计算。
 注意,插值计算的要求是,在世界空间中保证以三个顶点为基准进行线性计算,在二维屏幕上,以相应的投影后的三个顶点进行插值时不再是线性。插值方法如下图所示:
 
        不过,这一点了解一下就够了,毕竟这一步插值计算是完全由硬件完成的。如果想有兴趣了解的更多一点,可以参考《Mathematics for 3D Game Programming and Computer Graphics》,针对这个有详细讲解。

6. Pixel Shader Stage
        这个阶段也是完全可编程的一个阶段,也是跟顶点着色器阶段一样十分重要的阶段。因为在D3D11中,顶点着色器和像素着色器是程序员实现的两个最基本的阶段。
        像素着色器,从名字上也很容易看出,是在像素级别上进行的计算。对于三维空间中投影到屏幕上的每一个多边形,针对其在屏幕上所覆盖的每一个像素,逐个进行像素着色计算。这一阶段接受的数据是经过插值计算后的顶点属性。输出的是颜色值,以提供给下一阶段处理。
        像素着色器给程序员提供了相当多的灵活性和自由度,通过各种不同的算法来计算片段颜色以实现各种特效。

 

7. Output Merger Stage
        这个阶段即输出片段的混合阶段。该阶段不可编程,但是高度可调节。程序员可以灵活地调整管线的状态来实现不同的特效。比如针对深度缓冲区、模板缓冲区,混合等可以有各种不同的状态。利用它们来实现各种特效后面也有特别详细的介绍。


        D3D11整个渲染管线到这一步就结束了,小结一下:
        3D渲染管线的作用就是,给定场景描述:顶点属性、索引、照相机、光源、材质等信息,计算其在光栅显示器屏幕上对应的显示结果。其主要阶段包括:Input Assembler Stage、Vertex Shader Stage、Tessellation Stage(包括三个子阶段:Hull Shader Stage、Tessellator、Domain Shader Stage)、Geometry Shader Stage、Rasterizer Stage、Pixel Shader Stage、Output Merger Stage。
 
        3D渲染管线对于学习3D图形学还是D3D API,都相当重要。因此,请务必花时间深刻理解之,否则是不可能灵活地写Shader的。


D3D固定渲染管线

分类: D3D 游戏相关   319人阅读  评论(0) 收藏 举报
D3D渲染管线的意义是什么呢?说白了就是将3D图像转换成2D图像到屏幕的过程。

       那如何操作呢?这便是咱接下来需要解决的!

       此篇理论东西多点,随着下一章节的学习会好点,所以,大家伙就跟我一块重温学习下吧。

        在基于D3D的图元绘制均是以三角形网格的搭建为基础的,这个过程称之为建模。那如何在程序中实现一个三角形的绘制呢?你要记得一个关键点就是顺时针和逆时针的顺序,我个人比较喜欢顺时针。下边会讲解顺时针和逆时针的区别!本章的重点是讲述D3D的固定渲染管线,所以涉及的其他知识点,会在接下来的学习中,补充!

         一、顶点格式 创建一个顶点,并不是单纯数学意义上的只包含位置就完事了,D3D为我 们扩展了很多,咱举个例子,每个顶点,都有位置Postion、法线Noraml、纹 理TexTure1、颜色Colour等。那拥有这么多的附加属性,我们怎么弄呢?还记 得我们在C++中学过的结构体吗,对,就是它,用它来实现定义。举个例子:

             Struct Vertex

                                {

                                  float x, y , z; //位置

                                    float nx, ny; //法线

                                    float _u, _v; //纹理

                                    DWORD Colour; //颜色

                                }

            这里需要一个注意的地方,就是当你再定义灵活顶点格式(FVF)的时候,顺 序应与你定义的结构体的顺序一致。例如:

        #define FVF_VERTEX(D3DFVF_XYZ | D3DFVF_NORML | D3DFVF_TEX1 | D3DFVF_DIFFUSE)

         二、三角形的组织 这里先不说了,到下一章实战操作的时候再整!记得顺序、普通组织、 索引组织这几个概念。

        三、简要介绍下摄像机 摄像机的作用就是确定哪些可见的3D物体转换成2D图形。 可视体:由远近裁剪面组成的平截台体。只显示在可视体内部的图形,其他的 一律剔除,这个过程叫做裁剪。 投影窗口:是这个可视体内的3D几何图形投影生成的3D物体的2D图像的2D区域。 详细的说明会专门拿出一章来学习D3D的摄像机。

        四、固定渲染管线<本章的核心,前面仅需了解即可> 在我们的图形几何学上有了3D场景及摄像机,最后我们还需要将它们转换成2D 图形来显示在屏幕上。这就是固定渲染管线所作的工作。 实际上D3D的渲染管线大部分工作都是在做图形变换。D3提供了一个简便的函数 g_pDevice->SetTransform(变换类型,变换矩阵)。 下边我们一起回顾或者学习一下D3D的渲染流水线的理论细节:

               1、本地空间 说白了就是建模空间(美工建模,或者你在本地组织三角形的组织方式)

                2、世界空间 通过平移旋转缩放将那些本地空间的物体转换成世界空间内的物体,以 实现场景的组织。D3D提供了一个位置变换的函数D3DXMaterxTranslation; 旋转函数D3DXMaterxRoationX/Y/Z/Axis;缩放函数D3DXMaterxScalling。具体 请你参阅DXAPI。

               3、视图空间(即摄像机空间) 世界空间中的几何图和摄像机的位置是相对于世界坐标而定义的。但是有 一个缺陷是如果摄像机的位置在世界空间中的位置不是确定的或者死板的,那 通过该摄像机去观察物体那是非常难于控制和低效的。在这种尴尬局面下,诞 生了视图空间这个概念!我们这样操作摄像机,首先将摄像机移至世界空间的 原点,然后旋转摄像机,让它的正方向与世界空间的Z方向一致。这样当你再移 动或者旋转摄像机的时候,世界空间中的几何图就会随着摄像机的变化而做相 同的变化。使其变得顺其自然,而不是被动的啦! D3D同样为我们提供了一个简便的函数D3DXMatriLookAtLH。

              4、背面拣选 D3D通过背面拣选方式剔除(即删除多余的处理过程)无用的背面多边形,来 提高程序的执行效率。 D3D默认的顶点是以顺时针组织的多边形为该多边形的正面。 D3D同样给我们提供了一个函数来做这项工作: g_Device->SetRendState(D3DRS_CULLMODE,Value)。默认的是D3DCULL_CCW。

              5、光照 光照的定义是在世界空间中定义的,并不是在视图空间定义的。但是视图空间 将这些点弄的非常真实。

              6、裁剪 超出凭借台体的部分几何图将被无情裁剪,借此提高程序执行的效率跟性能。

               7、投影 投影的作用就是将3D场景转换成2D图像,然后转到投影窗口上去。 这种从n维到n-1维的过程就叫投影。游戏开发中用到的投影是透视投影。 因为透视投影可以使远离摄像机的图形在屏幕上显示的时候也变小,这使得 我们的效果更加逼真的转换成2D图像。 D3D同样也给我们一个简便的投影变换矩阵:D3DXMaterxPerspectiveFovLH。

              8、视口变换 视口变换就是将投影窗口变换为屏幕上一个矩形区域的可靠变换,这个矩形区域 就是所谓的视口。 D3D中有一个结构体帮助我们设定视口的相关属性D3DVIEWPORT9结构;并且D3D还 给我们提供了另外一个重要的函数g_pDevice->SetViewPort(D3DVIEWPORT结构的一个 变量地址)。 对于视口变换的矩阵的相关重要知识点下节进行重要分析。

              9、光珊化处理 经过视口变换这些个图像就到屏幕上去了。光栅化所处理的是计算需要显示的每个 三角形中每个点的像素值。它总是应该通过硬件来进行处理,因为它太过于繁琐了如果 微软自己编码处理的话。 在计算完了像素值之后呢,它就将这个成形的2D图像凸现出来啦!

        说了这么多,我感觉最后需要总结一下子,你觉得呢? 本章重点阐述了D3D的固定渲染流水线。涉及9小点,那你如何记忆呢? 还是之前说的D3D初始化那个记忆方法: 分为3个流程:

设计 --- 生产 --- 显示

设计:本地 ---> 世界 -->视图空间(摄像机空间) --> 拣选 -->光照 ---> 裁剪(超出平截台体的部分)

生产:按照以上设计的规格进入生产流程 --> 投影(将设计中的3D物体转换成现实的2D图像,并转到投影上去) --->视口变换(将2D图像映射到屏幕的某个区域内,给他提供可供显示的空间)

显示: 光栅化处理

批注: 光栅化做了什么什么事情: 光栅化就是把矢量的图形像素化,比如说3个顶点组成的一个三角形把它转化为屏幕上的像素的过程。 简单的说,就是把要显示的东西,显示在显示器上过程(给图像加颜色实际上)。



D3D把整个渲染分为9个步骤,9个步骤的组合,就叫做流水线,或者叫 管线 (参阅 设计模式 之流水线模式)。
D3D的渲染管线(Rendering Pipeline):局部坐标变换 -> 世界坐标变换 ->观察坐标变换->背面消除->光照->裁剪->投影->视口计算->光栅化。
无论是固定渲染管线还是可编程管线,都需要经过这九个步骤:
可编程管线,顾名思义,就是说管线中的某些环节是可以被控制的。人们可以通过对GPU中的着色器进行编程的方式,来控制、管理加速卡的渲染效果。
着色器分为顶点着色器和像素着色器。
顶点着色器是在进行坐标变换和光照计算时工作
像素着色器是在光栅化环节工作。
人们对着色器进行自定义编程时,这个流水线就叫做可编程管线。同时,D3D还提供默认的着色器程序,当游戏或应用程序完全使用默认着色器程序时,这个流水线就叫做固定管线。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Egret H5 是一种基于HTML5的游戏开发引擎,其渲染流程可以简单描述为以下几个步骤: 1. 准备阶段:在渲染之前,需要完成游戏资源的加载和初始化工作。这包括图片、声音、动画和其他资源的加载,以及游戏场景和界面的初始化设置。 2. 创建场景:Egret H5通过场景与层的概念来管理游戏的元素。在创建场景时,会设置游戏画布的大小和位置,同时创建不同的层,用于容纳游戏中的不同元素。 3. 加载场景元素:在此阶段,需要加载游戏的场景元素,如角色、背景、道具等。这些元素可以是静态的图片,也可以是可交互的动画。加载完成后,这些元素将被添加到对应的场景层中。 4. 渲染循环:Egret H5通过渲染循环不断更新画面,实现动态效果。渲染循环是一个不断循环的过,每一帧都会执行各种更新和渲染操作。 5. 更新元素状态:在每个渲染循环中,需要更新游戏中各个元素的状态,包括位置、旋转、缩放等。这些更新会基于各种因素,如用户输入、游戏逻辑等。 6. 碰撞检测:在游戏中,需要检测元素之间的碰撞,以便触发相应的事件。Egret H5通过检测元素的位置和形状来实现碰撞检测,一旦发生碰撞,会触发相应的逻辑处理。 7. 渲染画面:在每一帧更新之后,需要将更新后的画面渲染到屏幕上。Egret H5通过调用浏览器的Canvas或WebGL API来实现画面的渲染工作。 总的来说,Egret H5的渲染流程包括准备阶段、场景创建、元素加载、渲染循环、更新状态、碰撞检测和画面渲染。通过这些流程,Egret H5能够实现丰富多样的交互效果,让开发者能够灵活地创建优秀的HTML5游戏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值