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 Three.js, lights require a higher intensity:

const spotLight = new THREE.SpotLight(0xffffff, 3.6, 10, Math.PI * 0.3)

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 fov cannot be changed and will always be overridden by the angle of the SpotLight.

⚠️ Update

In the latest versions of Three.js, lights require a higher intensity:

const pointLight = new THREE.PointLight(0xffffff, 2.7)

The result will look slightly more realistic. Don’t be surprised if it’s not the exact same colors as in the video.

⚠️ Update

Textures used as map and matcap are supposed to be encoded in sRGB.

In the latest versions of Three.js we need to specify it by setting their colorSpace to THREE.SRGBColorSpace:

bakedShadow.colorSpace = THREE.SRGBColorSpace

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

13%

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

Shadows

Difficulty Hard

Introduction 00:00

Now that we have lights, we want shadows. The back of the objects are indeed in the dark, and this is called the core shadow. What we are missing is the drop shadow, where objects create shadows on the other objects.

Shadows have always been a challenge for real-time 3D rendering, and developers must find tricks to display realistic shadows at a reasonable frame rate.

There are many ways of implementing them, and Three.js has a built-in solution. Be aware, this solution is convenient, but it's far from perfect.

How it works 01:42

We won't detail how shadows are working internally, but we will try to understand the basics.

When you do one render, Three.js will first do a render for each light supposed to cast shadows. Those renders will simulate what the light sees as if it was a camera. During these lights renders, MeshDepthMaterial replaces all meshes materials.

The results are stored as textures and named shadow maps.

You won't see those shadow maps directly, but they are used on every material supposed to receive shadows and projected on the geometry.

Here's an excellent example of what the directional light and the spotlight see: https://threejs.org/examples/webgl_shadowmap_viewer.html

Setup 08:51

Our starter is composed of one simple sphere on a plane with one directional light and one ambient light.

You can control these lights and the material metalness and roughness in lil-gui.

How to activate shadows 09:24

First, we need to activate the shadow maps on the renderer:

const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.shadowMap.enabled = true

Then, we need to go through each object of the scene and decide if the object can cast a shadow with the castShadow property, and if the object can receive shadow with the receiveShadow property.

Try to activate these on as few objects as possible:

sphere.castShadow = true

// ...
plane.receiveShadow = true

Finally, activate the shadows on the light with the castShadow property.

Only the following types of lights support shadows:

And again, try to activate shadows on as few lights as possible:

const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5)
directionalLight.castShadow = true

You should get a shadow of the sphere on the plane.

Sadly, that shadow looks terrible. Let's try to improve it.

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