#define _MAT_VARIANT1(NEW_NAME, BASE_FN, TYPE_1, ARG_1) \ SurfacePoint NEW_NAME(float3 p, TYPE_1 ARG_1, Material mat = DEFAULT_MAT) {\ SurfacePoint o;\ o.dist = BASE_FN(p, ARG_1);\ o.mat = mat;\ return o;\ } #define _MAT_VARIANT2(NEW_NAME, BASE_FN, TYPE_1, ARG_1, TYPE_2, ARG_2) \ SurfacePoint NEW_NAME(float3 p, TYPE_1 ARG_1, TYPE_2 ARG_2, Material mat = DEFAULT_MAT) {\ SurfacePoint o;\ o.dist = BASE_FN(p, ARG_1, ARG_2);\ o.mat = mat;\ return o;\ } #define _MAT_VARIANT3(NEW_NAME, BASE_FN, TYPE_1, ARG_1, TYPE_2, ARG_2, TYPE_3, ARG_3) \ SurfacePoint NEW_NAME(float3 p, TYPE_1 ARG_1, TYPE_2 ARG_2, TYPE_3 ARG_3, Material mat = DEFAULT_MAT) {\ SurfacePoint o;\ o.dist = BASE_FN(p, ARG_1, ARG_2, ARG_3);\ o.mat = mat;\ return o;\ } // // Most of these are taken from https://iquilezles.org/articles/distfunctions/ // Thank you Inigo Quilez <3 float sdBox(float3 p, float3 size) { float3 q = abs(p) - size / 2.0; return length(max(q, 0)) + min(max(q.x, max(q.y, q.z)), 0); } _MAT_VARIANT1(mBox, sdBox, float3, size) float sdSphere(float3 p, float radius) { return length(p) - radius; } _MAT_VARIANT1(mSphere, sdSphere, float, radius) float sdTorus(float3 p, float radius, float thickness) { float2 q = float2(length(p.xz) - radius, p.y); return length(q) - thickness; } _MAT_VARIANT2(mTorus, sdTorus, float, radius, float, thickness) float sdPlaneY(float3 p, float height) { return p.y - height; } _MAT_VARIANT1(mPlaneY, sdPlaneY, float, height) float sdHexPrism(float3 p, float width, float height) { const float3 k = float3(-0.8660254, 0.5, 0.57735); p = abs(p); p.xz -= 2.0 * min(dot(k.xy, p.xz), 0) * k.xy; float2 d = float2(length(p.xz - float2(clamp(p.x,-k.z * width, k.z * width), width)) * sign(p.z - width), p.y - height); return min(max(d.x, d.y), 0) + length(max(d, 0)); } _MAT_VARIANT2(mHexPrism, sdHexPrism, float, width, float, height) float sdInfCylinder(float3 p, float3 c) { return length(p.xz - c.xy) - c.z; } _MAT_VARIANT1(mInfCylinder, sdInfCylinder, float3, c) float sdCylinder(float3 p, float r, float h) { float2 d = abs(float2(length(p.xz), p.y)) - float2(r, h); return min(max(d.x, d.y), 0) + length(max(d, 0)); } _MAT_VARIANT2(mCylinder, sdCylinder, float, r, float, h) float sdHelix(float3 p, float r1, float r2, float incline) { float x2 = length(p.xz) - r1; // vertical plane float angle = atan2(p.z, p.x); // angle around y axis float y = angle * incline - p.y; y = fmod(y, UNITY_PI * incline * 2) + UNITY_PI * incline; return length(float2(x2, y)) - r2; } _MAT_VARIANT3(mHelix, sdHelix, float, r1, float, r2, float, incline) float sdLine(float3 p, float3 a, float3 b, float r) { float3 pa = p - a; float3 ba = b - a; float h = clamp(dot(pa, ba) / dot(ba, ba), 0, 1); return length(p- a - (b-a) * h) - r; } _MAT_VARIANT3(mLine, sdLine, float3, a, float3, b, float3, r) SurfacePoint mDummy(float d, Material mat = DEFAULT_MAT) { SurfacePoint o; o.dist = d; o.mat = mat; return o; }