Skip to content

Advancing GLTF Scenes

Video Lecture

Section Video Links
Advancing GLTF Scenes : Part 1 Advancing GLTF Scenes Advancing GLTF Scenes : Part 1 
Advancing GLTF Scenes : Part 2 Advancing GLTF Scenes Advancing GLTF Scenes : Part 2 

 (Pay Per View)

You can use PayPal to purchase a one time viewing of this video for $1.49 USD.

Pay Per View Terms

  • One viewing session of this video will cost the equivalent of $1.49 USD in your currency.
  • After successful purchase, the video will automatically start playing.
  • You can pause, replay and go fullscreen as many times as needed in one single session for up to an hour.
  • Do not refresh the browser since it will invalidate the session.
  • If you want longer-term access to all videos, consider purchasing full access through Udemy or YouTube Memberships instead.
  • This Pay Per View option does not permit downloading this video for later viewing or sharing.
  • All videos are Copyright © 2019-2025 Sean Bradley, all rights reserved.

Description

With this example, we will improve on our knowledge of Blender, Leva, importing models, the Object3D hierarchy, Environment and introduce the Drei ContactShadows.

The glTF specification provides a way to describe whole scenes which may include a large hierarchy of other 3D objects, as well as lighting, animations, materials, textures, skeletons, morph targets, cameras and even other scenes.

This means that you can create almost your whole scene using a 3D modelling tool such a Blender, and import it into the Three.js scene with much less work that writing it all by hand.

However, while Threejs supports the glTF specification to a very high standard, and many 3D applications such as Blender, Maya, 3DS Max, etc., can also export the many features of glTF, there won't always be 100% compatibility between each implementation since each application is developed independently, uses different teams of people, and follows the priorities of different road maps and end use cases.

So you will have to fill in the gaps regardless. Needless to say, glTF is the best format to use in almost all use-cases where you want to import a model into Three.js.

We will begin this lesson by creating a new model in Blender. If you don't want to create the model in Blender, then you can download the final model as shown in this video from scene.zip. Then extract the contents into the folder ./public/models/.

./src/App.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import {
  Stats,
  OrbitControls,
  Environment,
  ContactShadows,
} from '@react-three/drei'
import { Canvas, useLoader } from '@react-three/fiber'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader'
import { Leva, useControls } from 'leva'

function Model() {
  const { scene } = useLoader(GLTFLoader, '/models/scene.glb')

  const {
    x,
    y,
    z,
    visible,
    color,
    metalness,
    roughness,
    clearcoat,
    clearcoatRoughness,
    transmission,
    ior,
    thickness,
  } = useControls('Suzanne', {
    x: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
    y: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
    z: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
    visible: true,
    color: { value: '#ffbc85' },
    metalness: { value: 0, min: 0, max: 1.0, step: 0.01 },
    roughness: { value: 0, min: 0, max: 1.0, step: 0.01 },
    clearcoat: { value: 1, min: 0, max: 1.0, step: 0.01 },
    clearcoatRoughness: { value: 0, min: 0, max: 1.0, step: 0.01 },
    transmission: { value: 1.0, min: 0, max: 1.0, step: 0.01 },
    ior: { value: 1.74, min: 1, max: 5, step: 0.01 },
    thickness: { value: 3.12, min: 0, max: 5, step: 0.01 },
  })

  return (
    <primitive
      object={scene}
      children-0-rotation={[x, y, z]}
      children-0-visible={visible}
      children-0-material-color={color}
      children-0-material-metalness={metalness}
      children-0-material-roughness={roughness}
      children-0-material-clearcoat={clearcoat}
      children-0-material-clearcoatRoughness={clearcoatRoughness}
      children-0-material-transmission={transmission}
      children-0-material-ior={ior}
      children-0-material-thickness={thickness}
    />
  )
}

function Env() {
  const { height, radius, scale } = useControls('Ground', {
    height: { value: 10, min: 0, max: 100, step: 1 },
    radius: { value: 115, min: 0, max: 1000, step: 1 },
    scale: { value: 100, min: 0, max: 1000, step: 1 },
  })
  return (
    <Environment
      preset="sunset"
      background
      ground={{
        height: height,
        radius: radius,
        scale: scale,
      }}
    />
  )
}

export default function App() {
  return (
    <>
      <Canvas camera={{ position: [-8, 5, 8] }}>
        <Env />
        <Model />
        <ContactShadows
          scale={150}
          position={[0.33, -0.33, 0.33]}
          opacity={1.5}
        />
        <OrbitControls target={[0, 1, 0]} maxPolarAngle={Math.PI / 2} />
        <Stats />
      </Canvas>
      <Leva collapsed />
    </>
  )
}

Working Example

<>
glTFAdvanced (Working Example) sbedit.net
GLTFLoader threejs.org sbcode.net
MeshPhysicalMaterial threejs.org sbcode.net

GitHub Branch

git clone https://github.com/Sean-Bradley/React-Three-Fiber-Boilerplate.git
cd React-Three-Fiber-Boilerplate
git checkout glTFAdvanced
npm install
npm start