GLTF sample models
Three.js documentation
- MeshStandardMaterial
- DirectionalLight
- WebGLRenderer
- GLTFLoader
- DRACOLoader
- CubeTextureLoader
- Scene
- Mesh
- Object3D
- Group
- CameraHelper
Others
Shortcuts ⌨️
SPACE
to play / pauseARROW RIGHT
orL
to go forwardARROW LEFT
orJ
to go backwardARROW UP
to increase volumeARROW DOWN
to decrease volumeF
to toggle fullscreenM
to toggle mute0 to 9
to go to the corresponding part of the videoSHIFT
+,
to decrease playback speedSHIFT
+.
or;
to increase playback speed
Want to learn more? 🤘
That's the end of the free part 😔
To get access to 71 hours of video, a members-only Discord server and future updates, join us for only $95!
Realistic render
Difficulty Hard
Introduction 00:00
When we imported our hamburger in the previous lesson, the colors were off. To put it in a nutshell: many things participate in a wrong looking model.
Sometimes, we want a very realistic render. Maybe it's because we want to showcase a real-life product on our website. Or perhaps we are 3D artists, and we want to show off our work with the best possible result. Anyway, we need a render as real as possible.
In this lesson, we will learn many techniques to improve our model looks once rendered in Three.js. Be careful though, some of those techniques can have a performance impact, and some techniques depend on your model. You'll have to adapt according to the situation.
Setup 01:04
We could use our hamburger, but it's better to try a more realistic model with textures, normal maps, etc. We will use the Flight Helmet from the GLTF Sample Models repository. You can find the model in the /static/models/
folder.
This lesson is also the perfect opportunity to revise what we already learned. That is why there isn't much code in the starter. We will have to instantiate the loaders, the lights, the shadows, etc., all by ourselves.
We will also use Dat.GUI to tweak as many parameters as possible. That is required if we want to create the perfect environment.
For now, all we have in our scene is a white sphere and an instance of Dat.GUI.
This sphere is just a placeholder to make sure that the starter is working, but we can use it to set up the lights. Change the material of testSphere
to MeshStandardMaterial to see the lights we are about to add:
const testSphere = new THREE.Mesh(
new THREE.SphereGeometry(1, 32, 32),
new THREE.MeshStandardMaterial()
)
As you can see, everything has gone black.
Lights 02:18
We are going to use only one DirectionalLight. But how can we have a realistic render with only one light? The environment map will do most of the heavy leverage and simulate light bounce. We could get rid of any light, but the DirectionalLight is important if we want to have more control over the lighting but also to create shadows:
const directionalLight = new THREE.DirectionalLight('#ffffff', 1)
directionalLight.position.set(0.25, 3, - 2.25)
scene.add(directionalLight)
Let's add some parameters to our Dat.GUI:
gui.add(directionalLight, 'intensity').min(0).max(10).step(0.001).name('lightIntensity')
gui.add(directionalLight.position, 'x').min(- 5).max(5).step(0.001).name('lightX')
gui.add(directionalLight.position, 'y').min(- 5).max(5).step(0.001).name('lightY')
gui.add(directionalLight.position, 'z').min(- 5).max(5).step(0.001).name('lightZ')
We can now control the position
and intensity
.
Default Three.js light intensity values aren't realistic. They are based on an arbitrary scale unit and don't reflect real-world values. You could say it doesn't matter, but it's better to base our scene on realistic and standard values. It might be more comfortable to reproduce real-life conditions that way.
To change Three.js lights for more realistic values, switch the physicallyCorrectLights
property of the WebGLRenderer instance (the renderer
) to true
:
renderer.physicallyCorrectLights = true
Our light appears dimmed. Let's increase its intensity to 3
:
const directionalLight = new THREE.DirectionalLight('#ffffff', 3)
Model 08:31
Let's load our model instead of that test sphere.
First, instantiate the GLTFLoader. We will regroup the different loaders together. There is no particular reason for that but to regroup things together:
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
// ...
/**
* Loaders
*/
const gltfLoader = new GLTFLoader()
We don't need the DRACOLoader because the model isn't compressed. But if you load a Draco compressed model, instantiate the DRACOLoader as we did in a previous lesson.
We can now load our model located in /static/models/FlightHelmet/glTF/FlightHelmet.gltf
:
/**
* Models
*/
gltfLoader.load(
'/models/FlightHelmet/glTF/FlightHelmet.gltf',
(gltf) =>
{
console.log('success')
console.log(gltf)
}
)
As always, go slow, make sure that the model is well loaded with no error, and study the imported result.
Because it's a complex model, we will simply add the gltf.scene
group to our own scene:
gltfLoader.load(
'/models/FlightHelmet/glTF/FlightHelmet.gltf',
(gltf) =>
{
scene.add(gltf.scene)
}
)
If you can't see it but don't get any error, Remove your testSphere
and zoom a little. The explanation is simple: the loaded model is too small.
Increase its scale, move it down a little, and rotate it so it fits our camera view better:
gltfLoader.load(
'/models/FlightHelmet/glTF/FlightHelmet.gltf',
(gltf) =>
{
gltf.scene.scale.set(10, 10, 10)
gltf.scene.position.set(0, - 4, 0)
gltf.scene.rotation.y = Math.PI * 0.5
scene.add(gltf.scene)
}
)
Let's also add a tweak to rotate the whole model in our Dat.GUI:
gltfLoader.load(
'/models/FlightHelmet/glTF/FlightHelmet.gltf',
(gltf) =>
{
// ...
gui.add(gltf.scene.rotation, 'y').min(- Math.PI).max(Math.PI).step(0.001).name('rotation')
}
)
How to use it 🤔
-
Download the
Starter pack
or
Final project
(if your browser detects a menace, do not worry, it is not) - Unzip it
- Open your terminal and go to the unzip folder
-
Run
npm install
to install dependencies
(if your terminal warn you about vulnerabilities, ignore it) -
Run
npm run dev
to launch the local server
(your browser should start automatically) - Start coding
- The JS is located in src/script.js
- The HTML is located in src/index.html
- The CSS is located in src/style.css