渲染流水线
渲染流水线概叙
1.流水线:流水线相当于一种并行操作,可以提高单位时间的生产量。流水线系统中决定生产速度的是最慢的工序所需的时间。
2.渲染流水线:
- 应用阶段:有开发者决定,输出渲染图元
- 场景数据准备:摄像机位置、视锥体、场景中的模型数据、光源信息;
- 不可见剔除工作(Culling):把不可见的物体进行剔除;
- 渲染状态设置:设置模型的材质(漫反射颜色、高光反射颜色)、使用的纹理、使用的Shader等;
- 几何阶段:将顶点坐标变换到屏幕空间中,、输出二维顶点坐标、每个顶点对应的深度值、着色器相关信息;
- 光栅化阶段:对几何阶段得到的数据进行插值,然后进行逐像素处理;
3.渲染中GPU的可配置和可编程阶段
几何阶段:
顶点着色器:必编,实现顶点的空间变化和着色功能;
曲面细分着色器:可编,用于细分图元;
几何着色器:可编,用于执行逐图元的着色操作,或者用于产生更多的图元;
裁剪:可配,将不在摄像机视野内的顶点裁剪掉,并剔除某些三角图元的面片;
屏幕映射:固定,将图元的坐标转换到屏幕坐标系中;
光栅化阶段
三角形设置:固定,程序函数阶段;
三角形遍历:固定,程序函数阶段;
片元着色器:可编,实现逐片元的着色操作;
逐片元操作:高可配,负责很多重要操作,例如修改颜色、深度缓冲、进行混合等;
应用阶段
主要对应的就是应用阶段,起点为CPU:
- 把数据加载到显存中:将渲染数据聪硬盘(HDD)加载到系统内存(RAM)中,网格和纹理等数据又被加载到显卡的存储空间(VRAM)。原因是显卡对显存的访问速度更快,一般来说,显卡没有对内存的访问权限;
- 设置渲染状态:定义网格怎么被渲染的,设置它们的顶点着色器、片元着色器、光源属性、材质等;
- 调用Draw Call:Draw Call是一个命令,由CPU发给GPU的一次渲染命令;这个命令仅仅指向一个需要被渲染的图元列表,而不会再包含任何材质信息,因为上一个阶段已经完成了;
几何阶段
几何阶段采用MVP 矩阵变换得到屏幕坐标
顶点着色器
顶点着色器处理的输入来自于CPU,本身处理的单元是顶点,对每个顶点都会调用一次顶点着色器。顶点着色器本身不可创建或者销毁任何顶点,而且无法得到顶点和顶点之间的关系。不过也正是因为这样的相互独立性,GPU可以并行的处理顶点,速度会很快,顶点着色器要的任务如下;
- 坐标变换:将顶点坐标从模型空间转换到齐次裁剪空间,再由硬件做透视除法后,最终得到归一化的设备坐标(NDC)
- OpenGL中,z分量范围在[-1,1]之间;
- DirectX中,NDC的z分量范围是[0,1]之间;
- 逐顶点光照;
- 输出后续阶段数据;
裁剪
这里的裁剪是对图元的裁剪,一个图元和摄像机视野的关系有三种关系,完全在视野内、局部在视野内、完全在视野外,只有部分在视野内的图元需要进行裁剪。这个阶段是对NDC下的顶点位置进行处理的,所以裁剪就在一个立方体的中进行操作,只有和单位立方体相交的图元进行裁剪,新的顶点被生成,旧的外部顶点被舍弃。
屏幕映射
屏幕映射即是将NDC三维坐标转换成屏幕坐标系,由于输入的坐标在-1到1之间,所以这个过程实际是一个缩放的过程,但屏幕映射不会对输入的z坐标做任何处理,所以屏幕坐标系和z坐标一起构成了窗口坐标系(WC),这些值被一起传递到光栅化做下一步处理;
- 在OpenGL中:左下角为最小的窗口坐标值
- 而在DirectX中:左上角为最小的屏幕坐标值
光栅化阶段
处理上一个阶段屏幕坐标系下的顶点位置以及它们的额外信息,如深度值、法线方向、视角方向;
三角形设置
得到三角形边界的表示方式,将三角网格的顶点转换得到像素坐标,为下一个阶段做准备;
三角形遍历