Skip to main content

sphereSDF: Three-Dimensional Spherical Distance Field

Fundamental 3D Primitive with Radial Distance

The sphereSDF function computes the signed distance from any 3D point to a spherical surface. This essential 3D primitive provides both unit spheres and custom-radius spheres, forming the foundation for many organic and geometric forms.

Mathematical Foundation

The sphere SDF uses the Euclidean distance formula:

dsphere(p)=pd_{\text{sphere}}(p) = \|p\|

For spheres with custom radius, the formula becomes:

dsphere(p,s)=psd_{\text{sphere}}(p, s) = \|p\| - s

where ss represents the sphere radius.

Function Signatures

sphereSDF (Unit Sphere)

ParameterTypeDescription
pvec3Sample point position

sphereSDFRadius (Custom Radius)

ParameterTypeDescription
pvec3Sample point position
sfloatSphere radius

Implementation Demonstrations

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