Shader "Custom/AvaliMaster"
{
    Properties
    {
		[Header(Avali HSV crappy shader made by alexx1)]
		[Header(Lighting settings)]
		_LightingClip ("Lighting Clip", Range (0, 4)) = 0.5
		_SheenStrength ("Sheen Strength", Range (0, 3)) = 0.5
		[IntRange] _SheenPow ("Sheen Pow", Range(0, 16)) = 6
		_RimStrength ("Rim Strength", Range (0, 3)) = 1.0
		[HDR]
		_AmbientColor("Ambient Color", Color) = (0.4,0.4,0.4,1)

		
		[Space(50)]
		[Header(Textures used for composition)]
		_MainTex ("Shader Override Texture", 2D) = "black" {}
		_PSDF_Composed ("PSDF RGB Composed (Body, Feathers1, Feathers2)", 2D) = "black" {}
		_OutlineClip ("Outline Clip", Range (0.000001, 1)) = 0.5
		[Space(16)]
		_Light_Composed ("Light RGB Composed (Body, Feathers1, Feathers2)", 2D) = "black" {}
		_LightStrength ("Light Layer Strength", Range (0, 1)) = 1.0
		[Space(16)]
		_Secondary_Composed ("Secondary Color RGB Composed (Body, Feathers1, Feathers2)", 2D) = "black" {}
		_Main_Extra ("Body: Extra", 2D) = "black" {}
		_Eyes_Base ("Eyes Base", 2D) = "black" {}

		[Space(50)]
		[Header(These values are overridden during runtime by the animations)]
		[Header(Please do not blindly change them)]
		_BaseColorH ("Base Color Hue", Range (0, 1)) = 0
		_BaseColorS ("Base Color Sat", Range (0, 1)) = 0
		_BaseColorV ("Base Color Val", Range (0, 1)) = 0
		
		_SecColorH ("Secondary Color Hue", Range (0, 1)) = 0
		_SecColorS ("Secondary Color Sat", Range (0, 1)) = 0
		_SecColorV ("Secondary Color Val", Range (0, 1)) = 0
		
		_DetColorH ("Detail Color Hue", Range (0, 1)) = 0
		_DetColorS ("Detail Color Sat", Range (0, 1)) = 0
		_DetColorV ("Detail Color Val", Range (0, 1)) = 0
	
		_DetVarying ("Detail Color Varying", Range (0, 1)) = 0
		

    }

    SubShader
    {
		Pass
		{
			Tags
			{
				"RenderType" = "Opaque"
				"LightMode" = "ForwardBase"
				"PassFlags" = "OnlyDirectional"
			}
			
			Cull Off
			ZWrite On
			
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"
			#include "Lighting.cginc"

			// #define OVERRIDE_TEST
			
			#define LIGHTPOS float3(0.276172, 0.920575, 0.276172)
			#define LIGHTCOL float4(0.9, 0.9, 0.9, 1.)
			
			struct appdata
			{
				float4 vertex : POSITION;				
				float4 uv : TEXCOORD0;
				float3 normal : NORMAL;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float4 vertex : COLOR;
				float2 uv : TEXCOORD0;
				float3 worldNormal : NORMAL;
				float3 viewDir : TEXCOORD1;
			};
			
			sampler2D _MainTex; // used for when shader is overidden
			
			sampler2D _PSDF_Composed;
			sampler2D _Light_Composed;
			sampler2D _Secondary_Composed;
			sampler2D _Main_Extra;
			sampler2D _Eyes_Base;

			float _LightingClip;		
			float _LightStrength;		
			float _OutlineClip;		
			float _SheenStrength;		
			float _RimStrength;		
			int _SheenPow;		


			float _BaseColorH;		
			float _BaseColorS;		
			float _BaseColorV;		

			float _SecColorH;		
			float _SecColorS;		
			float _SecColorV;		

			float _DetColorH;		
			float _DetColorS;		
			float _DetColorV;		
			float _DetVarying;		
			
			float4 _AmbientColor;
			
			float4 _MainTex_ST;
			
			float conv_smooth(float f, float tgt){
				return smoothstep(tgt-0.000001, tgt, f);
			}
			
			fixed3 hsv2rgb(fixed3 c) {
				fixed4 K = fixed4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
				fixed3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
				return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
			}
			
			v2f vert (appdata v)
			{

				
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.vertex = v.vertex;
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.viewDir = WorldSpaceViewDir(v.vertex);
				return o;
			}
			
			fixed3 DetColorG;
			float4 shade(v2f i, fixed3 step, float emissive, float alpha){
				clip(alpha - 0.5);
				
				emissive = clamp(emissive, 0.7, 1.0);
				
				// shading
				
				float3 normal = normalize(i.worldNormal);
				float NdotL = dot(LIGHTPOS, normal);
				float lightIntensity = smoothstep(0, 0.075 * _LightingClip, NdotL);
				float4 light = lightIntensity * LIGHTCOL;
				
				float4 ret = float4(step, 1.);
				
				float3 viewDir = normalize(i.viewDir);
				
				#define RimAmount 0.7
				float rimDot = 1 - dot(viewDir, normal);
				rimDot = min(rimDot, 1 - dot(viewDir, -normal)); // fix backface
				float rimIntensity = rimDot * pow(NdotL, 0.1) * _RimStrength;
				float4 rim = smoothstep(RimAmount - 0.02 * _LightingClip, RimAmount + 0.02 * _LightingClip, rimIntensity);
				
				
				// 2nd rim
				float rim2Intensity = pow(rimDot, _SheenPow) * 0.075 * _SheenStrength * 2.0;
				float4 rim2 = float4(rim2Intensity * DetColorG, 0.0);
				
				return (emissive * ret) + (1. - emissive) * ret * (_AmbientColor + light + rim) + rim2;
			}
			
			float4 shade_specular(v2f i, fixed3 step, float emissive, float alpha){
				clip(alpha - 0.5);
				
				float _Glossiness = 32.;
				float4 _SpecularColor = fixed4(0.9, 0.9, 0.9, 1.);
				
				// shading
				
				float4 shade_result = shade(i, step, emissive, alpha);
				
				// specular
				
				float3 normal = normalize(i.worldNormal);
				float NdotL = dot(LIGHTPOS, normal);
				float lightIntensity = smoothstep(0, 0.01, NdotL);
				
				float3 viewDir = normalize(i.viewDir);

				float3 halfVector = normalize(LIGHTPOS + viewDir);
				float NdotH = dot(normal, halfVector);

				float specularIntensity = pow(NdotH * lightIntensity, _Glossiness * _Glossiness);
				
				float specularIntensitySmooth = smoothstep(0.005, 0.01, specularIntensity);
				float4 specular = specularIntensitySmooth * _SpecularColor;
				
				return shade_result + specular;
			}



			
			float4 body(v2f i, fixed3 BaseColor, fixed3 SecColor, fixed3 DetColor){
				fixed3 step = BaseColor;	
				float emissive = 0.;
				
				float mask_v2 = (tex2D(_Main_Extra, i.uv)).a;
				float mask_v3 = (tex2D(_Secondary_Composed, i.uv)).r;
				float mask_v4 = conv_smooth((tex2D(_PSDF_Composed, i.uv)).r, _OutlineClip);
				float light = (tex2D(_Light_Composed, i.uv)).r;

				step	 = lerp(step, (tex2D(_Main_Extra, i.uv)).rgb, mask_v2);
				emissive = lerp(emissive, 0., mask_v2);

				step	 = lerp(step, SecColor, mask_v3);
				emissive = lerp(emissive, 0., mask_v3);

				step	 = lerp(step, DetColor, mask_v4);
				emissive = lerp(emissive, 1., mask_v4);

				step = lerp(step, step * clamp(light / 2.0 + 0.5, 0.2, 1.0), _LightStrength);
				
				return shade(i, step, emissive, 1.);
			}
			
			float4 eyes(v2f i, fixed3 BaseColor, fixed3 SecColor, fixed3 DetColor){
				float mask = tex2D(_Eyes_Base, i.uv).r;
				
				fixed3 step = fixed3(0., 0., 0.);
				float emissive = 0.;
				
				step = lerp(step, DetColor, mask);
				emissive = lerp(emissive, 1., mask);
				
				return shade_specular(i, step, emissive, 1.);
			}
			
			float4 wings2(v2f i, fixed3 BaseColor, fixed3 SecColor, fixed3 DetColor){
				fixed3 step = BaseColor;
				float emissive = 0.;

				float mask_v1 = tex2D(_Secondary_Composed, i.uv).b;
				float mask_v2 = conv_smooth(tex2D(_PSDF_Composed, i.uv).b, _OutlineClip);
				float light = tex2D(_Light_Composed, i.uv).b;
				
				step	 = lerp(step, SecColor, mask_v1);
				emissive = lerp(emissive, 0., mask_v1);

				step	 = lerp(step, DetColor, mask_v2);
				emissive = lerp(emissive, 1., mask_v2);

				step = lerp(step, step * (light + 0.7), _LightStrength);
				
				return shade(i, step, emissive, 1.);
			}
			
			float4 wings(v2f i, fixed3 BaseColor, fixed3 SecColor, fixed3 DetColor){
				fixed3 step = BaseColor;
				float emissive = 0.;

				float mask_v1 = (tex2D(_Secondary_Composed, i.uv)).g;
				float mask_v2 = conv_smooth((tex2D(_PSDF_Composed, i.uv)).g, _OutlineClip);
				float light = tex2D(_Light_Composed, i.uv).g;
				
				
				step	 = lerp(step, SecColor, mask_v1);
				emissive = lerp(emissive, 0., mask_v1);

				step	 = lerp(step, DetColor, mask_v2);
				emissive = lerp(emissive, 1., mask_v2);

				step = lerp(step, step * (light + 0.7), _LightStrength);
				
				return shade(i, step, emissive, 1.);
			}
			
			float4 frag(v2f i, half facing : VFACE) : SV_Target {
#ifdef OVERRIDE_TEST
				if(1){
					return tex2D(_MainTex, i.uv);
				}
#endif
				fixed3 BaseColor = hsv2rgb(fixed3(
					_BaseColorH,
					_BaseColorS,
					_BaseColorV
				));

				fixed3 SecColor = hsv2rgb(fixed3(
					_SecColorH,
					_SecColorS,
					_SecColorV
				));

				fixed3 DetColor = hsv2rgb(fixed3(
					_DetColorH + (sin(_Time.y*2.0 + i.vertex.y*5.0 + i.vertex.x*0.5 + i.vertex.z * 0.7)/4.0)*_DetVarying,
					_DetColorS,
					_DetColorV
				));
				
				DetColorG = DetColor;
				if(i.uv.x - 6. > 0.){
					clip(facing);
					return eyes(i, BaseColor, SecColor, DetColor);
				}else if(i.uv.x - 4. > 0.){
					return wings2(i, BaseColor, SecColor, DetColor);
				}else if(i.uv.x - 2. > 0.){
					return wings(i, BaseColor, SecColor, DetColor);
				}else{
					clip(facing);
					return body(i, BaseColor, SecColor, DetColor);
				}
				
				return float4(0., 1., 0., 0.);
			}
			ENDCG
		}

    }
}
