Skip to main content

octogonPrismSDF: Regular Octagonal Prism Distance Field

Eight-Sided Polygonal Extrusion with Geometric Precision

The octogonPrismSDF function computes the signed distance to a regular octagonal prism. This geometry features eight equal sides arranged in a regular octagon, extruded to a specified height. The function uses reflection operations to construct the octagonal cross-section efficiently.

Mathematical Foundation

The octagon construction employs reflection planes defined by precise geometric constants:

k=(0.92387953250.38268343230.4142135623)\vec{k} = \begin{pmatrix} -0.9238795325 \\ 0.3826834323 \\ 0.4142135623 \end{pmatrix}

The distance calculation involves multiple reflection operations:

pxypxy2min(kxypxy,0)kxy\vec{p}_{xy} \leftarrow \vec{p}_{xy} - 2 \min(\vec{k}_{xy} \cdot \vec{p}_{xy}, 0) \vec{k}_{xy}

Where the reflection process creates the eight-fold symmetry characteristic of regular octagons.

Function Signature

ParameterTypeDescription
pvec3Sample point position
rfloatOctagon radius (circumradius)
hfloatPrism height (half-height from center)

Implementation Demonstrations

Live Editor
const fragment = () => {
      const up = vec3(0, 1, 0)
      const eps = vec3(0.01, 0, 0)
      const eye = rotate3dY(iTime).mul(vec3(5))
      const args = [1.2, 0.8]
      const march = Fn(([eye, dir]: [Vec3, Vec3]) => {
              const p = eye.toVar()
              const d = octogonPrismSDF(p, ...args).toVar()
              Loop(16, ({ i }) => {
                      If(d.lessThanEqual(eps.x), () => {
                              const dx = octogonPrismSDF(p.add(eps.xyy), ...args).sub(d)
                              const dy = octogonPrismSDF(p.add(eps.yxy), ...args).sub(d)
                              const dz = octogonPrismSDF(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(octogonPrismSDF(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)
}