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

gearSDF: Parametric Mechanical Gear Distance Field

Complex Radial Tooth Geometry Through Hyperbolic Functions

The gearSDF function generates signed distance fields for mechanical gear shapes with parametrically controlled teeth. The function employs hyperbolic tangent modulation to create precise tooth profiles based on angular position and gear parameters.

Mathematical Foundation

The gear distance calculation combines radial base geometry with hyperbolic tooth modulation:

dgear=dbase+min(dbase,rteeth)d_{\text{gear}} = d_{\text{base}} + \min(d_{\text{base}}, r_{\text{teeth}})

where the base distance is:

dbase=p0.53sd_{\text{base}} = |\vec{p} - 0.5| \cdot 3 - s

and the teeth modulation uses hyperbolic functions:

ω=bsin(Narctan(py,px))\omega = b \cdot \sin(N \cdot \arctan(p_y, p_x)) rteeth=1btanh(2ω)r_{\text{teeth}} = \frac{1}{b} \cdot \tanh(2\omega)

The parameter mapping follows:

s=map(b,1,15,0.066,0.5)s = \text{map}(b, 1, 15, 0.066, 0.5)

Function Signature

ParameterTypeDescription
stvec22D coordinate position
bfloatBase radius and teeth sharpness control
NintNumber of gear teeth

Implementation Demonstrations

ライブエディター
const fragment = () => Scope(() => {
      const gearSystem = float(1000).toVar()
      Loop(4, ({ i }) => {
              const angle = i.toFloat().mul(1.57)
              const offset = vec2(angle.sin().mul(0.25), angle.cos().mul(0.25))
              const rotation = iTime.mul(i.add(1).toFloat())
              const rotatedUV = vec2(
                      uv.x.sub(0.5).mul(rotation.cos()).sub(uv.y.sub(0.5).mul(rotation.sin())).add(0.5),
                      uv.x.sub(0.5).mul(rotation.sin()).add(uv.y.sub(0.5).mul(rotation.cos())).add(0.5)
              )
              const teeth = int(i.mul(2).add(6))
              const size = i.toFloat().mul(0.5).add(2)
              const d = gearSDF(rotatedUV.add(offset), size, teeth)
              gearSystem.assign(gearSystem.min(d))
      })
      const brightness = gearSystem.step(0).mul(0.9).add(float(0.02).smoothstep(0, gearSystem.abs()).mul(0.4))
      return vec4(brightness.mul(vec3(0.7, 0.5, 0.3)), 1)
})