南京网站南京网站设计制作公司,低调与华丽wordpress下载,苏州网络seo,成都的网站建设公司哪家好Unity游戏开发中#xff0c;模型、界面、特效等#xff0c;需要规划好layer的概念#xff0c;涉及到摄像机#xff08;Camera#xff09;、画布#xff08;Canvas#xff09;、Shader等相关内容。
在 Unity 中#xff0c;渲染顺序是由多个因素共同决定的#xff0c;大…Unity游戏开发中模型、界面、特效等需要规划好layer的概念涉及到摄像机Camera、画布Canvas、Shader等相关内容。
在 Unity 中渲染顺序是由多个因素共同决定的大致分为三层优先级Camera depth、Sorting Layer/Order in Layer 和 RenderQueue。
一.Camera
一般游戏项目会创建至少两个摄像机一个3D摄像机使用透视视角和一个UI摄像机使用正交视角。 在 Unity 中每个 Camera 都有一个 depth 属性用于控制该 Camera 在渲染管线中的渲染顺序。Camera depth 值越小表示该 Camera 越优先被渲染即它会在其他 depth 值较大的 Camera 之前被渲染。这个规则同样适用于渲染物体即物体的 Camera depth 值越小表示该物体越优先被渲染。需要注意的是Camera depth 值相同的物体渲染顺序是不确定的因为它们会根据其他因素进行排序。 如图 3D摄像机 如图UI摄像机
一般UI摄像机的Depth要大于3D摄像机的Depth这样才能使UI在3D摄像机渲染的物体的前面显示。 摄像机的Clear Flags建议使用Depth only然后在Culling Mask选择相应的层Layer。默认就有UI layer 如图默认的UI层级 摄像机会根据Depth从小到大的顺序渲染各自Culling Mask的层。 注意在世界坐标下物体A挡在物体B前面但是只要渲染物体A的摄像机的Depth大于渲染物体B的摄像机的Depth那么在Game视图中看到的效果就是物体B挡在物体A前面如果物体A和物体B同在一个摄像机中渲染那么正常情况下就是物体A挡住物体B这里说正常情况下是因为还可以通过下文的RenderQueue、SortingLayer、SortingOrder等的设置让物体B挡在物体A前面。 UGUI中所有UI元素都必须在画布Canvas的子节点中。Canvas的Render Mode一般是使用Screen Space - Camera模式把UICamera赋值给Canvas的Render Camera canvas默认是屏幕空间的2D对象在屏幕空间时仅具有sort order属性当把它设置为世界空间时sort order属性消失了变成另外两个属性: sorting layer, order in layer。这个时候可以看到Canvas的面板中出现了两个关键的属性Sorting Layer、Order in Layer 添加Sorting Layer可以点击Inspector窗口的Tag - AddTag - SortingLayer
当把Canvas设置为worldspace后Canvas及Canvas上的UI对象在世界空间默认也是靠Z值来决定渲染顺序的离相机远的先渲染。当设置了sorting layer后渲染的次序就由sorting layer来确定了。sorting layer是自定义的标识符哪个sortinglayer在前在layer tags中设置的先后顺序哪个先渲染。 为什么要有这个Sorting Layer呢因为我们可以创建很多个Canvas默认Sorting Layer是Default这个时候渲染顺序是根据Canvas的节点在Hierarchy窗口中的顺序来决定的上层的先渲染下层的后渲染。 而有时候可能需要打破这个顺序让上层节点的Canvas后渲染这个时候就可以设置这个Sorting Layer为高的值当然也可以保持相等通过设置Order in Layer。层内排序
order in layer是个数值是在同一个sorting layer内的细分sorting layer相同时order in layer的数值越小越先渲染。
屏幕空间的东西都处于UI层不需要sorting layer只提供sort order(其实也就是order in layer)。 默认情况下sort oder都是0此时UI物件按照在hierachy中出现的顺序决定渲染顺序。如果sort order不同时值越小越先渲染。
UGUI会自动合并批次原理是它会把一个Canvas下的所有元素合并在一个Mesh里如果Canvas下的元素很多任意一个元素发生位置、大小的改变就需要重新合并所有元素的Mesh。如果元素非常多的话就可能会造成卡顿。 一个比较好的做法是每个UI界面都设置成一个Canvas。如果这个界面下的元素比较多可以考虑嵌套多几个Canvas。尤其是会频繁改变位置大小的元素这样可以降低它们合并Mesh的开销。但是Canvas嵌套太多也不好Mesh合并是降低了但是DrawCall又上去了因为每个Canvas都会单独占用一个DrawCall。
NGUI中的自动合批通常在Panel上执行。当你将多个相同材质Material的UI元素放置在同一个Panel中时NGUI会尝试将它们合并为一个绘制调用从而减少绘制操作的次数提高渲染性能。这种合并绘制操作可以减少CPU和GPU的负载因为绘制调用通常是较为耗费的操作之一过多的合批可能会导致内存占用增加WebGL慎用因为合批后的绘制调用可能会生成更大的顶点和三角形数据。因此在设计UI时需要综合考虑性能和内存的平衡。
Order in Layer就是Sorting Layer的内部排序这样配合Sorting Layer就是两级的排序可以解决大部分情况的渲染顺序需求。 当然如果创建多个UI摄像机不同Canvas绑定不同的UI摄像机再配合摄像机的Depth就是三级排序但一般不创建太多的UI摄像机。
比如挂在世界空间画布上的角色名字和用sprite实现的遮罩通过调整sorting layer及order in layer就可以实现两者之间的先后
另外ParticleSystem也有Sorting Layer和Order in Layer。所以我们通常会遇到 策划的 这种要求
我需要把C粒子插在AB两个UI中间。这种情况我们就需要把AB拆开调节RenderQueue 不用要用粒子的Order in Layer原因在总结时会提到
RenderQueue调节渲染顺序 提到RenderQueue就不得不提及unity内置的渲染队列了
Background(1000) 最早被渲染的物体的队列。
Geometry (2000) 不透明物体的渲染队列。大多数物体都应该使用该队列进行渲染也是Unity Shader中默认的渲染队列。
AlphaTest (2450) 有透明通道需要进行Alpha Test的物体的队列比在Geomerty中更有效。
Transparent(3000) 半透物体的渲染队列。一般是不写深度的物体Alpha Blend等的在该队列渲染。
Overlay (4000) 最后被渲染的物体的队列一般是覆盖效果比如镜头光晕屏幕贴片之类的。 Unity中设置渲染队列也很简单我们不需要手动创建也不需要写任何脚本只需要在shader中增加一个Tag就可以了当然如果不加那么就是默认的渲染队列Geometry。比如我们需要我们的物体在Transparent这个渲染队列中进行渲染的话就可以这样写 { “Queue” “Transparent”} 我们可以直接在shader的Inspector面板上看到shader的渲染队列甚至可以在代码里控制它RenderQueue调节渲染顺序
RenderQueue 2500的物体绝对会在RenderQueue 2500的物体前面即渲染时RenderQueue大的会挡住RenderQueue小的不论它的Sorting Layer和Order in Layer怎么设置都是不起作用的。
当两个的RenderQueue都在同一队列时在Sorting Layer高的绝对会在Sorting Layer前面无视RenderQueue跟Order in Layer只有在Sorting Layer相同的前提下Order in Layer高的会在Order in Layer低的前面无视RenderQueue解释上文,并且今天犯了这个错误。当Sorting Layer跟Order in Layer相同时才看RenderQueue的高低高的在前面。
后续我会更新SetRenderder的方法在粒子与NGUI中还有spine与NGUI的排序方式
参考文章 Unity中SortingLayer、Order in Layer和RenderQueue的讲解 unity Renderer unity粒子特效层级问题