Shader "RayMarching/FleshCube"
{
    Properties
    {
        [Header(Lighting)]
        _SunPos ("Sun position", Vector) = (8, 4, 2)

        [Header(Raymarcher Properties)]
        _MaxSteps ("Max steps", Integer) = 256
        _MaxDist ("Max distance", Float) = 256
        _SurfDist ("Surface distance threshold", Range(0.00001, 0.05)) = 0.001

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Cull Off
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            // #define USE_WORLD_SPACE
            #define DYNAMIC_QUALITY
            #define USE_REFLECTIONS
            // #define CONSTRAIN_TO_MESH
            #define MAX_REFLECTIONS 1
            #include "RayMarchLib.cginc"

            float3 _SunPos;

            sdfData gyroid(float3 p, float scale, float bias, material mat = DEFMAT)
            {
                sdfData o;
                o.dist = abs(dot(sin(p * scale), cos(p.zxy * scale))+bias) - 0.2;
                o.dist *= .75 / scale;
                o.mat = mat;
                return o;
            }


            sdfData scene(float3 p)
            {
                sdfData o;
                material mRed = mat(.12, 0.01, 0.01, sin(_Time*100)*0.1+0.6);
                float3 bias = -pow(sin(_Time*60 + p.y*0.1), 8)*.5+1.3;
                o = gyroid(p, .5, bias, mRed);
                //o = sdfTorus(p, 10 + pow(sin(_Time*50), 4)*5, bias+sin(100*_Time + .1*p.x)*0.5+.5, cRed);
                float3 gp = p + sin(_Time + p*0.1);
                o.dist -= gyroid(gp, 1.63,   .5).dist * 0.3;
                o.dist += gyroid(gp, 3.327,   0).dist * 0.1;
                o.dist += gyroid(gp, 7.351,  .5).dist * 0.1;
                o.dist -= gyroid(gp, 17.351, .5).dist * 0.05;
                o.dist -= gyroid(gp, 23.521, .2).dist * 0.05;
                o = sdfAdd(p, o, sdfSphere(p, 6 + bias*3, mRed), 5);

                // o = sdfInter(p, o, sdfSphere(p, 50, mat(0.04, 0.005, 0.035)), 1.1);
                o = sdfInter(p, o, sdfBox(p, 20,  mRed));
                // sdfData gyroid = o;
                // o = sdfAdd(p,
                //     sdfInter(p, gyroid, sdfBox(p, 30,  mRed)),
                //     sdfSub(p, gyroid, sdfBox(p, 30, mRed))
                //     );
                // o = p, o, sdfBox(p, 20,  mRed));
                //sdfData bobby = sdfSphere(p, 51, col(0.5, 0.25, 0.001));
                //bobby = sdfAdd(p, bobby, sdfSphere(p, 50.5, col(.5,.01,.01)));
                //bobby = sdfSub(p, bobby, sdfSphere(p, 50));
                //o = sdfAdd(p, o, bobby);
                //o = sdfAdd(p, o, sdfPlane(p, -50));
                return o;
            }

            fixed4 lightPoint(rayData ray)
            {
                float3 vSunDir = normalize(_SunPos);

                float4 fogCol = col(0.2, .05, 0.001);

                if (ray.bMissed)
                {
                    // discard;
                    // return fogCol;
                    return 0;
                }

                fixed4 col = 0;

                col += ray.mat.col * lightSun(ray.vNorm, vSunDir, col(5, 2, 0.1));
                col += ray.mat.col * lightSky(ray.vNorm, 1);
                // col *= lightAO(ray.vHit, ray.vNorm, 0.05);

                // col = pow(col, 0.7);
                // col = lightFog(col, fogCol, ray.dist, 0.5, 16);
                return col;
            }
            ENDCG
        }
    }
}
