Unity 中渲染顺序的理解以及一些坑点 以及2.5D游戏中的渲染排序解决方案
1.ZTest & ZWrite
ZTest:深度測試,開啟后測試結果決定片元是否被舍棄,可配置?
ZWrite:深度寫入,開啟后決定片元的深度值是否寫入深度緩沖,可配置
ZTest可設置的測試規則:
ZTest Less:深度小于當前緩存則通過
ZTest Greater:深度大于當前緩存則通過
ZTest LEqual:深度小于等于當前緩存則通過
ZTest GEqual:深度大于等于當前緩存則通過
ZTest Equal:深度等于當前緩存則通過
ZTest NotEqual:深度不等于當前緩存則通過
ZTest Always:不論如何都通過
注意,ZTest Off等同于ZTest Always,關閉深度測試等于完全通過。
ZWrite配置:?
ZWrite On 深度寫入開啟 ZWrite Off 深度寫入關閉
ZTest和ZWrite發生在逐片元操作過程,處于片元著色后,最終屏幕輸出前。ZTest與ZWrite的具體操作流程:
因為ZWrite默認值為On,ZTest默認值為LEqual,所以這很好地解釋了為什么在unity中,距離相機近的東西會阻擋住距離相機遠的東西。如果我們先繪制一個距離較近的物體,再繪制距離較遠的物體,則距離遠的物體因為后繪制,會把距離近的物體覆蓋掉,這時我們可以通過修改ZWrite和ZTest來改變物體的遮擋關系
所以對于透明物體的渲染,一般要關閉掉ZWrite,比如Unity中用于渲染Sprite的默認SpriteDefault材質的Shader:
加深對ZTest & ZWrite的理解,可以參考這篇文章的測試部分,把各例子理解明白非常有幫助。
https://www.jianshu.com/p/9137ee354dbd
2.Unity渲染順序
能夠影響渲染順序的因素有:
- Camera Depth:? ??相機組件上設置的相機深度,深度越大越靠后渲染。
- Sorting Layer:? ? ?在Tags & Layers設置中可見
- Order In Layer:? ??相對于Sorting Layer的子排序,用這個值做比較時只有都在同一層時才有效。
- RenderQueue:? ? ?Shader中對Tags設置的“Queue”。
- 物體距離相機的距離,ZDepth值
下面是結果:
1、Camera Depth
永遠最高。Camera Depth小的一定先進渲染管線。
2、當Sorting Layer和Order In Layer不相同時
- 當兩個材質使用了不同的RenderQueue,且這兩個RenderQueue都在[0~2500]或[2501~5000]時,SortingLayer和OrderInLayer的排序生效。
- ?當兩個材質使用了不同的RenderQueue,且這兩個RenderQueue分別在[0~2500]和[2501~5000]時,則一定會按照RenderQueue繪制,無視SortingLayer、OrderInLayer的排序。
3、當Sorting Layer和Order In Layer相同時
- RenderQueue不相等:
? ? ? ? RenderQueue小的先進渲染管線。
- ?RenderQueue 相等
? ? ? ? RenderQueue 2500以下,由近到遠排序優先 (不透明)
? ? ? ? RenderQueue 2500以上,?由遠到近排序優先??(透明)
說明一下:2500是關鍵值,它是透明跟不透明的分界點,因此我們考慮層級的時候要注意著點:renderqueue > 2500的物體絕對會在renderqueue <= 2500的物體前面,即渲染時renderqueue大的會擋住renderqueue小的,不論它的sortingLayer和sortingOrder怎么設置都是不起作用的。知道了這點,其他的就很好理解了。當兩個的RenderQueue都在同一側時,在SortingLayer高的絕對會在sortingLayer前面,無視renderqueue跟soringOrder,只有在sortingLayer相同的前提下,soringOrder高的會在sortingOrder低的前面,無視renderqueue。當sortingLayer跟sortingOrder相同時,才看renderqueue的高低,高的在前面。
總結下Unity影響渲染順序各參數的優先級
如果物體的RenderQueue在2500的同一側:
Camera Depth >?Sorting Layer >?Order In Layer > RenderQueue > 距離相機的距離
如果物體的RenderQueue在2500的不同側:
Camera Depth >?RenderQueue > Sorting Layer >?Order In Layer > 距離相機的距離
3.Unity中的一個坑
| 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. | 該隊列用于實現一些疊加效果,適合最后渲染的物體(如鏡頭光暈)。 |
從Unity文檔中這個圖我們可以看出來,Background理應最先被渲染,Unity中的skybox 應該屬于這個renderqueue,但是當你實際使用的時候,怪事發生了:
從FrameDebugger中可以看到,對于不透明物體的渲染,skybox是在opaque的最后渲染,從而減少OverDraw。這尼瑪不跟RenderQueue寫的1000沖突么?!Google一頓操作,結果是這樣:
?
?
總結來說就是:Unity關于Skybox部分的文檔好久沒有更新了,目前Skybox應該是RenderQueue 值為2500.5時渲染,在Opaque和AlphaTest之后,Transparent之前。
Unity這個文檔證明了這個說法:https://docs.unity3d.com/Manual/GraphicsCommandBuffers.html?_ga=2.53580588.563516390.1589165101-117244140.1588818896
?
4. 2.5D游戲渲染排序解決方案
上邊總結了Unity中渲染順序的相關知識,那利用這些知識,可以實現2D游戲中景深以及排序的問題,初步總結了幾種方案:
1.Order In Layer?
通過設置Order In Layer 為不同的值來進行排序,缺點是需要自定義一套標準來決定物體的Order In Layer值?
下邊這個插件用的是這個原理
https://assetstore.unity.com/packages/tools/sprite-management/isometric-toolkit-33032
2.用Shader自定義修改ZDepth
通過自己設置Shader中的ZDepth來達到排序的目的,也就是說Sprite在場景中的Z值都一樣,通過制定一套標準,來人為定義物體的ZDepth值?
下邊這個插件用的是這個原理
https://assetstore.unity.com/packages/templates/systems/2-5d-isometric-engine-106321
3.利用Z軸,實際就是ZDepth
在場景中把各個Sprite擺放位置根據前后關系設置Z軸位置,這樣2D游戲也可以擁有ZDepth的信息,從而可以正確渲染?
4.修改UnityProject 的設置
?改為Y軸為排序軸,這種方法不用考慮Z軸,完全根據Sprite的y軸大小設置,非常簡便。我是用的這種方式,暫時的缺點是無法根據sprite大小精確控制排序。
總結
以上是生活随笔為你收集整理的Unity 中渲染顺序的理解以及一些坑点 以及2.5D游戏中的渲染排序解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信用卡需要设置密码吗?不设密码安全吗?
- 下一篇: 兴业信用卡挂号信查询有哪些方法?这几种方