Shader "CrispyPin/LibGarbageSpinny"
{
	Properties
	{
		[Header(Raymarcher Properties)]
		_MaxSteps ("Max steps", Integer) = 128
		_MaxDist ("Max distance", Float) = 128
		_SurfDist ("Surface distance threshold", Range(0.0001, 0.05)) = 0.001
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		Cull Front
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			int _MaxSteps;
			float _MaxDist;
			float _SurfDist;
			#define MAX_STEPS _MaxSteps
			#define MAX_DIST _MaxDist
			#define SURF_DIST _SurfDist

			#define REFLECTIONS 5

			#define LIGHT_FN lighting
			#define SCENE_FN main

			// #define SEPARATE_MATERIAL_AND_DIST_FUNCTIONS
			// #define SCENE_FN separate_mat
			// #define DISTANCE_FN separate_dist

			// #define DISABLE_DEPTH
			#define DISCARD_ON_MISS
			// #define USE_WORLD_SPACE
			#define SCENE_SCALE 0.05
			#include "lib/libgarbage.cginc"

			SurfacePoint main(float3 p) {
				Material grass = mat(float3(0.26, 0.73, 0.35), 1);
				Material dirt = mat(float3(0.73, 0.48, 0.26), 0);
				Material metal = mat(1, 1);
				Material blue = mat(float3(0.73, 0.8, 1), 0);

				SurfacePoint d = mPlaneY(p, 0, grass);
				d = qIntersect(d, mSphere(p, 9, dirt), 0.5);
				d = qUnion(d, mSphere(p - float3(0, 2, 0), 2, metal));
				d = qUnion(d, mTorus(rotX(p, _Time * 40 + UNITY_PI / 2), 5, 0.5, blue), 0.5);
				d = qUnion(d, mTorus(rotZ(p, _Time * 40 + UNITY_PI / 2), 5, 0.5, blue), 0.5);
				d = qUnion(d, mTorus(rotX(p, _Time * 40), 5, 0.5, blue), 0.5);
				d = qUnion(d, mTorus(rotZ(p, _Time * 40), 5, 0.5, blue), 0.5);
				// small spheres
				float3 p2 = abs(rotY(p, -20 * _Time)) - float3(1.5, sin(_Time.y * 5) + 1, 1.5);
				d = qUnion(d, mSphere(p2, 0.7, metal), 0.2);
				return d;
			}

			// SurfacePoint separate_mat(float3 p) {
			// 	Material blue = mat(float3(0.05, 0.1, 0.2), 0);
			// 	SurfacePoint d = mSphere(p, 1, blue);
			// 	return d;
			// }

			// float separate_dist(float3 p) {
			// 	return main(p).dist;
			// }

			float3 lighting(Ray ray) {
				float3 sun_dir = normalize(float3(4, 2, 1));
				if (ray.missed) {
					return lRenderSky(ray.dir, sun_dir);
				}
				float3 light = lSun(ray.normal, sun_dir);
				light *= lShadow(ray.hit_pos + ray.normal * SURF_DIST, sun_dir, 50);
				light += lSky(ray.normal);

				return light;
			}

			ENDCG
		}
	}
}
