Shader "URP/Environment/Grass/GrassCutoffAnimation"{

Properties{
	[HideInInSpector] _MainTex("Albedo (RGB)", 2D) = "white" {}
	[HideInInSpector] _DisplacementV2Tex("DisplacementV2 (RGB)", 2D) = "white" {}
	[HideInInSpector] _InteractiveTex("Interactive (RGB)", 2D) = "white" {}
	[HideInInSpector] _RegionHeightMap("Region HeightMap (RGB)", 2D) = "white" {}

	//[Space(4)]
	//[Header(Grass Shape And Animation Setting)]
	[HideInInSpector] _Width("    Width", Float) = 0.8
	[HideInInSpector] _Height("    Height", Float) = 1.15
	[HideInInSpector] _UpOffset("    _UpOffset", Range(-1, 1)) = -0.05
	//_Stiffness("Stiffness", Range(0, 1)) = 0.03
	[HideInInSpector] _UpDir("    Growth Direction", Vector) = (0, 1, 0, 0)
	[HideInInSpector] _GroundCoef("    Ground Coefficient", Range(-2, 2)) = 0.5
	[HideInInSpector] _BendCoef("    Bend Coefficient", Range(-3, 3)) = 1.8
	[HideInInSpector]_CurDisplacementFrame("", Float) = 0
	[HideInInSpector] _DisplacementScale("    Displacement Scale", Float) = 1
	//_Idle("    Idle", Vector) = (1, 23.58, 1, 0)

	//[Space(4)]
	//[Header(Far Near Color Blend Setting)]
	[HideInInSpector] _FarColor("    FarColor", Color) = (0.8, 1.0, 0.0, 1)
	[HideInInSpector] _FarCoef("    Far Coef", Range(1, 10000)) = 2441

	//[Space(4)]
	//[Header(LOD Setting)]
	[HideInInSpector] _LODDes("	   (ScaleMin, ScaleMax, WidthMin, WidthMax)", Float) = 0
	[HideInInSpector] _LOD0("    LOD 0 ", Vector) = (1, 1.5, 1, 1.5)
	[HideInInSpector] _LOD1("    LOD 1", Vector) = (1.52, 3, 2, 4)
	[HideInInSpector] _LOD2("    LOD 2", Vector) = (3, 2, 4, 6)

	//[Space(4)]
	//[Header(Specular Setting)]
	[HideInInSpector] _SpecularPower("    Specular Power", Range(0.01, 1)) = 0.1
	[HideInInSpector] _Gloss("    Gloss", Range(0, 10)) = 0.99
	[HideInInSpector] _SpecGrayScale("    SpecGrayScale", Range(0, 0.999)) = 0.06

	//[Space(4)]
	//[Header(Shadow Setting)]
	[HideInInSpector] _ShadowCoef("    Shadow Coef", Range(-1, 1)) = 0.015
	[HideInInSpector] _SelShadowCoef("    SelShadow Coef", Range(0, 1)) = 0.5

	//[Space(4)]
	//[Header(Translucent Setting)]
	[HideInInSpector] _TranslucentDistortion("    Distortion", Float) = 0.01
	[HideInInSpector] _TranslucentAttenuation("    Attenuation", Color) = (0.8, 1.0, 0.0, 1)
	[HideInInSpector] _TranslucentPower("    Power", Float) = 11.39
	[HideInInSpector] _TranslucentScale("    Scale", Float) = 100.0

	//[Space(4)]
	[HideInInSpector] _GeoFadeBegin("GeometryGrass Fade Begin", Float) = 20.0
	//_AntiAliasing("Anti-Aliasing", Float) = 4
	[HideInInSpector] _FireColor("FireColor", Color) = (0.3, 0.3, 0.3, 1)
	[HideInInSpector] _GroundBlendCoef("Ground Blend Coef", Range(0, 10)) = 0


	[Space(4)]
	[Header(Cutoff Grass Animation Settings)]
	[Space(2)]
	[Header(Lifetime)]
	_AnimateTime("animate time", Float) = 0.6
	_AnimateTimeEnd(" ", Float) = 1.5
	[HideInInSpector] _AnimateTimeRand(" ", Float) = 0

	[Space(2)]
	[Header(Grass Density)]
	_Density("grass density", Range(0,1)) = 0.8

	[Space(2)]
	[Header(Wind Intense)]
	_WindDirX("wind intense in X component", Range(-1,1)) = 0.0
	_WindDirZ("wind intense in Z component", Range(-1,1)) = 0.0

	[Space(2)]
	[Header(Horizontal Velocity)]
	_VelocityInit("horizontal velocity", Float) = 1
	_VelocityInitEnd(" ", Float) = 2
	[HideInInSpector] _VelocityRand(" ", Float) = 1
	_DirRand("direction rand", Float) = 1.5
	//_VelocityRandZ("velocity rand in z", Float) = 1
	_VelocityFinal("final horizontal velocity", FLoat) = 1
	_VelocityDamp("horizontal velocity damp", Range(1,10)) = 8

	[Space(2)]
	[Header(Vertical Velocity)]
	_AriseVelocityInit("vertical velocity", Float) = 1
	_AriseVelocityInitEnd(" ", Float) = 1.2
	[HideInInSpector] _AriseVRand(" ", Float) = 0
	_AriseGravity("gravity", Float) = 0.3
	_AriseGravityEnd(" ", Float) = 0.5
	[HideInInSpector] _AriseGRand(" ", Float) = 0

	[Space(2)]
	[Header(Vertical Wave Noise)]
	[HideInInSpector] _AnimateNoiseAmp("vertical wave noise amplitude", Float) = 0.3
	[HideInInSpector] _AnimateNoiseFreq("vertical wave noise freq", Float) = 10

	[Space(2)]
	[Header(Grass Blade Scale)]
	//_InitScale("init grass scale", Range(1,2)) = 1
	_ScaleDamp("scale decrease rate", Range(0,1)) = 0

	[Space(2)]
	[Header(Rotation Velocity)]
	_RotVelocityInit("rotation velocity", Float) = -11
	_RotVelocityInitEnd(" ", Float) = 2
	[HideInInSpector] _RotRand(" ", Float) = 1
	//_RotVelocityFinal("final rotation veloctiy", Float) = 2
	_RotVelocityDamp("rotation damp", Range(0,10)) = 2

	//[Space(2)]
	//[Header(Grass Burn)]
	//[HideInInSpector][HDR]_InitColor1("burn color", Color) = (1, 0, 0, 1)
	//[HideInInSpector][HDR]_MiddleColor1("burn edge color", Color) = (0, 0, 1, 1)
	//[HideInInSpector]_TransitColorTime("color transition time percent", Range(0, 1)) = 0.3
	//[HideInInSpector]_FinalColor1("final color", Color) = (0, 1, 0, 1)

	[Space(2)]
	[Header(Transparent Transition)]
	_TransparentTime("Transparent time percent", Range(0, 1)) = 0.8

	//for satisfy srp shader property requirement
	[HideInInSpector]_DisplacementV2Tex_TexelSize("", Vector) = (0, 0, 0, 0)
	[HideInInSpector]_RegionHeightMap_TexelSize("", Vector) = (0, 0, 0, 0)
	[HideInInSpector]_SkillforGrassDirectionEncodeTex_TexelSize("", Vector) = (0, 0, 0, 0)
	[HideInInSpector]_SkillforGrassTimeEncodeTex_TexelSize("", Vector) = (0, 0, 0, 0)
	//[HideInInSpector]_MainCharPos("", Vector) = (0, 0, 0, 0)
	//[HideInInSpector]_WorldOffset("", Vector) = (0, 0, 0, 0)
	//[HideInInSpector]_TerrainBasePos("", Vector) = (0, 0, 0, 0)
	[HideInInSpector]_SkillDirection("", int) = 0
}

HLSLINCLUDE
#include "/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
#include "FoliageLighting.hlsl"
#include "../../Common/Function/Scene_Common.hlsl"

TEXTURE2D(_MainTex);							SAMPLER(sampler_MainTex);
TEXTURE2D(_DisplacementV2Tex);					SAMPLER(sampler_DisplacementV2Tex);
TEXTURE2D(_RegionHeightMap);					SAMPLER(sampler_RegionHeightMap);
TEXTURE2D(_SkillforGrassDirectionEncodeTex);	SAMPLER(sampler_SkillforGrassDirectionEncodeTex);
TEXTURE2D(_SkillforGrassTimeEncodeTex);			SAMPLER(sampler_SkillforGrassTimeEncodeTex);

CBUFFER_START(UnityPerMaterial)
float4 _DisplacementV2Tex_TexelSize;
float4 _RegionHeightMap_TexelSize;
//float4 _InteractiveTex_TexelSize;
float4 _SkillforGrassDirectionEncodeTex_TexelSize;
float4 _SkillforGrassTimeEncodeTex_TexelSize;
float4 _MainCharPos;
float4 _WorldOffset;

//for grass fly animate direction
float3 _TerrainBasePos;
int _SkillDirection;

//half4 _FireColor;
half4 _TranslucentAttenuation;

half4 _NearColor;
half4 _FarColor;
half4 _LOD0;

half _Width;
half _Height;
half _UpOffset;



half _BendCoef;
half _FarCoef;
half _SpecularPower;
half _SpecGrayScale;
half _ShadowCoef;
half _SelShadowCoef;
float _CurDisplacementFrame;
half _DisplacementScale;

half _TranslucentPower;
half _TranslucentDistortion;
half _TranslucentScale;

half _MaxDistance;






//for grass fly settings
half _WindDirX;
half _WindDirZ;

half _VelocityInit;
half _VelocityInitEnd;
half _VelocityRand;// = _VelocityInitEnd - _VelocityInit;
half _DirRand;
//half _VelocityRandZ;
half _VelocityFinal;
half _VelocityDamp;

half _AnimateNoiseAmp;
half _AnimateNoiseFreq;

half _AnimateTime;
half _AnimateTimeEnd;
half _AnimateTimeRand;// = _AnimateTimeEnd - _AnimateTime;

half _Density;

half _AriseGravity;
half _AriseGravityEnd;
half _AriseGRand;// = _AriseGravityEnd - _AriseGravity;

half _AriseVelocityInit;
half _AriseVelocityInitEnd;
half _AriseVRand;// = _AriseVelocityInitEnd - _AriseVelocityInit;
half _ScaleDamp;
//half _InitScale;

half _RotVelocityInit;
half _RotVelocityInitEnd;
//half _RotVelocityFinal;
half _RotVelocityDamp;
half _RotRand;// = _RotVelocityInitEnd - _RotVelocityInit;

//half4 _InitColor;
//half4 _MiddleColor;
//half _TransitColorTime;
//half4 _FinalColor;

half _TransparentTime;
half _Gloss;

CBUFFER_END

#include "X2mGrassAnimate.hlsl"

ENDHLSL

SubShader{
	Cull Off
	//Tags{ "Queue" = "Transparent" "RenderType" = "Transparent"  "IgnoreProjector" = "True" }
		Tags{ "Queue" = "Geometry" "RenderType" = "Opaque" "IgnoreProjector" = "True" }

	

	Pass
	{
		Cull Off
		//ZWrite Off
		ZWrite On
		//Blend SrcAlpha OneMinusSrcAlpha
		Name "ForwardLit"
		Tags{ "LightMode" = "LightweightForward" }
		//AlphaToMask On
		HLSLPROGRAM


#pragma target 3.0
//#pragma multi_compile_fwdbase
//#pragma multi_compile DIRECTIONAL 
//#pragma multi_compile LIGHTPROBE_SH
#pragma multi_compile_instancing
//#pragma multi_compile INSTANCING_ON

#pragma vertex vert
#pragma fragment frag


		struct v2f
		{
			float4 pos : SV_POSITION;
			half3 norm : NORMAL;
			float2 uv : TEXCOORD0;
				float3 posWorld : TEXCOORD1;
			//X2M_SHADOW_SSM_COORDS(3)
				half3 ambient : TEXCOORD2;
			half3 lambert : TEXCOORD3;
			half3 specular : TEXCOORD4;
			half4 translucency : TEXCOORD5;	// w is farCoef;
			half3 weaponClip : TEXCOORD6;
			//UNITY_SHADOW_COORDS(7)
			UNITY_VERTEX_INPUT_INSTANCE_ID
		};

		v2f vert(vertex_input_compress vCompress)
		{
			v2f o = (v2f)0;
			UNITY_SETUP_INSTANCE_ID(vCompress);
			vertex_input v = DecodeVertexInputCompress(vCompress);
			o.uv = v.texcoord;
			float4 root = 0;
			half dist = 0;
			half scale = 1;
			half randomValue = 0;
			half4 vertexColor = float4(0, 0, 0, 0);
			half maskScale = 1.0;
			CommonVertPosAnimate(v, root, dist, scale, randomValue,  vertexColor, maskScale);

			//decode grass animation texture
			half4 SkillforGrassTimeEncode = GetSkillforGrassTimeEncode(root.xyz);
			half4 SkillforGrassDirectionEncode = GetSkillforGrassDirectionEncode(root.xyz);

			//throw away grass not being cut or has already been burned 
			if (SkillforGrassTimeEncode.x < 0.9 || SkillforGrassTimeEncode.y > SkillforGrassTimeEncode.x)
			{
				o.pos.w = 0;
				return o;
			}

	//#ifdef _SCENE_EDITOR
	//		half2 LODScaleWidth = maskScale;
	//#else
			half2 LODScaleWidth = CalLOD0(dist, scale * maskScale);
	//#endif

			float3 overt;
			CommonVertTransformAnimate(v, root, dist, randomValue, vertexColor,
				LODScaleWidth,
				o.norm, overt);

			o.pos = float4(overt + root.xyz, 1.0);

			////begin grass fly animation
			_AnimateTimeRand = _AnimateTimeEnd - _AnimateTime;
			_VelocityRand = _VelocityInitEnd - _VelocityInit;
			_AriseGRand = _AriseGravityEnd - _AriseGravity;
			_AriseVRand = _AriseVelocityInitEnd - _AriseVelocityInit;
			_RotRand = _RotVelocityInitEnd - _RotVelocityInit;
			_RotVelocityInit = (_RotVelocityInitEnd + _RotVelocityInit)/2;

			//decode time
			half t = (SkillforGrassTimeEncode.x - 1);
			o.weaponClip.x = t;
			o.weaponClip.y = randomValue;

			//translation diretion
			half2 animGrassDir = half2(1,0);
			//half animGrassDirZ = 0;
			half2 skillDir = half2(0, 0);
			//half skillDirZ = 0;
			half2 initDir = half2(0,0);
			//half initDirZ = 0;

			//decode skill direction
			half temp = SkillforGrassDirectionEncode.a / 100;
			half tempx = 100 * frac(temp);
			skillDir.x = (tempx - 10) / 10;
			half tempz = temp - frac(temp);
			skillDir.y = (tempz - 10) / 10;

			//decode character position when cast skill 
			float2 castSkillPos = float2(_TerrainBasePos.x + SkillforGrassTimeEncode.b, _TerrainBasePos.z + SkillforGrassTimeEncode.a);
			half2 centerDir = normalize(root.xz - castSkillPos);

			//half dirSwitch = SkillforGrassDirectionEncode.g;
			//initDir.x = (1 - dirSwitch) * centerDir.x + dirSwitch * skillDir.x;
			//initDir.y = (1 - dirSwitch) * centerDir.y + dirSwitch * skillDir.y;
			initDir.x = (1 - _SkillDirection) * centerDir.x + _SkillDirection * skillDir.x;
			initDir.y = (1 - _SkillDirection) * centerDir.y + _SkillDirection * skillDir.y;
			//if (_SkillDirection == 0)
			//{
			//	initDir = centerDir;
			//}
			//else
			//{
			//	initDir = skillDir;
			//}
			half3 rotAxis = half3(-initDir.y, 0, initDir.x);
			//for direction vary, 
			half r1 = fmod(997.0*(randomValue), 211);
			//使用下面131071，OpenGL无砍草效果??
			//r1 = fmod(131071.0*(r1), 211);
			r1 = r1 / 211 - 0.5;

			half r2 = fmod(524287.0*(randomValue), 127);
			//r2 = fmod(524287.0*(r2), 127);
			r2 = r2 / 127 - 0.5;

			half2 grassDir;
			grassDir.x = initDir.x + _DirRand * r1;
			grassDir.y = initDir.y + _DirRand * r2;
			grassDir = normalize(grassDir);

			animGrassDir.x = grassDir.x + t * _WindDirX;
			animGrassDir.y = grassDir.y + t * _WindDirZ;

			////for height vary, increase height noise
			half hnoise;
			hnoise = fmod(8191.0*(root.x + root.z), 131);
			hnoise = hnoise / 131;

			half hVelocityInitNoise;
			hVelocityInitNoise = fmod(8191.0*(hnoise), 131);
			hVelocityInitNoise = _AriseVRand * hVelocityInitNoise / 131;

			half hGravityNoise;
			hGravityNoise = fmod(8191.0*(hVelocityInitNoise), 131);
			hGravityNoise = _AriseGRand * hGravityNoise / 131;

			half y = (_AriseVelocityInit + hVelocityInitNoise)*t - (_AriseGravity + hGravityNoise)*t*t;

			////for velocity vary
			half animateVelocity = 0;
			half animDeltaDisp = 0;
			animateVelocity = (_VelocityInit + _VelocityRand * randomValue) * (1 - 1 / (_VelocityDamp * t + 1)) / t + _VelocityFinal;
			//animateVelocity = _VelocityInit * (1 - 1 / (_VelocityDamp * t + 1)) / t;
			animDeltaDisp = (animateVelocity ) * t;

			if (t >= _AnimateTime + _AnimateTimeRand * randomValue)
			{
				o.pos.w = 0;
				return o;
			}


			if (SkillforGrassTimeEncode.x > 0)
			{
				//reduce grass density 
				if (ReduceDensity(_Density, randomValue) == true)
				{
					o.pos.w = 0;
					return o;
				}

				//scale
				//half scale = (-_ScaleDamp*t + _InitScale);
				half scale = saturate(1 - _ScaleDamp*t);
				//scale = clamp(scale, 0, 1);
				overt *= scale;

				//rotate
				half r0 = fmod(131071.0*(randomValue), 127);
				r0 = r0 / 127 - 0.5;

				half rotRad = (_RotVelocityInit + r0 * _RotRand) * (1 / (_RotVelocityDamp * t + 1));
				//overt = RotateZ(rotRad * t, overt);
				overt = RotateAboutAxis(rotRad * t, rotAxis, overt);
				o.pos.xyz = overt + root.xyz;

				//translate
				//X;
				o.pos.x += animDeltaDisp * animGrassDir.x +0.3*sin(7 * t*r1);
				//Z
				o.pos.z += animDeltaDisp * animGrassDir.y +0.2*sin(5 * t*r2 - 1.57);
				//Y
				half r3 = fmod(524287.0*(r2), 127);
				r3 = r3 / 127;
				o.pos.y += y + (_AnimateNoiseAmp * r3)*sin(_AnimateNoiseFreq*t*randomValue);// +animateNoiseAmp*sin(2 * animateNoiseFreq*o.pos.x*randomValue);
				
			}

			//// end grass fly animation
			//cmj: 
			o.posWorld = o.pos.xyz;
			o.pos.w = unity_ObjectToWorld[3][3];
			o.pos = mul(UNITY_MATRIX_VP, o.pos);

			// begin lighting
			half3 lightDir = normalize(_MainLightPosition.xyz);
			half3 viewDir = normalize(UnityWorldSpaceViewDir(o.posWorld));
			_SelShadowCoef = clamp(lightDir.y, 0, 0.5);// dot(vUP, lightDir)
			half nl = max(_SelShadowCoef, abs(dot(lightDir, o.norm)));
			//half spec = (0.6 + dot(_CameraForward, lightDir)) * _Gloss;
			//spec = clamp(spec, 0.0, 0.1);
			half3 vPseudoNormal = normalize(lerp(half3(0, 1, 0), o.norm, sqrt(dist / 32.0)));
			o.specular = _MainLightColor.rgb * PhongSpec(lightDir, viewDir, vPseudoNormal).rgb;
			o.lambert = _MainLightColor.rgb * nl;
			o.ambient = max(half3(0.0, 0.0, 0.0), SampleSH(o.norm));
			o.translucency.rgb = Translucency(lightDir, viewDir, vPseudoNormal);
			//o.translucency = TranslucencyLeaf(lightDir, viewDir, vPseudoNormal, randomValue);
			//o.farCoef = exp(-dist / _FarCoef);
			o.translucency.w = exp(-dist / _FarCoef);
			//o.regionBaseColor = GetRegionBaseColor(root.xyz + _WorldOffset.xyz);
			//o.regionBaseColor.a = clamp(0.5 - v.vertex.y, 0.0, 0.5) * 2.0 * _GroundBlendCoef;
			// end lighting

			return o;
		}

		half4 frag(v2f IN) : COLOR
		{

			half4 texColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv);
			half3 color = texColor.rgb;//texColor.r * _Color.rgb * _Color.a * 2;

			half t = IN.weaponClip.x;
			half alpha = 1;

			_AnimateTimeRand = _AnimateTimeEnd - _AnimateTime;
			half termiTime = _AnimateTime + _AnimateTimeRand * IN.weaponClip.y;
			half transitTransparentTime = _TransparentTime * termiTime;
			
			half tp = (t - transitTransparentTime) / (termiTime - transitTransparentTime);
			if (t > transitTransparentTime) {
				alpha = lerp(1, 0, tp);
			}
			
			half3 specularColor = IN.specular * max(0, (max(0, (texColor.a - _SpecGrayScale)) / (1.0 - _SpecGrayScale)));
			half3 translucencyColor = IN.translucency.rgb * (texColor.a/* * _TransluceGrayScale*/);

			//UNITY_LIGHT_ATTENUATION(atten, IN, IN.posWorld);
			//atten = saturate(atten + _ShadowCoef);
			half atten = 1.1;

			//color.rgb = IN.regionBaseColor.a * IN.regionBaseColor.rgb + (1.0 - IN.regionBaseColor.a) * color.rgb;
			color.rgb = IN.translucency.w * color.rgb + (1.0 - IN.translucency.w) * _FarColor.rgb;
			color.rgb = color.rgb * ((IN.lambert.rgb + translucencyColor.rgb) * atten + IN.ambient.rgb);
			color.rgb += (specularColor * atten);

			return half4(color.rgb, alpha);
		}
		ENDHLSL
	}


	/////////////////////////////////////////////////////////////////////////////////////
//	Pass{
//		Name "Caster"
//
//		Tags{ "LightMode" = "ShadowCaster" }
//
//		Cull Off
//		//AlphaToMask On
//		CGPROGRAM
//
//#pragma target 3.0
//#pragma multi_compile_fwdbase
//#pragma multi_compile_instancing
//#pragma multi_compile  __ _SCENE_EDITOR
//#pragma vertex vert
//#pragma fragment frag
//
//#include "../X2mIncludes/X2mForwardStrip.cginc"
//
//		struct v2f
//		{
//			V2F_SHADOW_CASTER;
//			//float4 pos : SV_POSITION;
//			half3 norm : NORMAL;
//			float3 posWorld : TEXCOORD1;
//			float2 uv : TEXCOORD2;
//
//			//half2 weaponClip : TEXCOORD3;
//			//float4 uvDisplacement : TEXCOORD5;	// debug only
//		};
//
//		v2f vert(vertex_input_compress vCompress)
//		{
//			v2f o = (v2f)0;
//			UNITY_SETUP_INSTANCE_ID(vCompress);
//			UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
//			vertex_input v = DecodeVertexInputCompress(vCompress);
//
//			o.uv = v.texcoord;
//
//			float4 root = 0;
//			float dist = 0;
//			half scale = 1;
//			float randomValue = 0;
//			float4 vertexColor = float4(0, 0, 0, 0);
//			half maskScale = 1.0;
//			CommonVertPosAnimate(v, root, dist, scale, randomValue, vertexColor, maskScale);
//
//
//			//decode grass animation texture
//			half4 SkillforGrassTimeEncode = GetSkillforGrassTimeEncode(root.xyz);
//			half4 SkillforGrassDirectionEncode = GetSkillforGrassDirectionEncode(root.xyz);
//
//			//throw away grass not being cut or has already been burned 
//			if (SkillforGrassDirectionEncode.x < 0.9 || SkillforGrassTimeEncode.x > 0.9)
//			{
//				o.pos.w = 0;
//				return o;
//			}
//
//#ifdef _SCENE_EDITOR
//			half2 LODScaleWidth = maskScale;
//#else
//			half2 LODScaleWidth = CalLOD0(dist, scale * maskScale);
//#endif
//
//			float3 overt;
//			CommonVertTransformAnimate(v, root, dist, randomValue, vertexColor,
//				LODScaleWidth,
//				o.norm, overt);
//
//			o.pos = float4(overt + root.xyz, 1.0);
//			;
//			////begin grass fly animation
//			_AnimateTimeRand = _AnimateTimeEnd - _AnimateTime;
//			_VelocityRand = _VelocityInitEnd - _VelocityInit;
//			_AriseGRand = _AriseGravityEnd - _AriseGravity;
//			_AriseVRand = _AriseVelocityInitEnd - _AriseVelocityInit;
//			_RotRand = _RotVelocityInitEnd - _RotVelocityInit;
//			_RotVelocityInit = (_RotVelocityInitEnd + _RotVelocityInit) / 2;
//
//			//decode time
//			half t = (SkillforGrassDirectionEncode.x - 1);
//
//			//translation diretion
//			half2 animGrassDir = half2(1, 0);
//			half2 skillDir = half2(0, 0);
//			half2 initDir = half2(0, 0);
//
//			//decode skill direction
//			half temp = SkillforGrassDirectionEncode.a / 100;
//			half tempx = 100 * frac(temp);
//			skillDir.x = (tempx - 10) / 10;
//			half tempz = temp - frac(temp);
//			skillDir.y = (tempz - 10) / 10;
//
//			//decode character position when cast skill 
//			float2 castSkillPos = float2(_TerrainBasePos.x + SkillforGrassDirectionEncode.g, _TerrainBasePos.z + SkillforGrassDirectionEncode.b);
//			half2 centerDir = normalize(root.xz - castSkillPos);
//
//			if (_SkillDirection == 0)
//			{
//				initDir = centerDir;
//			}
//			else
//			{
//				initDir = skillDir;
//			}
//			//for direction vary, 
//			half r1 = fmod(997.0*(randomValue), 211);
//			r1 = r1 / 211 - 0.5;
//
//			half r2 = fmod(524287.0*(randomValue), 127);
//			r2 = r2 / 127 - 0.5;
//
//			half2 grassDir;
//			grassDir.x = initDir.x + _DirRand * r1;
//			grassDir.y = initDir.y + _DirRand * r2;
//			grassDir = normalize(grassDir);
//
//			animGrassDir.x = grassDir.x + t * _WindDirX;
//			animGrassDir.y = grassDir.y + t * _WindDirZ;
//
//			////for height vary, increase height noise
//			half hnoise;
//			hnoise = fmod(8191.0*(root.x + root.z), 131);
//			hnoise = hnoise / 131;
//
//			half hVelocityInitNoise;
//			hVelocityInitNoise = fmod(8191.0*(hnoise), 131);
//			hVelocityInitNoise = _AriseVRand * hVelocityInitNoise / 131;
//
//			half hGravityNoise;
//			hGravityNoise = fmod(8191.0*(hVelocityInitNoise), 131);
//			hGravityNoise = _AriseGRand * hGravityNoise / 131;
//
//			half y = (_AriseVelocityInit + hVelocityInitNoise)*t - (_AriseGravity + hGravityNoise)*t*t;
//
//			////for velocity vary
//			half animateVelocity = 0;
//			half animDeltaDisp = 0;
//			animateVelocity = (_VelocityInit + _VelocityRand * randomValue) * (1 - 1 / (_VelocityDamp * t + 1)) / t + _VelocityFinal;
//			//animateVelocity = _VelocityInit * (1 - 1 / (_VelocityDamp * t + 1)) / t;
//			animDeltaDisp = (animateVelocity)* t;
//
//			if (t >= _AnimateTime + _AnimateTimeRand * randomValue)
//			{
//				o.pos.w = 0;
//				return o;
//			}
//
//
//			if (SkillforGrassDirectionEncode.x > 0)
//			{
//				//reduce grass density 
//				if (ReduceDensity(_Density, randomValue) == true)
//				{
//					o.pos.w = 0;
//					return o;
//				}
//
//				//scale
//				//half scale = (-_ScaleDamp*t + _InitScale);
//				half scale = saturate(1 - _ScaleDamp*t);
//				//scale = clamp(scale, 0, 1);
//				overt *= scale;
//
//				//rotate
//				half r0 = fmod(131071.0*(randomValue), 127);
//				r0 = r0 / 127 - 0.5;
//
//				half rotRad = (_RotVelocityInit + r0 * _RotRand) * (1 / (_RotVelocityDamp * t + 1));
//				overt = RotateZ(rotRad * t, overt);
//				o.pos.xyz = overt + root.xyz;
//
//				//translate
//				//X;
//				o.pos.x += animDeltaDisp * animGrassDir.x + 0.3*sin(7 * t*r1);
//				//Z
//				o.pos.z += animDeltaDisp * animGrassDir.y + 0.2*sin(5 * t*r2 - 1.57);
//				//Y
//				half r3 = fmod(524287.0*(r2), 127);
//				r3 = r3 / 127;
//				o.pos.y += y + (_AnimateNoiseAmp * r3)*sin(_AnimateNoiseFreq*t*randomValue);// +animateNoiseAmp*sin(2 * animateNoiseFreq*o.pos.x*randomValue);
//			}
//			//// end grass fly animation
//			o.posWorld = o.pos.xyz;
//			// TODO : local vertex???
//			v.vertex = mul(unity_WorldToObject, float4(o.pos.xyz, 1.0));
//			TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
//
//			return o;
//		}
//
//		half4 frag(v2f IN) : COLOR
//		{
//		//half4 color = tex2D(_MainTex, IN.uv);
//			SHADOW_CASTER_FRAGMENT(IN)
//		}
//		ENDCG
//
//	}

	}
}

