图形管线是目前使用最为广泛的渲染方式。
图形管线
图形管线中,顶点处理将3D的顶点转换到屏幕2D空间上,光栅化寻找每个图元对应的像素生成未着色的片段(fragments),片段处理步骤将每个片段着色,最后混合每个片段生成最终显示的图像。
更形象的几张图用来帮助理解,从中可以看到每一个操作的输入和输出。
顶点处理
在顶点处理中,主要用到的技术是坐标变换。
经过多次坐标变化,物体从世界坐标系中最终变换到2D的屏幕上。
其间,还需要剔除视野之外的物体。
光栅化
屏幕是像素点阵组成,而变换得到的屏幕空间仍然是连续的。光栅化就是将连续空间分配到每个离散像素的过程。
直线
对于直线来说,根据像素中点决定哪个像素在直线上:
三角形
对于三角形,使用质心坐标系计算每个像素的
片段处理
在光栅化步骤得到的片段是没有颜色的,在片段处理阶段给像素着色。
抗锯齿
锯齿的根本原因在于频谱混叠,解决办法是超采样和使用重建滤波器。
着色
着色主要考虑的是光。和光线追踪中的光照模型一样,要考虑环境光、漫反射光和镜面反射光。
每个像素处的颜色为:
其中
纹理映射
纹理映射的目的是为了得到每个像素的纹理值。三角形的每个顶点需要记录纹理图中的查询坐标,然后通过数值插值得到每个像素的纹理图坐标,最后查询纹理图得到该像素的纹理信息。这些纹理信息带入到上面的光照模型中可以得到最终的光照信息。
值得注意的是,在插值的时候会有一个问题:本来应该在3D世界坐标系上进行插值,但是现在的做法是在屏幕空间上插值,这样会导致透视错误。这一步需要引入透视校正,具体做法就是给
和光线追踪类似,在图形流水线中也要考虑镜面反射和阴影。这两个效果分别通过环境贴图和阴影贴图来实现的。
环境贴图的做法是,根据每个像素处的法线和入射光方向,计算反射光的方向,直接在环境贴图中查询。
阴影贴图的做法是先由光源处计算生成阴影贴图,然后使用相同的坐标变换得到每个顶点的深度,把这个深度和阴影贴图对比,以此判断这个顶点是否是阴影。
混合
上面得到的着色片段还是带有深度信息的,根据这些深度信息最终确定每个像素的值,深度小的片段最终才能显示在屏幕上。主要算法是z-buffer算法。