Skip to content

Mesh

import { Mesh } from '../lib/fabric'
<Mesh url="/models/robot.glb" scale={0.5} autoPlay material={{ shader: 'phong' }} />
PropTypeDefaultNotes
urlstringA .glb — standard glTF 2.0, no Draco or Meshopt
position[x, y, z][0, 0, 0]Applied once at mount
rotation[x, y, z][0, 0, 0]Degrees, applied once at mount
scalenumber or [x, y, z]1Applied once at mount
materialMeshMaterialReactive — each option may be a signal and re-applies on change
autoPlaystring, true, or () => string | true | undefinedClip name, first clip, or a thunk resolved each frame
animation{ clip: string, time: PhotonValue }Drives a morph-target clip from an animated time value

autoPlay as a thunk lets a flux accessor choose the clip at runtime without remounting. Returning '' or undefined pauses. The clock restarts whenever the active clip changes, so a switch mid-playback starts the new clip from zero.

Mesh materials are a separate set from shape materials, with overlapping names.

OptionTypeDefaultNotes
shader'lambert' | 'phong' | 'glass'lambert
colorstringOverrides vertex colour and texture when set
ambientnumber0.2
shininessnumber32phong
roughnessnumber0Normal bumping; on glass, background blur
roughnessScalenumber0.5Bump frequency, normalised to the mesh’s extent so it means the same on any GLB

Glass options match the shape glass set — ior, fresnel, fresnelColor, thickness, chromaticAberration, attenuationDistance, attenuationColor, distortion, distortionScale, temporalDistortion, anisotropy, anisotropyRotation, anisotropyBlur, metalness, grain, grainScale, iridescence, iridescenceThickness, clearcoat, clearcoatRoughness, sheen, sheenColor, reflection, reflectionRoughness, gloss, glossSharpness, glossCoverage — see Materials › glass for each — with these differences:

OptionTypeDefaultNotes
thicknessnumber1On a mesh this scales the measured back-face distance; 1 is physical. Under refraction: 'slab' it is a distance in world units instead
outlinenumber0Silhouette darkening
outlineSoftnessnumber0.20 tight rim, 1 broad gradient
silhouetteAAnumber1.5Edge fade width in screen pixels; 0 hard
silhouetteFloornumber0Minimum alpha at the silhouette; 1 disables the fade
silhouetteInsetnumber0Extra inward fade, as a fraction of the rim

Everything is lazy. <Mesh> imports the loader and the mesh engine on mount, fetches the GLB, builds the pipeline, uploads the buffers, applies the bind-pose skinning, then applies the material and starts playback. A scene without a <Mesh> ships none of it.