Unity 中渲染顺序的理解以及一些坑点 以及2.5D游戏中的渲染排序解决方案
1.ZTest & ZWrite
ZTest:深度測(cè)試,開(kāi)啟后測(cè)試結(jié)果決定片元是否被舍棄,可配置?
ZWrite:深度寫(xiě)入,開(kāi)啟后決定片元的深度值是否寫(xiě)入深度緩沖,可配置
ZTest可設(shè)置的測(cè)試規(guī)則:
ZTest Less:深度小于當(dāng)前緩存則通過(guò)
ZTest Greater:深度大于當(dāng)前緩存則通過(guò)
ZTest LEqual:深度小于等于當(dāng)前緩存則通過(guò)
ZTest GEqual:深度大于等于當(dāng)前緩存則通過(guò)
ZTest Equal:深度等于當(dāng)前緩存則通過(guò)
ZTest NotEqual:深度不等于當(dāng)前緩存則通過(guò)
ZTest Always:不論如何都通過(guò)
注意,ZTest Off等同于ZTest Always,關(guān)閉深度測(cè)試等于完全通過(guò)。
ZWrite配置:?
ZWrite On 深度寫(xiě)入開(kāi)啟 ZWrite Off 深度寫(xiě)入關(guān)閉
ZTest和ZWrite發(fā)生在逐片元操作過(guò)程,處于片元著色后,最終屏幕輸出前。ZTest與ZWrite的具體操作流程:
因?yàn)閆Write默認(rèn)值為On,ZTest默認(rèn)值為L(zhǎng)Equal,所以這很好地解釋了為什么在unity中,距離相機(jī)近的東西會(huì)阻擋住距離相機(jī)遠(yuǎn)的東西。如果我們先繪制一個(gè)距離較近的物體,再繪制距離較遠(yuǎn)的物體,則距離遠(yuǎn)的物體因?yàn)楹罄L制,會(huì)把距離近的物體覆蓋掉,這時(shí)我們可以通過(guò)修改ZWrite和ZTest來(lái)改變物體的遮擋關(guān)系
所以對(duì)于透明物體的渲染,一般要關(guān)閉掉ZWrite,比如Unity中用于渲染Sprite的默認(rèn)SpriteDefault材質(zhì)的Shader:
加深對(duì)ZTest & ZWrite的理解,可以參考這篇文章的測(cè)試部分,把各例子理解明白非常有幫助。
https://www.jianshu.com/p/9137ee354dbd
2.Unity渲染順序
能夠影響渲染順序的因素有:
- Camera Depth:? ??相機(jī)組件上設(shè)置的相機(jī)深度,深度越大越靠后渲染。
- Sorting Layer:? ? ?在Tags & Layers設(shè)置中可見(jiàn)
- Order In Layer:? ??相對(duì)于Sorting Layer的子排序,用這個(gè)值做比較時(shí)只有都在同一層時(shí)才有效。
- RenderQueue:? ? ?Shader中對(duì)Tags設(shè)置的“Queue”。
- 物體距離相機(jī)的距離,ZDepth值
下面是結(jié)果:
1、Camera Depth
永遠(yuǎn)最高。Camera Depth小的一定先進(jìn)渲染管線。
2、當(dāng)Sorting Layer和Order In Layer不相同時(shí)
- 當(dāng)兩個(gè)材質(zhì)使用了不同的RenderQueue,且這兩個(gè)RenderQueue都在[0~2500]或[2501~5000]時(shí),SortingLayer和OrderInLayer的排序生效。
- ?當(dāng)兩個(gè)材質(zhì)使用了不同的RenderQueue,且這兩個(gè)RenderQueue分別在[0~2500]和[2501~5000]時(shí),則一定會(huì)按照RenderQueue繪制,無(wú)視SortingLayer、OrderInLayer的排序。
3、當(dāng)Sorting Layer和Order In Layer相同時(shí)
- RenderQueue不相等:
? ? ? ? RenderQueue小的先進(jìn)渲染管線。
- ?RenderQueue 相等
? ? ? ? RenderQueue 2500以下,由近到遠(yuǎn)排序優(yōu)先 (不透明)
? ? ? ? RenderQueue 2500以上,?由遠(yuǎn)到近排序優(yōu)先??(透明)
說(shuō)明一下:2500是關(guān)鍵值,它是透明跟不透明的分界點(diǎn),因此我們考慮層級(jí)的時(shí)候要注意著點(diǎn):renderqueue > 2500的物體絕對(duì)會(huì)在renderqueue <= 2500的物體前面,即渲染時(shí)renderqueue大的會(huì)擋住renderqueue小的,不論它的sortingLayer和sortingOrder怎么設(shè)置都是不起作用的。知道了這點(diǎn),其他的就很好理解了。當(dāng)兩個(gè)的RenderQueue都在同一側(cè)時(shí),在SortingLayer高的絕對(duì)會(huì)在sortingLayer前面,無(wú)視r(shí)enderqueue跟soringOrder,只有在sortingLayer相同的前提下,soringOrder高的會(huì)在sortingOrder低的前面,無(wú)視r(shí)enderqueue。當(dāng)sortingLayer跟sortingOrder相同時(shí),才看renderqueue的高低,高的在前面。
總結(jié)下Unity影響渲染順序各參數(shù)的優(yōu)先級(jí)
如果物體的RenderQueue在2500的同一側(cè):
Camera Depth >?Sorting Layer >?Order In Layer > RenderQueue > 距離相機(jī)的距離
如果物體的RenderQueue在2500的不同側(cè):
Camera Depth >?RenderQueue > Sorting Layer >?Order In Layer > 距離相機(jī)的距離
3.Unity中的一個(gè)坑
| Background | 1000 | This render queue is rendered before any others. | 這個(gè)隊(duì)列通常被最先渲染(比如 天空盒)。 |
| Geometry | 2000 | Opaque geometry uses this queue. | 這是默認(rèn)的渲染隊(duì)列。它被用于絕大多數(shù)對(duì)象。不透明幾何體使用該隊(duì)列。 |
| AlphaTest | 2450 | Alpha tested geometry uses this queue. | 需要開(kāi)啟透明度測(cè)試的物體。Unity5以后從Geometry隊(duì)列中拆出來(lái),因?yàn)樵谒胁煌该魑矬w渲染完之后再渲染會(huì)比較高效。 |
| GeometryLast | 2500 | Last render queue that is considered “opaque”. | 所有Geometry和AlphaTest隊(duì)列的物體渲染完后 |
| Transparent | 3000 | This render queue is rendered after Geometry and AlphaTest, in back-to-front order. | 所有Geometry和AlphaTest隊(duì)列的物體渲染完后,再按照從后往前的順序進(jìn)行渲染,任何使用了透明度混合的物體都應(yīng)該使用該隊(duì)列(例如玻璃和粒子效果) |
| Overlay | 4000 | This render queue is meant for overlay effects. | 該隊(duì)列用于實(shí)現(xiàn)一些疊加效果,適合最后渲染的物體(如鏡頭光暈)。 |
從Unity文檔中這個(gè)圖我們可以看出來(lái),Background理應(yīng)最先被渲染,Unity中的skybox 應(yīng)該屬于這個(gè)renderqueue,但是當(dāng)你實(shí)際使用的時(shí)候,怪事發(fā)生了:
從FrameDebugger中可以看到,對(duì)于不透明物體的渲染,skybox是在opaque的最后渲染,從而減少OverDraw。這尼瑪不跟RenderQueue寫(xiě)的1000沖突么?!Google一頓操作,結(jié)果是這樣:
?
?
總結(jié)來(lái)說(shuō)就是:Unity關(guān)于Skybox部分的文檔好久沒(méi)有更新了,目前Skybox應(yīng)該是RenderQueue 值為2500.5時(shí)渲染,在Opaque和AlphaTest之后,Transparent之前。
Unity這個(gè)文檔證明了這個(gè)說(shuō)法:https://docs.unity3d.com/Manual/GraphicsCommandBuffers.html?_ga=2.53580588.563516390.1589165101-117244140.1588818896
?
4. 2.5D游戲渲染排序解決方案
上邊總結(jié)了Unity中渲染順序的相關(guān)知識(shí),那利用這些知識(shí),可以實(shí)現(xiàn)2D游戲中景深以及排序的問(wèn)題,初步總結(jié)了幾種方案:
1.Order In Layer?
通過(guò)設(shè)置Order In Layer 為不同的值來(lái)進(jìn)行排序,缺點(diǎn)是需要自定義一套標(biāo)準(zhǔn)來(lái)決定物體的Order In Layer值?
下邊這個(gè)插件用的是這個(gè)原理
https://assetstore.unity.com/packages/tools/sprite-management/isometric-toolkit-33032
2.用Shader自定義修改ZDepth
通過(guò)自己設(shè)置Shader中的ZDepth來(lái)達(dá)到排序的目的,也就是說(shuō)Sprite在場(chǎng)景中的Z值都一樣,通過(guò)制定一套標(biāo)準(zhǔn),來(lái)人為定義物體的ZDepth值?
下邊這個(gè)插件用的是這個(gè)原理
https://assetstore.unity.com/packages/templates/systems/2-5d-isometric-engine-106321
3.利用Z軸,實(shí)際就是ZDepth
在場(chǎng)景中把各個(gè)Sprite擺放位置根據(jù)前后關(guān)系設(shè)置Z軸位置,這樣2D游戲也可以擁有ZDepth的信息,從而可以正確渲染?
4.修改UnityProject 的設(shè)置
?改為Y軸為排序軸,這種方法不用考慮Z軸,完全根據(jù)Sprite的y軸大小設(shè)置,非常簡(jiǎn)便。我是用的這種方式,暫時(shí)的缺點(diǎn)是無(wú)法根據(jù)sprite大小精確控制排序。
總結(jié)
以上是生活随笔為你收集整理的Unity 中渲染顺序的理解以及一些坑点 以及2.5D游戏中的渲染排序解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 信用卡需要设置密码吗?不设密码安全吗?
- 下一篇: LeetCode 240. 搜索二维矩阵