咱們在作手機遊戲開發過程當中常常使用 Diffuse shader,並對場景進行烘培,這樣能用很低的消耗達到不錯的效果。 DiffuseShader 不能設置Alpha通道,在實際開發過程當中遇到須要透明,或者實現漸隱效果。編碼
所有Shader代碼以下spa
Shader "Mobile/Diffuse_Aplha" { Properties{ _Color("Color",Color) = (1,1,1,1) _MainTex("MainTex",2D) = "white"{} _AlphaScale("AlphaScale",Range(0,1)) = 1 } SubShader{ Tags{"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"} //"RenderType"="Transparent"指明該shader爲使用了透明度混合的shader //開啓深度寫入的Pass是爲了將模型的深度信息寫入深度緩衝中,從而剔除模型中被自身遮擋的片元 Pass{ ZWrite On ColorMask 0 } Pass{ //Tags{"LightMode" = "ForwardBase"} Zwrite Off //關閉深度寫入 Blend SrcAlpha OneMinusSrcAlpha //設置混合因子爲源的透明度 CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON #include "Lighting.cginc" fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; fixed _AlphaScale; struct a2v { float4 vertex : POSITION; float2 uv : TEXCOORD0; float2 uv1 : TEXCOORD1; }; struct v2f { float4 vertex:SV_POSITION; float2 uv:TEXCOORD0; #ifdef LIGHTMAP_ON float2 uvLM : TEXCOORD1; #endif }; v2f vert(a2v v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); #ifdef LIGHTMAP_ON o.uvLM = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; #endif return o; } fixed4 frag(v2f i) :SV_Target{ fixed4 col = tex2D(_MainTex, i.uv); col = col * _Color; #ifdef LIGHTMAP_ON fixed3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM)); col.rgb *= lm; #endif return fixed4(col.rgb, _AlphaScale); } ENDCG } } FallBack "Transparent/VertexLit" }
首先咱們須要透明,咱們須要渲染隊列 "Queue" = "Transparent"code
接受場景烘培貼圖 加入編輯指令 #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ONhtm
(#ifdef LIGHTMAP_ON ) 處理LightMap 代碼隊列
這裏爲何要用DecodeLightmap又要用UNITY_SAMPLE_TEX2D來解讀ligtmap呢?遊戲
實際上unity生成的lightmap的有兩種編碼格式:doubleLDR和RGBMip
Unity使用了兩種編碼方式來存儲lightmap:遊戲開發
一、doubleLDR,須要一張rgb24貼圖 二、RGBM,須要一張rgba32貼圖開發
在移動設備上使用doubleLDR格式,能夠得到更快的計算速度。它只用到了lightmap的RGB通道。get
PC上則使用RGBM格式,能夠得到更廣的亮度範圍,而犧牲一點速度。它使用了貼圖的RGBA通道,而A通道是用來作乘法,因此稱爲RGBM格式。
這兩種格式的差別就是致使不一樣平臺下lightmap表現不一樣的緣由,固然Unity會在切換平臺時幫咱們對貼圖進行轉換,而不須要太關心這個差別。