Shader "Quantum/CellSpace"
{
    Properties{
        _Size ("Size", Range(0,100.0)) = 25.
        _Seed ("RNG Seed", Range(0,100000.0)) = 43758.5453
    }

    CGINCLUDE
	float _Size;
    float _Seed;

    float3 noise_3d(float3 p) {
		return frac(sin(float3(
			dot(p,float3(127.1,311.7,413.5)),
			dot(p,float3(269.5,183.3,197.7)),
			dot(p,float3(597.3,835.1,791.3))
				))*43758.5453);
	}

    float voronoi( in float3 pos ) {
        float3 n = floor(pos);
        float3 f = frac(pos);

        // first pass: regular voronoi
        float md1 = 8.0, md2 = 8.0;
		float3 mp1, mp2;
        for (int x= -1; x <= 1; x++) {
			for (int y= -1; y <= 1; y++) {
				for (int z= -1; z <= 1; z++) {
	                float3 g = float3(float(x),float(y),float(z));
	                float3 o = noise_3d(n + g);

	                float3 r = g + o - f;
	                float d = dot(r,r);

					if(md1 >= md2){
						if(d < md1) {
		                    md1 = d;
		                }
					}else{
						if(d < md2) {
							md2 = d;
						}
					}
				}
			}
        }
        return distance(md1, md2);
    }

    ENDCG

    SubShader
    {
        // Draw ourselves after all opaque geometry
		Tags { "QUEUE"="Transparent-10" "IGNOREPROJECTOR"="true" "RenderType"="Transparent" "PreviewType"="Plane" }
        Cull Off
		Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
        // Render the object with the texture generated above, and invert the colors
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata{
				float4 vertex : POSITION;
			};

            struct v2f
            {
                float4 vertex : SV_POSITION;
				float3 worldPos : TEXCOORD0;
            };

            v2f vert(appdata v) {
                v2f o;
                o.worldPos = mul (unity_ObjectToWorld, v.vertex);
				o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            sampler2D _BackgroundTexture;

            half4 frag(v2f i) : SV_Target
            {
				float3 pos = i.worldPos;
				float4 posObj = mul(unity_ObjectToWorld,float4(0, 0, 0, 1));
                float v = clamp(pow(1.0-voronoi((posObj/3 + (pos-posObj))*_Size), 6)-0.5, 0.0, 1.0);
                return float4(v, v, v, v);
            }
            ENDCG
        }

    }
}
