原地址:http://blog.csdn.net/yanchezuo/article/details/74502945
NGUI層級中間的特效顯示
1.使用NGUI的過程中,有一個具有半透明效果的特效,想顯示在Panel_A和Panel_B中間。
效果如下圖所示:
實現原理:
- UIPanel下的界面渲染順序,由UIDrawCall.renderQueue決定。
最終,使用Material.renderQueue=x來設定渲染順序
打開UIPanel下的”Show Draw Calls”,可以看到每個Widget的渲染序列 RenderQ的值。
想要把特效顯示在界面中間,只要改變特效的渲染序列就可以了
因此,我們可以先獲取到特效的Materials,修改每一個材質的renderQueue,代碼如下:
- UIPanel下的界面渲染順序,由UIDrawCall.renderQueue決定。
using UnityEngine;
using System.Collections;
public class Shaderutility {
public static void ChangeQueue(GameObject go,int queue)
{
if(go==null)
{
return;
}
Renderer[] re = go.GetComponentsInChildren<Renderer>();
if(re==null)
{
return;
}
for(int i=0,imax=re.Length;i<imax;++i)
{
for(int k=0,kmax=re[i].materials.Length;k<kmax;++k)
{
re[i].materials[k].renderQueue = queue;
}
}
}
}
如果不修改queue,是這樣的效果:
因爲默認UIPanel的渲染序列是從3000開始增長,而半透明的shader的queue也是3000,因此,半透明特效會被遮擋。
2.有一個展示模型,在Panel_A中,當打開Panel_B的時候,希望能遮擋住模型
效果如下圖所示:
- 實現原理:
- 不透明的物體,可以通過z軸區分在前在後。
- 不透明的物體,可以通過z軸區分在前在後。
因此,只需要讓模型的z在Panel_A和Panel_B中間即可。
Panel_A和Panel_B的設置爲:
Panel_A:
Panel_B:
3.深入理解Shader的渲染
- 渲染順序(Queue)
shader按照Queue序列進行操作,即,先操作 queue值小的,後操作queue大的。
在Unity Shader中,表現爲 subShader的Tags{“Queue”=”…”}。ZTest
Unity Shader中,如果沒有指定,默認是ZTest LEqual
如果深度測試沒有通過,會直接丟棄掉片元;否則,進入下一步,是否寫入深入值ZWrite
如果打開了深度寫入(Unity中默認是打開的),會將片元的深度值寫入深度緩衝區;
如果關閉了深度寫入(ZWrite Off),則不會講片元寫入深度緩衝區。
之後,進行下一步,混合操作Blend(混合)
如果開啓了混合,會進行顏色的疊加後寫入顏色緩衝區;
否則,會直接將顏色寫入顏色緩衝區
4.Queue和ZWrite的使用過程
- ZTest —> 一定會進行,默認是LEqual,也就是前面的物體會遮擋後面的物體
ZTest如果不通過,也就是說,被前面的遮擋着,片元就不再往下進行了
ZTest通過的情況下,
是否開啓了ZWrite影響了下一個物體渲染時候的深度測試是否能夠通過
開啓混合的Shader,ZWrite開啓和關閉的必要性
在開啓混合的狀態下:
如果此物體被其他物體遮擋住了,那麼在深度測試的階段就被拋棄了;因此,開啓混合的物體,一般放在最上方(or 最前面)
如果沒有被其他物體遮擋,z本來就是在最上方的,因此,沒有必要開啓ZWrite。如果所有shader都是關閉ZWrite的,並且Transform.position.z都一樣:
因爲默認的ZTest 是LEqual 小於或者等於,所以,所有片元的ZTest都會通過。
那麼,渲染順序就是材質的queue的順序。
所以,此時,可以通過修改材質的queue值,來將某個shader的渲染放到兩個Panel之間總結
1.永遠關注深度值,也即transform.position.z
2.如果z值相同, 修改queue
3.如果z值不同,ZTest會先過濾,所以調整前後位置