本文记录《实时渲染》的读书笔记。
图形渲染的流水线包括三个阶段:应用阶段、几何阶段、光栅化阶段。
1. 应用阶段
应用阶段是应用所驱动的,因此是被软件所执行,并且运行在CPU上。根据不同的应用这个阶段包括碰撞检测、全局加速算法、动画、物理模拟等。
2. 几何阶段
几何阶段负责每个多边形和每个顶点的操作,通常这个阶段可以分成以下几个功能阶段:模型和视觉变换——顶点shading——投影——裁剪——屏幕映射。
模型变化:每个模型都有它自己的坐标系,我们要把模型放到时间坐标系去中,就需要通过模型变换。每个模型都有一个与之相关的模型变换,通过这个模型变换可以把这个模型放在世界坐标系中合适的位置。
视觉变换:在场景中的所有模型,都必须在相机的可视范围内才会变渲染出来,而这个相机也是放置在世界坐标系中的某个方位。为了方便后面裁剪和投影的计算,我们需要把世界坐标系变换成相机坐标系,也就是变换世界坐标系使相机处在坐标系的原点,X轴指向右边,Y轴指向上方,朝向-Z轴(有些可能使用+Z轴)。而这个过程是通过视觉变换来完成的。
顶点shading:决定光线在某个材质上产生的效果的这个操作叫做shading。它涉及在不同的顶点上计算shading方程,产生的结果将用于光栅化。
投影:把可视空间(view volume)变换到单位立方体中,这个立方体的坐标范围在(-1,-1,-1)到(1,1,1)之间,这个立方体叫做正规可视化空间(canonical view volume)。包括两种投影,正交投影和透视投影。投影后的坐标系称作标准设备坐标系(normalized device coordinates)。尽管这个过程是从一个空间变换到另一个空间,但这里仍用投影这个术语是因为经过显示后z坐标不在存储在图像中(而是保存在Z-buffer中)。从这个角度上看,这是一个从三维到二维的变换。这里指的是经过显示后的坐标,事实上,投影后坐标还是三维的。
裁剪:只有全部或者部分基本图元的顶点出现在可视空间内才会被传到光栅化阶段,然后显示在屏幕上。一个图元的全部顶点都在可视空间内时,这个图元会直接被传到光栅化阶段,如果全部顶点都不在可视空间内时,这个图元就会直接被丢弃,因此只有那些部分顶点在可视空间的图元才需要进行裁剪。不像其他可编程的阶段,这个阶段通常是被固定的硬件所操作。
屏幕映射:经过这个阶段后坐标将从三维变成二维,这里的二维坐标将变成屏幕上的坐标。在DX10 之前每个像素的中心坐标为“0.0”形式,DX10以后以及OpenGL每个像素的中心坐标为“0.5”形式。另外,OpenGL以左下角为原点,DX以右上角为原点。
3. 光栅化阶段
给定变换和投影后的顶点以及它们相应的shading数据,光栅化的目标是计算覆盖在每个物体上的像素颜色。这个阶段也可以分为几个功能阶段:三角形设置——三角形遍历——像素shading——合并。
三角形设置:三角形表面的差异和其他的相关数据被计算出来。固定的硬件操作来完成。
三角形遍历:这个阶段检查每个像素是否在三角形内部,fragment在这个阶段产生。通常采用插值方法。
像素shading:使用插值shading数据作为输入,输出一个或者多个颜色值用于下一阶段使用。这个阶段是可以通过编程来控制GPU执行,在这个阶段最常用的技术是纹理技术。
合并: 每个像素的颜色值存储在颜色缓存(color buffer)中,并在这个阶段进行颜色合并。这个阶段不是完全可编程的,它可以被配置以产生不同的效果。这个阶段会通过Z-buffer负责解决能见度(visibility)问题。除了color buffer和Z-buffer外,还有其他的一些buffer也在这个阶段产生作用,比如alpha通道,用于执行alpha test,stencil buffer,用于记录已渲染图元的位置。