DirectionalLight shadow camera helper pointing in the wrong direction

This seems like an almost identical problem to the one @Drumstructor helped me with previously: previous post

I’m adding a DirectionalLight to a scene, followed by a DirectionalLightHelper and then a CameraHelper for the shadow.

    function initLight(){
      const light = new THREE.DirectionalLight(0xFFFFFF, 5);
      light.name = 'light';
      light.castShadows = true;
      light.position.set(-100, 100, 0);
      light.target.position.set(0, 100, 100);
      scene.add(light);
      light.target.name = 'light.target';
      scene.add(light.target);
      //add light helper
      const lightHelper = new THREE.DirectionalLightHelper(light, 10);
      lightHelper.name = 'lightHelper';
      scene.add(lightHelper);
      lightHelper.parent.updateMatrixWorld();
      lightHelper.update();
      //add shadow helper
      const shadowHelper = new THREE.CameraHelper(light.shadow.camera);
      shadowHelper.name = 'shadowHelper';
      scene.add(shadowHelper);
      shadowHelper.parent.updateMatrixWorld();
      shadowHelper.update();
    }

The problem is that the direction shadowHelper is pointing in seems to be unrelated to either the light or the camera.

In function initLight, I tried the same technique @Drumstructor gave me in that previous post

      shadowHelper.parent.updateMatrixWorld();
      shadowHelper.update();

but in this situation it doesn’t do anything I can make sense of.

What am I doing wrong?

Full code below and a link to where I’ve put the example page online.

<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>directional-light-shadow-helper-problem-01</title>
  <style>
    canvas{
      height: 100%;
      width: 100%;
    }
  </style>
  <script type='module'>

    import * as THREE from '../lib/three-js-129/build/three.module.js';
    import {OrbitControls} from '../lib/three-js-129/examples/jsm/controls/OrbitControls.js';

    const RED    = 0xff0000;
    const GREEN  = 0x00ff00;
    const BLUE   = 0x0000ff;
    const AXIS_LENGTH = 100;

    let canvas, scene, renderer, camera;

    function initRenderer() {
      renderer = new THREE.WebGLRenderer({ canvas:canvas, antialias: true });
    }

    function initCamera() {
      camera = new THREE.PerspectiveCamera(70, 1, 1, 10000);
      camera.name = 'camera';
      scene.add(camera);
      camera.position.set(180, 150, 100); 
    }

    function initLight(){
      const light = new THREE.DirectionalLight(0xFFFFFF, 5);
      light.name = 'light';
      light.castShadows = true;
      light.position.set(-100, 100, 0);
      light.target.position.set(0, 100, 100);
      scene.add(light);
      light.target.name = 'light.target';
      scene.add(light.target);
      //add light helper
      const lightHelper = new THREE.DirectionalLightHelper(light, 10);
      lightHelper.name = 'lightHelper';
      scene.add(lightHelper);
      lightHelper.parent.updateMatrixWorld();
      lightHelper.update();
      //add shadow helper
      const shadowHelper = new THREE.CameraHelper(light.shadow.camera);
      shadowHelper.name = 'shadowHelper';
      scene.add(shadowHelper);
      shadowHelper.parent.updateMatrixWorld();
      shadowHelper.update();
    }

    function initAxes(){
      function makeAxis(start, finish, material, name){
        const points = [start, finish];
        const axisGeometry = new THREE.BufferGeometry().setFromPoints(points);
        const newAxis = new THREE.Line(axisGeometry, material);
        newAxis.name = name;
        scene.add(newAxis);
      }
      var xAxisMaterial = new THREE.LineBasicMaterial({ color: RED });
	    var yAxisMaterial = new THREE.LineBasicMaterial({ color: GREEN });
	    var zAxisMaterial = new THREE.LineBasicMaterial({ color: BLUE });
      makeAxis(new THREE.Vector3(-AXIS_LENGTH, 0, 0), new THREE.Vector3(AXIS_LENGTH, 0, 0), xAxisMaterial, 'xAxis');
      makeAxis(new THREE.Vector3(0, -AXIS_LENGTH, 0), new THREE.Vector3(0, AXIS_LENGTH, 0), yAxisMaterial, 'yAxis');
      makeAxis(new THREE.Vector3(0, 0, -AXIS_LENGTH), new THREE.Vector3(0, 0, AXIS_LENGTH), zAxisMaterial, 'zAxis');
    }

    function render() {
      requestAnimationFrame(render);
      renderer.render(scene, camera);
    }

    function listSceneObjects(){
      console.log(`id: ${scene.id}, name: ${scene.name}, parent.id: ${scene?.parent?.id}`);
      for(const obj of scene.children){
        console.log(`id: ${obj.id}, name: ${obj.name}, parent.id: ${obj.parent.id}`);
      }
    }

    window.onload = function(){   
      canvas = document.getElementById('canvasId');
      scene = new THREE.Scene();
      scene.name = 'scene';
      initRenderer();
      initCamera();
      initLight();
      initAxes();
      new OrbitControls(camera, canvas);
      listSceneObjects();
      render();
    }

  </script>
</head>
<body>
  <canvas id='canvasId'></canvas>
</body>
</html>

https://mytestpages.com/three/directional-light-shadow-helper-problem-01.html

You have a typo in your code. It is not castShadows but castShadow.

You also have to globally enable shadow maps via renderer.shadowMap.enabled = true;.

Live example: https://jsfiddle.net/pugd0sLv/2/

1 Like

Thank you again @Mugen87