Moving DirectionalLight shadow frustum with camera

I have a scene big enough that it feels natural not to make the shadow frustum encompass the entire scene, but only whatever the player camera sees. But how can I move the frustum without also moving the light (and the light direction)? Right now, the only way to move the frustum was to move directionalLight.position and directionalLight.target.position, but that makes it as if the light is emitted from the camera.

Any tips greatly appreciated :slight_smile:

The shadow camera frustum projects from the light’s position, exactly the way a light in the real world creates shadows. You can view it using a CameraHelper:

const shadowHelper = new THREE.CameraHelper( light.shadow.camera )

but that makes it as if the light is emitted from the camera.

Really not sure what you mean here. Which camera? The shadow camera?

Yeah, I already have a CameraHelper up and running. Problem is that the only way (so far) I found of moving the shadow frustum was to move the directional light’s position, but that would change the light direction as well.

If I reposition the light so that the frustum is in front of the camera, then it would always be relative to the camera position. Am I way off here? If the frustum is placed from light and target position then how could I possibly move the frustum without affecting the angel and direction in which the light falls?

Right, exactly the way a light in the real world creates shadows. The shadows are in fact created by viewing the scene from the point of view of the light. But you can still control the frustum’s near, far, top, bottom, left, and right to limit it’s size.

move both the light and light target positions the same amount -> translate x,z according to the camera x,z. they keep their relative positions and thus keep the same angle, but both get translated along the x,z axes.

I have a little solution for it
hope you like it :grin:

//Move Light Along With Camera
camera.updateMatrixWorld(); //Update the camera location
vector = camera.position.clone(); //Get camera position and put into variable
vector.applyMatrix4( camera.matrixWorld ); //Hold the camera location in matrix world
light.position.set( vector.x, vector.y, vector.z); //Set light position from that we get
//render(); use if the scene is static

I mucked around for 2 hours trying all sorts of things here too - there is one important line in the docs.

to manually move the target, you must:

scene.add( light.target )

otherwise everything will appear to be working but just silently fail in all sorts of weird ways when you try to move things.

1 Like