Skip to content


 Zabbix
 Grafana
 Prometheus
 React Three Fiber
 Threejs and TypeScript
 SocketIO and TypeScript
 Blender Topological Earth
 Sweet Home 3D
 Design Patterns Python
 Design Patterns TypeScript
   
 Course Coupon Codes
Three.js and TypeScript
Kindle Edition
$6.99 $9.99 Paperback 
$22.99 $29.99




Design Patterns in TypeScript
Kindle Edition
$6.99 $9.99 Paperback
$11.99 $19.99




Design Patterns in Python
Kindle Edition
$6.99 $9.99 Paperback
$11.99 $19.99




GLTFJSX

Video Lecture

Section Video Links
GLTFJSX : Part 1 GLTFJSX : Part 1 GLTFJSX : Part 1
GLTFJSX : Part 2 GLTFJSX : Part 2 GLTFJSX : Part 2

Description

GLTFJSX is a command line tool that will read through a glTF model, and extract its components into a JSX equivalent.

When each of the components of the model are referenced using JSX it makes it easier to turn the different components on or off or add even more interaction to each.

GLTFJSX is beneficial if your model is quite large and contains many child meshes, lights, materials, animations, etc., and you want to access those individual components within your code to add interactivity, or even only use parts of the original file.

GLTFJSX is not the only way to traverse a model and extract its components for individual use, but it does make it quick and easy to have the JSX automatically created for you.

Resources

The shoe model used in the lesson originally came from the pushmatrix glTF-Sample-Models repository at https://github.com/pushmatrix/glTF-Sample-Models/tree/master/2.0/MaterialsVariantsShoe.

Download shoe-draco.zip and save it into your projects ./public/models/ folder.

After downloading the file and saving it to the correct folder, we will create some JSX from it using the command,

npx gltfjsx .\public\models\shoe-draco.glb

./src/App.jsx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { Canvas } from '@react-three/fiber'
import { OrbitControls, Environment, ContactShadows } from '@react-three/drei'
import { Model } from './Shoe'

export default function App() {
  return (
    <Canvas shadows camera={{ position: [0, 0, 1.66] }}>
      <Environment preset="forest" />
      <Model />
      <ContactShadows position={[0, -0.8, 0]} color="#ffffff" />
      <OrbitControls autoRotate />
    </Canvas>
  )
}

./src/Shoe.jsx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { useEffect, useState } from 'react'
import { useGLTF } from '@react-three/drei'
import { useControls } from 'leva'
import { Color } from 'three'

export function Model() {
  const [hovered, setHovered] = useState(false)
  const { nodes, materials } = useGLTF('./models/shoe-draco.glb')

  useEffect(() => {
    document.body.style.cursor = hovered ? 'pointer' : 'auto'
  }, [hovered])

  useControls('Shoe', () => {
    console.log('creating color pickers')

    // using forEach
    // const colorPickers = {}
    // Object.keys(materials).forEach((m) => {
    //   colorPickers[m] = {
    //     value: '#' + ((Math.random() * 0xffffff) << 0).toString(16).padStart(6, '0'),
    //     onChange: (v) => {
    //       materials[m].color = new Color(v)
    //     }
    //   }
    // })
    // return colorPickers

    // using reduce
    return Object.keys(materials).reduce(
      (acc, m) =>
        Object.assign(acc, {
          [m]: {
            value:
              '#' +
              ((Math.random() * 0xffffff) << 0).toString(16).padStart(6, '0'),
            onChange: (v) => {
              materials[m].color = new Color(v)
            },
          },
        }),
      {}
    )
  })

  // JSX of glTF created using the command
  // npx gltfjsx .\public\models\shoe-draco.glb

  return (
    <group
      dispose={null}
      onPointerOver={() => setHovered(true)}
      onPointerOut={() => setHovered(false)}
      onClick={(e) => {
        e.stopPropagation()
        document.getElementById('Shoe.' + e.object.material.name).focus()
      }}
    >
      <mesh geometry={nodes.shoe.geometry} material={materials.laces} />
      <mesh geometry={nodes.shoe_1.geometry} material={materials.mesh} />
      <mesh geometry={nodes.shoe_2.geometry} material={materials.caps} />
      <mesh geometry={nodes.shoe_3.geometry} material={materials.inner} />
      <mesh geometry={nodes.shoe_4.geometry} material={materials.sole} />
      <mesh geometry={nodes.shoe_5.geometry} material={materials.stripes} />
      <mesh geometry={nodes.shoe_6.geometry} material={materials.band} />
      <mesh geometry={nodes.shoe_7.geometry} material={materials.patch} />
    </group>
  )
}

useGLTF.preload('./models/shoe-draco.glb')

Compression

Another benefit of the GLTFJSX tool is that it can compress a large glTF file quickly and effectively. Use the -T option. E.g.,

npx gltfjsx ./my-very-large-gltf-file.glb -T

This will compress the file using the Draco compression algorithm. I used this tool to compress the house model from my House example from 9Mb to 1.5Mb.

R3F Shoe Configurator codesandbox.io
GLTFJSX github.com/pmndrs
glTF Sample Models github.com/pushmatrix

Working Example