Shortcuts ⌨️

  • SPACE to play / pause
  • ARROW RIGHT or L to go forward
  • ARROW LEFT or J to go backward
  • ARROW UP to increase volume
  • ARROW DOWN to decrease volume
  • F to toggle fullscreen
  • M to toggle mute
  • 0 to 9 to go to the corresponding part of the video
  • SHIFT + , to decrease playback speed
  • SHIFT + . or ; to increase playback speed

⚠️ 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!

Next lesson

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.

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!

Next lesson

Code structuring for bigger projects

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

If you get stuck and need help, join the members-only Discord server: