メインコンテンツまでスキップ

tetrahedronSDF: Regular Tetrahedron Distance Field

Four-Faced Platonic Solid Geometry​

The tetrahedronSDF function computes the signed distance from any 3D point to a regular tetrahedron. This primitive represents the simplest of the Platonic solids, featuring four triangular faces meeting at each vertex with perfect symmetry.

Mathematical Foundation​

The tetrahedron SDF calculation involves distance computation from multiple planes:

d1=∣qz∣−max⁡(0,y)d_1 = |q_z| - \max(0, y) d2=max⁡(0.5∣qx∣+0.5y,0)−min⁡(h,h+y)d_2 = \max(0.5|q_x| + 0.5y, 0) - \min(h, h + y) dtetrahedron=length(max⁡(d⃗,0.005))+min⁡(max⁡(d1,d2),0)d_{\text{tetrahedron}} = \text{length}(\max(\vec{d}, 0.005)) + \min(\max(d_1, d_2), 0)

where q⃗=∣p∣\vec{q} = |p| represents the absolute coordinates and y=pyy = p_y is the vertical component.

Function Signature​

ParameterTypeDescription
pvec3Sample point position
hfloatTetrahedron height parameter

Implementation Demonstrations​

ライブエディター

const fragment = () => {
      const up = vec3(0, 1, 0)
      const eps = vec3(0.01, 0, 0)
      const eye = rotate3dX(iTime).mul(vec3(4))
      const args = [0.5]
      const march = Fn(([eye, dir]: [Vec3, Vec3]) => {
              const p = eye.toVar()
              const d = tetrahedronSDF(p, ...args).toVar()
              Loop(128, ({ i }) => {
                      If(d.lessThanEqual(eps.x), () => {
                              const dx = tetrahedronSDF(p.add(eps.xyy), ...args).sub(d)
                              const dy = tetrahedronSDF(p.add(eps.yxy), ...args).sub(d)
                              const dz = tetrahedronSDF(p.add(eps.yyx), ...args).sub(d)
                              return vec4(vec3(dx, dy, dz).normalize().mul(0.5).add(0.5), 1)
                      })
                      p.addAssign(d.mul(dir))
                      d.assign(tetrahedronSDF(p, ...args))
              })
              return vec4(0)
      })
      const z = eye.negate().normalize()
      const x = z.cross(up)
      const y = x.cross(z)
      const scr = vec3(uv.sub(0.5), 2)
      const dir = mat3(x, y, z).mul(scr).normalize()
      return march(eye, dir)
}
結果
Loading...