Why are meshes not casting shadows on just one side of light camera frustum just on the XZ plane?

I have a scatter of 500 cubes and 3 spot lights pointing at the YZ, ZX and XY planes. The shadows seem fine for the other planes but are getting cut on one side of the frustrum for the XZ plane.

    this.lightZX = new THREE.SpotLight(0xFFFFFF, 100);
    this.lightZX.position.set(100, 2000, 100);
    this.lightZX.target.position.set(100, 0, 100);
    this.scene.add(this.lightZX);
    this.scene.add(this.lightZX.target);
    this.lightZX.castShadow = true;
    this.lightZX.angle = Math.PI / 45;
    this.lightZX.penumbra = 1;
    this.lightZX.shadow.mapSize.width = this.shadowMapSize;
    this.lightZX.shadow.mapSize.height = this.shadowMapSize;
    this.lightZX.decay = 0.5;
    this.lightZX.shadow.camera.near = 1800;
    this.lightZX.shadow.camera.far = 2000;

Some of the camera helper line segments are visible.
I have similar code for lightXY and lightYZ with position and target changed

I had the same issue with a directional light with position (100,200,100) and -100, 100 for the top/botton. Changing the position to (0,200,0) with -200, 0 for the top bottom fixed the issue. All the meshes started projecting shadows.

It is hard the guess by looking at a static image and fragment of code. But are all objects well within the light’s camera frustum? Does it make any change if you set the far property to something more than 2000?

this.lightZX.shadow.camera.far = 3000;
2 Likes

Ok thank you and I feel very silly for not trying this :sweat_smile:

I increased the far value and the shadows are rendering properly.

this.lightZX.shadow.camera.far = 2100; is working fine.

That was a simple enough fix - perhaps at the border condition there are issues. I would assume that since the meshes are within the frustum there would be no issues. The meshes are randomly scattered between 25 and 175 on each axis.

    for (let i = 0; i < this.numberOfCubes; i++) {
      const x = 25 + Math.random() * 150;
      const y = 25 + Math.random() * 150;
      const z = 25 + Math.random() * 150;
      let rndMaterial = new THREE.MeshPhongMaterial({
        color: 0x888888,
        shininess: 50,
        specular: 0x222222
      });

      const mesh = new THREE.Mesh(geometry, rndMaterial);
      mesh.position.set(x, y, z);
      mesh.castShadow = true;
      mesh.receiveShadow = false;
      this.scene.add(mesh);
      this.meshes.push(mesh);
    }
1 Like