Simple Spot Light Shadow Not Working

I have a basic spot light shadow program that create two boxes on the screen and calculates the shadows.

import { OrbitControls } from "https://unpkg.com/three@v0.126.1/examples/jsm/controls/OrbitControls.js"

        import * as three from "https://unpkg.com/three@0.141.0/build/three.module.js"
        /* Scene set up */
        var scene = new three.Scene();
        var camera = new three.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        var renderer = new three.WebGLRenderer({
        shadowMap: {
        enabled: true,
        type: three.PCFSoftShadowMap
        }
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
        camera.position.y = 20
        camera.position.x = 20
        camera.position.z = 20
        const controls = new OrbitControls(camera, renderer.domElement);
        
        
        let light = new three.SpotLight()
        light.castShadow = true
        light.shadow.mapSize.width = 2056;
        light.shadow.mapSize.height = 2056;
        light.shadow.camera.near = 0.5;
        light.shadow.camera.far = 1000;
        light.shadow.bias = -0.00001;
        light.shadow.penumbra = 0.5
        light.shadow.focus = 1;
        light.position.set(11,11,11)
        const spotLightHelper = new three.SpotLightHelper( light );
        scene.add( spotLightHelper );
        const helper = new three.CameraHelper( light.shadow.camera );
        scene.add( helper );
        scene.add(light)
        light.position.set(0,0,30)
        
        let box = new three.Mesh(new three.BoxGeometry(10,10,10), new three.MeshPhongMaterial())
        box.receiveShadow = true;
        box.castShadow = true;
        scene.add(box)
        light.target = box
        
        let box2 = new three.Mesh(new three.BoxGeometry(100,100,0.1), new three.MeshPhongMaterial())
        box2.receiveShadow = true;
        box2.castShadow = true;
        scene.add(box2)
        box2.position.set(0,0,-10)
        
        
        let delta;
        let clock = new three.Clock()
        const animate = () => {
            delta = clock.getDelta()
            requestAnimationFrame(animate);
            controls.update()
            helper.update()
            box.rotation.x += Math.sin(0.01)
            box.rotation.y += Math.sin(0.01*5)
            spotLightHelper.update();
            renderer.render(scene, camera);
        };
        animate();

Despite this, I do not see any shadow:

The plane behind the cube should have a shadow?

Idk, it works for me

1 Like

If I try to scale up this example and use a for loop in order to generate multiple lights, the shadow is disappearing:

Example that uses a for loop, but generates 0 < 1. Red is the light

0 < 5

Your shadow test but on code sandbox for reference:

This for loop is of the following code:

let lights = {};
for (let i = 0; i < 5; i++) {
  lights[i] = new three.SpotLight(0xffffff, 1, 0, Math.PI / 2, 0.5);
  lights[i].castShadow = true;
  lights[i].shadow.mapSize.width = 2056;
  lights[i].shadow.mapSize.height = 2056;
  lights[i].shadow.camera.near = 0.1;
  lights[i].shadow.camera.far = 200;
  lights[i].shadow.bias = 0.5;
  lights[i].position.x = Math.random() * 50;
  lights[i].position.y = Math.random() * 20;
  lights[i].position.z = Math.random() * 50 + 50;
  // Box to show where the camear is
  let box = new three.Mesh(
    new three.BoxGeometry(5, 5, 5),
    new three.MeshBasicMaterial({
      color: "red"
    })
  );
  scene.add(box);
  box.position.set(lights[i].position.x, lights[i].position.y, lights[i].position.z);
  lights[i].target = box3;
  lights[i].shadow.camera.updateProjectionMatrix();
}
for (let i = 0; i < Object.keys(lights).length; i++) {
  console.log("Light: " + i);
  console.log(lights[i]);
  scene.add(lights[i]);
}

I didn’t put shadow helpers on this one for complexity right now. The reason I am progressively scaling up this issue is because I have a very large program that is having this issue right now, but I am trying to isolate it.

Maybe need bias = -0.0005;

1 Like

Still encountering the same issue.

this is normal, you are maxing out the brightness with so many lights. just add this line:

  lights[i].intensity = 0.2;

2 Likes

this is hopeless, lol - every time I fix your fiddle you find new way to break it :sweat_smile:

1 Like

Hey, thanks for help. I ended up deleting the two previous comments because of the shadow test 3 I proposed that also had issues was just a simple recieveShadow was set to false.

In the final application I was working up to, the user was able to input custom parameters for the shadows.

 lights[i] = new three.SpotLight(
        this._lightOptions.colorHex,
        this._lightOptions.intensity,
        0,
        Math.PI / 2,
        this._lightOptions.penumbra
      );

Apparently the angle should’ve been Math.PI/3, not 2. This changed the angle and the shadow did not generate correctly.

Its been five days trying to track down this issue. Glad that it is all over.