一种基于高度的材质混合方式-地表篇

发现守望先锋的地表很特别,不像是在unity那里画的那种材质间线性过渡,找了一下资料,感觉像是根据高度在shader中计算的

 

这是一种简单的近似方法

高度混合的原理:

简单的线性混合是这样的,就是mix/lerp一下,但是这样很丑,不自然

 

 

得到高度图只取最大高度的材质就是这种结果,像是泥土平铺在石头上

 

 

还有一种是最需要的,材质间的过渡

这就需要有一个2X2的float信息来先画分好材质间的大分水岭,同样是进行上面的取最大值。(细节高度与分水岭高度相加)

 

 

 

 

 

分水岭高度实现情况有下面两种:

 

A.绘制法

1.如果想要地形材质受美工控制,就像守望这样的,可以由美工绘制,位置也确定的,可以在绘制地表的shader中直接加这种高度材质混合

 

 

 

 

 

B.随机法

1.找一张或多张的四方连续噪声贴图做混合,多张重复性会减少(两张就好,一张大的一张小一些的,密度不同,再在shader中进行一下uv的缩放与偏移,增加多样性,减少重复)||或者干脆shader计算出噪音(手游要考虑消耗,pc主机可以使用)

Google一下seamless noisetexture

 

先大体混合出材质划分即分水岭高度

 

 

 

2.再用高度混合

 

 

 

		float4 c = tex2D(_MainTex, i.uv_MainTex);
		float4 c2 = tex2D(_MainTex2, i.uv_MainTex);
		float noise = tex2D(_NoiseTex, i.uv_NoiseTex).x;
		float noise2 = tex2D(_NoiseTex2, i.uv_NoiseTex2).x;

		noise =saturate(pow(saturate(noise*noise2*1.5),_NI)*_NI*_NS);



		float height = saturate(tex2D(_HeightTex, i.uv_MainTex).y*_H1);
		float height2 =saturate( tex2D(_HeightTex2, i.uv_MainTex).y*_H2);



		float depth = _DI;
		float ma = max((1-noise) + height, noise +height2) - depth;

		float b1 = max((1-noise) + height - ma, 0);
		float b2 = max(noise + height2 - ma, 0);

		c =  (c * b1 + c2 * b2) / (b1 + b2);

 

 

此处的noise即是分水岭高度

 

贴图是在网上随便找了两张无缝贴图,高度图是找了个工具用贴图转了高度图

 

 

 

 

 

 

 

多材质也可以使用这种方法,可以多加高度图进行计算,也可以把近似相同高度的材质共用一个高度

 

 

 

参考:

http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/advanced-terrain-texture-splatting-r3287

 

 ----wolf96  2016/12/21

 

posted @ 2016-12-21 20:36  战狼96  阅读(703)  评论(0编辑  收藏  举报