Unity 渲染原理(八)Unity渲染顺序和渲染路径

前面的几篇博客讲了游戏渲染的基本原理和如何在Unity里写一个Shader,这篇博客先插入两个概念:

  • Unity中不同物体之间的渲染顺序何覆盖关系是怎样的,也就是渲染顺序。
  • Unity的渲染路径又是什么,和渲染顺序有什么关系?

渲染顺序

在Unity中我们会有很多的物体,这些物体是不是同时渲染,渲染的顺序是怎样的,覆盖关系又是怎样的?我们一起看一下会影响的一些因素。

Camera Depth

这个属性表明的是相机的深度,如果场景中存在多个摄像机,深度越大的越靠后,也就是说,深度大的摄像机的内容会直接覆盖在深底小的摄像机的内容上。

透明与不透明物体的分割线(Render Queue = 2500)

RenderQueue 2500是透明与不透明的分水岭。

同一个相机下

Renderqueue小于2500的物体 始终在 Renderqueue大于2500之前绘制。

Sorting Layers

在Tags & Layers设置中可见

如果Camera相同,那接下来就看Sorting Layers,越低越早绘制。

Sorting Layers是通过Renderer的sortingLayerName属性设置的。

注意这个Layer不是GameObject的Inspector右上角设置的那个Layer,那个Layer是给摄像机用来做Culling Mask的,这个Layer是Renderer Compoennt上面的一个属性。

Order In Layer

相对于Sorting Layer的子排序,用这个值做比较时只有都在同一层时才有效。

soringOrder也是Render的一个属性,这个order是设置一个数字,数字越大,越在上面显示。

Render Queue

Shader中对Tags设置的“Queue”。

如果上述几项都相同,那就要看renderQueue了,renderQueure是Material的一个属性,其实就是Shader中的renderQueue,这个也是一个int属性,数值越小,越靠前渲染。

默认情况下,Unity会基于对象距离摄像机的远近来排序你的对象。因此,当一个对象离摄像机越近,它就会优先绘制在其他更远的对象上面。对于大多数情况这是有效并合适的,但是在一些特殊情况下,你可能想要自己控制对象的绘制顺序。而使用Tags{}块我们就可以得到这样的控制。

Unity提供给我们一些默认的渲染队列,每一个对应一个唯一的值,来指导Unity绘制对象到屏幕上。这些内置的渲染队列被称为Background, Geometry, AlphaTest, GeometryLast,Transparent, Overlay。这些队列不是随便创建的,它们是为了让我们更容易地编写Shader并处理实时渲染的。

同时需在SubShader中显示声明ZWrite Off,通知Unity我们会重写物体的渲染深度排序。

这个与上面讲的透明不透明的分割线不冲突

深度排序。按照包围盒的深度进行排序

当上面的要素都相同的时候,比如有几个建筑物从摄像机看过去是层层遮挡的,那么最后渲染哪个,取决于该物体与摄像机之间的距离。

该属性由Shader中的ZTest开启。

不透明物体由近到远排序优先

透明物体由远到近排序优先

按照包围盒的中心点的深度进行排序。

总结

依次按条件先后顺序进行排序渲染处理。先按大项条件排序,后按小项条件排序

  1. Camera Depth: 越小越优先
  2. RenderQueue 2500以下
    1. Sorting Layer/Order in Layer
           1. 按照Sorting Layer/Order in Layer 设置的值,越小越优先
           2. 无此属性,等同于 Sorting Layer=default ,Order in Layer=0 参与排序
    2. RenderQueue 越小越优先
    3. RenderQueue 相等,由近到远排序优先
      3.RenderQueue 2500以上
    4. Sorting Layer/Order in Layer
           1. 按照Sorting Layer/Order in Layer 设置的值,越小越优先
           2. 无此属性,等同于 Sorting Layer=default ,Order in Layer=0 参与排序
    5. RenderQueue 越小越优先
    6. RenderQueue 相等,

说明一下:2500是关键值,它是透明跟不透明的分界点,因此我们考虑层级的时候要注意着点:renderqueue > 2500的物体绝对会在renderqueue <= 2500的物体前面,即渲染时renderqueue大的会挡住renderqueue小的,不论它的sortingLayer和sortingOrder怎么设置都是不起作用的。知道了这点,其他的就很好理解了。当两个的RenderQueue都在同一侧时,在SortingLayer高的绝对会在sortingLayer前面,无视renderqueue跟soringOrder,只有在sortingLayer相同的前提下,soringOrder高的会在sortingOrder低的前面,无视renderqueue。当sortingLayer跟sortingOrder相同时,才看renderqueue的高低,高的在前面。

渲染路径

讲完了渲染顺序,我们讲一下Unity中另外一个很相似的名词,叫做渲染路径

Unity 的内置渲染管线支持不同渲染路径。渲染路径是与光照和阴影相关的一系列操作。不同的渲染路径具有不同功能和性能特征。应根据项目类型以及目标硬件,确定哪种渲染路径最适合您的项目。

可在 Graphics 窗口中选择项目使用的渲染路径,并可为每个摄像机覆盖该路径。

如果运行项目的设备上的 GPU 不支持所选的渲染路径,则 Unity 将自动使用较低保真度的渲染路径。例如,在无法处理延迟着色的 GPU 上,Unity 使用前向渲染。

前向渲染

前向渲染是内置渲染管线中的默认渲染路径。这是通用的渲染路径。

采用前向渲染方式渲染实时光源会非常消耗资源。为了抵消此成本,可以选择 Unity 在任何一个时间应该为每个像素渲染的光源数量。Unity 会以较低保真度渲染场景中的其余光源:每个顶点或每个对象。

如果项目没有使用大量实时光源,或者光照保真度对项目而言不重要,则此渲染路径可能是这个项目的不错选择。

延迟着色

延迟着色是内置渲染管线中具有最大光照和阴影保真度的渲染路径。

延迟着色需要 GPU 支持,并且有一些局限性。这种着色方式不支持半透明对象(Unity 使用前向渲染来渲染这些对象)、正交投影(Unity 对这些摄像机使用前向渲染)或硬件抗锯齿(但可以使用后期处理效果来获得类似结果)。延迟着色对剔除遮罩的支持有限,并会将 Renderer.receiveShadows 标志始终视为 true。

如果项目具有大量的实时光源并需要高级别的光照保真度,而目标硬件支持延迟着色,那么此渲染路径对于该项目而言可能是一个不错的选择。

LightMode

渲染路径(Rendering Path)决定光照如何应用到UnityShader中。为了获取场景中的光源数据,需要为每个Pass指定其渲染路径。5.0以后的版本中,Unity支持前向渲染(Forward Renddering Path)和 延迟渲染(Deferred Rendering Path)。系统默认情况下选择的是前向渲染路径,可以更改,同时若想使用多个渲染路径,可以在不同的摄像机中调节 Rendering Path选项。
通过在每个Pass中使用标签来指定Pass使用的渲染路径,即使用 LightMode标签实现。不同类型的渲染路径可能包含多种标签设置。

1
2
3
Pass{
Tags{"LightMode"="ForwardBase"}
}

参考文章:
Unity中渲染顺序总结
Unity渲染顺序(Queue,ZWrite,ZTest)