This post is about shadow casting, a technique which approximates the effect you see in real life everyday. They may be tricky to tune but they looks so good, it worths it. Shadows are an efficient tool when you to make your scene more realistic. We will see how they can be used inside three.js and see more about lights while we are at it.

As usual, there is a demo. It is kept it real simple thus you can read the code more easily. The scene is a simple object in the middle, a spotlight moving around and a plane to receive the object shadow. The light frustum is left visible in orange.

Let’s Code Shadows

Casting shadows in three.js involves 3 parts: the renderer which does the computation, the lights which cast shadows, and objects which receives lights and shadows.

Set up the Renderer

The renderer is the one which will compute the shadows positions for your 3D scene. Shadow casting is quite expensive. It is only supported by WebGLRenderer. It uses Shadow mapping, a technique specific to WebGL, performed directly on the GPU.

1 renderer . shadowMapEnabled = true ;

You can smooth produced shadows with shadowMapSoft . It default to false. On the left, the shadow is crisp, on the right it is soft.

1 2 // to antialias the shadow renderer . shadowMapType = THREE . PCFSoftShadowMap ;

Configure your objects

For Object3D, two parameters controls how they interact with lights and shadows. Set .castShadow to true if the object occludes light, so to cast a shadow. Set .receiveShadow to true if the object is supposed to receive shadows. Both default to false

1 2 object3d . castShadow = true ; object3d . receiveShadow = false ;

This is the configuration for the central object in the demo. It will occlude lights but won’t be able to receive shadow. So you wont see any self shadow.

Tune your Lights

THREE.DirectionalLight or THREE.SpotLight are able to cast shadows. Let’s details them. A directional light is when light rays are parallel. A bit like when you look at the sun rays on the left. It mostly behaves like a light source very far from us. A spot light is when light rays seems to originate from a single point, and spreads outward in a coned direction, like in the dance club on the right (Images are from wikipedia). To enable the shadow casting on a light, just use this line.

1 light . castShadow = true ;

You can tune the shadowDarkness . It is the opacity of the shadow. 0 means no shadow, 1 means pure back shadow.

1 light . shadowDarkness = 0.5 ;

In the same vibe, it possible to show the shadow camera on the screen with shadowCameraVisible . A very usefull feature during tuning or debugging.

1 light . shadowCameraVisible = true ;

More of Directional Lights

Additionally, when casting shadow with a THREE.DirectionalLight, you need to setup an orthographic camera. What is that ? it is a different form of 3D projection. Perspective is the way we see things in real life. So it seems more natural to us than orthographic projection. On the left, an illustration shows a perspective projection. You can see what is inside the orange shape. On the right, the same for a orthographic one.

Recent three.js r47 release includes a very didactic example from alteredq. Play with it, it may understand the difference between orthographic and perspective cameras. Here is a possible configuration of the frustum for the orthographic camera of our light.

1 2 3 4 light . shadowCameraRight = 5 ; light . shadowCameraLeft = - 5 ; light . shadowCameraTop = 5 ; light . shadowCameraBottom = - 5 ;

Conclusion

This is it, you can code shadow casting in three.js now :) Go ahead and play with them. They are hard to master but very efficient visually. Keep in mind that those shadows aren’t real. They only uses ‘some tricks’ to make them appears as real. And they do so in real time !! To achieve this result, they take significant shortcuts which produce artifacts. To avoid those require tuning and experience.

That’s all for today folks. Have fun.