UnityShader RenderTypeQueue 渲染顺序
整理自這兩篇博文
https://blog.csdn.net/u013477973/article/details/80607989?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1
https://www.jianshu.com/p/0341f0ab9020
RenderType
在Unity Shader中會經常在SubShader中使用Tags,其中就會涉及RenderType和Queue,如:
SubShader{
? ? Tags{"RenderType"="Opaque" ?"Queue"="Geometry"}
? ? ...
} ? ??
RenderType
RenderType通常使用的值包括:
Opaque: 用于大多數著色器(法線著色器、自發光著色器、反射著色器以及地形的著色器)。
Transparent:用于半透明著色器(透明著色器、粒子著色器、字體著色器、地形額外通道的著色器)。
TransparentCutout: 蒙皮透明著色器(Transparent Cutout,兩個通道的植被著色器)。
Background: Skybox shaders. 天空盒著色器。
Overlay: GUITexture, Halo, Flare shaders. 光暈著色器、閃光著色器。
TreeOpaque: terrain engine tree bark. 地形引擎中的樹皮。
TreeTransparentCutout: terrain engine tree leaves. 地形引擎中的樹葉。
TreeBillboard: terrain engine billboarded trees. 地形引擎中的廣告牌樹。
Grass: terrain engine grass. 地形引擎中的草。
GrassBillboard: terrain engine billboarded grass. 地形引擎何中的廣告牌草。
這些RenderType的類型名稱實際上是一種約定,用來區別這個Shader要渲染的對象,當然你也可以改成自定義的名稱,只不過需要自己區別場景中不同渲染對象使用的Shader的RenderType的類型名稱不同,也就是說RenderType類型名稱使用自定義的名稱并不會對該Shader的使用和著色效果產生影響。
指定RenderType的名稱,主要是為了配合使用替代渲染的方法:
Camera.SetReplacementShader("shader","RenderType") ?
在使用替代渲染方法時,相機會使用指定的 shader 來代替場景中的其他 shader 對場景進行渲染。比如現在有 shader1:
Shader "shader1"{
? ? Properties{...}
? ? SubShader{
? ? Tags{"RenderType"="Opaque"}
? ? Pass{...} ??
? ? }
? ? SubShader{
? ? Tags{"RenderType"="Transparent"}
? ? Pass{...} ??
? ? }
}
場景中一部分物體當前使用的是 shader2:
Shader "shader2"{
? ? Properties{...}
? ? SubShader{
? ? Tags{"RenderType"="Opaque"}
? ? Pass{...} ??
? ? }
}
另一部分使用的是 shader3:
Shader "shader3"{
? ? Properties{...}
? ? SubShader{
? ? Tags{"RenderType"="Transparent"}
? ? Pass{...} ??
? ? }
}
調用替代渲染的方法:
Camera.SetReplacementShader("shader1","") ??
這種情況下,場景中所有的物體就都使用shader1進行渲染(當Shader中包含多個SubShader,在渲染時顯卡根據性能從上到下選擇第一個能支持的shader)?
如果在調用時,第二個參數不為空字符串,即:
Camera.SetReplacementShader("shader1","RenderType") ??
這種情況下,首先在場景中找到標簽中包含該字符串(這里為"RenderType")的shader,再去看標簽中的該字符串的值與shader1中包含該字符串的值是否一致,一致的話,替換渲染,否則不渲染;由于shader2中包含"RenderType"="Opaque",而且shader1中的第一個SubShader中包含"RenderType"="Opaque",因此將shader1中的第一個SubShader替換場景中的所有shader2,同理,將shader1中的第二個SubShader替換場景中的所有的shader3。
如果shader1為:
Shader "shader1"{
? ? Properties{...}
? ? SubShader{
? ? Tags{"RenderType"="Opaque" "A"="On"}
? ? Pass{...} ??
? ? }
? ? SubShader{
? ? Tags{"RenderType"="Transparent" ?"A"="Off"}
? ? Pass{...} ??
? ? }
} ??
shader2為:
Shader "shader2"{
? ? Properties{...}
? ? SubShader{
? ? Tags{"RenderType"="Opaque" "A"="On"}
? ? Pass{...} ??
? ? }
} ?
shader3為:
Shader "shader3"{
? ? Properties{...}
? ? SubShader{
? ? Tags{"RenderType"="Transparent" "A"="On"}
? ? Pass{...} ??
? ? }
} ? ? ?
替代渲染的調用方式為:
Camera.SetReplacementShader("shader1","A") ? ? ?
最后的結果是,shader1的第一個SubShader將會替換shader2和shader3
渲染順序和RenderQueue
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暴露出來供自己定制。
簡單總結一下,決定Unity渲染關系的層級順序是:
Camera
sorting layer
sortingorder
但是這些還不夠,因為還沒有說到比較讓初學者頭疼的(筆者一開始就很頭疼)RenderQueue ,RenderQueue 其實就是shader中tags中的Queue
?
Tags { "Queue"="Geometry" }默認情況下,Unity會基于對象距離攝像機的遠近來排序你的對象。因此,當一個對象離攝像機越近,它就會優先繪制在其他更遠的對象上面。對于大多數情況這是有效并合適的,但是在一些特殊情況下,你可能想要自己控制對象的繪制順序。而使用Tags{}塊我們就可以得到這樣的控制。
Unity提供給我們一些默認的渲染隊列,每一個對應一個唯一的值,來指導Unity繪制對象到屏幕上。這些內置的渲染隊列被稱為Background, Geometry, AlphaTest, GeometryLast,Transparent, Overlay。這些隊列不是隨便創建的,它們是為了讓我們更容易地編寫Shader并處理實時渲染的。
同時需在SubShader中顯示聲明ZWrite Off,通知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. | 該隊列用于實現一些疊加效果,適合最后渲染的物體(如鏡頭光暈)。 |
好了,最后給出一個最終的總結:
依次按條件先后順序進行排序渲染處理。先按大項條件排序,后按小項條件排序
1.Camera Depth: 越小越優先
2.RenderQueue 2500以下
? ??1. Sorting Layer/Order in Layer
? ? ? ? ? ?1. 按照Sorting Layer/Order in Layer 設置的值,越小越優先
? ? ? ? ? ?2. 無此屬性,等同于 Sorting Layer=default ,Order in Layer=0 參與排序
? ? ?2.RenderQueue 越小越優先
? ? ?3.RenderQueue 相等,由近到遠排序優先
3.RenderQueue 2500以上
? ? ?1. Sorting Layer/Order in Layer
? ? ? ? ? ?1. 按照Sorting Layer/Order in Layer 設置的值,越小越優先
? ? ? ? ? ?2. 無此屬性,等同于 Sorting Layer=default ,Order in Layer=0 參與排序
? ? ?2.RenderQueue 越小越優先
? ? ?3.RenderQueue 相等,由遠到近排序優先
說明一下:2500是關鍵值,它是透明跟不透明的分界點,因此我們考慮層級的時候要注意著點:renderqueue > 2500的物體絕對會在renderqueue <= 2500的物體前面,即渲染時renderqueue大的會擋住renderqueue小的,不論它的sortingLayer和sortingOrder怎么設置都是不起作用的。知道了這點,其他的就很好理解了。當兩個的RenderQueue都在同一側時,在SortingLayer高的絕對會在sortingLayer前面,無視renderqueue跟soringOrder,只有在sortingLayer相同的前提下,soringOrder高的會在sortingOrder低的前面,無視renderqueue。當sortingLayer跟sortingOrder相同時,才看renderqueue的高低,高的在前面。
UGUI中的ui默認使用的是UI/Default 材質,對應的shader中的渲染隊列是Transparent
Shader "UI/Default" {Properties{...}SubShader{Tags{"Queue"="Transparent""IgnoreProjector"="True""RenderType"="Transparent""PreviewType"="Plane""CanUseSpriteAtlas"="True"}...} }?
?
總結
以上是生活随笔為你收集整理的UnityShader RenderTypeQueue 渲染顺序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#监控类属性的更改(大花猫动了哪些小玩
- 下一篇: 民生银行信用卡临时额度有效期多久?还不上