Shader "CrispyPin/Nut" { Properties { [Header(Raymarcher Properties)] _MaxSteps ("Max steps", Int) = 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 2 #define SCENE_FN main #define LIGHT_FN lighting // #define SEPARATE_MATERIAL_AND_DIST_FUNCTIONS // #define SCENE_FN separate_mat // #define DISTANCE_FN separate_dist // #define STEP_MULTIPLIER 0.1 #define SCENE_SCALE 0.8 // #define DISABLE_DEPTH // #define DISCARD_ON_MISS #define LIMIT_DEPTH_TO_MESH // #define USE_WORLD_SPACE #include "lib/libgarbage.cginc" float3 checkers(float3 p, float3 a, float3 b, float2 size) { float2 q = p.xz / size; q = int2(abs(q) + 0.5); int s = ((q.x + q.y) % 2); return s * a + (1 - s) * b; } float3 floor(float3 p) { return lerp(0.15, checkers(p - 1, 0.10, 0.18, .2), smoothstep(16, 0, length(p)) ); } SurfacePoint mRoundedHex(float3 p, float girth, float height) { SurfacePoint d; d = qRound(mHexPrism(p, girth, height), 0.01); float rounding = 3; d = qIntersect(d, mSphere(p - float3(0, -rounding + height, 0), rounding), 0.01); d = qIntersect(d, mSphere(p + float3(0, -rounding + height, 0), rounding), 0.01); return d; } SurfacePoint main(float3 p) { float girth = 0.3; float height = 0.1; float inner_radius = 0.18; float thread = 0.013; // float thread = 0.01 + sin(_Time.x * 8) * 0.01 + 0.01; SurfacePoint d; float3 rp = rotY(p, _Time.y); rp = rotX(rp, _Time.x); // nut d = mRoundedHex(rp, girth, height); d = qSub(d, mInfCylinder(rp, float3(0, 0, inner_radius)), 0.02); d = qSub(d, mHelix(rp - float3(0, -1, 0), inner_radius, thread, thread/2), 0.003); // bolt SurfacePoint bolt_thread = mInfCylinder(rp, float3(0, 0, inner_radius + 0.3)); bolt_thread = qSub(bolt_thread, mInfCylinder(rp, float3(0, 0, inner_radius)), 0.02); bolt_thread = qSub(bolt_thread, mHelix(rp - float3(0, -1, 0), inner_radius, thread, thread/2), 0.03); // d = qUnion(d, bolt_thread); float h = sin(_Time.y) * 0.15 + 0.2; float3 bp = rotY(rp, sin(_Time.y) * UNITY_PI * 4); bp.y -= h; SurfacePoint bolt = qSub(mCylinder(bp, inner_radius+thread*2, 0.2), bolt_thread); bolt = qUnion(bolt, mRoundedHex(bp - float3(0, 0.13, 0), girth, height)); bolt = qUnion(bolt, mCylinder(bp - float3(0, -0.17, 0), inner_radius , 0.1), 0.05); Material metal1 = mat(float3(0.5, 0.3, 0.1), 1); Material metal2 = mat(float3(0.3, 0.3, 0.5), 1); d.mat = metal1; bolt.mat = metal2; // cube // float3 cp = rotX(bp - float3(0, -0.32, 0), _Time.w * 5); // bolt = qUnion(bolt, mBox(cp, 0.1, mat(float3(0,1,1))),.1); d = qUnion(d, bolt); // floor // d = qUnion(d, mPlaneY(p, -0.5, mat(floor_col, 0)), 0.01); // d = qIntersect(d, mPlaneY(-p, 0.6, mat(floor_col, 0)), 0.01); d = qUnion(d, mBox(p - float3(0, -0.6, 0), float3(6, 0.05, 6), mat(floor(p), 0))); // d = qUnion(d, mSphere(p - float3(0, -0.5, 1), 0.4)); return d; } float3 lighting(Ray ray) { float3 sun_dir = normalize(float3(4, 2, 1)); if (ray.missed) { if (ray.dir.y >= 0) { return lRenderSky(ray.dir, sun_dir); } else { float3 cam = ray.start; cam.y += 0.6 - 0.0275; float3 dir = ray.dir; float3 surface_pos = float3 ( cam.x - cam.y / (dir.y / dir.x), 0, cam.z - cam.y / (dir.y / dir.z) ); float col = 1; col = floor(surface_pos); return col * (lSky(float3(0,1,0)) + lSun(float3(0,1,0), sun_dir)); } } float3 col = 0; col = // ray.mat.col * lSun(ray.normal, sun_dir); col *= lShadow(ray.hit_pos + ray.normal * SURF_DIST, sun_dir, 50); col += // ray.mat.col * lSky(ray.normal); // float3(0.5, 0.8, 0.9); // col = ray.mat.col; return col*ray.mat.col; } ENDCG } } }