渲染流水线:从一个三维场景出发,生成我们在屏幕上看到的图像的过程。
渲染流水线分为三个阶段:
应用阶段------------>几何阶段----------------->光栅化阶段
1.应用阶段:Cpu来负责,拥有绝对控制权,属于可编程阶段。该阶段准备场景数据,将渲染所需数据从硬盘加载到内存中,网格数据等被加载到显存中。不可见剔除。设置渲染状态,使用什么类型的着色器,光源属性,材质等等。紧接着调用DrawCall,通知GPU进行渲染,DrawCall指的是一个命令,发起方是Cpu,接收方是Gpu,该命令只会指向被渲染的图元列表(渲染所需要的东西)。该阶段会输出渲染图元到几何阶段。
2.几何阶段:Gpu负责,把顶点坐标变换到屏幕空间中,交给光栅器处理。最终输出屏幕空间的顶点信息(深度值,着色等)到光栅化阶段。
3.光栅化阶段:Gpu负责,使用上个阶段传递的数据来产生屏幕上的像素,并最终输出图像。
几何阶段和光栅化阶段,开发者无法拥有绝对控制权,实现载体为Gpu。Gpu通过实现流水线化,大大加快渲染速度。虽然我们无法拥有绝对的控制权,但是Gpu 开放了很多控制权。
顶点处理:通过一系列的坐标系转换(本地坐标系-->世界坐标系-->观察坐标系-->投影坐标系),将模型的顶点在摄像机前进行位移,并最终投影到摄像机的投影屏幕上。该阶段抓取数据并最终传入顶点着色器。
顶点着色器:处理单位是顶点,输入进来的每个顶点都会调用一次顶点着色器。顶点着色器本身不可以创建或者销毁任何顶点,无法得到顶点与顶点之间的关系。完全可编程。
面处理:面的组装,截取,剔除。
一个图元与摄像机的关系有三种,完全在视野内,部分在视野内,完全在视野外部。完全在视野内的图元就继续传递给下一阶段,完全在视野外的图元不会继续向下传递,部分在视野内的需要进行裁剪。
裁剪:这一阶段目的是将那些不在摄像机视野内的顶点裁剪掉,剔除某些三角图元的面片,该阶段可配置。
屏幕映射:该阶段不可配置和编程。将裁减后的齐次坐标转换到屏幕坐标系,屏幕坐标系是一个二维坐标系。实际上是一个缩放过程,在这个过程中Z轴不作处理。OpenGL的零点坐标在左下角,而DX的在左上角。
光栅化:以向量为基本结构的面转换成一个个点阵形式的像素。
三角形设置:该阶段会计算光栅化一个三角网格所需要的信息。我们在上一个阶段得到的三角形网格顶点即每条边的两个端点。如果要计算正规三角形网格对像素的覆盖情况,必须计算每条边的像素坐标。
三角形遍历:检查每个像素是否被一个三角形网格所覆盖。如果被覆盖,就会产生一个片元。该过程也被称为扫描变换。
三角形遍历阶段会根据上一个阶段的计算结果来判断一个三角网格覆盖了哪些像素,并使用三角网格3个顶点的顶点信息对整个覆盖区域的像素进行插值。
4.片元着色器:片元着色器的输入是上一个阶段对顶点信息插值得到的结果。在该阶段可以完成很多重要的渲染技术,比如纹理采样,为了方便在片元着色器中进行纹理采样,我们通常在顶点着色器阶段输出每个顶点对应的纹理坐标,经过光栅化进行插值后,就可以得到起覆盖的片元的纹理坐标。
5.逐片元操作:在OpenGL中叫做逐片元,在DX中被称作输出合并阶段。
该阶段决定了每个片元的可见性,涉及很多测试工作,比如:深度测试,模板测试等。假如一个
片元通过了所有测试,就需要将该片元的颜色值和已经存储在颜色缓冲区的色彩进行混合。
6.像素处理:对每个像素区域进行着色,对像素贴上贴图形成最终画面。
总的来说,材质球,shader,和贴图的关系相当于,材质球是最终的商品,shader是加工方法,而贴图是加工原料。