Shader "Quantum/GPU Particles/SymbolVisualizer"{
	Properties{
		_Size ("Size", Range(0.001, 0.1)) = 0.02
		_AnimPart ("Animated Part", Range(0.0, 1.0)) = 0.5
		_AnimSpeed ("Animation Speed", Range(0.0, 10.0)) = 2.0
		_Color1 ("Color1", Color) = (0.0, 0.0, 1.0, 1.0)
		_Color2 ("Color2", Color) = (0.0, 1.0, 0.0, 1.0)
		_Color3 ("Color3", Color) = (1.0, 0.0, 0.0, 1.0)
		_ChangeSpeed ("Colorchange Speed", Range(0.0, 10.0)) = 1.0
		[HideInInspector] _Particles ("Size", Float) = 128
		[HideInInspector] _DstBlend ("DstBlend", Float) = 1.0
		[HideInInspector] _ColorMode ("ColorMode", Float) = 0.0
	}

	SubShader{
		Tags { "Lightmode" = "Forwardbase" "Queue" = "Transparent+1" "RenderType" = "Transparent" }
		LOD 100

		Pass{
			Tags { "Lightmode" = "Forwardbase" "Queue" = "Transparent+1" "RenderType" = "Transparent" }
			ZWrite Off
			Cull Off
			BlendOp Add
			Blend SrcAlpha [_DstBlend]
			CGPROGRAM
			#pragma shader_feature CM_STATIC CM_PULSE CM_CHANGING
			#pragma vertex vert
			#pragma fragment frag
			#pragma geometry geom

			#include "UnityCG.cginc"

			struct appdata{
				float4 pos : POSITION;
			};

			struct v2g{
				float4 pos : POSITION;
			};

			struct g2f{
				float4 pos : SV_POSITION;
				float3 uvPos : TEXCOORD0;
			};

			v2g vert (appdata v){
				v2g o;
				o.pos = v.pos;
				return o;
			}

			float _Size;
			float _AnimSpeed;
			float _AnimPart;
			float _ChangeSpeed;
			float4 _Color1;
			float4 _Color2;
			float4 _Color3;
			float _Particles;
			#define SQRT3 1.7320508075688772935274463415059
			#define PI 3.1415926535897932384626433832795

			[maxvertexcount(3)]
            void geom(triangle v2g IN[3], uint primID : SV_PrimitiveID, inout TriangleStream<g2f> tristream){
                g2f o;

				//GET NECESSARY DATA
				float4 c = float4(0.0, 0.0, 0.0, 1.0);

				float t = clamp((frac(_Time.x*_AnimSpeed)-(1.0-_AnimPart))/_AnimPart, 0.0, 1.0);
				if(primID < _Particles*7.0/8.0){
					bool start = t < 0.5;
					if(start){
						t*=2.0;
					}else{
						t = 2.0-t*2.0;
					}
					t = t*t*t * (t*(t*6 - 15) + 10);
					float r = primID/(_Particles*7.0/8.0);
					if(start){
						c.xy = float2(cos(r*PI*2.0), sin(r*PI*2.0))*cos(r*t*PI*8.0);
					}else{
						c.xy = float2(cos(r*PI*2.0), sin(r*PI*2.0))*cos((1.0-r)*t*PI*8.0);
					}
				}else{
					t = t*t*t * (t*(t*6 - 15) + 10);
					float r = frac((primID/_Particles)*8.0)*0.03 + 0.47+t;
					c.xy = float2(cos(r*PI*2.0), sin(r*PI*2.0))*sin(r*PI*8.0)*2.5;
					float adjust = -PI/4.0;
					c.xy = float2(c.x*cos(adjust) - c.y*sin(adjust), c.x*sin(adjust) + c.y*cos(adjust));
				}

				c = mul(unity_ObjectToWorld, c);

				float d = 1.0;//distance(c.xyz, _WorldSpaceCameraPos.xyz);

				//FIRST VERTEX
				o.uvPos = float3(float2(-SQRT3, -1.0)*_Size*d, d);
				o.pos = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_V, c) + float4(o.uvPos.xy, 0.0, 0.0));

				tristream.Append(o);

				//SECOND VERTEX
				o.uvPos = float3(float2(0.0, 2.0)*_Size*d, d);
				o.pos = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_V, c) + float4(o.uvPos.xy, 0.0, 0.0));

				tristream.Append(o);

				//THIRD VERTEX
				o.uvPos = float3(float2(SQRT3, -1.0)*_Size*d, d);
				o.pos = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_V, c) + float4(o.uvPos.xy, 0.0, 0.0));

				tristream.Append(o);

				//FINISH IT UP
				tristream.RestartStrip();
            }

			fixed4 frag (g2f i) : SV_Target{
				// APPLY COLOR

				#ifdef CM_STATIC
				float4 color = _Color1;
				#endif

				#ifdef CM_PULSE
				float4 color = lerp(_Color1, _Color2, sin(_Time.z*_ChangeSpeed)*0.5+0.5);
				#endif

				#ifdef CM_CHANGING
				float4 color = 1.0;
				float s = frac(_Time.x*_ChangeSpeed);
				if(s < 0.33333){
					color = lerp(_Color1, _Color2, s*3);
				}else if(s < 0.66666){
					color = lerp(_Color2, _Color3, s*3-1.0);
				}else{
					color = lerp(_Color3, _Color1, s*3-2.0);
				}
				#endif

				// APPLY SHAPE

				color.a *= clamp(1.0 - length(i.uvPos.xy)/_Size/i.uvPos.z, 0.0, 1.0);

				// END

				return color;
			}
			ENDCG
		}
	}
	CustomEditor "SymbolVisualizerInspector"
}
