|
| 1 | +// authoring credit to inigo Quilez |
| 2 | +// from https://iquilezles.org/articles/distfunctions/ |
| 3 | + |
| 4 | + |
| 5 | +// Sphere - exact (https://www.shadertoy.com/view/Xds3zN) |
| 6 | +float sdSphere( vec3 p, float s ) |
| 7 | +{ |
| 8 | + return length(p)-s; |
| 9 | +} |
| 10 | + |
| 11 | + |
| 12 | +// Box - exact (Youtube Tutorial with derivation: https://www.youtube.com/watch?v=62-pRVZuS5c) |
| 13 | +float sdBox( vec3 p, vec3 b ) |
| 14 | +{ |
| 15 | + vec3 q = abs(p) - b; |
| 16 | + return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0); |
| 17 | +} |
| 18 | + |
| 19 | + |
| 20 | +// Round Box - exact |
| 21 | +float sdRoundBox( vec3 p, vec3 b, float r ) |
| 22 | +{ |
| 23 | + vec3 q = abs(p) - b; |
| 24 | + return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r; |
| 25 | +} |
| 26 | + |
| 27 | + |
| 28 | +// Box Frame - exact (https://www.shadertoy.com/view/3ljcRh) |
| 29 | +float sdBoxFrame( vec3 p, vec3 b, float e ) |
| 30 | +{ |
| 31 | + p = abs(p )-b; |
| 32 | + |
| 33 | + vec3 q = abs(p+e)-e; |
| 34 | + |
| 35 | + return min(min( |
| 36 | + length(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0), |
| 37 | + length(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)), |
| 38 | + length(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0)); |
| 39 | +} |
| 40 | + |
| 41 | + |
| 42 | +// Torus - exact |
| 43 | +float sdTorus( vec3 p, vec2 t ) |
| 44 | +{ |
| 45 | + vec2 q = vec2(length(p.xz)-t.x,p.y); |
| 46 | + return length(q)-t.y; |
| 47 | +} |
| 48 | + |
| 49 | + |
| 50 | +// Capped Torus - exact (https://www.shadertoy.com/view/tl23RK) |
| 51 | +float sdCappedTorus( vec3 p, vec2 sc, float ra, float rb) |
| 52 | +{ |
| 53 | + p.x = abs(p.x); |
| 54 | + |
| 55 | + float k = (sc.y*p.x>sc.x*p.y) ? dot(p.xy,sc) : length(p.xy); |
| 56 | + return sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb; |
| 57 | +} |
| 58 | + |
| 59 | + |
| 60 | +// Link - exact (https://www.shadertoy.com/view/wlXSD7) |
| 61 | +float sdLink( vec3 p, float le, float r1, float r2 ) |
| 62 | +{ |
| 63 | + vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z ); |
| 64 | + return length(vec2(length(q.xy)-r1,q.z)) - r2; |
| 65 | +} |
| 66 | + |
| 67 | + |
| 68 | +// Infinite Cylinder - exact |
| 69 | +float sdCylinderExact( vec3 p, vec3 c ) |
| 70 | +{ |
| 71 | + return length(p.xz-c.xy)-c.z; |
| 72 | +} |
| 73 | + |
| 74 | + |
| 75 | +// Cone - exact |
| 76 | +float sdConeExact( vec3 p, vec2 c, float h ) |
| 77 | +{ |
| 78 | + // c is the sin/cos of the angle, h is height |
| 79 | + // Alternatively pass q instead of (c,h), |
| 80 | + // which is the point at the base in 2D |
| 81 | + vec2 q = h*vec2(c.x/c.y,-1.0); |
| 82 | + |
| 83 | + vec2 w = vec2( length(p.xz), p.y ); |
| 84 | + vec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 ); |
| 85 | + vec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 ); |
| 86 | + float k = sign( q.y ); |
| 87 | + float d = min(dot( a, a ),dot(b, b)); |
| 88 | + float s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) ); |
| 89 | + return sqrt(d)*sign(s); |
| 90 | +} |
| 91 | + |
| 92 | + |
| 93 | +// Cone - bound (not exact!) |
| 94 | +float sdConeBound( vec3 p, vec2 c, float h ) |
| 95 | +{ |
| 96 | + float q = length(p.xz); |
| 97 | + return max(dot(c.xy,vec2(q,p.y)),-h-p.y); |
| 98 | +} |
| 99 | + |
| 100 | + |
| 101 | +// Infinite Cone - exact |
| 102 | +float sdConeInfiniteExact( vec3 p, vec2 c ) |
| 103 | +{ |
| 104 | + // c is the sin/cos of the angle |
| 105 | + vec2 q = vec2( length(p.xz), -p.y ); |
| 106 | + float d = length(q-c*max(dot(q,c), 0.0)); |
| 107 | + return d * ((q.x*c.y-q.y*c.x<0.0)?-1.0:1.0); |
| 108 | +} |
| 109 | + |
| 110 | + |
| 111 | +// Plane - exact |
| 112 | +float sdPlane( vec3 p, vec3 n, float h ) |
| 113 | +{ |
| 114 | + // n must be normalized |
| 115 | + return dot(p,n) + h; |
| 116 | +} |
| 117 | + |
| 118 | + |
| 119 | +// Hexagonal Prism - exact |
| 120 | +float sdHexPrism( vec3 p, vec2 h ) |
| 121 | +{ |
| 122 | + const vec3 k = vec3(-0.8660254, 0.5, 0.57735); |
| 123 | + p = abs(p); |
| 124 | + p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy; |
| 125 | + vec2 d = vec2( |
| 126 | + length(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x), |
| 127 | + p.z-h.y ); |
| 128 | + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| 129 | +} |
| 130 | + |
| 131 | + |
| 132 | +// Triangular Prism - bound |
| 133 | +float sdTriPrism( vec3 p, vec2 h ) |
| 134 | +{ |
| 135 | + vec3 q = abs(p); |
| 136 | + return max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5); |
| 137 | +} |
| 138 | + |
| 139 | + |
| 140 | +// Capsule / Line - exact |
| 141 | +float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) |
| 142 | +{ |
| 143 | + vec3 pa = p - a, ba = b - a; |
| 144 | + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); |
| 145 | + return length( pa - ba*h ) - r; |
| 146 | +} |
| 147 | + |
| 148 | + |
| 149 | +// Capsule / Line - exact |
| 150 | +float sdVerticalCapsule( vec3 p, float h, float r ) |
| 151 | +{ |
| 152 | + p.y -= clamp( p.y, 0.0, h ); |
| 153 | + return length( p ) - r; |
| 154 | +} |
| 155 | + |
| 156 | + |
| 157 | +// Vertical Capped Cylinder - exact (https://www.shadertoy.com/view/wdXGDr) |
| 158 | +float sdCappedCylinder( vec3 p, float h, float r ) |
| 159 | +{ |
| 160 | + vec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h); |
| 161 | + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| 162 | +} |
| 163 | + |
| 164 | + |
| 165 | +// Arbitrary Capped Cylinder - exact (https://www.shadertoy.com/view/wdXGDr) |
| 166 | +float sdCappedCylinder( vec3 p, vec3 a, vec3 b, float r ) |
| 167 | +{ |
| 168 | + vec3 ba = b - a; |
| 169 | + vec3 pa = p - a; |
| 170 | + float baba = dot(ba,ba); |
| 171 | + float paba = dot(pa,ba); |
| 172 | + float x = length(pa*baba-ba*paba) - r*baba; |
| 173 | + float y = abs(paba-baba*0.5)-baba*0.5; |
| 174 | + float x2 = x*x; |
| 175 | + float y2 = y*y*baba; |
| 176 | + float d = (max(x,y)<0.0)?-min(x2,y2):(((x>0.0)?x2:0.0)+((y>0.0)?y2:0.0)); |
| 177 | + return sign(d)*sqrt(abs(d))/baba; |
| 178 | +} |
| 179 | + |
| 180 | + |
| 181 | +// Rounded Cylinder - exact |
| 182 | +float sdRoundedCylinder( vec3 p, float ra, float rb, float h ) |
| 183 | +{ |
| 184 | + vec2 d = vec2( length(p.xz)-2.0*ra+rb, abs(p.y) - h ); |
| 185 | + return min(max(d.x,d.y),0.0) + length(max(d,0.0)) - rb; |
| 186 | +} |
| 187 | + |
| 188 | + |
| 189 | +// Capped Cone - exact (https://www.shadertoy.com/view/tsSXzK) |
| 190 | +float sdCappedCone( vec3 p, vec3 a, vec3 b, float ra, float rb ) |
| 191 | +{ |
| 192 | + float rba = rb-ra; |
| 193 | + float baba = dot(b-a,b-a); |
| 194 | + float papa = dot(p-a,p-a); |
| 195 | + float paba = dot(p-a,b-a)/baba; |
| 196 | + float x = sqrt( papa - paba*paba*baba ); |
| 197 | + float cax = max(0.0,x-((paba<0.5)?ra:rb)); |
| 198 | + float cay = abs(paba-0.5)-0.5; |
| 199 | + float k = rba*rba + baba; |
| 200 | + float f = clamp( (rba*(x-ra)+paba*baba)/k, 0.0, 1.0 ); |
| 201 | + float cbx = x-ra - f*rba; |
| 202 | + float cby = paba - f; |
| 203 | + float s = (cbx<0.0 && cay<0.0) ? -1.0 : 1.0; |
| 204 | + return s*sqrt( min(cax*cax + cay*cay*baba, |
| 205 | + cbx*cbx + cby*cby*baba) ); |
| 206 | +} |
| 207 | + |
| 208 | + |
| 209 | +// Solid Angle - exact (https://www.shadertoy.com/view/wtjSDW) |
| 210 | +float sdSolidAngle( vec3 p, vec2 c, float ra ) |
| 211 | +{ |
| 212 | + // c is the sin/cos of the angle |
| 213 | + vec2 q = vec2( length(p.xz), p.y ); |
| 214 | + float l = length(q) - ra; |
| 215 | + float m = length(q - c*clamp(dot(q,c),0.0,ra) ); |
| 216 | + return max(l,m*sign(c.y*q.x-c.x*q.y)); |
| 217 | +} |
| 218 | + |
| 219 | + |
| 220 | +// Cut Sphere - exact (https://www.shadertoy.com/view/stKSzc) |
| 221 | +float sdCutSphere( vec3 p, float r, float h ) |
| 222 | +{ |
| 223 | + // sampling independent computations (only depend on shape) |
| 224 | + float w = sqrt(r*r-h*h); |
| 225 | + |
| 226 | + // sampling dependant computations |
| 227 | + vec2 q = vec2( length(p.xz), p.y ); |
| 228 | + float s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y ); |
| 229 | + return (s<0.0) ? length(q)-r : |
| 230 | + (q.x<w) ? h - q.y : |
| 231 | + length(q-vec2(w,h)); |
| 232 | +} |
| 233 | + |
| 234 | + |
| 235 | +// Cut Hollow Sphere - exact (https://www.shadertoy.com/view/7tVXRt) |
| 236 | +float sdCutHollowSphere( vec3 p, float r, float h, float t ) |
| 237 | +{ |
| 238 | + // sampling independent computations (only depend on shape) |
| 239 | + float w = sqrt(r*r-h*h); |
| 240 | + |
| 241 | + // sampling dependant computations |
| 242 | + vec2 q = vec2( length(p.xz), p.y ); |
| 243 | + return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : |
| 244 | + abs(length(q)-r) ) - t; |
| 245 | +} |
| 246 | + |
| 247 | + |
| 248 | +// Death Star - exact (https://www.shadertoy.com/view/7lVXRt) |
| 249 | +float sdDeathStar( vec3 p2, float ra, float rb, float d ) |
| 250 | +{ |
| 251 | + // sampling independent computations (only depend on shape) |
| 252 | + float a = (ra*ra - rb*rb + d*d)/(2.0*d); |
| 253 | + float b = sqrt(max(ra*ra-a*a,0.0)); |
| 254 | + |
| 255 | + // sampling dependant computations |
| 256 | + vec2 p = vec2( p2.x, length(p2.yz) ); |
| 257 | + if( p.x*b-p.y*a > d*max(b-p.y,0.0) ) |
| 258 | + return length(p-vec2(a,b)); |
| 259 | + else |
| 260 | + return max( (length(p )-ra), |
| 261 | + -(length(p-vec2(d,0.0))-rb)); |
| 262 | +} |
| 263 | + |
| 264 | + |
| 265 | +// Round cone - exact |
| 266 | +float sdRoundCone( vec3 p, float r1, float r2, float h ) |
| 267 | +{ |
| 268 | + // sampling independent computations (only depend on shape) |
| 269 | + float b = (r1-r2)/h; |
| 270 | + float a = sqrt(1.0-b*b); |
| 271 | + |
| 272 | + // sampling dependant computations |
| 273 | + vec2 q = vec2( length(p.xz), p.y ); |
| 274 | + float k = dot(q,vec2(-b,a)); |
| 275 | + if( k<0.0 ) return length(q) - r1; |
| 276 | + if( k>a*h ) return length(q-vec2(0.0,h)) - r2; |
| 277 | + return dot(q, vec2(a,b) ) - r1; |
| 278 | +} |
| 279 | + |
| 280 | + |
| 281 | +// Ellipsoid - bound (not exact!) (https://www.shadertoy.com/view/tdS3DG) |
| 282 | +float sdEllipsoid( vec3 p, vec3 r ) |
| 283 | +{ |
| 284 | + float k0 = length(p/r); |
| 285 | + float k1 = length(p/(r*r)); |
| 286 | + return k0*(k0-1.0)/k1; |
| 287 | +} |
| 288 | + |
| 289 | + |
| 290 | +// Revolved Vesica - exact) (https://www.shadertoy.com/view/Ds2czG) |
| 291 | +float sdVesicaSegment( in vec3 p, in vec3 a, in vec3 b, in float w ) |
| 292 | +{ |
| 293 | + vec3 c = (a+b)*0.5; |
| 294 | + float l = length(b-a); |
| 295 | + vec3 v = (b-a)/l; |
| 296 | + float y = dot(p-c,v); |
| 297 | + vec2 q = vec2(length(p-c-y*v),abs(y)); |
| 298 | + |
| 299 | + float r = 0.5*l; |
| 300 | + float d = 0.5*(r*r-w*w)/w; |
| 301 | + vec3 h = (r*q.x<d*(q.y-r)) ? vec3(0.0,r,0.0) : vec3(-d,0.0,d+w); |
| 302 | + |
| 303 | + return length(q-h.xy) - h.z; |
| 304 | +} |
| 305 | + |
| 306 | +// Octahedron - exact (https://www.shadertoy.com/view/wsSGDG) |
| 307 | +float sdOctahedronExact( vec3 p, float s ) |
| 308 | +{ |
| 309 | + p = abs(p); |
| 310 | + float m = p.x+p.y+p.z-s; |
| 311 | + vec3 q; |
| 312 | + if( 3.0*p.x < m ) q = p.xyz; |
| 313 | + else if( 3.0*p.y < m ) q = p.yzx; |
| 314 | + else if( 3.0*p.z < m ) q = p.zxy; |
| 315 | + else return m*0.57735027; |
| 316 | + |
| 317 | + float k = clamp(0.5*(q.z-q.y+s),0.0,s); |
| 318 | + return length(vec3(q.x,q.y-s+k,q.z-k)); |
| 319 | +} |
| 320 | + |
| 321 | + |
| 322 | +// Octahedron - bound (not exact) |
| 323 | +float sdOctahedron( vec3 p, float s) |
| 324 | +{ |
| 325 | + p = abs(p); |
| 326 | + return (p.x+p.y+p.z-s)*0.57735027; |
| 327 | +} |
| 328 | + |
| 329 | + |
| 330 | +// Pyramid - exact (https://www.shadertoy.com/view/Ws3SDl) |
| 331 | +float sdPyramid( vec3 p, float h ) |
| 332 | +{ |
| 333 | + float m2 = h*h + 0.25; |
| 334 | + |
| 335 | + p.xz = abs(p.xz); |
| 336 | + p.xz = (p.z>p.x) ? p.zx : p.xz; |
| 337 | + p.xz -= 0.5; |
| 338 | + |
| 339 | + vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| 340 | + |
| 341 | + float s = max(-q.x,0.0); |
| 342 | + float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| 343 | + |
| 344 | + float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| 345 | + float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| 346 | + |
| 347 | + float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| 348 | + |
| 349 | + return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y)); |
| 350 | +} |
0 commit comments