Search code examples
three.jsshadowtraversal

three js only some child shadows show


i currently have a scene with a GLB model, the model has child meshes but only some are casting shadows

you can see the word peripherals, the big island and the small island and the whale all cast shadows but the rest dont,

enter image description here

i am currently using this.

  gltf.scene.traverse(function(child) {
  if (child.isMesh) {
  child.castShadow = true;
  child.receiveShadow = true;
}
})

which seems to work fine, for some parts of the model but not others, ive tried everything i can find on the internet, but nothing works, ive also tried everything i can within c4d, but still no change.

i am using this light:

const sunLight = new THREE.DirectionalLight(0xe8c37b, 0.96);
sunLight.position.set(10, 30, -60);
sunLight.castShadow = true
scene.add(sunLight);

i am also using water and sun for the reflection /sky, (not sure if this is the cause of it, but thought id add it for reference)

function updateSun() {
const phi = THREE.MathUtils.degToRad(90 - parameters.elevation);
const theta = THREE.MathUtils.degToRad(parameters.azimuth);

sun.setFromSphericalCoords(1, phi, theta);

sky.material.uniforms["sunPosition"].value.copy(sun);
water.material.uniforms["sunDirection"].value.copy(sun).normalize();
water.material.uniforms["size"].value = 100;

if (renderTarget !== undefined) renderTarget.dispose();

renderTarget = pmremGenerator.fromScene(sky);

scene.environment = renderTarget.texture;
}

updateSun();

please bear in mind i have over a thousand lines of code in this project so i cant post it all, but if people have ideas i can grab snippets,

any help would be really appreciated


Solution

  • Your directionalLight generates an orthographic camera to calculate its shadowmap. By the looks of your screenshot, the outer islands are outside the range of this orthographic camera. By default, the side values range from [-5, +5], so I'm sure that making this range wider will help include the outer islands in your shadow map:

    // Extend vertical range
    sunLight.shadow.camera.top = 10;
    sunLight.shadow.camera.bottom = -10;
    
    // Extend horizontal range
    sunLight.shadow.camera.left = -10;
    sunLight.shadow.camera.right = 10;
    

    You could also add a CameraHelper like in this example to help you visualize what's inside and outside this shadow camera:

    scene.add( new THREE.CameraHelper( sunLight.shadow.camera ) );