ShaderLab學習小結(十)簡單的支持光照貼圖的shader
阿新 • • 發佈:2018-02-01
process auto double defined erl plane lock 代碼 img 場景中建一個plane,一個cube一個cylinder
把場景平行光的強度調低一些,再加一個點光源,設置為綠色吧,俗話說的好:愛是一道光,綠到你發荒……
把點光源的shadowtype設置為hard shadow(默認的是無陰影)
如上圖,平行光和點光源都產生了陰影。
然後烘出來,可以把燈光關了
物體的光照還有陰影還在
這個unity_Lightmap和unity_LightmapST是內建的直接用
但是註意,unity_Lightmap與ST之間並無下劃線,這個和TRANSFORM_TEX定義的不一樣,所以得這樣寫
這裏用到了v.texcoord1,查看unitycg.cginc,發現vert的參數得用appdata_full
v.texcoord對應主紋理,v.texcoord1對應的是光照貼圖(就這樣理解吧)
把場景平行光的強度調低一些,再加一個點光源,設置為綠色吧,俗話說的好:愛是一道光,綠到你發荒……
把點光源的shadowtype設置為hard shadow(默認的是無陰影)
如上圖,平行光和點光源都產生了陰影。
要烘焙lightmap,就要把被烘物體設置上lightmap static
平行光和點光源都把Baking設置為Baked
在lighting面板中,把Ambient GI選成Baked
烘出來感覺暗一些,稍微把General GI裏的indirect Intensity調高一些到1.5(這個不為追求什麽效果)
把底下的auto前面的勾選取消掉,再點擊Build
然後烘出來,可以把燈光關了
物體的光照還有陰影還在
Shader代碼:
Shader "Custom/TestLightMapShader" { Properties{ _MainTex("Main Tex",2d) = ""{} } SubShader { pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" sampler2D _MainTex; float4 _MainTex_ST; struct v2f { float4 pos:POSITION; float2 uv0:TEXCOORD0; float2 uv1:TEXCOORD1; }; v2f vert(appdata_full v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv0 = TRANSFORM_TEX(v.texcoord, _MainTex); o.uv1 = v.texcoord1.xy*unity_LightmapST.xy + unity_LightmapST.zw; return o; } fixed4 frag(v2f IN) :COLOR { fixed4 col = tex2D(_MainTex,IN.uv0); float3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv1)); col.rgb *= lm*2; return col; } ENDCG } } FallBack "Diffuse" }
定義了一個_MainTex,這裏並沒有賦紋理,為了和光照貼圖有區別
結構體裏定義:uv0與uv1
uv1對應的是光照貼圖的處理
o.uv1 = v.texcoord1.xy*unity_LightmapST.xy + unity_LightmapST.zw;
看這個公式和unitycg.cginc裏的TRANSFORM_TEX的定義好像是一樣的
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
為什麽不用TRANSFORM_TEX呢
但是註意,unity_Lightmap與ST之間並無下劃線,這個和TRANSFORM_TEX定義的不一樣,所以得這樣寫
這裏用到了v.texcoord1,查看unitycg.cginc,發現vert的參數得用appdata_full
v.texcoord對應主紋理,v.texcoord1對應的是光照貼圖(就這樣理解吧)
然後到frag函數中
fixed4 col = tex2D(_MainTex,IN.uv0);
float3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv1));
col.rgb *= lm*2;
return col;
tex2D主紋理采樣 沒變
之後對lightmap貼圖進行采樣
float3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv1));
這個在unitycg.cginc中定義,返回值是個half3
inline half3 DecodeLightmap( fixed4 color, half4 decodeInstructions)
{
#if defined(UNITY_NO_RGBM)
return DecodeLightmapDoubleLDR( color );
#else
return DecodeLightmapRGBM( color, decodeInstructions );
#endif
}
再與主顏色的rgb疊加
col.rgb *= lm*2;
這裏lm*2是因為太暗,所以增加亮度
當然,從圖上能看出來,lightmap與實時渲染的效果是不一樣的,這個就需要調整了,本文不涉及。
ShaderLab學習小結(十)簡單的支持光照貼圖的shader