Shader "HiddenURP/Environment/Grass/Mobile-Grass-Func"
{
		SubShader{
    		HLSLINCLUDE	 
			//#define LIGHTMAP_ON 1   
			#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" 
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl"
			TEXTURE2D(_LightMap);SAMPLER(sampler_LightMap);half4 _LightMap_ST;
			#define unity_Lightmap _LightMap     
			#define samplerunity_Lightmap sampler_LightMap    
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
			#include "../../Common/Template Shader/Transforms.hlsl"
			#include "../../Common/Template Shader/Define.hlsl"
			#include "../../Common/Function/Scene_Common.hlsl"
			#include "../../Common/Function/BlackHole.hlsl"
			#include "../../Environment/Sky&Fog/VolumetricFogForObject.hlsl"

			TEXTURE2D(_MainTex);		SAMPLER(sampler_MainTex);
            TEXTURE2D(_RegionHeightMap);	SAMPLER(sampler_RegionHeightMap);
			TEXTURE2D(_CollisionTex);	SAMPLER(sampler_CollisionTex);
			TEXTURE2D(_InteractiveTex);	SAMPLER(sampler_InteractiveTex);
			TEXTURE2D(_SkillforGrassTimeEncodeTex);			SAMPLER(sampler_SkillforGrassTimeEncodeTex);

			sampler2D _Wind;
			sampler2D _ColorM;
			float4 _ColorM_ST;
			float4 _Wind_ST;
			float4 _MainTex_ST;
			half4 _RegionHeightMap_ST;

			half4 _CollisionTex_TexelSize;
            half4 _RegionHeightMap_TexelSize;
			half4 _InteractiveTex_TexelSize;
			half4 _SkillforGrassTimeEncodeTex_TexelSize;
			half4 _PlayerPos;

			//half4 _TerrainSize;
			half4 _Spec_Speed_Blade;
			//CBUFFER_START(UnityPerMaterial)

			 //half _Radius;
			 //half _RadiusStrength;

			half3 _ColorTop,_CMaskTop,_CMaskTopG,_ColorHL;
			half3 _ColorBottom,_CMaskBottom,_CMaskBottomG;
			half3 _ColorFar,_CMaskFar,_CMaskGFar;
			half4 _EnvShadow;
			half4 _BladeHeight;
			//half _SceneBloomFactor;
			//CBUFFER_END

			TEXTURE2D(_WindRT); SAMPLER(sampler_WindRT);
			half4 _WindDir;
            #include "X2mGrass.hlsl"

            struct appdata
            {
                half4 vertex : POSITION;
				half4 texcoord : TEXCOORD0;
				half3 normal :NORMAL;
				UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            struct v2f
            {
                half4 pos : SV_POSITION;
				half2 uv : TEXCOORD0;
				float3 worldpos : TEXCOORD1;
				float4 fogCoord : TEXCOORD2;
				half3 weaponClip : TEXCOORD3;
				half WaveMask : TEXCOORD7;
				half wavemutation : TEXCOORD9;
				float lineDistance : TEXCOORD4;
				float4 posW:TEXCOORD5;
				half3 worldNormal : TEXCOORD6;
				DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 8);
				half burnTime : TEXCOORD10;
                UNITY_VERTEX_INPUT_INSTANCE_ID 
            };
			#include "../../Common/Function/Lightmap_Output.hlsl"
            UNITY_INSTANCING_BUFFER_START(Props)
                //UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
				//UNITY_DEFINE_INSTANCED_PROP(float4,_Stepon)
				//UNITY_DEFINE_INSTANCED_PROP(float4, _Colorone)
				UNITY_DEFINE_INSTANCED_PROP(half4, _lightmapUV)

				UNITY_DEFINE_INSTANCED_PROP(half4, _ColorMask)
				UNITY_DEFINE_INSTANCED_PROP(half4, _windParam)

            UNITY_INSTANCING_BUFFER_END(Props)
			
			half4 GetSkillforGrassTimeEncode(float3 worldPos)
			{
				half4 ret = half4(0, 0, 0, 0);
				float2 uv = floor(worldPos.xz * 5) - floor(_PlayerPos.xz * 5);
				uv *= _SkillforGrassTimeEncodeTex_TexelSize.xy;
				uv += float2(0.5, 0.5);

#if UNITY_UV_STARTS_AT_TOP
				// DX
				uv.y = 1.0 - uv.y;
				// OpenGL, don't need 1.0 - y
#endif
				if (uv.x >= 0 && uv.x <= 1 && uv.y >= 0 && uv.y <= 1)
				{
					ret = SAMPLE_TEXTURE2D_LOD(_SkillforGrassTimeEncodeTex, sampler_SkillforGrassTimeEncodeTex, uv, 0);
				}

				return ret;
			}

			half3 GetWeaponClip(float3 worldPos, float height)
			{
				half3 ret = 0;
				// begin weapon fire interactive
				half4 vInteractive = GetInteractive(float3(worldPos.x, unity_ObjectToWorld[1][3], worldPos.z));

				//ret.xy = half2(vInteractive.r + vInteractive.g, height);
				//ret.z = vInteractive.g;
				ret.xy = vInteractive.rg;
				ret.z = half2(vInteractive.r + vInteractive.g, height);
				//// end weapon fire interactive
				return ret; 
				
			}

            v2f vert(appdata v)
            {
				v2f o;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_TRANSFER_INSTANCE_ID(v, o);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				o.uv=v.texcoord.xy;
				half3 center = half3(0, 0, 0);
				float4 worldpos=mul(UNITY_MATRIX_M,half4(center,1));
				half4 SkillforGrassTimeEncode = GetSkillforGrassTimeEncode(worldpos);
				o.weaponClip = GetWeaponClip(worldpos.xyz, v.vertex.y);
				o.burnTime = SkillforGrassTimeEncode.y - 1;
				//half windmutation =1-tex2Dlod(_Wind,float4(worldpos.x/10,worldpos.z/10,0,0)).b;
				o.wavemutation =1-tex2Dlod(_Wind,half4(worldpos.x/_Wind_ST.x+_Time.y*_Spec_Speed_Blade.z,worldpos.z/_Wind_ST.x+_Time.y*_Spec_Speed_Blade.z,0,0)).r;
				o.WaveMask = tex2Dlod(_Wind, half4(worldpos.x/200-_Time.x,worldpos.z/200-_Time.x,0,0)).g;
				half2 VertexScale =UNITY_ACCESS_INSTANCED_PROP(Props, _windParam).xy;
				v.vertex.xyz +=v.vertex.xyz*_BladeHeight.zwz;
				v.vertex.xy +=v.vertex.xy*VertexScale.y*_BladeHeight.xy;
				//half4 offset = half4(0,0,0,0);
				//offset.xz = sin(3.1416 * _Time.y * v.texcoord.y) * _Wind_ST.z*0.2;
				//v.vertex.xz += offset;

				float3 localPos = v.vertex.xyz;
    float g = GetMaskInBlade(worldpos.xyz);
    //o.weaponClip = half3(0, g, 0);
    //TODO：暂时屏蔽高度图
    //localPos *= g;
				[BRANCH]
				if (o.weaponClip.x > 0 )
				{
					//grass has been cutted
					localPos.y *= 0.5f;
				}
				else{
					//草地交互的计算
					half dis = distance(_PlayerPos.xyz, worldpos.xyz);
					half _Radius= 0.4;
					half _RadiusStrength= 0.8;
					float pushDown = saturate((1 - dis + _Radius)) * o.uv.y * _RadiusStrength;
					float3 playerPosLocal = mul(UNITY_MATRIX_I_M, float4(_PlayerPos.xyz, 1));
					float3 normalDir = playerPosLocal - center; 
					normalDir = normalize(normalDir);
					normalDir.y *= 0.5f;
					//v.vertex.xz += pushDown * normalDir;// ret.x*0.01f; o.uv.y
					float3 upDir = float3(0, 1, 0);
					float3 rightDir = normalize(cross(upDir, normalDir));
					float3 centerOffs = v.vertex.xyz - center;
					float3 rotate = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;//根据顶点相对锚点的偏移与正交基矢量相乘得到新定点位置
					rotate = rotate - pushDown * normalDir;
					rotate.y += 0.1f;
					localPos = lerp(localPos, rotate, saturate(1 - dis + _Radius));
					////拖尾
					//half4 ret = GetCollision(worldpos.xyz);
					//if (saturate(1 - dis +_Radius) == 0)
					//{
					//	localPos.y -= o.uv.y * ret.x ;
					//}
					//---风
					//half4 localwindvector = normalize(mul(UNITY_MATRIX_I_M, _Windvector.xyz));
					//half time=(_Time.y)*(_TimeScale);
					//localPos.xz += sin(_Time.y+windmutation*_Wind_ST.z)*cos(_Time.y*2/3+windmutation*_Wind_ST.z)*v.texcoord.y;
					localPos += VertexScale.x*_Spec_Speed_Blade.w * (v.texcoord.y - 0.2);
					localPos += sin(o.wavemutation*o.WaveMask*_Wind_ST.y)*cos(o.wavemutation*o.WaveMask*_Wind_ST.y)*v.texcoord.y;
				}
				
				VertexPositionInputs vertexInput = GetVertexPositionInputs(localPos);
				//o.pos = vertexInput.positionCS;
				o.worldpos = vertexInput.positionWS;
				half2 wind = SAMPLE_TEXTURE2D_LOD(_WindRT, sampler_WindRT, o.worldpos.xz * _WindDir.w, 0).xy;
				half windStrength = _WindDir.y;
                windStrength *= wind.r * (wind.g * 2.0h - 0.243h );
                o.worldpos.xz += _WindDir.xz * windStrength*v.texcoord.y;
				o.pos = TransformWorldToHClip(o.worldpos);

				o.worldNormal = TransformObjectToWorldNormal(v.normal);
				o.posW = VertCalaShadow(float4(o.worldpos,0), _DirX, _DirY);
				o.lineDistance = distance(o.worldpos.xyz, _WorldSpaceCameraPos.xyz);
				//o.fogCoord = vertexInput.positionCS.z;
				o.fogCoord = VolumetricFog_GetFogCoord(vertexInput.positionNDC, vertexInput.positionVS.z);
	
#ifdef LIGHTMAP_ON
				half4 lightmapUV = UNITY_ACCESS_INSTANCED_PROP(Props, _lightmapUV);
				OUTPUT_LIGHTMAP_UV(lightmapUV.xy, _LightMap_ST, o.lightmapUV);
				OUTPUT_SH(o.worldNormal.xyz, o.vertexSH);
#endif

				return o;
            }  
			void ColorLerp(half3 Color,half3 CMask,half3 CMaskG,float4 VColorMask,out half3 col)
			{
				half3 ColorTop = lerp(Color,CMaskG,VColorMask.y);
				ColorTop = lerp(ColorTop, CMask,VColorMask.x);
			 	col = ColorTop;
			}
			half4 frag_ramp(v2f i) : SV_Target
            {
    UNITY_SETUP_INSTANCE_ID(i);
    //return half4(i.weaponClip, 1);
				Light light = MainLight(i.worldpos);
				half3 bakedGI;i.worldNormal = half3(0,1,0);
				LightmapResult(light,i,bakedGI,i.worldNormal,i.worldpos);
				half4 c = SampleAlbedoAlpha(i.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
				clip(c.a - _Cutoff);
				half4 VColorMask = UNITY_ACCESS_INSTANCED_PROP(Props, _ColorMask);
				// VColorMask.x =tex2Dlod(_ColorM,float4(i.worldpos.xz/_ColorM_ST.x,0,0)).r;
				// VColorMask.y =tex2Dlod(_ColorM,float4(i.worldpos.xz/_ColorM_ST.y,0,0)).g;
				float ColorDis = saturate((i.lineDistance-_MainTex_ST.z) / (_MainTex_ST.w-_MainTex_ST.z));
				half3 ColorTop, ColorBottom, ColorFar;
				//half3 _Flip_CMaskTopG = _CMaskTop;half3 _Flip_CMaskBottomG = _CMaskBottom;
                ColorLerp(_ColorTop, _CMaskTop, _CMaskTopG, VColorMask, ColorTop);
                ColorLerp(_ColorBottom, _CMaskBottom, _CMaskBottomG, VColorMask, ColorBottom);
                ColorLerp(_ColorFar, _CMaskFar, _CMaskGFar, VColorMask, ColorFar);
				half GradientUv = pow(1 - i.uv.y, _MainTex_ST.y);
				#ifdef _UseR
				GradientUv = 1 - c.r * _MainTex_ST.y;
				#endif
                ColorTop = lerp(ColorTop, ColorBottom, GradientUv);
                ColorTop += _ColorHL * (1 - c.g) * VColorMask.a;
				//return half4(i.weaponClip,1);
				//return _burnTime - 4;
                c.rgb = lerp(ColorTop, ColorFar, ColorDis);
				if ( i.weaponClip.y > 0 && i.weaponClip.z >= (0.6f - i.weaponClip.z))
				{	//grass has been burned and not contain edge
					//discard; 
					{
						half3 luminance = saturate(saturate(1-i.burnTime) + 0.3f)* c.rgb; 
						return half4(luminance,1);
					}
				}
				half wValue = 1-saturate(i.lineDistance / _Spec_Speed_Blade.y);
            
				light.shadowAttenuation =FragCalaShadowAtten(light.shadowAttenuation, i.posW, _Time.x, _Speed, _ShadowAlphaRatio, _ShadowTex);
				half NdotL = saturate(dot(i.worldNormal, light.direction));
				half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation) * NdotL;
    			half3 diffuseColor = bakedGI + attenuatedLightColor;
                c.rgb += c.rgb*i.wavemutation * i.WaveMask * _Spec_Speed_Blade.x * wValue * i.uv.y;
                c.rgb *= diffuseColor;
			#ifdef _ADDITIONAL_LIGHTS
				uint pixelLightCount = GetAdditionalLightsCount();
				for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
				{
					Light additional_light = GetAdditionalLight(lightIndex, i.positionWS);
					half3 attenuatedLightColor = additional_light.color * (additional_light.distanceAttenuation * additional_light.shadowAttenuation);
					c.rgb += LightingLambert(attenuatedLightColor, additional_light.direction, i.worldNormal);
				}
			#endif
				//c.rgb *= _MainLightColor.w;
				c.rgb *= BalckHole_GetLightIntensity(i.worldpos);
				if (i.weaponClip.y > 0)
				{
					//float luminance = dot(float3(0.2126, 0.7152, 0.0722), color.rgb);
					half luminance = dot(half3(0.299, 0.687, 0.114), c.rgb);
					c.rgb = luminance;
				}
				//half density = ComputeFogFactor(i.fogCoord);
				//c.rgb = MixFog( c.rgb ,density);
				//c.rgb = VolumetricFog_GetFog(c.rgb, i.fogCoord);
				//c.rgb = 0.1*attenuatedLightColor*_MainTex_ST.x;
				//c.rgb = bakedGI;
				// #if defined(LIGHTMAP_ON) && defined(SHADOWS_SHADOWMASK)
				// c.rgb = SampleShadowMask(i.lightmapUV).rgb;
				// #endif
				c.a = 1;
	
				return c;
			}
            ENDHLSL
		Pass
        {
			Name "Grass-Ramp-Alpha"
			Tags{ "LightMode" = "UniversalForward" }
			Cull Off
			ColorMask RGBA
			ZWrite On
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag_ramp
            #pragma shader_feature _UseR
            #pragma multi_compile_instancing
			//#pragma multi_compile_fog
			#pragma multi_compile _ LIGHTMAP_ON
			#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
			#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
			#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
			#pragma shader_feature _RECEIVE_SHADOWS_OFF
			#pragma multi_compile _ SHADOWS_SHADOWMASK
			ENDHLSL
		}
		Pass
		{
			Name "DepthOnly"
			Tags
			{
				"LightMode" = "DepthOnly"
			}

			Cull Off
			ColorMask RGBA
			ZWrite On
			HLSLPROGRAM

			#pragma multi_compile_instancing
			#pragma multi_compile_shadowcaster

			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"

			#pragma vertex vert
			#pragma fragment frag

			half4 frag(v2f i) : SV_TARGET
			{
				clip(SampleAlbedoAlpha(i.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a - _Cutoff);
				return 0;
			}

			ENDHLSL
		}
		
    }
}