每個shader里面有很多的subshader,如果所以的subshader都不執行的話就,就執行fallback。每個subshader都可以設置一個LOD,整個shader也有一個LOD。
系統就去找第一個LOD小於等於shader的LOD的subshader執行,其他的subshader就不會被執行。
LOD
1:LOD Level of Detail, 根據LOD來設置使用不同版本的Shader;
2:着色器中給SubShader一個LOD值,程序來設置這個shader的LOD值,只有第一個小於等於LOD值subShader才會被執行;
3: 每個shader最多只會有一個SubShader被使用;
4: 通過Shader maximumLOD來設置最大的LOD值;
5: 設置全局的LOD值,Shader.globalMaximumLOD;
6: Unity內置着色器分LOD等級:
(1)VertexLit kind of shaders 100
(2) Decal, Reflective VertexLit 150
(3)Diffuse 200
(4)Difuse Detail 250
(5) Bumped, Specular 300
(6) BumpedSpecular 400
(7) Parallax 500
(8) Parallax Specular 600
LOD案例
1.創建Unity工程目錄
2.在resources文件夾下面創建一個shaders文件夾
3.在shaders里面創建一個create---->shader---->standard surface shader,重命名LODShader
4.打開LODShader:
Shader "Custom/LODShader" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 } // 每次只會根據情況來選擇一個可執行的SubShader // 找到第一個<= Shader.maximumLOD 這個subShader執行; SubShader { Tags { "RenderType"="Opaque" } LOD 600 // LOD-----------------這里設置為600 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard fullforwardshadows // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 sampler2D _MainTex; struct Input { float2 uv_MainTex; }; half _Glossiness; half _Metallic; fixed4 _Color; void surf (Input IN, inout SurfaceOutputStandard o) { o.Albedo = fixed3(1.0, 0.0, 0.0); } ENDCG } SubShader { Tags { "RenderType"="Opaque" } LOD 500 // LOD-----------------這里設置為500 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard fullforwardshadows // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 sampler2D _MainTex; struct Input { float2 uv_MainTex; }; half _Glossiness; half _Metallic; fixed4 _Color; void surf (Input IN, inout SurfaceOutputStandard o) { o.Albedo = fixed3(0.0, 1.0, 0.0); } ENDCG } SubShader { Tags { "RenderType"="Opaque" } LOD 400 // LOD-----------------這里設置為400 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard fullforwardshadows // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 sampler2D _MainTex; struct Input { float2 uv_MainTex; }; half _Glossiness; half _Metallic; fixed4 _Color; void surf (Input IN, inout SurfaceOutputStandard o) { o.Albedo = fixed3(0.0, 0.0, 1.0); } ENDCG } FallBack "Diffuse" }
5.創建一個cube立方體,創建一個材質球為LODShader,材質拖進cube材質屬性
6.材質的shader選擇custom---->LODShader
7.立方體變紅
8.創建一個腳本LOD_ctrl來控制LOD
9.打開LOD_ctrl
using UnityEngine; using System.Collections; public class LOD_ctrl : MonoBehaviour { public Shader shader;//公開屬性需要關聯 public int LOD_value = 600;//外部來設置shader的LOD的值 // Use this for initialization void Start () { Debug.Log(this.shader.maximumLOD); } // Update is called once per frame void Update () { // 當前這個shader最大的LOD_value; this.shader.maximumLOD = this.LOD_value;//關聯的節點可以直接使用和改變 } }
10.當我們改變的公開屬性LOD_value的時候,如果是600則是紅色,500是綠色,400是藍色,小於400是fallback白色,如果小於100將不顯示任何東西。
渲染隊列
Unity的game視圖的繪制順序是先繪制前面的物體,再繪制后面的物體,因為如果是從后面開始繪制,那新的物體如果在前面把舊的物體擋住了,那舊的物體的繪制就是無效的,很浪費。不像2D是先繪制舊物體再和新物體疊加在一起。
Unity會把物體分成幾個繪制的隊列,屬於哪種類型的就丟到哪個隊列里面,可以使得繪制的時候最優化,
如果前面的物體是透明的,那后面它擋住的物體只能再繪制,如果前面的物體是不透明的,那后面它擋住的物體可以不繪制,所以要分好幾類,減少不必要的繪制。它是基於Mesh繪制的。
所以我們遍歷渲染管道來剔除遮擋關系是有意義的,遮擋剔除的運算很厲害。
1:渲染隊列標簽可選值:
(1)Background 背景,對應的值為1000;
(2)Geometry(default) 幾何體對應的值為2000, 這個隊列是默認的渲染隊列,大多數不透明的物體;
(3)AlphaTest Alpha測試,對應值為2450, alpha測試的幾何體使用這種隊列,它是獨立於 Geometry的隊列,它可以在所有固體對象繪制后更有效的渲染采用Alpha測試的對象;
(4)Transparent:透明,對應值3000, 這個渲染隊列在Geometry被渲染,采用從后向前的次序;
任何有alpha混合的對象都在這個隊列里面渲染;
(5) Overlay 覆蓋對應值為4000, 這個渲染隊列是最后渲染的物體;
2: Unity 渲染模式: 普通物體從前向后, Alpha從后向前(這個沒辦法,要看到后面的東西);
2:渲染隊列的數值決定了Unity在渲染場景物體時的先后順序,關閉深度測試的情況下;
渲染隊列案例
1:創建兩個深度不同的求,配置不同的顏色前面是紅,后面是綠;
2.在shaders里面創建一個create---->shader---->standard surface shader,重命名RenderQueue
3: 使后面的綠球使用這個RenderQueue的shader模式
4.打開RenderQueue
Shader "Custom/RenderQueue" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 } SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry+100" }//設置渲染隊列的值,+左右不能用空格,多個tag,不能用逗號; LOD 200 ZTest off//關閉深度測試 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard fullforwardshadows // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 sampler2D _MainTex; struct Input { float2 uv_MainTex; }; half _Glossiness; half _Metallic; fixed4 _Color; void surf (Input IN, inout SurfaceOutputStandard o) { // Albedo comes from a texture tinted by color o.Albedo = _Color.rgb; } ENDCG } FallBack "Diffuse" }
5.會發現綠色球顯示在紅色球前面,本來紅色球會把綠色球擋住,但是我們修改了綠球渲染隊列的值,又關閉了深度測試,使得綠色球先繪制,所以綠球顯示在紅色球前面。