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




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

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/examples/jsm/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 />
    </>
  )
}
GLTFLoader threejs.org sbcode.net
MeshPhysicalMaterial threejs.org sbcode.net

Working Example