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
GLTF sample models
Three.js documentation
- MeshStandardMaterial
- DirectionalLight
- WebGLRenderer
- GLTFLoader
- DRACOLoader
- CubeTextureLoader
- Scene
- Mesh
- Object3D
- Group
- CameraHelper
Others
Shortcuts ⌨️
⚠️ Update
In the latest versions of Three.js, lights require a higher intensity
:
const directionalLight = new THREE.DirectionalLight('#ffffff', 6)
The result will look slightly more realistic. Don’t be surprised if it’s not the exact same colors as in the video.
⚠️ Update
In the latest versions of Three.js, the intensity of the environment map is set directly on scene.environmentIntensity
.
For this reasons, updateAllMaterials
isn’t doing anything anymore, but I kept the function with the traverse(…)
so that you can still add what’s following in the video.
Unlock content 🔓
To get access to 93 hours of video, a members-only Discord server, subtitles, lesson resources, future updates and much more join us for only $95!
Want to learn more? 👋
That's the end of the free part 😔
To get access to 93 hours of video, a members-only Discord server and future updates, join us for only $95!
Introduction 00:00
When we imported our hamburger a few lessons ago, it didn’t look very good. 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 the rendering quality of our models.. 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:12
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 and it’s already loaded and added to the scene.
We will also use lil-gui to tweak as many parameters as possible. That is required if we want to create the perfect render.
Environment map 02:01
An environment map is also set, and we are using an HDR equirectangular texture. This results in an already good looking scene with good lighting and reflection.
We are not going to cover this topic again since we dedicated a whole lesson to this. Just remember that HDR environment will get you a better lighting, but at the cost of performance and an increase in file size.
Try to use the smallest possible texture and if don’t use the environment map as a background, you can go really low with the resolution without the user noticing.
Now let’s talk about the WebGLRenderer and some of its properties that you need to discover.
Tone mapping 03:11
The tone mapping intends to convert High Dynamic Range (HDR) values to Low Dynamic Range (LDR) values.
While we are indeed talking about the same HDR as for the environment map, tone mapping in Three.js will actually fake the process of converting LDR to HDR even if the colors aren’t HDR resulting in a very realistic render.
To change the tone mapping, update the toneMapping
property on the WebGLRenderer.
There are multiple possible values:
THREE.NoToneMapping
(default)THREE.LinearToneMapping
THREE.ReinhardToneMapping
THREE.CineonToneMapping
THREE.ACESFilmicToneMapping
Let’s start with THREE.ACESFilmicToneMapping
:
// Tone mapping
renderer.toneMapping = THREE.ACESFilmicToneMapping
To appreciate the difference, let's add the toneMapping
to our lil-gui. We can create a drop-down tweak by sending an object with different keys and values as the third parameter of gui.add(...)
:
gui.add(renderer, 'toneMapping', {
No: THREE.NoToneMapping,
Linear: THREE.LinearToneMapping,
Reinhard: THREE.ReinhardToneMapping,
Cineon: THREE.CineonToneMapping,
ACESFilmic: THREE.ACESFilmicToneMapping
})
Let’s go for the THREE.ReinhardToneMapping
:
renderer.toneMapping = THREE.ReinhardToneMapping
While this tone mapping may give the impression of washed-out colors, it actually achieves a high level of realism, akin to that of a camera with improper settings.
We have the flexibility to adjust the tone mapping exposure, influencing the amount of light allowed into the scene, and the algorithm will adapt accordingly. To modify this value, we simply update the toneMappingExposure
property directly on the renderer
:
renderer.toneMappingExposure = 2
Let's add it to lil-gui as well:
gui.add(renderer, 'toneMappingExposure').min(0).max(10).step(0.001)
Let’s stick to a toneMappingExposure
to 3
for now:
renderer.toneMappingExposure = 3
Antialiasing 10:35
We call aliasing an artifact that might appear in some situations where we can see a stair-like effect, usually on the edge of the geometries.
How to use it 🤔
- Download the Starter pack or Final project
- Unzip it
- Open your terminal and go to the unzip folder
-
Run
npm install
to install dependencies
(if your terminal warns you about vulnerabilities, ignore it) -
Run
npm run dev
to launch the local server
(project should open on your default browser 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