Shader "Zhanyou/Character/PlayerFlow"
{
	Properties
	{
		_MainTex ("Main Texture", 2D) = "white" {}
		_Emission ("Emission", float) = 0
		_ColorRate("Color Rate", Range(0, 1)) = 0.9
		_Cutoff("Alpha Cutoff", Range(0, 1)) = 0.5
		[NoScaleOffset]_BumpTex("Normal Map", 2D) = "bump" {}
		// ChannelTex,r表示漫反射亮度,g表示镜面反射亮度,b表示边缘光亮度,a表示流光亮度
		[NoScaleOffset]_ChannelTex("Channel(RGBA Specular/Color/Outline", 2D) = "white" {}
		_SpecPower ("Specular", float) = 5
		_SpecGloss("Gloss", float) = 10
		_OutlinePower("Outline Power", float) = 2
		_OutlineColor("Outline Color", Color) = (1,1,1,1)
		_UiLightDir ("Ui Light Dir", Vector) = (1, 0, 0, 0)
		// 角色材质颜色,乘法运算
		_Color("Blend Color", Color) = (1, 1, 1, 1)
		// Emission叠加颜色,加法运算
		_AddColor("Additive Color", Color) = (0, 0, 0, 1)
		_FlowTex ("Flow (RGB)", 2D) = "black" {}
		[NoScaleOffset]_FlowBrightTex("Flow Brightness (R)", 2D) = "white" {}
		_FlowColor ("Flow Color", Color) = (1, 1, 1, 1)
		_FlowSpeed ("Flow Speed", float) = 1
	}
	SubShader
	{
		Tags{"Queue"="AlphaTest+10" "RenderType"="CharacterCutout" }
		Pass
		{
			Stencil {
                Ref 1
                Comp always
                Pass replace
            }
		
			CGPROGRAM
			#include "UnityCG.cginc"
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile __ CHARACTER_NORMAL_OFF
			#pragma multi_compile __ UseSpecular
			#pragma multi_compile_fog

			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float2 texcoord : TEXCOORD0;
				float2 texcoord2 : TEXCOORD1;
			};

#if UseSpecular && !CHARACTER_NORMAL_OFF
			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float4 flowUv : TEXCOORD1;
				float4 tSpace0 : TEXCOORD2;
				float4 tSpace1 : TEXCOORD3;
				float4 tSpace2 : TEXCOORD4;
				float3 lightDir : TEXCOORD5;
                UNITY_FOG_COORDS(6)
			};
            uniform float _ColorRate;
			uniform float _SpecPower;
			uniform float _SpecGloss;
			uniform float _OutlinePower;
			uniform float4 _OutlineColor;
            uniform float4 _UiLightDir;
#else
            struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float4 flowUv : TEXCOORD1;
				UNITY_FOG_COORDS(2)
			};
#endif

			uniform sampler2D _MainTex;
#if UseSpecular && !CHARACTER_NORMAL_OFF
			uniform sampler2D _BumpTex;
            uniform sampler2D _ChannelTex;
#endif
			uniform float _Cutoff;
            uniform float _Emission;
            uniform float4 _Color;
			uniform float4 _AddColor;
			uniform sampler2D _FlowBrightTex;
			uniform sampler2D _FlowTex;
			uniform half4 _FlowTex_ST;
			uniform half4 _FlowColor;
			uniform float _FlowSpeed;
			v2f vert (appdata v)
			{
				v2f o;
				UNITY_INITIALIZE_OUTPUT(v2f, o);
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = v.texcoord;
				o.flowUv.xy = v.texcoord2;
				o.flowUv.zw = TRANSFORM_TEX(v.texcoord2, _FlowTex);
				o.flowUv.w += _Time.y * _FlowSpeed;
#if UseSpecular && !CHARACTER_NORMAL_OFF
				float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
				fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
				fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w;
				fixed3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign;
				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);
                o.lightDir = normalize(_UiLightDir.xyz);
				float4 worldForward;
				worldForward.x = -UNITY_MATRIX_IT_MV[2].x;
				worldForward.y = -UNITY_MATRIX_IT_MV[2].y;
				worldForward.z = -UNITY_MATRIX_IT_MV[2].z;
				worldForward.w = 1;
				worldForward = mul(unity_ObjectToWorld, worldForward);
                float3 x = normalize(cross(float3(0, 1, 0), worldForward.xyz));
                float3 z = normalize(cross(x, float3(0, 1, 0)));
                o.lightDir = normalize(x * o.lightDir.x + float3(0, o.lightDir.y, 0) + z * o.lightDir.z);
#endif
				UNITY_TRANSFER_FOG(o, o.pos);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				clip(col.a - _Cutoff);
				col.rgb += col.rgb * _Emission;
				col.rgb *= _Color.rgb;
#if UseSpecular && !CHARACTER_NORMAL_OFF
				float3 worldPos = float3(i.tSpace0.w, i.tSpace1.w, i.tSpace2.w);
				fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos));
				half3 normal = UnpackNormal(tex2D(_BumpTex, i.uv));
				half4 channelCol = tex2D(_ChannelTex, i.uv);
				fixed3 worldNormal;
				worldNormal.x = dot(i.tSpace0.xyz, normal);
				worldNormal.y = dot(i.tSpace1.xyz, normal);
				worldNormal.z = dot(i.tSpace2.xyz, normal);
				worldNormal = normalize(worldNormal);
				half3 h = normalize (i.lightDir + worldViewDir);
				half nh = max (0, dot (worldNormal, h));
				half specular = pow (nh, _SpecPower) * _SpecGloss;
				half outline = max(0, 1 - dot(worldNormal, worldViewDir));
				col.rgb = col.rgb * (_ColorRate + (1 - _ColorRate) * channelCol.g)  + col.rgb * specular  * channelCol.r + _OutlineColor.rgb * pow(outline, _OutlinePower) * channelCol.b;
#endif
				half flowAlpha = tex2D(_FlowBrightTex, i.flowUv.xy);
				fixed4 flowCol = tex2D(_FlowTex, i.flowUv.zw) * _FlowColor;
				col.rgb += flowCol.rgb * flowCol.a * flowAlpha;
				col.rgb += _AddColor.rgb;
				// apply fog
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
		Pass
		{
			Name "ShadowCaster"
			Tags { "LightMode" = "ShadowCaster" }
			
			ZWrite On ZTest LEqual Cull Off
		
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 2.0
			#pragma multi_compile_shadowcaster
			#include "UnityCG.cginc"
		
			struct v2f { 
				V2F_SHADOW_CASTER;
			};
		
			v2f vert( appdata_base v )
			{
				v2f o;
				TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
				return o;
			}
		
			float4 frag( v2f i ) : SV_Target
			{
				SHADOW_CASTER_FRAGMENT(i)
			}
			ENDCG
		}
	}
    CustomEditor "PlayerShaderGui"
	Fallback "Zhanyou/Character/NPCAlpha"
}