上次講了動态生成網格,這次說說怎樣分層顯示紋理。
一般的地形會支援大概4層的紋理,比如草地、岩石之類,然後通過一張遮罩貼圖來區分各自的顯示區域。這裡我做了同樣的事情。我寫了一個shader,支援4層貼圖的顯示。先來看看效果,最後貼上shader源碼:
這是一張遮罩圖檔
導入unity自帶的地形資源,裡面有不同地形紋理的貼圖,使用我這個shader,然後設定前兩個通道和遮罩通道
把材質賦予給一個面片,會出現這樣的效果。
這就是2個通道的融合了。紋理通過拾取遮罩圖檔不同的顔色值,來顯示不同的通道混合,最終顯示出來。
這裡對應四個紋理通道,我分别用到了圖檔的RGBA四個值來控制。是以我們可以做一個這樣的試驗,做一張黑色背景的圖檔,前面三個數字1、2、4分别用紅綠藍三種顔色,最後右下角在透明通道寫一個白色的4。
指定紋理和遮罩:
最後會看到這樣的效果。
最後我們結合第一節的生成地形網格,做一個效果測試:
用ps随便畫一張高度圖,或者你用其他三維軟體生成也行
用上一節的腳本,生成了這樣一個地形
然後根據地形畫出了一張遮罩圖檔,指定在遮罩的通道
這時候可以看到地形的效果是這樣的
再改變一下各個通道的平鋪重複次數
一個地形的效果就出來了。
這裡由于是使用RGBA四個通道來控制,是以限定最多隻能用4個不同的紋理。其實這個是可以自己擴充的,也可以把顔色分成不同的範圍,然後逐個範圍來指定對應的紋理。這個就自由發揮了。不過我覺得4層紋理應該也夠用了。
下面是shader的源碼:
Shader “Custom/MyTerrainShader” {
Properties {
_MainTex (“Base (RGB)”, 2D) = “white” {}
_SecondTex(“Second (RGB)”,2D) = “white”{}
_ThirdTex(“ThirdTex (RGB)”,2D) = “white”{}
_FourthTex(“FourthTex (RGB)”,2D) = “white”{}
_Mask(“Mask(RG)”,2D) = “white”{}
//_Color(“Color”,Color) = (1,1,1,1)
}
SubShader {
Tags { “RenderType”=”Opaque” }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
sampler2D _SecondTex;
sampler2D _ThirdTex;
sampler2D _FourthTex;
sampler2D _Mask;
struct Input {
float2 uv_MainTex;
float2 uv_SecondTex;
float2 uv_ThirdTex;
float2 uv_FourthTex;
float2 uv_Mask;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c1 = tex2D (_MainTex, IN.uv_MainTex);
half4 c2 = tex2D (_SecondTex, IN.uv_SecondTex);
half4 c3 = tex2D (_ThirdTex, IN.uv_ThirdTex);
half4 c4 = tex2D (_FourthTex, IN.uv_FourthTex);
half4 cm = tex2D (_Mask, IN.uv_Mask);
o.Albedo = c1.rgb*cm.r+c2.rgb*cm.g+c3.rgb*cm.b+c4.rgb*cm.a;
o.Alpha = c1.a;
}
ENDCG
}
FallBack "Diffuse"
}