王者荣耀地图资源

简单分析地表混合

Posted by Bob on October 21, 2018

王者荣耀地表用的Terrain Splatting技术,简单说就是合并多层贴图,平滑融合边缘。

这个技术由Charles Bloom发明的,他有一篇文章介绍说明,另外wiki上也有一些基本原理介绍。

image

整个地表没有用高度图,直接用 分割粒度适中的Mesh 做的,下图是战斗地图右直道,uv是路边缘草(_Splat0),uv2是石块(_Splat1)。colors是用于做二层融合,alpha没有单独使用贴图直接存在mesh中,节省的小技巧。很多年前一位美女让我帮忙做个地形编辑器,我居然用了八层地表,逃~~~~~

image

下图屏蔽石块层后渲染效果,可看出alpha层实际就是一个简单的渐变,没有用笔刷刷。

image

如下脑洞分析后人工重写的shader,可能与原始游戏效果有些差异。

Shader "S_Game_Scene/TerrainVertexUV2Tiling" 
{
Properties 
{
	_Splat0 ("Layer1(uv1)", 2D) = "black" {}
	_Splat1 ("Layer2(uv2)", 2D) = "white" {}
}
	
SubShader 
{
	Tags{ "Queue" = "Geometry+110"   }
	Pass 
	{
			
		Tags{"LightMode" = "ForwardBase" }

		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 2.0
			#include "UnityCG.cginc"

	
			sampler2D _Splat0;
			sampler2D _Splat1;

			float4 _Splat0_ST;
			float4 _Splat1_ST;


			struct v2f
			{
				float4	pos : SV_POSITION;
				half2  uv_Tex0:TEXCOORD0;
				half2  uv_Tex1:TEXCOORD1;

				float4 color : COLOR;
			}; 
			
			struct appdata
			{
			    float4 vertex : POSITION;
				float4 texcoord : TEXCOORD0;
				float4 color : COLOR;
			};


			v2f vert (appdata v)
			{
				float4 worldPos = mul(unity_ObjectToWorld, v.vertex);

				v2f o;
			
				o.uv_Tex0 = TRANSFORM_TEX(v.texcoord ,_Splat0);
				o.uv_Tex1 = TRANSFORM_TEX(v.texcoord ,_Splat1);
				o.color = v.color;
				o.pos =  UnityObjectToClipPos(float4(v.vertex.xyz, 1));

				return o;
			}
				

		
			fixed4 frag(v2f i) : COLOR
			{
			
				fixed4 color = fixed4(1,1,1,1);
				fixed4 Tex0Color = tex2D(_Splat0, i.uv_Tex0);
				
				fixed4 Tex1Color = tex2D(_Splat1, i.uv_Tex1);

				
				color = lerp(Tex0Color,Tex1Color, i.color.a);

				

				return color;
			}

		ENDCG
	}	
}
	FallBack "Diffuse"
}

image

另外还有基于高度的融合,融合效果更自然,下篇再介绍吧~