学习-渲染流水线

渲染流水线

渲染流水线是由CPU 、GPU共同完成的。


学习-渲染流水线_第1张图片
概念流水线

CPU上的应用阶段

这一阶段开发者拥有绝对的控制权,主要完成3个任务:准备场景数据(摄像机位置、视锥体、模型场景准备等等);粗颗粒剔除;设置模型渲染状态(材质、纹理、shader等等)。
应用阶段分为三个步骤:

  1. 把数据加载到显存
  2. 设置渲染状态
  3. 调用DrawCall

完整GPU流水线:几何阶段、光栅化阶段

学习-渲染流水线_第2张图片
GPU流水线.png

颜色表示了不同阶段的可配置性或可编程性:绿色表示该流水线阶段是完全可编程控制的,黄色表示该流水线阶段可以配置但不是可编程的,蓝色表示该流水线阶段是由GPU固定实现的,开发者没有任何控制权。实线表示该shader必须由开发者编程实现,虚线表示该Shader是可选的 。

几何阶段摘讲

1. 顶点着色器
它是完全可编程的,通常用于实现顶点的空间变换、顶点着色等功能。它接收CPU传入的顶点数据进行处理。顶点着色器主要完成的工作有:坐标变换和逐顶点光照。除此之外,还可以输出后续阶段所需的数据。

  1. 坐标变换
    顶点着色器可以在这一步中改变顶点的位置,这个在顶点动画中非常有用。经典例子:模拟水面、布料等等。
    需要注意的是:无论我们怎么改变顶点位置,都必须把顶点坐标从模型空间转换到齐次裁剪空间。在顶点着色器中会看到以下代码:
o.pos = mul(UNITY_MVP , v.position);
  1. 顶点着色

2. 裁剪
裁剪的目的是为了让摄像机不处理视野外的物体。完全在视野内的图元就继续传递给下一个流水线阶段,完全不再视野内的就不传递。而那些部分在视野内的就需要裁剪。这一步骤是不可编程的,但是我们可以配置它。

学习-渲染流水线_第3张图片
Clipping.png

光栅化阶段摘讲

光栅化阶段最重要的两个任务是:计算每个图元覆盖哪些像素、以及为这些像素计算他们的颜色。
片元着色器
这一阶段可以完成很多重要的渲染技术,其中最重要的技术之一就是纹理采样

为了实现纹理采样,我们通常会在顶点着色器阶段输出每个顶点对应的纹理坐标,然后经过光栅化阶段对三角网格的3个顶点对应的纹理坐标进行插值后,就可以得到其覆盖的片元的纹理坐标了。
虽然,片元着色器能完成很多重要效果,但它的局限在于,它仅可以影响单个片元。只有一个例外,它可以访问导数信息(gradient/derivative)。

逐片元操作
这个阶段是可配置的,目的就是“合并”。 主要任务是:
1) 决定每个片元的可见性。涉及很多测试工作。例如:深度测试、模板测试等等。
2) 如果一个片元通过了所有测试,就需要把这个片元的颜色值和已经储存在颜色缓冲区的颜色进行混合。

Per-fragment Operations

基本测试流程图
学习-渲染流水线_第4张图片
Stencil Test_Depth Test

测试的目的是将不符合开发者设置的阈值的片元舍弃掉。最后我们通过测试,进行修改缓冲区的操作。
1) 模板测试通常用于限制渲染区域。不管有没有通过,我们都可以决定是否用测试结果更新模板缓冲区。高级用法例如:渲染阴影,轮廓渲染等等。
2) 与模版测试不同,如果一个片元没有通过深度测试,那它就没有权利更改深度缓冲区中的值,一旦通过,我们就能通过开/闭深度写入来决定是不是要用该片元的深度值覆盖原有阈值。例如:透明效果

当一个片元通过了所有测试,就意味着它能被渲染。但是真正渲染前还要经过“合并”。即决定此片元像素位置上的颜色信息是否要覆盖之前的信息。对于不透明的物体,我们通过关闭混合(Blend)来覆盖之前的颜色信息,这样就有了前面物体遮住后面物体的感觉。对于半透明物体来说,就需要开启混合,把之前的颜色和新得到的颜色进行混合,让这个物体看起来是透明的。

学习-渲染流水线_第5张图片
Blending流程图

一些问题
1) CPU和GPU是如何实现并行工作的?
解决方法是使用一个命令缓冲区。CPU向其中添加命令,GPU从中读取命令。命令缓冲区中有一个不得不提的命令就是DrawCall。
2) 什么是固定管线渲染?
它通常是指在较旧的GPU上实现的渲染流水线。这种流水线只给开发者提供一些配置操作。在shader中有一种叫Fixed Function Shader,它就是这种渲染方式的使用。

3)unity shader 和上述渲染管线shader的不同

你可能感兴趣的:(学习-渲染流水线)