// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'


Shader "FZDL_Shader/Environment/Tree/JR_TreeAdvance" {
Properties {
	[ToggleOff]_Receive_Shadows("接收阴影", Float) = 1.0
	_Cutoff ("Alpha cutoff", Range(0,1)) = 0.3
	_Brightness("贴图亮度", Range(0,10)) = 1
	[Toggle(_HSV_ON)]_HSV("HSV",Float) = 0
	_HueShift("色相", Range( -1 , 1)) = 0
	_Sat("饱和度", Range( -1 , 1)) = 0
	_Val("明度", Range( -1 , 1)) = 0
	[Main(Tex,_NORMALMAP)]
	//_Tex("Tex", float) = 0
	_UseNormalMap ("(法线开关)主纹理+法线", float) = 0
	[Sub(Tex)]_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
	//[Toggle(_NORMALMAP)]_UseNormalMap("Use NormalMap",Float) = 0
	[Sub(Tex)]_BumpTransSpecMap ("Normal (GA) Trans(R) Smoothness(B)", 2D) = "bump" {}
	[Sub(Tex)]_NormalScale("NormalScale", Range(0,2)) = 1
	//[Header(___________Specular___________)]
	[Main(SpecularAo,_)]
	_DebugShowAo("(显示AO开关)高光+AO", float) = 0
	[Title(SpecularAo, Specular)]
	[Sub(SpecularAo)]_Shininess("粗糙度", Range(0.03,1)) = 0.1
	[Sub(SpecularAo)]_SpecularIntensity("高光强度", Range(0,1)) = 1
	[Sub(SpecularAo)]_SpecularColor("高光颜色", Color) = (1,1,1,1)
	//[Header(___________AO___________)]
	// [Main(AO,_)]
	// _DebugShowAo("显示AO", float) = 0
	//[ToggleOff]_DebugShowAo("显示AO",Float) = 0
	[Title(SpecularAo, Ao)]
	[Sub(SpecularAo)]_VertexColorMul ("AO颜色", Color) = (1,1,1,1)
	[Sub(SpecularAo)]_AoMin("Ao最低亮度",Range(-0.5,0.5)) = 0
	[Sub(SpecularAo)]_AoMax("Ao最高亮度",Range(0.5,2)) = 1
	//_DarkColorHADD ("Dark Color H Add", Range(0,5)) = 0
	[Sub(SpecularAo)]_DarkColor ("暗部颜色", Color) = (0,0,0,1)
	[Sub(SpecularAo)]_DarkIntensity("暗部亮度", Range(0.5, 1)) = 0.5
	//_DarkColorRGBADD ("Dark Color RGB Add", Vector) = (0, 0, 0, 0)
	//[Header(___________Wind___________)]
	[Main(Wind,_,2)]
	_Wind("风", float) = 0
	[KWEnum(Wind, None, WIND_NONE, Uv, WIND_UV, Vertex, WIND_VERTEX)]
	Wind("Wind Control Type", Float) = 0
	//[KeywordEnum(None,Uv,Vertex)]Wind("Wind Control Type", Float) = 0
	//speed
	[Title(Wind, speed)]
	[Sub(Wind)]_BendSpeed("最小速率", Range(0, 3)) = 0.1
	[Sub(Wind)]_BendSpeedMax("使用Uv调节最大速率", Range(0, 3)) = 0.3
	[Sub(Wind)]_JRWind("XZ:方向Y:速率配合最大值W:强度", Vector) = (0.707,0,0.707,1)
	//side bend
	[Title(Wind, side bend)]
	[Sub(Wind)]_SideBendIntensity("侧边最小强度", Range(0, 1)) = 0.1
	[Sub(Wind)]_SideBendIntensityMax("侧边最大强度", Range(0, 1)) = 0.3
	[Sub(Wind)]_SideBendVariance("使用Vertex侧边变化强度", Range(0, 1)) = 1
	[Sub(Wind)]_SideBendSoftness("侧边柔度", Range(0, 3)) = 2
	//down bend
	[Title(Wind, down bend)]
	[Sub(Wind)]_DownBendIntensity("朝下最小强度", Range(0, 0.2)) = 0.01
	[Sub(Wind)]_DownBendIntensityMax("朝下最大强度", Range(0, 0.2)) = 0.03
	[Sub(Wind)]_DownBendVariance("使用Vertex朝下变化强度", Range(0, 1)) = 1
	//gust
	[Title(Wind, gust)]
	[Sub(Wind)]_Gust("狂风", Range(0,2)) = 0.25
	[Sub(Wind)]_TimeScale("TimeScale", Float) = 1
	
}
SubShader 
{ 
	Tags 
	{
		"Queue" = "AlphaTest" 
		"IgnoreProjector"="True"
	}
	LOD 200
	Cull Off	
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		ENDHLSL
		Pass
		{
			Tags{ "LightMode" = "UniversalForward" }

			HLSLPROGRAM
			#pragma multi_compile_local WIND_NONE WIND_UV WIND_VERTEX
			#pragma shader_feature_local _NORMALMAP
			#pragma shader_feature_local _HSV_ON
			#include "JR_TreeLibrary.hlsl"

			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_instancing
			#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
			#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
			//#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
			#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
			//#pragma multi_compile _ SHADOWS_SHADOWMASK

			half4 _SpecularColor;
			half4 _VertexColorMul;
			sampler2D _BumpTransSpecMap;
			float4 _BumpTransSpecMap_TexelSize;
			float _Shininess;

			half _SpecularIntensity;
			half _Brightness;
			half _NormalScale;
			half _DarkIntensity;
			half _DebugShowAo;
			half _AoMin,_AoMax;
			uniform half4 _GiantEnviromentLight;
			uniform half3 _DarkColor;
			float _HueShift,_Sat,_Val;
			v2f vert(appdata v)
			{
				v2f o = (v2f)0;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				VertexPositionInputs Input = GetVertexPositionInputs(v.vertex.xyz);
				o.position = Input.positionCS;
				//WIND
				#if WIND_NONE
					float4 worldPos = float4(Input.positionWS,v.vertex.w);
				#elif WIND_UV
					float4 worldPos = AfsLeafWaveWithBakedData(v.vertex, UnpackDirFromUV(v.branchDir.xy));
				#elif WIND_VERTEX
					float4 worldPos = AfsLeafWave(v.vertex, normalize(v.vertex.xyz));
				#endif
				o.position = TransformWorldToHClip(worldPos);

				VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
				float3 worldNormal = normalInput.normalWS;
				float3 worldTangent = normalInput.tangentWS;
				float3 worldBinormal = normalInput.bitangentWS;
				o.texcoord.xy = v.texcoord.xy;
				o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
				o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
				o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
				OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
				OUTPUT_SH(worldNormal, o.vertexSH);
				o.color = v.color;
				//o.uv = v.texcoord2;
				#if defined(_MAIN_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
                    o.shadowCoord = GetShadowCoord(Input);
                #endif
				return o;
			}

			half4 frag(v2f i): SV_Target
			{
				UNITY_SETUP_INSTANCE_ID(i);
				half4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord.xy);
				#ifdef _HSV_ON
				half3 hsv = RGBToHSV(albedo.rgb);
				albedo.rgb = HSVToRGB(float3((hsv.x + _HueShift),(hsv.y + _Sat),(hsv.z + _Val)));
				#endif
				albedo.rgb *= _Brightness;
				clip(albedo.a - _Cutoff);
				#if defined(_MAIN_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
                    half4 shadowCoord = i.shadowCoord;
                #else
                    half4 shadowCoord = half4(0, 0, 0, 0);
                #endif
				Light light = GetMainLight(shadowCoord);
				half4 trngls = tex2D(_BumpTransSpecMap, i.texcoord.xy);
				float3 worldPos = float3(i.tSpace0.w, i.tSpace1.w, i.tSpace2.w);
				half3 worldN;
				#if defined (_NORMALMAP)
                    float4 sampleNormal = tex2D(_BumpTransSpecMap, i.texcoord.xy);
                    half3 normal = UnpackNormalAG(sampleNormal,_NormalScale);
					worldN.x = dot(i.tSpace0.xyz, normal.xyz);
					worldN.y = dot(i.tSpace1.xyz, normal.xyz);
					worldN.z = dot(i.tSpace2.xyz, normal.xyz);
                    half gloss = sampleNormal.b * _SpecularIntensity;
                #else
                    worldN = half3(i.tSpace0.z,i.tSpace1.z,i.tSpace2.z);
                    half gloss = _SpecularIntensity;
                #endif
				//half3 Ao = _VertexColorMul.a == 0?i.color.aaa:i.color.rgb;
				half3 Ao = i.color.aaa;
				Ao = smoothstep(_AoMin,_AoMax, Ao);
				albedo.rgb *= lerp(_VertexColorMul.rgb, 1, Ao);
				half3 lightDir = light.direction;
				half3 lightColor = light.color;
				//return half4(lightDir,1);
				//darkColor
				// half t = saturate(-dot(worldN, lightDir));
				// albedo.rgb += t * _DarkColorRGBADD.rgb;
				half3 darkColor = _DarkColor;
				half darkColorIntensity = saturate(darkColor.r*0.229 + darkColor.g*0.587 + darkColor.b*0.114);
				half t = darkColorIntensity * saturate(-dot(worldN, lightDir));
				albedo.rgb = lerp(albedo.rgb, darkColor.rgb, t);
				half halfLambert = 0.5 + 0.5 * dot(worldN, float3(0, 2, 0));
				albedo.rgb *= lerp(_DarkIntensity, 1.5, halfLambert);
				//spec
				half3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz - worldPos);
				//return half4(_WorldSpaceCameraPos.xyz,1);
				half3 spec = gloss*_SpecularColor.rgb;
				//Calculate Light
				half3 bakedGI = SAMPLE_GI(i.lightmapUV, i.vertexSH, worldN);
				#if defined(LIGHTMAP_ON) && defined(SHADOWS_SHADOWMASK)
					half4 shadowmask = SampleShadowMask(i.lightmapUV);
				#else
					half4 shadowmask = half4(0,0,0,0);
				#endif
				MixRealtimeAndBakedGI(light, worldN, bakedGI,shadowmask,worldPos);
				bakedGI *= _GiantEnviromentLight.xyz;

				albedo.rgb = CalculateForwardLight(light, bakedGI, albedo.rgb, spec, worldN, worldViewDir,1 - _Shininess);
				//ShowAo
				albedo.rgb = _DebugShowAo?Ao:albedo.rgb;
				//return i.uv.xxxx;
				return albedo;
			}

			ENDHLSL
		}
		Pass
        {
            Name "ShadowCaster"
            Tags{"LightMode" = "ShadowCaster"}
            ZTest LEqual

            HLSLPROGRAM
			#pragma vertex vert
            #pragma fragment frag
            // Required to compile gles 2.0 with standard srp library
            #pragma prefer_hlslcc gles
            #pragma exclude_renderers d3d11_9x
            #pragma target 2.0
			//Wind
			#define TREE_SHAODW_PASS 1
			#pragma multi_compile_local WIND_NONE WIND_UV WIND_VERTEX
			#include "JR_TreeLibrary.hlsl"

            // -------------------------------------
            // Material Keywords
            #pragma multi_compile _ALPHATEST_ON

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
			float3 _LightDirection;
			v2f vert(appdata v)
			{
				v2f output = (v2f)0;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

				output.texcoord = v.texcoord;
				//WIND
				VertexPositionInputs Input = GetVertexPositionInputs(v.vertex.xyz);
				#if WIND_NONE
					float4 worldPos = float4(Input.positionWS,v.vertex.w);
				#elif WIND_UV
					float4 worldPos = AfsLeafWaveWithBakedData(v.vertex, UnpackDirFromUV(v.branchDir.xy));
				#elif WIND_VERTEX
					float4 worldPos = AfsLeafWave(v.vertex, normalize(v.vertex.xyz));
				#endif

				float3 normalWS = TransformObjectToWorldNormal(v.normal);
				output.position = TransformWorldToHClip(ApplyShadowBias(worldPos, normalWS, _LightDirection));
			#if UNITY_REVERSED_Z
				output.position.z = min(output.position.z, output.position.w * UNITY_NEAR_CLIP_VALUE);
			#else
				output.position.z = max(output.position.z, output.position.w * UNITY_NEAR_CLIP_VALUE);
			#endif
				return output;
			}
			half4 frag(v2f i) : SV_TARGET
			{
				Alpha(SampleAlbedoAlpha(i.texcoord, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, half4(1,1,1,1), _Cutoff);
				return 0;
			}
            ENDHLSL
        }
		Pass
        {
            Name "DepthOnly"
            Tags{"LightMode" = "DepthOnly"}
            ColorMask 0

            HLSLPROGRAM
            // Required to compile gles 2.0 with standard srp library
            #pragma prefer_hlslcc gles
            #pragma exclude_renderers d3d11_9x
            #pragma target 2.0

            #pragma vertex vert
            #pragma fragment frag
			//Wind
			#define TREE_DEPTH_PASS 1
			#pragma multi_compile_local WIND_NONE WIND_UV WIND_VERTEX
			#include "JR_TreeLibrary.hlsl"

            // -------------------------------------
            // Material Keywords
            #pragma multi_compile _ALPHATEST_ON
            #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing

			v2f vert(appdata v)
			{
				v2f output = (v2f)0;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

				output.texcoord = v.texcoord;
				//WIND
				VertexPositionInputs Input = GetVertexPositionInputs(v.vertex.xyz);
				#if WIND_NONE
					float4 worldPos = float4(Input.positionWS,v.vertex.w);
				#elif WIND_UV
					float4 worldPos = AfsLeafWaveWithBakedData(v.vertex, UnpackDirFromUV(v.branchDir.xy));
				#elif WIND_VERTEX
					float4 worldPos = AfsLeafWave(v.vertex, normalize(v.vertex.xyz));
				#endif
				output.position = TransformWorldToHClip(worldPos);
				//output.positionCS = TransformObjectToHClip(input.position.xyz);
				return output;
			}

			half4 frag(v2f input) : SV_TARGET
			{
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

				Alpha(SampleAlbedoAlpha(input.texcoord, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, half4(1,1,1,1), _Cutoff);
				return 0;
			}
            ENDHLSL
        }
	}
	CustomEditor "FZDL.ShaderDrawer.LWGUI"
}