npx gltfjsx
An experimental tool that turns GLTF's files into react-three-fiber-JSX components.
npx gltfjsx input.gltf [Output.js] [options]
Options:
--draco, -d adds DRACOLoader [string] [default: "/draco-gltf/"]
--animation, -a extracts animation clips [boolean]
--help Show help [boolean]
--version Show version number [boolean]
You need to be set up for asset loading and the actual GLTF has to be present in your /public folder. This tools loads it, creates a hashmap of all the objects inside and writes out a JSX tree which you can now freely alter.
A typical output looks like this:
import React from 'react'
import { useLoader } from 'react-three-fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
export default function Model(props) {
const gltf = useLoader(GLTFLoader, '/scene.glb')
return (
<group {...props}>
<scene name="Scene">
<mesh name="Cube000" position={[0.3222085237503052, 2.3247640132904053, 10.725556373596191]}>
<bufferGeometry attach="geometry" {...gltf.__$[1].geometry} />
<meshStandardMaterial attach="material" {...gltf.__$[1].material} name="sillones" />
</mesh>
</scene>
</group>
)
}
This component suspends, so you must wrap it into <Suspense />
for fallbacks and, optionally, error-boundaries for error handling:
<ErrorBoundary>
<Suspense fallback={<Fallback />}>
<Model />
</Suspense>
</ErrorBoundary>
--draco
Adds a DRACOLoader, for which you need to be set up. The necessary files have to exist in your /public folder. It defaults to /draco-gltf/
which should contain dracos gltf decoder.
It will then extend the loader-section:
const gltf = useLoader(GLTFLoader, '/stork.glb', loader => {
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('/draco-gltf/')
loader.setDRACOLoader(dracoLoader)
})
--animation
If your GLTF contains animations it will add a THREE.AnimationMixer to your component and extract the clips:
const actions = useRef()
const [mixer] = useState(() => new THREE.AnimationMixer())
useFrame((state, delta) => mixer.update(delta))
useEffect(() => {
actions.current = { storkFly_B_: mixer.clipAction(gltf.animations[0]) }
return () => gltf.animations.forEach(clip => mixer.uncacheClip(clip))
}, [])
If you want to play an animation you can do so at any time:
<mesh onClick={e => actions.current.storkFly_B_.play()} />