GPU流水线

概述

  渲染流水线能够简单分为3个阶段即应用阶段、几何阶段、光栅化阶段。应用阶段是由CPU来完成的,而几何阶段和光栅化阶段是由GPU来完成。对于后两个阶段,GPU经过实现流水线化,大大加快了渲染速度,咱们没法彻底控制这两个阶段的实现细节,可是GPU向开发者开放了不少控制权。下图展现了流水线的具体流程:编程

GPU的渲染流水线接收顶点数据做为输入,这些顶点数据是由CPU控制的应用阶段加载到显存中,再由DrawCall指定。网络

几何阶段

顶点着色器(Vertex Shader):是彻底可编程的,它一般用于实现顶点的空间变换,顶点着色等功能app

曲面细分着色器(Tessellation Shader):可选着色器,用于细分图元函数

几何着色器(Geometry Shader):可选着色器,用于执行逐图元着色操做,或用于产生更多的图元测试

剪裁(Clipping):能够配置但不可编程,裁剪掉不在摄像机视野的顶点,并剔除某些三角图元的面片。spa

屏幕映射(Screen Mapping):不可配置和编程,负责把每一个图元坐标转换到屏幕坐标系中。orm

光栅化阶段

三角形设置(Triangle Setup)和三角遍历(Triangle Traversal):固定函数阶段blog

片元着色器(Fragment Shader):彻底可编程,用于实现逐片元的着色操做ip

逐片元操做(Per-Fragment Operations):不可编程,但具备很高的可配置性 负责执行不少操做,例如修改颜色、深度缓冲、进行混合。ci

顶点着色器(Vertex Shader)

  顶点着色器自己不能够建立或者销毁任何顶点,并且没法的到顶点与顶点之间的关系。这种相互独立性使得GPU能够并行化处理每个顶点, 这意味着这一阶段处理速度会很快。

  顶点着色器除了坐标变换和逐顶点光照这两个主要任务外,还能够输出后续阶段所需的数据

  顶点着色器有不一样的输出方式,最多见的是经光栅化后交给片元着色器进行处理,在现代 Shader Model 中,它还能够把数据发送给曲面细分着色器和几何着色器

坐标变换

  一个最基本的顶点着色器必须完成的工做是把顶点坐标从模型空间转换到齐次剪裁空间,常见代码为:(o.pos = mul(UNITY_MVP,v.position)),接着再由硬件作透视除法,最终获得归一化设备坐标(Normalized Device Coordinate,NDC)值在[-1,1]之间。咱们能够经过改变顶点的位置来模拟水面、布料等。

剪裁(Clipping)

  一个图元若是部分在视野内须要通过剪裁,方法是讲视野外的顶点由视野内的顶点代替。这一步是硬件上的固定操做,咱们能够经过自定义剪裁操做来对这一步进行配置。

屏幕映射(Screen Mapping)

  把每一个图元的x和y坐标转换到屏幕坐标系,因为咱们输入的坐标值在-1到1之间,因此这个过程其实是一个缩放的过程,注意屏幕映射不会对z坐标作任何处理。屏幕坐标系和z坐标一块儿构成窗口坐标系,屏幕映射获得的屏幕坐标决定了顶点对应屏幕上的哪一个像素以及距离这个像素有多远。

 三角形设置(Triangle Setup)

  计算光栅化一个三角网络所需的信息(一个计算三角网格表示数据的过程)

三角形遍历(Triangle Traversal)

  根据上一个阶段的计算结果来判断一个三角形覆盖了哪些像素,并使用网格3个顶点的顶点信息对整个覆盖区域的像素进行插值。最后输出一个片元(fragment)序列,这个阶段也被称为扫描变换(Scan Conversion)。

  一个片元并非真正意义上的像素,它包含了不少状态集合(屏幕坐标、深度信息、顶点信息),这些状态用于计算每一个像素的最终颜色。 

片元着色器(Fragment Shader)

  又称像素着色器(Pixel Shader),片元着色器的输入是上一个阶段对顶点信息插值获得的结果,这一阶段完成不少重要的渲染技术,其中最重要的技术是纹理采样。

逐片元操做(Per-Fragment Operations)

  又称输出合并阶段(Output-Merger)

  这一阶段有几个主要任务。

  (1)决定每一个片元的可见性。这会涉及不少测试工做,好比深度测试、模板测试

  (2)若是一个片元经过的全部测试,就须要把这个片元的颜色值和已经存储在颜色缓冲区的颜色进行合并,或者说是混合。

 

 

模板测试(Stencil Test)

  若是开启了模板测试,GPU会首先读取(使用读取掩码)模板缓冲区中该片元位置的模板值而后将该值和读取(使用掩码读取)到的参考值(reference value)进行比较,开发者能够指定该比较函数,例如小于时舍弃该片元,或者大于时舍弃该片元。若是该片元没有经过测试,该片元就会被舍弃。无论一个片元有没有经过测试,开发者均可以根据模板测试和深度测试来修改模板缓冲区。另外,模板测试还有一些高级用法,如渲染阴影、轮廓渲染等

深度测试(Depth Test)

  片元经过模板测试后就会进行深度测试,若是开启了深度测试,GPU会把该片元的深度值和已经存在于深度缓冲区中的深度值进行比较。和模板测试同样,开发者能够指定该函数。和模板测试不一样的是,若是一个片元没有经过深度测试,它就没有权利修改深度缓冲区的值。若是经过了测试,开发者还能够指定是否要用这个片元的深度值覆盖掉原有的深度值。

混合

  该过程主要针对透明的物体,对于不透明的物体能够关闭混合。是当前获得的颜色信息与颜色缓冲区中的信息的混合。开发者能够选择开启和关闭混合功能,关闭后就会直接使用片元的颜色覆盖掉缓冲区的颜色。

总结

  当模型的图元通过上面的层层计算和测试后,就会显示到屏幕上。咱们屏幕显示的就是颜色缓冲区的颜色值,为了保证咱们看到的图像是连续的,GPU会使用双重缓冲的策略,对场景的渲染在后置缓冲中(Back Buffer),一旦场景已经被渲染到了后置缓冲中,GPU就会交换后置缓冲和前置缓冲(Front Buffer)中的内容。

相关文章
相关标签/搜索