上次讲了动态生成网格,这次说说怎样分层显示纹理。
一般的地形会支持大概4层的纹理,比如草地、岩石之类,然后通过一张遮罩贴图来区分各自的显示区域。这里我做了同样的事情。我写了一个shader,支持4层贴图的显示。先来看看效果,最后贴上shader源码:
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img1.ph.126.net/OrR-USDAZGF4s9p6_wFI9g==/196751008820820067.jpg)
这是一张遮罩图片
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img2.ph.126.net/EncatBM_vFJkwmE0hjPAug==/2096707101617748704.jpg)
导入unity自带的地形资源,里面有不同地形纹理的贴图,使用我这个shader,然后设定前两个通道和遮罩通道
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img2.ph.126.net/D0Sz2_fXVgVSe4zA6zLanA==/6597330350913472748.jpg)
把材质赋予给一个面片,会出现这样的效果。
这就是2个通道的融合了。纹理通过拾取遮罩图片不同的颜色值,来显示不同的通道混合,最终显示出来。
这里对应四个纹理通道,我分别用到了图片的RGBA四个值来控制。所以我们可以做一个这样的试验,做一张黑色背景的图片,前面三个数字1、2、4分别用红绿蓝三种颜色,最后右下角在透明通道写一个白色的4。
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img0.ph.126.net/uNFtD-UPf1J9z7Omm1c80g==/89509042694081418.jpg)
指定纹理和遮罩:
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img2.ph.126.net/opk2Of0yH1FYMxc57gjnVQ==/2044352755949576495.jpg)
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img2.ph.126.net/tBFsSHHGgOKkEfswEIzXQg==/3903494977123598351.jpg)
最后会看到这样的效果。
最后我们结合第一节的生成地形网格,做一个效果测试:
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img0.ph.126.net/9hg9cTSW8F6dJr733tlwhg==/6597839424797638416.jpg)
用ps随便画一张高度图,或者你用其他三维软件生成也行
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img2.ph.126.net/XRSV790bdWexD0nHA6nfnA==/816840382514405204.jpg)
用上一节的脚本,生成了这样一个地形
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img0.ph.126.net/RrLaAgB7kvudQlBCDy6hfA==/2112188225336833941.jpg)
然后根据地形画出了一张遮罩图片,指定在遮罩的通道
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img0.ph.126.net/5DlLjgFifuMAMGYzBS-3DA==/2006635109070349050.jpg)
这时候可以看到地形的效果是这样的
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img1.ph.126.net/B22lQKOA1g1pjEZ6cWvXBg==/1404278658909522163.jpg)
再改变一下各个通道的平铺重复次数
![Unity3D动态创建地形网格(二) - 阿赵 - 有爪的小羔羊阿赵](http://img0.ph.126.net/1A42qmmFCbS-Y6AQzzKptg==/6597965868634838247.jpg)
一个地形的效果就出来了。
这里由于是使用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"
}