本文主要是对《Shader入门精要》(冯乐乐著)第2章的内容进行简要总结和一些自己的理解,如果读者和我一样是初学者,建议先看一遍冯女神的第二章,再观看本文,如果文章有任何错误,不足,特别欢迎各位大佬给我进行指正,感谢大家!
首先我们要明白:渲染流水线的最终目的是将一些“零件”(从一个三维场景获得资源:顶点数,纹理,光源等)通过一系列“工厂操作”,最终成为电脑屏幕上的有效果的二维纹理图。
一.简述渲染流水线
1.流水线
结合原文章的例子,以相同时间完成洋娃娃的个数为比较标准,假设为4道工序,每个工序1小时,一个人制作一个洋娃娃4小时,若将这4道工序分配给4位工人做,4小时明显可以得到一个洋娃娃,一个完成前3道工序的洋娃娃,一个完成前2道工序的洋娃娃,一个完成1道工序的洋娃娃,明显可以看到并行开发的效率的优势。流水线中决定生产速度的是最耗费时间的那一道工序的时间(可以自己举例看看),理想状态下,一个非流水线系统转换成n个流水线阶段(每段的耗时相同)则可以使整个系统速度提升n倍。
2.渲染流水线
一个渲染流程分成3个阶段:应用阶段,几何阶段,光栅化阶段(每个阶段也同样是一个流水线),这些阶段由CPU和GPU共同完成。接下来对三个阶段分别做一个总结。
应用阶段
特点:通常由CPU实现,此阶段流水线由开发者主导。
三大任务:1.准备场景数据(摄影机位置,模型,光源等)->2.粗粒度剔除(优化,将不可见的地方去掉,不用交付给下一阶段,减少工作量)->3.设置模型渲染状态(这个模型用 什么材质呀,用什么Shader呀,用什么纹理等)
输出:渲染图元(里面是一些渲染所需的几何信息),其形式可以是点,线,面。
几何阶段
输入来源:渲染图元
特点:通常在GPU上处理,可以分为更小的流水线阶段
任务:处理一切和要绘制的几何相关的事情,需要绘制的图元是什么,如何绘制,在哪绘制。重要任务:将顶点坐标变换到屏幕空间上。
输出:屏幕空间的二维顶点坐标,顶点对应的深度值,着色等信息。
光栅化阶段
特点:还是在GPU上工作,可以分为更小的流水线阶段
任务:用前面两个阶段的数据,产生像素,渲染成图,决定渲染图元的哪些像素显示在屏幕上,对上个阶段的逐顶点数据进行插值,然后进行逐像素处理。
二.CPU和GPU之间的通信
通过上面的介绍,可以看出整个渲染流水线可以分成CPU阶段和GPU阶段,这里主要是介绍CPU到GPU之间的过程(GPU工作之前)。
应用阶段可以分为三个部分:
1.数据加载到显存
渲染数据的走位:硬盘(HDD)->系统内存(RAM)->显存(VRAM)[显卡上的存储空间]
主要的问题:
提问1:为什么要加载到显存中?
回答1:显卡对显存访问速度更快,并且大部分显卡对RAM没有访问权限。
提问2:加载到显存中的数据有哪些?
回答2:所有渲染所需的数据(包括但不限于顶点的位置信息,顶点的颜色,法线方向,纹理坐标等)
提问3:加载到显存后,RAM里面的数据可以删掉了吗?
回答3:有部分数据,由于CPU还希望继续访问,所以不会删掉,因为从硬盘重新加载到系统内存也是要耗费时间的。
2.设置渲染状态
提问1:什么是渲染状态?
回答1:可以理解为描述一个渲染效果是怎样的,是如何被渲染的,例如:使用哪个顶点着色器(Vertex)/片元着色器(Fragment Shader)光源属性,材质等。
3.调用Draw call
提问1:这是个啥玩意?
回答1:就是一条命令,是CPU对GPU说接下来渲染哪个?然后通过CPU的指向去指向相应的渲染图元。(注意,这里只会指向渲染图元列表中的元素),因为经过上一个阶段,每一个图元已经知道自己的渲染状态是什么样了。
提问2:后续工作是什么?
回答2:GPU收到指令,然后GPU根据渲染状态和所有输入的顶点进行计算,最终得到屏幕上的像素。
至此,第二章的前半部分就先总结到这里,下半部分是重点,所以单独在另一篇文章。欢迎大家给我留言哦!
浙公网安备 33010602011771号