00:00/00:00TIME LEFT
Choosing the a bcd

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

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!

Next lesson


Difficulty Hard

Starter packFinal project

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 Dat.GUI.

How to activate shadows 09:24

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

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:

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 71 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
    (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

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