精华内容
下载资源
问答
  • Unity&NGUI渲染层级

    千次阅读 2017-11-08 14:00:02
    尊重原创,转载请在文首注明... 项目中经常遇到层级的显示问题,来总结下。 一,Unity 按优先级从高到低排列: 1,Camera.depth depth小的先渲染。 2,Renderer.sortingLayerID sortingLayerID为基类Rend

    尊重原创,转载请在文首注明出处:http://blog.csdn.net/cai612781/article/details/78477944

    项目中经常遇到层级的显示问题,来总结下。

    一,Unity

    按优先级从高到低排列:

    1,Camera.depth

    depth小的先渲染。


    2,Renderer.sortingLayerID

    sortingLayerID基类Renderer的属性,sortingLayerID小的先渲染。

    3,Renderer.sortingOrder

    sortingOrder同为基类Renderer的属性,sortingOrder小的先渲染。


    sortingLayerIDsortingOrder虽然是基类Renderer的属性,但只适用于Unity2d的排序,因此我们在面板中可以看到只有显示图片的SpriteRenderer和显示粒子的

    ParticleSystemRenderer有这两个属性。



    4,Material.renderQueue

    该属性对应的是Shader的renderQueue,renderQueue的范围必须是[0,5000],数值小的先渲染。Shader中使用SubShader的Queue标签来设定模型属于哪个渲染队列。

    Unity内置了几个渲染队列的枚举:

    public enum RenderQueue
    {
            Background = 1000,//最先渲染,通常用来绘制背景
            Geometry = 2000,//不透明物体的渲染
            AlphaTest = 2450, // 需要透明度测试的物体,在不透明物体渲染后再渲染会更高效
            GeometryLast = 2500, // 分界线,[0,2500]为不透明物体,[2501,5000]为半透明物体
            Transparent = 3000,//半透明物体的渲染,任何使用了透明度混合(例如关闭了深度写入)的物体都用得用该队列
            Overlay = 4000,//用于叠加效果
    }


    上述排序是在Shader关闭了深度写入(ZWrite Off)的情况下,当开启了深度写入时,物体的空间位置(transform.position.z)会影响层级,z值小的在前面。

    另外,Unity菜单Edit->Project Settings->Tags中的Layers,只是一个逻辑的分层,用于Camera的Culling Mask来设置相机渲染哪个Layer的物体,辅助Camera.depth来管理层级。


    二,NGUI

    按优先级从高到低排列:

    1,UIPanel.sortingOrder

    通过源码可以看到UIPanel.sortingOrder更改的就是上文中Renderer.sortingOrder。

    2,UIPanel.depth

    depth小的先渲染

    3,UIWidget.depth

    depth小的先渲染,NGUI根据UIWidget.depth的排序合并drawcall(因此尽量将相同材质的图集在depth上排在一起可以减少UI上的drawcall)。


    UIPanel面板还有个Render Q属性,用来设置该面板的renderQueue的起始值,所有面板总的起始值默认为3000。该属性有三种选项,分别是

    Automatic,StartAt,Explicit,后两者可自定义renderQueue的起始值。



    当Render Q默认为Automatic时,根据UIPanel.depth的排序对drawcall的材质的renderqueue进行排序。

    当Render Q默认为StartAt或Explicit时,UIPanel.depth则不起作用,根据自定义的值对drawcall的材质的renderqueue进行排序。


    NGUI所用的shader都是关闭了深度写入的,因此z值不影响层级。所以NGUI本质还是通过Unity的sortingOrder和renderQueue来管理层级。


    三,NGUI与模型或特效的夹层问题

    我们在处理模型或特效显示在两个UI之间的层级显示问题,有两种方式:

    1,利用Camera.depth属性,将界面A,模型或特效,界面B分别放在三个Layer,用三个depth递增的相机来渲染。(该方式不推荐,因为一个界面上可能会打开新的界面,以及两个界面的相对层次不是固定的,这样会导致相机不断增加,层次管理混乱)

    2,利用renderQueue属性,给两个UIPanel之间留下一定范围的renderQueue数值,将模型或特效的renderQueue设置在这个范围内。(推荐该方式)


    代码如下:

    第一步,新增renderQueue控制脚本:RenderQueueContro.cs

    using System.Collections.Generic;
    using UnityEngine;
    
    public class RenderQueueControl : MonoBehaviour
    {
    	private UIPanel _panel;
    	
    	private int _rq;
    	private List<Material> _materialList = new List<Material>();
    	private int i, len;
    	
    	void Start()
    	{
    	}
    	
    	public void Init()
    	{
    		_panel = NGUITools.FindInParents<UIPanel>(gameObject);
    		UIPanel.AddModelRQ(this);
    		InitMaterials();
    	}
    	
    	private void InitMaterials()
    	{
    		_materialList.Clear();
    		Renderer[] ren = GetComponentsInChildren<Renderer>();
    		if(ren != null)
    		{
    			for(i = 0, len = ren.Length; i < len; i++)
    			{
    				_materialList.AddRange(ren[i].materials);
    			}
    		}
    	}
    	
    	public void UpdateRQ()
    	{
    		if(_panel != null && _panel.drawCalls.Count > 0)
    		{
    			_rq = _panel.drawCalls[_panel.drawCalls.Count - 1].renderQueue + 1;
    			for(i = 0, len = _materialList; i < len; i++)
    			{
    				if(_materialList[i].renderQueue != _rq)
    				{
    					_materialList[i].renderQueue = _rq;
    				}
    			}
    		}
    	}
    	
    	void OnDestroy()
    	{
    		_materialList.Clear();
    		UIPanel.RemoveRQ(this);
    	}
    }


    第二步,给两个UIPanel之间留下一定范围的renderQueue数值,并在UIPanel更新时修改模型的renderQueue。我们修改UIPanel.LateUpdate(注释为修改处)。

    void LateUpdate()
    {
    	if(mUpdateFrame != Time.frameCount)
    	{
    		mUpdateFrame = Time.frameCount;
    		
    		for(int i = 0, imax = list.Count; i < imax; ++i)
    		{
    			list[i].UpdateSelf();
    		}
    		
    		int rq = 3000;
    		for(int i = 0, imax = list.Count; i < imax; ++i)
    		{
    			UIPanel p = list[i];
    			if(p.renderQueue == RenderQueue.Automatic)
    			{
    				p.startingRenderQueue = rq;
    				p.UpdateDrawCalls();
    				rq += p.drawCalls.Count * 2;//加上*2
    			}
    			else if(p.renderQueue == RenderQueue.StartAt)
    			{
    				p.UpdateDrawCalls();
    				if(p.drawCalls.Count != 0)
    				{
    					rq = Mathf.Max(rq, p.startingRenderQueue + p.drawCalls.Count * 2);//加上*2
    
    				}
    			}
    			else
    			{
    				p.UpdateDrawCalls();
    				if(p.drawCalls.Count != 0)
    				{
    					rq = Mathf.Max(rq, p.startingRenderQueue + 1 * 2);//加上*2
    				}
    			}
    		}
    		UpdateModelRQ();//加上刷新rq
    	}
    }
    
    private static List<RenderQueueControl> _modelRQList = new List<RenderQueueControl>();
    
    public static void AddModelRQ(RenderQueueControl control)
    {
    	if(!_modelRQList.Contains(control))
    	{
    		_modelRQList.Add(control);
    	}
    }
    
    public static void RemoveModelRQ(RenderQueueControl control)
    {
    	_modelRQList.Remove(control);
    }
    
    private void UpdateModelRQ()
    {
    	for(int i = 0, len = _modelRQList.Count; i < len; i++)
    	{
    		if(_modelRQList[i] == null)
    		{
    			continue;
    		}
    		_modelRQList[i].UpdateRQ();
    	}
    }


    第三步,加载模型或特效后的调用

    public static void AddModelParent(GameObject modelGo, Transform parentTran)
    {
    	if(modelGo == null || parentTran == null || parentTran.gameObject == null)
    	{
    		return;
    	}
    	modelGo.transform.parent = parentTran;
    	
    	int layerUi = parentTran.gameObject.layer;
    	SetLayerRecursively(parentTran.gameObject, layerUi);
    	
    	RenderQueueControl rqControl = modelGo.AddMissingComponent<RenderQueueControl>();
    	rqControl.Init();
    }
    
    public static void SetLayerRecursively(GameObject parent, int layer)
    {
    	if(parent == null)
    	{
    		return;
    	}
    	parent.layer = layer;
    	foreach(Transform child in parent.transform)
    	{
    		if(child == null)
    		{
    			continue;
    		}
    		SetLayerRecursively(child.gameObject, layer);
    	}
    }


    效果图


    展开全文
  • Unity中的渲染顺序自上而下大致分为三层。 最高层为Camera层,可以在Camera的depth那里设置,设置之后,图形的渲染顺序就是先绘制depth低的相机下的物体,再绘制depth高的相机下的物体,也就是说,depth高的相机会...

    最近连续遇到了几个绘制图像之间相互遮挡关系不正确的问题,网上查找的信息比较凌乱,所以这里就把自己解决问题中总结的经验记录下来。

    Unity中的渲染顺序自上而下大致分为三层。 最高层为Camera层,可以在Camera的depth那里设置,设置之后,图形的渲染顺序就是先绘制depth低的相机下的物体,再绘制depth高的相机下的物体,也就是说,depth高的相机会覆盖depth低的相机(具体的覆盖关系有don’t clear, solid color等等几种)

    比Camera层稍低一层的是sorting layer层, 随便找一个可以设置sorting layer的地方,选择sorting layer,点添加按钮,就可以看到当前所有的sorting layer,并且可以更改sorting layer的顺序,排位靠后的sorting layer会覆盖排位靠前的sorting layer。 设置好sorting layer的相互关系之后,就可以给任何一个继承于Renderer类,或者有renderer的子类作为field的对象设置sorting layer了。 注意这些sorting layer的遮挡关系是在同一个camera的层级下的。 不同camera下的renderer渲染顺序以camera的depth为准。 有的component的sorting layer可以直接在unity editor里面设置,比如Sprite Renderer。 有的则需要用代码来设置,比如设置Particle system的sorting layer, 就需要在代码中取到 ParticleSystem.Renderer.SortingLayer 来进行设置。

    比sorting layer再低一层的是sorting order, 这个数字指代的是在同一个sorting layer下的渲染顺序,用法很明显就不赘述了。

    需要注意不要混淆的是gameobject的layer,和renderer的sorting layer。 gameObject的layer个人理解是一个逻辑上的分层,用于camera的culling mask等。 而renderer的sorting layer则用于渲染。只有继承与renderer或者有renderer作为filed的component才需要设置sorting layer。

    另外需要指出的是,常用的NGUI的widget depth其本质也是一个sorting layer下的sorting order。 NGUI好像用的是一个叫做“UI”的sorting layer。 由此大家如果有需要,也可以自己取Hack NGUI的代码,把NGUI的sorting layer暴露出来供自己定制。

    展开全文
  • 1、要使粒子渲染在两张图片中间,必须将两个图片的渲染批分开,就在同一个深度段内,假如没有其它其它图集的批渲染添加进来,图片的渲染顺序是depth顺序,但是此时粒子和图集是一个批次渲染,粒子始终在这个图集图片...
    1、要使粒子渲染在两张图片中间,必须将两个图片的渲染批分开,就在同一个深度段内,假如没有其它其它图集的批渲染添加进来,图片的渲染顺序是depth顺序,但是此时粒子和图集是一个批次渲染,粒子始终在这个图集图片的上方,设置z轴也不管用。
    
    2、当粒子和设置前置图片一起渲染时,此时z轴的必须为前置图片的一半;即前置图片z轴为-100,此时,粒子的z轴必须小于-50,如果前置图片z轴为100,则粒子z轴必须小于50。
    3、两个图集:在同一depth,则设置z轴无用。如果粒子前图片(A图集)depth大于粒子后图片(B图集),此时粒子即可设置在两张图片中间。
    4、要让粒子在两张图片中间,必须是让一个图集DrawCall两次。
    展开全文
  • ngui中,depth(深度)控制ui界面的渲染层级,深度越大,显示的越上面,而且在ngui中不受unity的子物体比父物体优先渲染的逻辑控制,全部都是按照深度控制。 NGUI按渲染优先级排序: 1.UIPanel.sortingOrder 2....

       一.渲染层级

         在ngui中,depth(深度)控制ui界面的渲染层级,深度越大,显示的越上面,而且在ngui中不受unity的子物体比父物体优先渲染的逻辑控制,全部都是按照深度控制。

    NGUI按渲染优先级排序:

    1.UIPanel.sortingOrder

    2.UIPanel.depth

    3.UIWidget.depth

            UIPanel面板还有个Render Q属性,用来设置该面板的renderQueue的起始值。该属性有三种选项,分别是Automatic,StartAt,Explicit

            全部都默认的Automatic的话,NGUI会自己帮我们按照Panel的depth为第一优先级,Widget的depth为第二优先级来处理好渲染序列。后两者可自定义renderQueue的起始值。

            当Render Q默认为StartAt或Explicit时,UIPanel.depth则不起作用。

    二.size无法调整

    在ngui中如果Sprite的长宽无法调整,可以到对应图片的图集下改变其Border的长宽。

    展开全文
  • NGUI 层级问题

    2018-09-16 23:15:48
    我的 总结。。。panel层和panel层比,layer和layer比 同个pane比深度Depth, panel... 层级问题一直以来都是令人头疼的问题。尤其是项目后期复杂度增加以后,更多的开发人员参与,使得它维护起来相当困难。这里...
  • 参考方案:NGUI中穿插粒子或者mesh渲染层级 在UIpanel.cs/UIDrawCall.cs/UIWidget中添加 onRenderQueueChanged回调的位置参考中已经给出了,此处不赘述了 UITextureRecombine.cs /* *2018-07-20 19:49:00...
  • NGUI深度、层级总结

    2019-01-11 10:57:32
    1、同一个panel下,同一个atlas的不同sprite的显示只受depth的控制,这是最经常用的方式。...简单总结一下,决定Unity渲染关系的层级顺序是: Camera  sorting layer sorting order  
  • NGUI渲染层级顺序是由UIPanel来确定的,看源码我们得知UIPanel下的所有UIWidget的RenderQueue是递增的。 而Unity的物体,如果是Transparent渲染的话,会和NGUI一样,这就有可能处于同一层级导致随机前后的情况。 ...
  • unity和NGUI的各种层级关系整理
  • NGUI渲染解析

    2018-06-26 12:03:09
    NGUI 渲染流程深入研究 (UIDrawCall UIGeometry UIPanel UIWidget) 上图是一个简要的NGUI的图形工作流程,UIGeometry被UIWidget实例化之后,通过UIWidget的子类,也就是UISprit,UILabel等,在OnFill()函数里算出...
  • Unity NGUI内特效与UI层级关系的设置

    千次阅读 2016-08-25 19:38:14
    作为新手,最近正在做的项目用到了特效。...在NGUI内UIPanel会默认的将UI的渲染层级提高到3000以上,而特效的层级也是3000。因此为了将特效放在最上层,应该讲UI的渲染层级降低到3000以下。 将图片中的rq降低到3000
  • NGUI 渲染原理

    2018-02-01 15:21:15
    NGUI 渲染原理 链接:https://zhuanlan.zhihu.com/p/23063061 NGUI内部架构 NGUI的核心架构,其实就在于3块:UIPanel、UIWidget、UIDrawcall。 其中Panel和Widget是会显示在Hierarchy层级...
  • NGUI渲染流程

    2019-10-18 19:25:52
    本文将从整体类图出发,先对NGUI渲染涉及到几个重点的类的关系有一个整体的了解,接着再讲下各个类的作用,然后通过源码将下整个渲染的流程,最后尝试解答几个问题。本文使用的NGUI版本是3.8.2。 1. 整体类图 我们...
  • NGUI Mesh 粒子 Spine 层级解决方案

    千次阅读 2016-11-13 01:01:39
    ngui 层级排序原理 代码实现 本质就是把 mesh 的渲染序列加入到uipanel里面,粒子也是一样 RenderQueueModifier.cs using UnityEngine; using System.Collections; public c
  • unity之NGUI 渲染原理

    2019-06-07 17:47:51
    NGUI 渲染原理 NGUI内部架构 NGUI的核心架构,其实就在于3块:UIPanel、UIWidget、UIDrawcall。 其中: Panel和Widget是会显示在Hierarchy层级中的,而UIDrawcall则不会。 Panel和Widget Widget是NGUI中负责界面显示...
  • 上图是一个简要的NGUI的图形工作流程,UIGeometry被UIWidget实例化之后,通过UIWidget的子类,也就是UISprit,UILabel等,在OnFill()函数里算出所需的Geometry缓存(顶点数,UV,Color,法线,切线)。PS:之所以要生成...
  • 在项目中由于特效的层级与NGUI UI的层级不太还规范,导致特效的渲染层级较为杂乱于是就想把特效层级与NGUI的层级管理混合在一起;在修改之前首先要了解NGUI的层级管理以及DC的合并:在NGUI中层级的管理以及Drawcall...
  • unity 渲染层级详解

    千次阅读 2019-02-25 14:08:39
    Camera是unity中最优先的渲染顺序控制。depth越大,渲染顺序越靠后。  2、Sorting Layer 在Tags &amp; Layers设置中可见 3、Order In Layer 相对于Sorting Layer的子排序,用这个值做比较时只有都在同一...
  • Unity NGUI和UGUI与模型、特效的层级关系

    万次阅读 多人点赞 2016-10-05 11:39:34
    7、NGUI与模型和粒子特效穿插层级管理 8、UGUI与模型和粒子特效穿插层级管理写在前面这篇笔记是整理了之前做的记录,在做项目的过程中,遇到了各种各样的界面穿插问题,界面层级混乱,比如,手机卡了或点快了,就...
  • Unity渲染层级关系

    千次阅读 2018-01-24 11:35:33
    一、条件:Render Mode都是Screen Space-Camera时的渲染顺序 1.遵循刷油漆规则 2.依次由Render Camera的Depth值、Sorting Layer先后顺序、Order in Layer值决定 Render Camera不同时,由Render Camera的...
  • 解决骨骼动画与ngui层级关系

    千次阅读 2015-06-18 18:19:58
    不管是什么内容,都要通过draw call来渲染,我们更改下渲染队列的顺序就行了,首先我们要知道 ngui的panel默认的Render Queue是3000 打开UIPanle.cs文件,可以找到: ///  /// Render queue used ...
  • NGUI层级

    2014-11-13 16:03:59
    1.默认NGUI中panel的Render Queue从3000网上增加,
  • UGUI的UGUI渲染层级层深(layer)问题

    千次阅读 2020-06-18 18:27:42
    1.先来说说我们的问题:由于unity渲染物体时是从上到下直接渲染的,这就导致了渲染出来的效果和我们预期的不一致,因此必须设置层级,指定渲染的先后顺序(层级低的先渲染)才行。 那么问题来了,UGUII并没有NGUI...
  • NGUI 层级关系控制

    2016-12-01 01:08:00
    NGUI元素的遮挡情况是不依赖空间关系,所以在NGUI上添加特效有...在写之前,还是记录下这篇随笔参考的资源:《NGUI 渲染流程深入研究》) , 一篇不错的介绍,对理解整个流程很有帮助,对层级关系也做了很多描述;...
  • 7、NGUI与模型和粒子特效穿插层级管理  8、UGUI与模型和粒子特效穿插层级管理 写在前面 这篇笔记是整理了之前做的记录,在做项目的过程中,遇到了各种各样的界面穿插问题,界面层级混乱,比如,手机卡了或点快了...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 587
精华内容 234
关键字:

ngui渲染层级