您现在的位置是:首页 > 正文

UnityShader入门精要_要点整理_渲染流程

2024-01-30 19:57:17阅读 0

该章节多是介绍了渲染流程涉及的概念内容,未接触过渲染的同学,可能理解起来比较吃力。但是还是建议要坚持看完。个人认为其中比较重要的是,GPU流水线(顶点着色器,片元着色器,深度测试)。下面会将自己认为比较重要的部分,整理一下,以便分享和后续快速查阅。

目录

什么是渲染流水线(渲染流程)?

CPU和GPU之间通信

※※GPU流水线※※


什么是渲染流水线(渲染流程)?

渲染流水线一般分为三个概念阶段(不是真正的GPU流水线阶段,只是这样分更好理解):应用阶段,几何阶段,光栅化阶段。

  1. 应用阶段:主要是准备场景中的数据,计算摄像机位置,场景中的模型数量,使用哪些光源,同时还会粗粒度剔除(把不可见的剔除出去),最后会设置每个模型的渲染状态,将数据传输到几何阶段。(数据包括但不限于,模型的材质,贴图,shader,颜色,还有渲染图元),该阶段通常在CPU上进行。。PS:渲染图元一般是模型的顶点,线,三角面几何信息等。
  2. 几何阶段:处理所有和我们要绘制的几何(PS:这里几何是名词)相关的事情。比如将顶点坐标变换到屏幕空间中去。该阶段通常在GPU上进行。 PS:常对应UnityShader中的顶点着色器vertex。
  3. 光栅化阶段,光栅化的主要任务是决定每个图元中的哪些像素应该被绘制到屏幕上,它需要对上一个阶段的得到的逐顶点数据进行插值,然后再进行逐像素处理,并最终渲染出图形。该阶段通常在GPU上进行。PS:常对应UnityShader中的片元着色器frag。

概念流水线.png-16.9kB

CPU和GPU之间通信

  1. 把数据加载到显存中。GPU访问显存更快,而且大多数GPU对RAM(系统的运行时内存)没有访问权限。PS:传输后可选是否将RAM中的数据移除。
  2. 设置渲染状态。这些状态定义了场景中的网格是如何被渲染的,例如vertex,frag,光源和材质等,如果没有更改渲染状态,那么所有的网格都将使用同一种渲染状态,最直观的表现就是会使用同一套材质渲染。
  3. 调用DrawCall。DrawCall仅仅只是一个命令调用,由CPU发起GPU接收。该命令将不会包含大量数据(数据前面的阶段传输过了),该命令指向需要被渲染的图元列表。

※※GPU流水线※※

下图代表了GPU流水线的所有流程,开发者无法完全掌控这些流程,下图的颜色代表了开发者可以掌控的程度。

GPU流水线.png-82.2kB

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

  1. 顶点着色器:一般负责坐标变换和逐顶点光照。输入来自CPU,单位是顶点,也就是输入进来的每个顶点都会调用一次顶点着色器。顶点着色本身不可以创建或者销毁任何一个顶点。而且只会处理传进来的这个顶点,无法得到各个顶点之间的联系。
  2. 裁剪:一个模型比较大,往往包含极多的图元。所以该模型可能完全在视野内,只有一部分在视野内,或完全在视野外。裁剪主要是剔除掉看不到的那部分图元。该步骤不可编程,但是可以配置一个自定义裁剪。
    Clipping.png-25.5kB
    比如图中红色的被完全舍弃,黄色的被裁剪掉了一不可见的部分。
  3. 屏幕映射:将每个图元的3D坐标转换到2D的屏幕坐标中,屏幕坐标系的坐标值主要与分辨率有关系(比如1920*1080的X总长度是1920,Y是1080,另外要注意实际渲染过程中多会使用NDC值)。另外要注意苹果的OpenGL(左下角0,0)和微软的DirectX(左上角0,0)的坐标Y轴是反的。
  4. 三角形设置:使用前面阶段输出的三角形网格顶点连成的线,计算整个三角网格的边界对像素点的覆盖情况,主要是为三角形遍历阶段做准备
  5. 三角形遍历:检查所有的像素是否有被三角形覆盖,如果有则生成一个片元。并且会使用三角网格的三个顶点对整个覆盖区域的像素进行插值。(插值!很重要)
  6. 片元着色器:该阶段完全可编程,每次调用片元着色器仅仅可以影响单个片元(有个例外情况,片元着色器可以访问到导数信息gradient,但书上未细说)。实际上很多重要的效果都是片元着色器完成的。
  7. 逐片元操作:该阶段有几个主要任务,
    1. 决定每个片元的可见性。这涉及很多测试工作,例如深度测试,模板测试。
    2. 如果一个片元通过了所有的测试,就需要把这个片元的颜色值和已经存储在颜色缓冲区中的颜色进行覆盖或合并(或者说是混合)。
  • 深度测试:书上着重介绍了深度测试,深度测试简单来说就是通过深度值来判断,该片元是否被其他片元遮挡了,如果被遮挡则将该片元舍弃。如果没有被遮挡,且开启了深度写入,就将该片元的深度值写到深度缓冲中。为了优化性能,GPU常常会将深度测试提前(Early-Z技术),提前知道哪些片元被剔除,就可以减少需要处理的片元PS:“深度值如果不好理解的话,暂时可以简单理解为,距离观察相机的的远近。”
  • 颜色合并(混合):一般是半透明效果时开启的。如果没有开启颜色合并,颜色缓冲中的颜色会被最新新通过深度测试的片元的颜色覆盖,也就是说颜色缓冲中只会保留一个颜色。如果开启了颜色合并,新片元的颜色会与颜色缓冲的颜色混合(开发者可以指定混合函数如相加,相乘等)。

 

Blending.png-67.6kB

文章对你有帮助么,点个赞可以嘛。攒攒人气,谢谢啦。

 

网站文章