About: 这个系列blog是在阅读Realtime Rendering 3rd过程中记录的东西,并不是完全的翻译,只是挑了一部分重点,有些地方加上了自己的理解。有些介绍性的章节翻译的比重比较多,技术性的章节可能只记录核心思想,没有逐字翻译。
---------------------------------------------------------------
Chapter 2 The Graphics Rendering Pipeline
流水线的速度由最慢的环节决定。 概念性的stage可细分为功能stages,功能stage可以成为流水线stage也可以不成为。流水线stage是可以同时执行的。例如两个功能stage可以合并为一个流水线stage,某个功能stage被划分为多个流水线stage。
FPS和Hz: fps是每秒钟渲染的帧数,程序生成一帧图像的时间通常是变化的,因此fps表示某个特定帧的速度或者表示一段时间的平均性能。 Hertz(Hz)是1/seconds的记号。Hz用于硬件设备,比如显示器,被设置为固定的速度。
实际fps的计算举例: 输出设备的最大更新频率是60Hz,流水线瓶颈阶段的时间消耗是62.5ms, 那么不考虑输出设备时,最大的渲染速度是1/0.0625=16fps。 然后将这个值匹配到输出设备的频率。 60Hz意味着渲染速度可以是60Hz,60/2=30Hz,60/3=20Hz,60/4=15Hz,60/5=12Hz等等。 这意味着我们能期望的渲染速度是15Hz,因为这是比16Hz小的输入设备可到达的最大固定速度。
三个概念性stage:
-----------------
application stage: 程序控制,软件实现,cpu执行。例如:碰撞检测,全局加速算法,动画,物理模拟等。 这个阶段的最重要的任务是产生rendering primitives。因为是软件实现,app stage就不能被划分为多个substages。 然而为了提高性能,app stage可以在多个处理器核心上平行执行,即超标量架构:在同一时间同一个stage上运行多个进程。
--------------
geometry stage: 处理变换投影等,计算画什么,如何画,画在哪儿。通常由GPU执行。GPU包含很多可编程核心,以及固定操作硬件。 geo stage主要负责per-polygon,per-vertex的操作。
geo stage被细分为这几个功能stage: model and view transform, vertex shading, projection, clipping, sreen mapping. 根据实现的不同,这些功能stages可能等价也可能不等价于流水线stage. 在某些情况下,很多连续的功能stages组成一个单一的流水线stage(这个流水线stage和其他的流水线stage并行运行) 另外一些情况下,一个功能stage可能被划分进几个小的流水线stages。
screen mapping时浮点坐标到像素坐标的确定: dx9(以及之前)中0.0是像素的中心,像素范围[0,9]覆盖了[-0.5,9.5). opengl和dx10(以及之后)中0.5是像素的中心,像素范围[0,9]覆盖了[0.0,10.0)。计算公式为:d=floor(c), c=d+0.5,其中d为像素索引,c为连续的浮点坐标
opengl和directX的差异:opengl总使用笛卡尔坐标系,左下角是最小值,而dx某些地方定义左上角为最小值。
clipping和screen mapping是用固定功能的硬件单元实现的。(非可编程)
----------------
rasterizer stage: 使用上一个stage生成的数据绘制一幅图像,以及任意逐像素计算。完全由GPU执行。 pixels = picture elements
光栅化进行顶点到像素的转换(opengl中图元到片段的转换) 包括以下功能阶段:Triangle Setup -> Triangle Traversal -> Pixel Shading -> Merging
Triangle Setup && Triangle Traversal两个stage: 大概就是计算扫描插值。由固定功能硬件单元实现
pixel shading: 在opengl中,pixel shading即fragment shading是不包含在光栅化阶段中的。pixel shading阶段最重要的技术是texturing。ps通常是可编程的。
Merging阶段: 相当于opengl的per-fragment operations,opengl中紧接在fs之后,也是不包含在光删化中的。
merging包括alpha test(可能没有,比如dx10,gles2.0),stencil/depth test, blending等。 (alpha test主要用来保证全部透明的fragment不会影响z-buffer,也就是说如果半透明物体和不透明的物体混在一起绘制,可以通过alpha test避免z buffer被弄错)
frame buffer通常包括系统的所有buffer,但有时仅指color buffer和z buffer。1990年,accumulation buffer出现了,在这个buffer中图像可以被累加计算,实现:motion blur, depth of field, antialiasing, soft shadows等效果。 当图元通过光栅化阶段后,从当前视点可见的图元被显示到屏幕上,屏幕显示color buffer的内容,为了防止人看到更新的过程,double buffering被使用。 即,绘制是在back buffer上进行的,当绘制完成后,back buffer和front buffer进行交换,交换在vertical retrace(竖直回描)期间进行,这个期间是安全的。
总结: 这个流水线是10多年来实时渲染方面API和图形硬件进化的结果。 需要重要说明的是,这不是唯一的流水线类型。离线渲染经历了不同的进化路径。 电影渲染最常用的是micropolygon流水线,学术研究和预渲染程序例如建筑预现通常使用ray tracing渲染器。 多年以来,这个过程开发者可以用的唯一的方式是固定功能流水线,通过修改一些状态来使用,但不能改变执行的顺序。 最近(很可能是最后)的固定功能流水线机器是任天堂的Wii。