Hello!
I am working on learning react-three/fiber, and am trying to create a JSX component from a gltf Blender file.
First, I enter this command in the terminal to convert the file to gltf:
gltf-pipeline -i Monkey.glb -o Monkey.gltf
After that I enter this command to convert it to a JSX file:
npx gltfjsx public/models/Monkey.gltf
However, the animations still don’t appear as part of the JSX file as I’ve seen on some tutorials:
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx gltfjsx@6.2.12 public/models/Monkey.gltf
*/
import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'
export function Model(props) {
const { nodes, materials } = useGLTF('/Monkey.gltf')
return (
<group {...props} dispose={null}>
<group position={[0, 2.829, 0]} scale={1.288}>
<primitive object={nodes.spine0} />
<primitive object={nodes.legIK} />
<primitive object={nodes.legIKRight} />
<primitive object={nodes.legIKLeft} />
<skinnedMesh geometry={nodes.Cube_1.geometry} material={materials.Material} skeleton={nodes.Cube_1.skeleton} />
<skinnedMesh geometry={nodes.Cube_2.geometry} material={materials['Material.003']} skeleton={nodes.Cube_2.skeleton} />
<skinnedMesh geometry={nodes.Cube002_1.geometry} material={materials.Material} skeleton={nodes.Cube002_1.skeleton} />
<skinnedMesh geometry={nodes.Cube002_2.geometry} material={materials['Material.003']} skeleton={nodes.Cube002_2.skeleton} />
<skinnedMesh geometry={nodes.Cube005_1.geometry} material={materials.Material} skeleton={nodes.Cube005_1.skeleton} />
<skinnedMesh geometry={nodes.Cube005_2.geometry} material={materials['Material.003']} skeleton={nodes.Cube005_2.skeleton} />
<skinnedMesh geometry={nodes.Cube006.geometry} material={materials.Material} skeleton={nodes.Cube006.skeleton} />
<skinnedMesh geometry={nodes.Cube006_1.geometry} material={materials['Material.003']} skeleton={nodes.Cube006_1.skeleton} />
</group>
</group>
)
}
My options in Blender for exporting the file show this:
If you have any suggestions on what is preventing the animations from automatically showing up as a part of the JSX code upon execution of the gltfjsx command, please let me know!
Thank you!
drcmda
August 29, 2023, 3:36pm
2
imo you should never use gltf on the web, you dont need gltf-pipeline. just this
npx gltfjsx yourfile.gltf --transform
and it will create a compressed glb. as to why keyframes aren’t in it, that must have something to do with blender. animations never show up in jsx btw, all it will do is add a useAnimations hook.
1 Like
Hi, drcmda!
Out of curiosity, what are the downsides to using gltf files on the web?
In that case, I will look around to find out how to useAnimations hook.
Thank you for letting me know!
So I converted the glb file exported from Blender directly to a jsx file using the command you provided, and the useAnimation hook was mentioned right there in the file!
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx gltfjsx@6.2.12 Monkey.glb --transform
Files: Monkey.glb [225.68KB] > Monkey-transformed.glb [96.22KB] (57%)
*/
import React, { useRef } from 'react'
import { useGLTF, useAnimations } from '@react-three/drei'
export function Monkey(props) {
const group = useRef()
const { nodes, materials, animations } = useGLTF('/Monkey-transformed.glb')
const { actions } = useAnimations(animations, group)
return (
<group ref={group} {...props} dispose={null}>
<group name="Scene">
<group name="Armature" position={[0, 2.829, 0]} scale={1.288}>
<primitive object={nodes.spine0} />
<primitive object={nodes.legIK} />
<primitive object={nodes.legIKRight} />
<primitive object={nodes.legIKLeft} />
</group>
<group name="Cube" position={[0, 2.829, 0]} scale={1.288}>
<skinnedMesh name="Cube_1" geometry={nodes.Cube_1.geometry} material={materials.PaletteMaterial001} skeleton={nodes.Cube_1.skeleton} />
<skinnedMesh name="Cube_2" geometry={nodes.Cube_2.geometry} material={materials.PaletteMaterial002} skeleton={nodes.Cube_2.skeleton} />
</group>
<group name="Cube002" position={[0, 2.829, 0]} scale={1.288}>
<skinnedMesh name="Cube002_1" geometry={nodes.Cube002_1.geometry} material={materials.PaletteMaterial001} skeleton={nodes.Cube002_1.skeleton} />
<skinnedMesh name="Cube002_2" geometry={nodes.Cube002_2.geometry} material={materials.PaletteMaterial002} skeleton={nodes.Cube002_2.skeleton} />
</group>
<group name="Cube004" position={[0, 2.829, 0]} scale={1.288}>
<skinnedMesh name="Cube005_1" geometry={nodes.Cube005_1.geometry} material={materials.PaletteMaterial001} skeleton={nodes.Cube005_1.skeleton} />
<skinnedMesh name="Cube005_2" geometry={nodes.Cube005_2.geometry} material={materials.PaletteMaterial002} skeleton={nodes.Cube005_2.skeleton} />
</group>
<group name="Cube005" position={[0, 2.829, 0]} scale={1.288}>
<skinnedMesh name="Cube006" geometry={nodes.Cube006.geometry} material={materials.PaletteMaterial001} skeleton={nodes.Cube006.skeleton} />
<skinnedMesh name="Cube006_1" geometry={nodes.Cube006_1.geometry} material={materials.PaletteMaterial002} skeleton={nodes.Cube006_1.skeleton} />
</group>
</group>
</group>
)
}
useGLTF.preload('/Monkey-transformed.glb')
Thank you!
drcmda
August 30, 2023, 9:12am
5
gltf is big and refers to external files. glb is small and everything is contained in a single file.
1 Like
drcmda
August 30, 2023, 9:13am
6
right, so all you have to do now is
export function Monkey(props) {
const group = useRef()
const { nodes, materials, animations } = useGLTF('/Monkey-transformed.glb')
const { actions } = useAnimations(animations, group)
useEffect(() => {
actions.actionName.play()
}, [])
return (
<group ref={group} {...props} dispose={null}>
..
gltfjsx should have also compressed the model, /Monkey-transformed.glb should be considerably smaller.
1 Like
Minor thing – there shouldn’t be a size difference unless you’re using the “glTF Embedded” mode (e.g. in Blender) that tries to pack all the data into a single .gltf
file with Base64 strings… but I agree with @drcmda – .glb
is usually a better choice, unless you’re working with more advanced situations like sharing textures across multiple glTF files.
1 Like
So if it was a more advanced project, it would be better to choose the gltf Separate?
No, I guess I mean that there are certain less common cases where you might want glTF Separate. If you don’t already know you have one of those rare cases, best to stick with GLB as the default.
1 Like