2d短草丛踩踏及idle效果

一般我们用短草丛被角色经过或平常的飘动效果都是用3d实现的,3d实现起来就比较简单,就是对模型上的顶点做与角色距离的相反方向偏移就好了,平常的飘动效果一般是用sin做弧度变化或者甚至就直接uv的来回移动就好。
2d短草丛踩踏及idle效果

我们是3渲2的画面俯四十五度固定视角的游戏,因为2d就一个面片,所有顶点都在一个面片上,如果一个面片上的点往3d的四周扩散,会让这个效果显得很2d。

 

在这里的话我采取了另一种实现方式,因为从踩短草丛的效果上看,一般是

1.草往斜前方偏移或者往后前方偏移的(找不到图演示)

2.草完全被人踩在脚底的。

 

草完全被踩在脚底就相当于不显示了,这一块我的做法其实和前面做法是一样的。

 

首先确定的是我们的游戏是俯四十五度固定视角,是固定的。所以我们就可以思考下这个视角的特点。这个视角要操作的是正面的草,不能操作侧面的草。所以我们要做偏移可以往三个方向做“固定”的偏移。

首先要调整法向量:

xy方向是要一起移动的,不然只移动x方向或只移动y方向都看不到效果。因为希望的是他变形之后是呈现梯形变化的,所以也就需要底部小,顶部大。

顶点的法向量需要调整一下,主要是法向的y需要调低,法向量的x轴则需要根据角色位置点与顶点的距离,如果大则向右,小则向左偏移。

 

然后调整真正的顶点三个方向的值,x需要根据角色与顶点位置向两边扩散,y需要向下移动,z需要根据位置角色与顶点的位置向前后扩散。

2d短草丛踩踏及idle效果

2d短草丛踩踏及idle效果

 

草的飘动效果就比较简单,根据uv的y来确定他飘动的幅度就好,草的根是不动的

 

// Diablo Lite Shaders - Dave Lindsay

Shader "DiabloLite v2/Grass"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_FakeNrm ("Fake Bump", 2D) = "white" {}
_HighlightPow("Highlight Power", Range(0,4)) = 2
_HighlightAmt("Highlight Strength", Range(0,4)) = 2
_GrassDistance("Grass Distance", Range(0,4)) = 2
_GrassPower("Grass Power", Range(1,3)) = 2
_GrassSway("Grass Sway", Range(0,0.4)) = 0.2
}
	
Subshader
{

ZWrite Off
//ZTest Off
Fog{ Mode Off }
Lighting Off
Cull Off

Tags { "RenderType"="Transparent" "Queue" = "Transparent" }

Blend SrcAlpha OneMinusSrcAlpha

Pass
{
	CGPROGRAM
	#pragma vertex vert
	#pragma fragment frag
	#pragma fragmentoption ARB_precision_hint_fastest
	#include "UnityCG.cginc"
	#include "Light2DNormalMgr.cginc"

	// =========================================================

	uniform sampler2D _MainTex;
	uniform sampler2D _FakeNrm;
	uniform float4 _MainTex_ST;

	uniform float _GrassDistance;
	uniform float _GrassPower;
	uniform float _GrassSway;

	uniform half _HighlightAmt;
	uniform half _HighlightPow;

	uniform float3 _GrassPos;

	uniform float3 _LightPos;
	uniform float4 _LightColor;
	uniform float4 _ShadeColor;
	uniform float _LightRangeMin;
	uniform float _LightRangeMax;
	uniform float _LightRangeNormal;
	uniform float _GrassHandlerDistance;
	uniform float _GrassVerticalPow;
	uniform float _GrassTransversePow;
	
	// =========================================================

	struct v2f
	{
		float4 pos	: SV_POSITION;
		float2 texture_uv : TEXCOORD0;
		float3 light_dir : TEXCOORD1;
		float light_dst : TEXCOORD2;
		float3 worldPos : TEXCOORD3;
	};

	// =========================================================

	v2f vert (appdata_full v)
	{
		v2f o;
		
		o.texture_uv = TRANSFORM_TEX(v.texcoord, _MainTex);

		float3 tempWorldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
		tempWorldPos.z += 0.5;
		half dis = distance(_LightPos, tempWorldPos);

		dis = dis >= _GrassHandlerDistance ? 0 : (_GrassHandlerDistance - dis);
		v.normal.y -= dis;
		v.normal.x += (tempWorldPos.x - _LightPos.x) * _GrassTransversePow;
		v.vertex.xy += dis * (v.normal.xy * _GrassVerticalPow * o.texture_uv.y);
		v.vertex.z += (tempWorldPos.z - _LightPos.z) * dis;//

		float bending;
		float bend_coef = 10 * (tempWorldPos.x + tempWorldPos.z);
		bending = sin(bend_coef + _Time.z) * _GrassSway;

		float3 grass_dir = normalize(_GrassPos - tempWorldPos);
		bending += grass_dir.x * max(0, _GrassDistance - pow(distance(_GrassPos.xz, tempWorldPos.xz), _GrassPower));
		bending *= v.color.a;
		v.vertex.x -= bending * o.texture_uv.y;
		o.pos = UnityObjectToClipPos(v.vertex);

		float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
		o.worldPos = worldPos;
		
		return o;
	}

	// =========================================================

	fixed4 frag (v2f i) : COLOR
	{
		fixed4 colortex = tex2D(_MainTex, i.texture_uv);
		fixed4 outcolor = colortex;

		half2 normalUV = i.texture_uv;

		outcolor.rgb = Light2DHandler(colortex, _LightColor, _ShadeColor, _FakeNrm, normalUV, _HighlightPow, _HighlightAmt, i.worldPos,
			_LightPos, _LightRangeMax, _LightRangeMin, _LightRangeNormal);

		return outcolor;
	}
	ENDCG
}
}
}

 

上一篇:HikariCP 连接池


下一篇:【数通面试私房菜之BGP专题】第二期:BGP状态机详解