又是一个七天七夜。对于3D游戏、图形卡原理;一个图形学初哥总算弄明白一些了。但疑惑的更多,以至于每天都有“十万个为什么”在脑海中翻腾;辗转难眠。意念力已耗尽,必须休闲一段时间了。尽管,对于实时光线追踪算法有了新的解决方案;但论证还是要放在后面的章节。下面内容,相当部分是网上抄录整理的,以便后面对APO的GPU作规划。
顶点渲染单元(Vertex Shader):根据描述3D图形外观的三角形顶点数据确定3D图形的形状及位置关系; 作几何变换、生成3D图像的骨架。
光栅化:显示的图像是由像素组成的,我们需要将描述3D图像骨架的一系列三角形通过一定的算法转换到相应屏幕上的像素点。把一个矢量图形转换为一系列像素点的过程就称为光栅化。例如,一条数学表示的斜线段,最终被转化成阶梯状的连续像素点。
像素渲染(Pixel Shader):光照、光线追踪、纹理帖图、像素着色。 也就是对每个像素进行计算,从而确定每个像素的最终颜色。最后由ROP(光栅化引擎)完成像素的输出,1帧渲染完毕后,被送到显存帧缓冲区;然后经由D/A转换输出到显示器上。
纹理帖图:所有3D场景的对象都是由顶点形成。一个顶点是X、Y、Z坐标形成的3D空间中的一点,多个顶点聚在一起可形成一个多边形,如三角形、立方体或更复杂的形状,将材质贴在其上可使该组件(或几个排好的组件)看起来更真实。纹理映射(texture mapping)工作由TMU(Texture mapping unit)单元完成对多边形表面的帖图。
顶点光照:在vetext shader中计算光照颜色,该过程将为每个顶点计算一次光照颜色,然后在通过顶点在多边形所覆盖的区域对像素颜色进行线性插值。现实中,光照值取决于光线角度,表面法线,和观察点。
逐像素光照:是对所有光照元素进行单独插值,简单地说就是在pixel shader中计算颜色。
光线追踪技术:现在游戏基本都没有应用光线追踪技术,光线都是由你能看到的亮光的物体自身发出的。电脑只是通过演算物体阴影和控制光线的强弱来“模拟”人眼看到的真实情况。尽管现在很多采用了HDR(高动态范围)效果的游戏都有很不错的光影效果,但是那远非真实的光影效果。如果,视角前面有一个类似镜子的物体,该物体的多个三角形镜面反映的是背面的景象;就像汽车的后视镜;但背面的物体GPU已经裁掉了。还有,像水面的物体倒影等;必须采用光线追踪技术。由于从光源发出的光线有无穷多条,使得直接从光源出发对光线进行跟踪变得非常困难。实际上,从光源发出的光线只有少数经由场景的反射和透射(折射)后到达观察者的眼中。为此标准光线跟踪算法采用逆向跟踪技术完成整个场景的绘制;这便在最大程度上节省了计算资源。要想用光线追踪算法渲染出达到现代游戏的画面质量,同时跑出可流畅运行的帧数,每秒需要计算大概10亿束光线。这包括每帧每像素大概需要30束不同 的光线用以分别计算着色、光照与其他特效。按这个公式推算,入门级的1024×768分辨率一共有786432个像素,乘以每像素30束光线以及每秒60帧,我们就需要每秒能计算14.1亿束光线的硬件。而Intel双路四核心处理器每秒也不过只能处理830万束光线。如果将分辨率提升为现在主流的1920×1080,那所需要的运算量将不可想象。APO支持电影模式8192×4096,那就更不用活了。所以,必须有新的算法与硬件。
光线追踪运算中会大量用到递归算法,如有时会出现这样的情况:对每个光源射出一条光线来检测是否处在阴影中,如果表面是反射面,生成反射光,将会运用递归继续跟踪;如果表面透明,生成折射光,还是运用递归继续跟踪。当前交点所在的物体表面为理想漫射面,跟踪结束。递归算法是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。光线追踪算法需要双精度浮点运算的支持?不太了解。
二、流处理器SP(Stream Processor,就是可编程流式并行运算单元ALU)
ALU(逻辑算术单元,顾名思义,可以进行加、减、乘、除、乘加、开方、倒数,平方根倒数,log2, exp2,sin,cos等算术运算)。在APO中,SP的最小单元是管线,一个管线是一个ALU单元支持32位单精度浮点数的运算。双精度浮点数的运算则需要2根管线,一条管道有8根管线,管道内是SIMD架构。每条管线都支持1D、2D、3D、4D到nD的向量和矩阵的单精度浮点数运算。数据的基本单元是Scalar(标量),就是指一个单独的值,SP的ALU进行一次这种变量操作,被称做1D标量。每条管线都可以按照动态流模式控制,智能的执行各种4D/3D/2D/1D指令,无论什么类型的指令执行效率都能接近于100%。SP有256条管道,多个管道单元都是根据不同的控制流程执行不同的操作,处理不同的数据,因此,SP是多指令流多数据流处理器,即管道间MIMD(Multiple Instruction Stream Multiple Data Stream,简称)架构,管道内部的8根管线是SIMD架构。一根管线的1D乘法、除法、开方、加、减运算速度是2G/S。4D向量与变换矩阵的乘加速度是0.125G/S,一条管道的速度是1G/S;一个SP(256条管道)全用来作矩阵变换的速度是256G/S。APO支持电影模式8192×4096,颜色是64位。有32M个像素,即使所有三角形都是最小的,对应变换后的像素只是3个顶点;那一个视锥体最多有32M/3个三角形。那6个方向,360度场景最多有6*32M/3 = 64M个三角形。APO支持28位表示的将近3亿的三角形数场景。通常要处理的顶点数会小于1M个;如果一条管道的流水深度是1K个顶点,那么APO需要4次批数据存储传输,几何变换时间是:60帧*4*1K/1G/S = 0.24mS。APO中,当打开场景文件时,空间管理者CPU的SP就已经帮处理好几何变换形成有序的文件给显示管理者。显示管理者CPU的SP只是多了光栅化单元、纹理单元等功能吧。其实,光照、光线跟踪、像素着色等也可在APO的其它CPU部件进行。光栅化只能在显示管理者的SP进行。当然,可编程的SP你可以有一部分管道做VS的功能,另一部分管道做PS的功能。3D图形生成就是一个运算过程! 在3D图形进行渲染时,其实就是改变RGBA四个通道或者XYZW四个坐标的数值。GS(几何着色器Geometry Shader)、PS(像素着色器Pixel Shader)、VS(顶点着色器Vertex Shader)都是1D—4D的流运算吧。每个像素可以提供多种数据的像素着色器,由你的顶点着色器生成并由光栅化成线性插值。这允许你的像素着色器依照光照条件调整像素的颜色,添加反射,执行凹凸贴图和纹理采样等。你也可以用像素着色器应用后处理效果在整个要渲染的场景, 像亮度,色彩增强,饱和度和模糊。额外的,像素着色器可以改变像素深度。这个深度用在输出合并时决定哪个像素被绘制哪个不被绘制。这个深度指示原始三角形离相机有多远。但是,如果你想影响输出合并的决定,你可以自己指定这个值。传统的一条渲染管线是由包括Pixel Shader Unit(像素着色单元)+ TMU(纹理贴图单元) + ROP(光栅化引擎)三部分组成的。用公式表达可以简单写作:PS = PSU+TMU+ROP 。从功能上看,PSU完成像素处理,TMU负责纹理渲染,而ROP则负责像素的最终输出。所以,一条完整的像素管线意味着在一个时钟周期完成至少进行1个PS运算,并输出一次纹理。顶点着色器,取代固定渲染管线中的变换和光照部分,程序员可以自己控制顶点变换、光照等。
三、 三角形调整引擎
face culling:
user clip planes:除了使用投影矩阵定义出的6个clipplane之外我们也可以额外自己定义对应的clipplane来剪裁。
frustum culling:视锥裁剪。
CVV culling:规范立方体(Canonical view volume,CVV)。CVV 的*面(梯形体较小的矩形面)的X、Y 坐标对应屏幕像素坐标(左下角是0、0),Z 坐标则是代表画面像素深度。多边形裁剪就是CVV 中完成的。所以,从视点坐标空间到屏幕坐标空间(screen coordinate space)事实上是由三步组成:
1. 用透视变换矩阵把顶点从视锥体中变换到裁剪空间的 CVV 中;
2. 在 CVV 进行三角形裁剪;
3. 屏幕映射:将经过前述过程得到的坐标映射到屏幕坐标系上。
法向量从object space 到world space 的转换矩阵是world matrix 的转置矩阵的逆矩阵。
四.
物体空间:
世界空间:
一个物体的物体空间和其它对象没有空间上的关系。世界空间的目的是为在你的场景中的所有物体提供一个绝对的参考。一个世界空间坐标系如何建立可以任意选择。例如:你可以决定世界空间的原点是你房间的中心。然户,房间里的物体就可以相对房间的中心和某个比例和某个方向放置了。
建模变换:
眼空间:
最后,你要从一个特殊的视点(“眼睛”)观看你的场景。在称为眼空间(或视觉空间)的坐标系统里,眼睛位于坐标系统的原点。朝“上”的方向通常是轴正方向。遵循标准惯例,你可以确定场景的方向使眼睛是从z轴向下看。
视变换:
剪裁空间:
投影变换:
标准化的设备坐标:
透视除法:
窗口坐标:
五.
六.