NGUI 渲染顺序概述

NGUI渲染顺序概述

渲染结构

NGUI用Panel来管理渲染.
一个UIPanel实例表示一个Panel.

  • UIPanel.widgets 表示 Panel 中需要渲染的物体
  • UIPanel.drawCalls 表示 Panel 中的渲染指令.
  • static UIPanel.list 存放所有的 Panel

在渲染时,Panel遍历它管理的所有Widgets. 生成DrawCall命令list.

于是NGUI需要控制的渲染顺序包括以下:

  • 不同Panel之间的渲染顺序;
  • 同一个Panel中所有Widget的渲染顺序;
  • 同一个DrawCall中绘制的三角形顺序;

渲染顺序

UI 是 2D 的,不需要在渲染时开启深度测试(depth test)。因此,若渲染位置相同时,后渲染的图形覆盖先渲染的图形。
在使用 NGUI 时,都知道可以设置 Panel 和 Widget 的 Depth 属性。Depth 值越低,越容易被覆盖。
Depth 值低的 Panel 或 Widget 会先被处理。

  • 根据 Depth 排序 Panel 。在 UIPanel.cs 文件查找 list.Sort(CompareFunc); ,再看 UIPanel.CompareFunc 函数刚好发现 Depth 越小,在 list 中越靠前。
  • 根据 Depth 排序 Widget 。 UIPanel.cs 文件查找 widgets.Sort(UIWidget.PanelCompareFunc); 再看比较函数,发现和 Panel 一样,Depth 越小在列表中越靠前。注:NGUI 并不是每次都重新排序所有的 Widget ,新加的 Widget 根据 Depth 插入到指定位置就避免了完全重排,但是排序规则都一样的。
  • 合并 DrawCall 。查看函数 UIPanel.FillAllDrawCalls 可知,若 UIPanel.widgets 相邻的 Widget 满足 Material 、Texture 、Shader 相同,则会把此 Widget 的绘制合并到前一个 Widget 的 DrawCall 中。其实合并或者不合并,后一个 Widget 都是后绘制,因此不影响最终的结果。

我们明白了应用层面 Depth 的设置,但是实际的渲染是在 Shader 中进行的
如何根据应用层的 Depth 控制 Shader 的渲染呢?

  • 其实很简单。排序后设置相应的 renderQueue 即可
  • 具体实现搜索 UIDrawCall.cs 中 mDynamicMat.renderQueue = mRenderQueue; 。

经过上面分析,Depth 小的 Panel 先绘制,同一 Panel 中 Depth 小的 Widget 先绘制。这就是 NGUI 渲染顺序。

由于需要控制 Panel 绘制顺序,所以 NGUI 绘制时在单个 LateUpdate 中根据列表处理所有的 Panel ,为了避免所有 Panel 的 LateUpdate 都处理一遍,因此引入了 static UIPanel.mUpdateFrame 控制调用频率。

void LateUpdate ()
{
	if (mUpdateFrame != Time.frameCount)
	{
		mUpdateFrame = Time.frameCount;

		// Update each panel in order
		for (int i = 0, imax = list.Count; i < imax; ++i)
			list[i].UpdateSelf();
	}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值