Shader "URP/Environment/Grass/GrassCutoffEncode"
{
    Properties
    {
		//for satisfy srp shader property requirement
		[HideInInSpector]_SkillforGrassDirectionEncodeTex_TexelSize("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_SkillforGrassTimeEncodeTex_TexelSize("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_InteractiveTex_TexelSize("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_MaskTex_TexelSize("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_CenterPos("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_Dif("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_SkillDir("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_CastSkillCharPos("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_SampleChannel("", int) = 0
    }

	HLSLINCLUDE
		#include "/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		#include "/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
		#include "/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" 		

		#include "FoliageLighting.hlsl"
		#include "../../Common/Function/Scene_Common.hlsl"

	TEXTURE2D(_SkillforGrassDirectionEncodeTex);	SAMPLER(sampler_SkillforGrassDirectionEncodeTex);
	TEXTURE2D(_InteractiveTex);	SAMPLER(sampler_InteractiveTex);
	TEXTURE2D(_SkillforGrassTimeEncodeTex);	SAMPLER(sampler_SkillforGrassTimeEncodeTex);
	TEXTURE2D(_MaskTex);	SAMPLER(sampler_MaskTex);

	CBUFFER_START(UnityPerMaterial)
		half4 _SkillforGrassDirectionEncodeTex_TexelSize;
	half4 _InteractiveTex_TexelSize;
	half4 _SkillforGrassTimeEncodeTex_TexelSize;
	half4 _MaskTex_TexelSize;
	half4 _CenterPos;
	half4 _Dif;
	half3 _SkillDir;
	half3 _CastSkillCharPos;
	int _SampleChannel;
	CBUFFER_END
		ENDHLSL


    SubShader
    {	
		Cull Off
		Tags{ "Queue" = "Geometry" "IgnoreProjector" = "True" "RenderType" = "Opaque" }
        LOD 100

		
        Pass
        {
			Tags{ "LightMode" = "LightweightForward" }
			Name "GrassDirectionEncodeandMove"
			ZWrite Off
			Cull off
			Lighting Off
			ZTest Always

			HLSLPROGRAM

            #pragma vertex vert
            #pragma fragment frag
			#pragma multi_compile INSTANCING_ON
			#pragma target 3.0

            struct appdata
            {
                half4 vertex : POSITION;
                half2 uv : TEXCOORD0;
            };

            struct v2f
            {
                half2 uv : TEXCOORD0;
				half2 uv1 : TEXCOORD1;
                half4 pos : SV_POSITION; 
				UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            v2f vert (appdata v)
            {
				v2f o;
				o.pos = half4(v.vertex.xyz, 1.0);

				half2 uv = v.uv;
				o.uv1 = v.uv;
#if UNITY_UV_STARTS_AT_TOP
				// DX 
				uv.y = 1.0 - uv.y;
				o.uv1.y = 1 - o.uv1.y;
				_Dif.z *= -1;
				// OpenGL, don't need 1.0 - y
#endif
				o.uv = uv + _Dif.xz * _SkillforGrassDirectionEncodeTex_TexelSize.xy;
				return o;
            }

            half4 frag (v2f i) : SV_Target
            {
				//return tex2D(_MaskTex, i.uv);
				UNITY_SETUP_INSTANCE_ID(i);
				half4 moved = half4(0, 0, 0, 0);
				half4 interactiveTex = SAMPLE_TEXTURE2D(_InteractiveTex, sampler_InteractiveTex, i.uv1);

				half4 tex = SAMPLE_TEXTURE2D(_SkillforGrassDirectionEncodeTex, sampler_SkillforGrassDirectionEncodeTex, i.uv);
				half4 timeEncode = SAMPLE_TEXTURE2D(_SkillforGrassTimeEncodeTex, sampler_SkillforGrassTimeEncodeTex, i.uv);
				if (i.uv.x >= 0 && i.uv.x < 1 && i.uv.y >= 0 && i.uv.y < 1)
				{
					moved = tex;
				}

				////采样_InteractiveTex贴图，由于该贴图在释放技能后每帧都随人物移动；而_SkillforGrassDirectionEncodeTex只在释放技能后的动画期间移动；
				////因此加如下判断：如果该像素点<0.001说明标记已经被清除；此时也应该将_SkillforGrassDirectionEncodeTex上的编码信息清除。
				//if (interactiveTex.r < 0.001) {
				//	moved = half4(0, 0, 0, 0);
				//}

				if ((timeEncode.r > 0.9 && timeEncode.r < 1.2) || (timeEncode.g > 0.9 && timeEncode.g < 1.2))
				{

					//encode skill direction in A channel
					moved.a = round(10 * _SkillDir.x + 10) + 100 * round(10 * _SkillDir.z + 10);
				}

				////encode time, note moved.r == 1 means a skill in this range is triggered
				//if (moved.r > 0.99 ) {
				//	moved.r += unity_DeltaTime.x;
				//	//moved.r += 1;
				//}
				return moved;

            }
			ENDHLSL
        }

		Pass
		{	Tags{ "LightMode" = "LightweightForward" }
			Name "MarkSkillDirection"

			ZWrite Off
			Cull off
			Lighting Off
			ZTest Always
			BlendOp MAX

			HLSLPROGRAM

			#pragma vertex vert
			#pragma fragment frag
			//#pragma multi_compile_instancing
			#pragma multi_compile INSTANCING_ON
			#pragma target 3.0

			struct v2f
			{
				half4 pos : SV_POSITION;
				half2 uv : TEXCOORD0;//sample skill mask
				half2 uv2 : TEXCOORD2;//store burnColorIndex
				//half2 uv3 :TEXCOORD2;//transfer from NDC to texture coords to sample _SkillforGrassTimeEncodeTex; 
			};

			UNITY_INSTANCING_BUFFER_START(Props)
			UNITY_DEFINE_INSTANCED_PROP(half4, _maskStartUVSize)
			UNITY_DEFINE_INSTANCED_PROP(half4, _interactiveCastSkillPos)
			UNITY_DEFINE_INSTANCED_PROP(half, _burnColorIndex)
			//UNITY_DEFINE_INSTANCED_PROP(half, _directionIndex)
			UNITY_INSTANCING_BUFFER_END(Props)

			struct appdata_full {
				float4 vertex : POSITION;
				float4 tangent : TANGENT;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
				float4 texcoord1 : TEXCOORD1;
				float4 texcoord2 : TEXCOORD2;
				float4 texcoord3 : TEXCOORD3;
				half4 color : COLOR;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			v2f vert(appdata_full v)
			{
				v2f o = (v2f)0;
				UNITY_SETUP_INSTANCE_ID(v);
				half4 interactivePos = UNITY_ACCESS_INSTANCED_PROP(Props, _interactiveCastSkillPos);
				half4 maskStartUVSize = UNITY_ACCESS_INSTANCED_PROP(Props, _maskStartUVSize);
				half burnColorIndex = UNITY_ACCESS_INSTANCED_PROP(Props, _burnColorIndex);
				o.uv2.x = burnColorIndex;
				//half dirIndex = UNITY_ACCESS_INSTANCED_PROP(Props, _directionIndex);
				//o.uv2.y = dirIndex;
				o.pos = mul(UNITY_MATRIX_M, half4(v.vertex.xyz, 1.0));
				////keep skill range stay in place that being cast
				////_interactivePos is On_Weapon params character's worldpos when cast skill, _CenterPos.xz is character's current worldpos;
				
				//如果256*256的RT范围设置为51.2m*51.2m  <--> 2*2 in NDC，那么1m <--> 5pixel <--> 1/25.6 in NDC;
				//如果512*512的RT范围设置为51.2m*51.2m  <--> 2*2 in NDC，那么1m <--> 10pixel <--> 1/25.6 in NDC;所以从世界坐标单位m到NDC转换要除以25.6；
				half posOffsetX = (interactivePos.x - _CenterPos.x) / 25.6;
				half posOffsetZ = (interactivePos.z - _CenterPos.z) / 25.6;
				o.pos.x += posOffsetX;
				o.pos.y += posOffsetZ;
				
				//o.uv3 = o.pos * 0.5 + half2(0.5, 0.5);

				o.uv = v.texcoord.xy;	// now the (0, 0) is left top
				
				o.uv *= maskStartUVSize.zw;
				o.uv += maskStartUVSize.xy;
				o.uv *= _MaskTex_TexelSize.xy;


//Untiy采样普通纹理时统一（0，0）在左下角，采样RT时需要变换y轴；以下旧代码有误因此注释掉
//#if UNITY_UV_STARTS_AT_TOP
//				// DX 
//				o.uv.y = 1.0 - o.uv.y;	// after this, the (0, 0) is left bottom
//
//#else
//				// OpenGL, don't need 1.0 - y						
//
//#endif
				return o;
			}

			half4 frag(v2f IN): SV_Target
			{
				//half4 timeEncode = tex2D(_SkillforGrassTimeEncodeTex, IN.uv3);
				half4 maskValue = half4(0, 0, 0, 0);
				//half4 sampTex = half4(0, 0, 0, 0);
				//mask the skill range and encode intial time
				half4 sampleValue = SAMPLE_TEXTURE2D(_MaskTex, sampler_MaskTex, IN.uv);
				half sValue = 0;

				if (_SampleChannel == 0)
					sValue = round(sampleValue.r);
				else if (_SampleChannel == 1)
					sValue = round(sampleValue.g);
				else if (_SampleChannel == 2)
					sValue = round(sampleValue.b);
				else if (_SampleChannel == 3)
					sValue = round(sampleValue.a);


				maskValue.r = sValue;
				maskValue.b = IN.uv2.x;
				//maskValue *= half4(IN.uv2.x, IN.uv2.y, 0, 0);
				return  maskValue;
			}
			ENDHLSL
		}

    }
}
