Search code examples
three.jsshadowlightdirectional-light

Shadows Distance problems in ThreeJS


I'm currently working with a directionnal ligth for my scene. A small character can move around. All shadows works. But if I start to go a bit further with the avatar, the shadows don't work anymore on it. I think it's may come from the angle of the light but I can't change it. I can draw a square around the shadow/non-shadow area.

Here is my code. Huge numbers were here for me to test things

                const dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
                dirLight.color.setHSL( 0.1, 1, 0.95 );
                dirLight.position.set( - 1, 1.75, 1 );
                dirLight.position.multiplyScalar( 30 );
                dirLight.distance = 1200;
                dirLight.focus = 1200;
                dirLight.angle = Math.PI / 1;
                scene.add( dirLight );

                dirLight.castShadow = true;

                dirLight.shadow.mapSize.width = 2048;
                dirLight.shadow.mapSize.height = 2048;

                const d = 100;

                dirLight.shadow.camera.left = - d;
                dirLight.shadow.camera.right = d;
                dirLight.shadow.camera.top = d;
                dirLight.shadow.camera.bottom = - d;

                dirLight.shadow.camera.far = 35000;
                dirLight.shadow.bias = - 0;

                const dirLightHelper = new THREE.DirectionalLightHelper( dirLight, 10 );
                scene.add( dirLightHelper );

Here is the code of the ground that recive shadows

const groundGeo = new THREE.PlaneBufferGeometry( 10000, 10000 );
                const groundMat = new THREE.MeshLambertMaterial( { color: 0xffffff } );
                groundMat.color.setHSL( 0.095, 1, 0.75 );

                const ground = new THREE.Mesh( groundGeo, groundMat );
                ground.position.y = - 33;
                ground.rotation.x = - Math.PI / 2;
                ground.receiveShadow = true;
                scene.add( ground );

I reused a huge part of the code provided by the ThreeJS example with the flamingo https://threejs.org/examples/?q=light#webgl_lights_hemisphere

Here is also a link to an imgur where I just put some picture to see the shadows https://i.sstatic.net/jWHra.jpg

Thanks


Solution

  • If your shadows are working within a limited area, then it must be that your character is walking beyond the frustum of the shadow-camera.

    To create directional shadows, you create an orthographic camera and assign its dimensions with .left, .right, .top, .bottom, in this case your camera is has 100 in each direction. When your character walks beyond those 200 units, it is outside the shadow camera, and it no longer receives shadows.

    You should add a CameraHelper to the light shadow to let you see the space within its view frustum, as seen in the DirectionalLightShadow code sample

    const helper = new THREE.CameraHelper( dirLight.shadow.camera );
    scene.add( helper );
    

    Maybe you could have the shadow camera follow the character so he'll always be inside of it.