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

boxFrameSDF: Three-Dimensional Hollow Frame Distance Field

Architectural Border Structure in Signed Distance Space

The boxFrameSDF function computes the signed distance to a hollow box frame structure. This primitive creates a border-only box geometry where the interior is carved out, useful for wireframe visualizations and architectural elements.

Mathematical Foundation

The box frame SDF operates through coordinate manipulation and selective edge computation:

dframe=min{dx,dy,dz}d_{\text{frame}} = \min\{d_x, d_y, d_z\}

where each component evaluates the distance along one primary axis:

dx=max(px,0)+min(max(px,max(qy,qz)),0)d_x = \|max(\vec{p}_x, 0)\| + \min(\max(p_x, \max(q_y, q_z)), 0)

The transformation q=p+ee\vec{q} = ||\vec{p} + e|| - e creates the interior cutout where ee defines the frame thickness.

Function Signature

ParameterTypeDescription
pvec3Sample point position
bvec3Box half-extents (width, height, depth)
efloatFrame thickness parameter

Implementation Demonstrations

ライブエディター
const fragment = () => {
      const up = vec3(0, 1, 0)
      const eps = vec3(0.01, 0, 0)
      const eye = rotate3dY(iTime).mul(vec3(5))
      const args = [vec3(1), 0.1]
      const march = Fn(([eye, dir]: [Vec3, Vec3]) => {
              const p = eye.toVar()
              const d = boxFrameSDF(p, ...args).toVar()
              Loop(16, ({ i }) => {
                      If(d.lessThanEqual(eps.x), () => {
                              const dx = boxFrameSDF(p.add(eps.xyy), ...args).sub(d)
                              const dy = boxFrameSDF(p.add(eps.yxy), ...args).sub(d)
                              const dz = boxFrameSDF(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(boxFrameSDF(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)
}