00:00/00:00
3:22
00:03:22

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 Blender, the default tone mapping makes the lights looks whiter.

It’s not an issue because, later, we save the file as HDR which will ignore the tone mapping.

Yet, if you are curious on how to fix it, go into the Render tab, then the Color Management section and change the View Transform from AgX to Filmic.

⚠️ Update

BlockadeLabs recently changed Skybox Lab.

You now need to subscribe to a paid plan to download the environment maps you generate, making this section of the lesson irrelevant.

Yet, you can keep on following the lesson and use the files provided with the starter if you are curious.

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? 🤘

28%

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
24.

Environment map

Difficulty Easy

Introduction 00:00

We’ve already talked about environment maps in a previous lesson.

It’s those images surrounding the scene that can be used as a background, but also directly on the objects as reflection and lighting. Yes, you’ve read it right, environment maps can be used to light up the whole scene in a very realistic manner.

In this lesson, we are going to discover the different formats of environment maps and the various techniques to implement them.

We are also going to discover how to find and generate those environment maps using resources such as Blender and Artificial Intelligence-powered image generators.

Setup 00:56

We are going to use a realistic model with many details and material variations in order to appreciate the different environment maps we are going to test. We will use the Flight Helmet from the GLTF Sample Models repository and you can find it in the /static/models/ folder.

For now, all we have in our scene is a white torus knot and an instance of lil-gui.

Model 02:01

Let's load our model.

First, instantiate the GLTFLoader. We will regroup the different loaders together right after the imports. The main reason for doing so is the ability 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 without any errors.

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)
    }
)

Can’t see it? Move the camera underneath the white torus knot and you should see the helmet’s silhouette.

The model is too small, but also fully black because its materials are MeshStandardMaterial instances and those need light.

We are going to add lighting in a minute, but for now, let’s make the model bigger:

gltfLoader.load(
    '/models/FlightHelmet/glTF/FlightHelmet.gltf',
    (gltf) =>
    {
        gltf.scene.scale.set(10, 10, 10)
        scene.add(gltf.scene)
    }
)

Cube texture environment map 05:46

First, we are going to use the cube texture. We actually already did that in one of the previous lessons, but it’s always good to practice and it’ll be a good reminder.

Loading the textures

There are multiple environment map textures located in the /static/environmentMaps/ folder.

The 0/, 1/ and 2/ folders contain environment maps taken from the HDRI section of https://polyhaven.com and they have been converted to cube textures using https://matheowis.github.io/HDRI-to-CubeMap/.

We are going to use the first one in the 0/ folder.

Because these textures are composed of 6 images (like the faces of a cube), we have to use a CubeTextureLoader.

Add the CubeTextureLoader to our loaders:

/**
 * Loaders
 */
// ...
const cubeTextureLoader = new THREE.CubeTextureLoader()

Now we can load the textures. The order is positive x, negative x, positive y, negative y, positive z, and negative z.

Add these parameters after creating the scene:

/**
 * Environment map
 */
// LDR cube texture
const environmentMap = cubeTextureLoader.load([
    '/environmentMaps/0/px.png',
    '/environmentMaps/0/nx.png',
    '/environmentMaps/0/py.png',
    '/environmentMaps/0/ny.png',
    '/environmentMaps/0/pz.png',
    '/environmentMaps/0/nz.png'
])

Nothing should have changed because we are loading the environment map but we are not using it yet.

Check the logs for potential errors.

Using the environment map as the background

To add the environment map to our scene's background, we could create a massive cube around the scene, set its face to be visible on the inside, and apply the texture to it. It should work and look OK, but it would be very limited and only serve as a background.

Instead, let’s use Three.js features.

To apply an environment map to a scene, assign the environmentMap to the Scene's background property. Make sure to do this once you’ve created the environmentMap and the scene first:

scene.background = environmentMap

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!

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:

Discord