【西川善司的3D图形技术连载】3D图形的概念和渲染管线(Render P
3D图形的概念和渲染管线(Render Pipeline)
前面介绍了3D图形历史,接下来要解说的是3D图形的处理流程。 3D图形管线的流程图 图1是3D图形的流程模型。这个虽然是对应DirectX 10/SM4的GPU流程模型,不过部分流程会根据GPU的不同,有时会有更细致的处理,有时也会做一些简略,这点敬请谅解。 首先,介绍一下3D图形的处理为什么会变成这样的根本原因。会变成这个样子,是由于在漫长又短暂的实时3D图形历史中,这个部分需要进行最顺畅的处理,更重要的是因为这样设计GPU会更容易实现的原因。这个流程不管是在Direct3D还是在OpenGL里都没有太大的差异。 CPU负责的3D图形处理部分 = 游戏引擎? 图1的[1]和[2]的部分,主要是在CPU里进行的处理。 配置3D物体或是移动后再设置,因为这两种很类似,所以把这些在系统中处理的部分全部称作[游戏引擎]。 在游戏引擎中,遵从键盘输入、鼠标输入、游戏控制输入让3D角色移动,或是进行开枪击中敌人的命中时的碰撞检测,根据碰撞的结果,虽然要进行把3D角色们击飞的物理模拟,但这些是游戏逻辑的部分,某种意味上,是和[1][2]相同的部分。 另外,在[2]中如果有对应DirectX 10/SM4.0的GPU,要是能利用Geometry Shader,那么也可以在GPU上进行了,例如关于particle或billboard这样的point sprite,把创建和销毁用Geometry Shader来处理,就可以实现让GPU介入的处理。虽然如此,一般的3D游戏处理中,这部分还是由CPU来处理的部分。 Vertex Pipeline和Vertex Shader的坐标系是什么? 图中红线的[3][4][5][6]的部分,是进行顶点相关处理的顶点管线。 通常从这里开始是在GPU内部进行处理的部分。但是,为了简化内部逻辑以降低成本,所以要让图形机能整合,就是所谓的[统一芯片组],把这个顶点管线转移到CPU的(仿真)系统也是存在的。 那么,直到稍早之前,很多时候把这个顶点管线称为[几何体处理]。所谓几何体(Geometry)就是是[几何学]。在高中,虽然就会在数学或是[代数?几何]的课程中,学到[向量(Vector)运算]和[线性映射(Linear Map)或线性变换(Linear Transformation)],不过这就是那个世界的事了。说句闲话,NVIDIA的GPU,GeForce系列的名字是由「Geometric Force(几何学的力量)」的缩写所造的名词,可以说有着[G-Force重力]的双关语。 把话题转回来,说回3D图形上的[3次元向量]的概念,简单而言想成是[三次元空间上的”方向”]就可以了。这些”方向”被x,y,z的3个轴的坐标值来表示,以这些”方向”为基准的被称之为[坐标系]。 「局部坐标系」,如果具体的描述就是对于某个3D角色来说,设置为基准的坐标系,3D角色的方向就是这个3D角色的基准坐标系,通过处理[朝向是哪里],控制的人会很轻松,所以利用了局部坐标系这个概念。 对了,一般的3D角色上虽然有很多是带有手臂和脚,考虑到那些手脚在关节处弯曲的情况,如果用关节为基准的局部坐标系进行控制会更容易理解,但是这样考虑的话,就要把局部坐标系做成多层的结构,最终的处理会变得不容易理解。 接下来,支配3D全局空间的整体坐标系就很有必要了,这就是[世界坐标系]。在处理3D图形的顶点管线中的顶点单位时,从局部坐标系向世界坐标系的变换会多次发生。 这样生成的顶点要根据shader程序进行坐标系的变换处理,就是[3][顶点着色语言][Vertex Shader]。通过着色器编程,就可以进行独特而特殊的坐标系变换。 图2 坐标系的概念图
Vertex Shader的另一项工作:顶点空间的阴影处理。 Geometry Shader可以增减顶点的厉害东西 在DirectX 9/SM3.0之前,GPU并不包含Geometry Shader,3D模型的顶点信息是通过CPU这边预先准备好之后,再输入到GPU中,在GPU这里不能随意的进行增减。 为了打碎这个“原则性限制”,拥有可以自由增减顶点功能的着色器就是[Geometry Shader]。 通过Shader程序可以指定Geometry Shader对顶点信息进行增减。还有,因为实际增减的是复数的顶点,所以对各种的线段、多边形、粒子等图元也可以进行增减。 利用Geometry Shader的各种方法被创造出来,因为可以自由的生成多边形,那么就可以在地面上生长出草的多边形,或者让3D角色生长出毛发等是最基本的使用方法。在游戏中,还可以把不需要做逻辑交互处理的例如火花等特效的表现,使用Geometry Shader来生成。 【千里马肝注:Geometry Shader并不如想像中,或者说是宣传中那么好。可能是由于成本或是其他的什么原因,Geometry Shader通常是在display driver中实现的,也就是说其实是由CPU负责计算,当重新返回GPU的VS时,对流水线的影响很大,所以Geometry Shader的实际效能并不高,甚至是非常低。】 大致上就是可以做到这些吧。 用Geometry Shader生成的顶点,因为还可以再返回到Vertex Shader,所以可以对返回的顶点重新进行处理。例如普通方法不能实现的,把低多边形的3D模型,在Geometry Shader里通过插值生成更平滑的高多边形,理论上也是可行。 顶点管线处理的最后 【千里马肝:即Independent Transparency,从视点观察时模型时,可能出现由于顶点传入顺序的原因,背面的顶点在前面的顶点之前就绘制的问题,于是Alpha Blend就不正确了。】 负责分解和发送像素单位工作的光栅器(rasterrizer) 当变换到视野空间,无用多边形都剔除后,在[7]上进行的是,把到没有实际形态的多边形,绘制为对应在画面上的像素的处理。另外,在最新的3D图形上,并不只是绘制显示帧,也有把场景渲染到纹理的情况,这个时候[7]会进行多边形和纹理像素的处理。 在[7]上的处理,实质上是将从顶点管线上把成为顶点单位(多边形单位)输出的计算结果,作为像素单位进行分解,持续的向像素管线发送任务,可以说是起到中介的作用。 这个[7]的处理被称作[triangle setup],或者是[rasterise处理],因为是个规范化的处理,所以从1990年代初期的GPU里就作为固定功能实现在GPU里,到现在也没有太大的进化。 通常,一个多边形因为要用多个像素来绘制,所以多边形通过光栅化被分解成大量的Pixel Task。在GPU上Pixel Shader处理单元的数量如此之多,是由于需要处理的像素是如此繁多的原故。 进行像素单位阴影处理的Pixel Shader,纹理(Texture)不只是图像而已
渲染的后端 Render BackEnd [是不是可以写入的验证]的部分为[Alpha Test]、[Stencil Test]和[Depth Test]。 Alpha Test是对输出的Pixel颜色是否完全透明的测试。α元素为0时为透明不需要绘制,意味着将放弃对应Pixel的绘制。 Stencil Test能够以多种方式进行检测,以Stencil Buffer的内容为参照来计算Frame Buffer,对于设定好的条件如果不能通过,就会把那个Pixel放弃绘制。应用之一,作为Stencil Shadow Volume 的影子生成技术。 深度测试是检查所有要绘制的可见像素中,哪些是从视点来看最近的像素。和绘制像素一一对应的用来存放深度值的称作Z Buffer,从这里读出的深度值和要绘制的像素的深度值做比较,就是[深度测 试的实际状态],深度值由Pixel Shader计算获得。 另外,在绘制半透明3D对象的像素时,也有不进行这个深度测试的情况。 [是否可以写入的验证]的变化还有[Alpha Blending]和[Fog]。 α混合,并不能将像素直接进行绘制,而需要和当前位置已经写入的像素做半透明计算后再写回的处理。从渲染对象的Frame Buffer中读出像素颜色,因为需要读取显存的处理,所以进行Alpha Blending相比普通的像素处理是需要更多的负荷。那些3D测试软件都是以连续绘制重叠的半透明来作为性能评价的。 Fog(雾),是根据绘制像素的深度值,调整预先设定的雾的混合颜色来进行处理。越远的地方的像素颜色越接近白色,用作表现场景深处可以看到朦胧感的空气。 当然,不处理Alpha Blending和Fog的时候,就可以直接把像素颜色写入显存。并且在写入的时候,为了下一次像素的深度测试作准备,同时进行深度值的更新。 另外,画面中的像素是以格子型排列的,为了减少画面的锯齿感,要在渲染的BackEn。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |