文章目录

  • 一. 前言
  • 二. 摄像机(Camera)
  • 1. 3D摄像机
  • 2. UI摄像机
  • 3. 摄像机的Depth和Clear Flags设置
  • 三. 画布(Canvas)
  • 1. Sorting Layer
  • 2. Order in Layer
  • 四. Shader的RenderQueue


一. 前言

Unity游戏开发中,模型、界面、特效等等,需要规划好层的概念,涉及到摄像机(Camera)、画布(Canvas)、Shader等相关内容。

二. 摄像机(Camera)

一般3D游戏项目,会创建至少两个摄像机,一个3D摄像机(使用透视视角)和一个UI摄像机(使用正交视角)。

1. 3D摄像机

unity AR绑定摄像机导航指引 unity ui摄像机_Order in Layer

2. UI摄像机

unity AR绑定摄像机导航指引 unity ui摄像机_Order in Layer_02

3. 摄像机的Depth和Clear Flags设置

一般UI摄像机的Depth要大于3D摄像机的Depth,这样才能使UI3D摄像机渲染的物体的前面显示。

摄像机的Clear Flags建议使用Depth only,然后在Culling Mask选择相应的层(Layer)。

比如3D摄像机的Culling Mask如下:

unity AR绑定摄像机导航指引 unity ui摄像机_unity_03


UI摄像机的Culling Mask如下:

unity AR绑定摄像机导航指引 unity ui摄像机_unity_04


这个Culling Mask的下拉列表中就是一个个的层(Layer),如果要添加新的层,可以点击Inspector窗口中的Layer,然后点击Add Layer...进行添加。

unity AR绑定摄像机导航指引 unity ui摄像机_Order in Layer_05


unity AR绑定摄像机导航指引 unity ui摄像机_unity_06


创建3D物体或UI界面的时候,都会设定物体的Layer3D物体默认是Default层,UI默认是UI层。

unity AR绑定摄像机导航指引 unity ui摄像机_shader_07


摄像机会根据Depth从小到大的顺序,渲染各自Culling Mask的层。

注意,在世界坐标下,物体A挡在物体B前面,但是只要渲染物体A的摄像机的Depth大于渲染物体B的摄像机的Depth,那么在Game视图中看到的效果就是物体B挡在物体A前面,如果物体A和物体B同在一个摄像机中渲染,那么正常情况下就是物体A挡住物体B(这里说正常情况下,是因为还可以通过下文的RenderQueue、SortingLayer、SortingOrder等的设置,让物体B挡在物体A前面)。

三. 画布(Canvas)

UGUI中,所有UI元素都必须在画布(Canvas)的子节点中。CanvasRender Mode一般是使用Screen Space - Camera模式,把UICamera赋值给CanvasRender Camera

unity AR绑定摄像机导航指引 unity ui摄像机_unity AR绑定摄像机导航指引_08


这个时候,可以看到Canvas的面板中,出现了两个关键的属性:Sorting LayerOrder in Layer

1. Sorting Layer

添加Sorting Layer可以点击Inspector窗口的Tag -> AddTag -> SortingLayer

unity AR绑定摄像机导航指引 unity ui摄像机_unity AR绑定摄像机导航指引_09


然后Canvas就可以在Sorting Layer中看到新加的Sorting Layer了(有点绕口)

unity AR绑定摄像机导航指引 unity ui摄像机_unity_10


为什么要有这个Sorting Layer呢,因为我们可以创建很多个Canvas,默认Sorting LayerDefault,这个时候,渲染顺序是根据Canvas的节点在Hierarchy窗口中的顺序来决定的,上层的节点先渲染,下层的节点后渲染。

而有时候,可能需要打破这个顺序,让上层节点的Canvas后渲染,这个时候,就可以设置这个Sorting Layer为高的值,当然,也可以保持相等,通过设置Order in Layer

拓展:UGUI会自动合并批次,原理是它会把一个Canvas下的所有元素合并在一个Mesh里,如果Canvas下的元素很多,任意一个元素发生位置、大小的改变,就需要重新合并所有元素的Mesh。如果元素非常多的话,就可能会造成卡顿。
一个比较好的做法是每个UI界面都设置成一个Canvas。如果这个界面下的元素比较多,可以考虑嵌套多几个Canvas。尤其是会频繁改变位置大小的元素,这样可以降低它们合并Mesh的开销。但是Canvas嵌套太多也不好,Mesh合并是降低了,但是DrawCall又上去了,因为每个Canvas都会单独占用一个DrawCall。

注意:到这里,应该明白了Layer与Sorting Layer无关,它们是两个概念。

2. Order in Layer

Order in Layer顾名思义,就是Sorting Layer的内部排序,这样配合Sorting Layer就是两级的排序,可以解决大部分情况的渲染顺序需求。
当然,如果创建多个UI摄像机,不同Canvas绑定不同的UI摄像机,再配合摄像机的Depth,就是三级排序,但一般不创建太多的UI摄像机,除非逼不得已。

小结: 渲染排序级别:Camera的Depth > Canvas的Sorting Layer > Canvas的Order in Layer

另外,ParticleSystem也有Sorting LayerOrder in Layer

unity AR绑定摄像机导航指引 unity ui摄像机_sortingLayer_11

四. Shader的RenderQueue

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

Tags{ "RenderType" = "Geometry" }

在材质球中可以看到显示。

unity AR绑定摄像机导航指引 unity ui摄像机_sortingLayer_12

Properties

Value

渲染队列描述

备注

Background

1000

This render queue is rendered before any others.

这个队列通常被最先渲染(比如 天空盒)。

Geometry

2000

Opaque geometry uses this queue.

这是默认的渲染队列。它被用于绝大多数对象。不透明几何体使用该队列。

AlphaTest

2450

Alpha tested geometry uses this queue.

需要开启透明度测试的物体。Unity5以后从Geometry队列中拆出来,因为在所有不透明物体渲染完之后再渲染会比较高效。

GeometryLast

2500

Last render queue that is considered “opaque”

所有Geometry和AlphaTest队列的物体渲染完后

Transparent

3000

This render queue is rendered after Geometry and AlphaTest, in back-to-front order.

所有Geometry和AlphaTest队列的物体渲染完后,再按照从后往前的顺序进行渲染,任何使用了透明度混合的物体都应该使用该队列(例如玻璃和粒子效果)

Overlay

4000

This render queue is meant for overlay effects.

该队列用于实现一些叠加效果,适合最后渲染的物体(如镜头光晕)。

RenderQueue填-1是使用shader自定义的值,否则使用手动填的值。
2500是关键值,它是透明跟不透明的分界点
知识点:
RenderQueue > 2500的物体绝对会在RenderQueue <= 2500的物体前面,即渲染时RenderQueue大的会挡住RenderQueue小的,不论它的Sorting LayerOrder in Layer怎么设置都是不起作用的。

当两个的RenderQueue都在同一侧时,在Sorting Layer高的绝对会在Sorting Layer前面,无视RenderQueueOrder in Layer,只有在Sorting Layer相同的前提下,Order in Layer高的会在Order in Layer低的前面,无视RenderQueue。当Sorting LayerOrder in Layer相同时,才看RenderQueue的高低,高的在前面。