渲染流水线概叙

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中:左上角为最小的屏幕坐标值

光栅化阶段

​ 处理上一个阶段屏幕坐标系下的顶点位置以及它们的额外信息,如深度值、法线方向、视角方向;

三角形设置

​ 得到三角形边界的表示方式,将三角网格的顶点转换得到像素坐标,为下一个阶段做准备;

三角形遍历

片元着色器

逐片元操作