Model not casting/receiving shadows

The following code produces this result:

image

Notice how the scene is automatically centered and the camera configured according to the model’s dimensions.

var container, stats, controls;
var camera, scene, renderer;

init();
animate();

function init() {

    container = document.createElement( 'div' );
    document.body.appendChild( container );

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
    camera.position.set( - 1.8, 0.9, 2.7 );

    controls = new THREE.OrbitControls( camera );

    var ambientLight = new THREE.AmbientLight( 0xffffff, 0.4 );
    scene.add( ambientLight );

    var spotLight = new THREE.SpotLight( 0xffffff, 1 );
    spotLight.position.set( 500, 400, 200 );
    spotLight.angle = 0.4;
    spotLight.penumbra = 0.05;
    spotLight.decay = 1;
    spotLight.distance = 2000;

    spotLight.castShadow = true;
    scene.add( spotLight );

    spotLight.target.position.set( 3, 0, - 3 );
    scene.add( spotLight.target );

    var lightHelper = new THREE.SpotLightHelper( spotLight );
    // scene.add( lightHelper );

    // model
    var loader = new THREE.GLTFLoader().setPath( 'models/gltf/test/' );
    loader.load( 'scene.gltf', function ( gltf ) {

        gltf.scene.traverse( function ( child ) {

            if ( child.isMesh ) {

                child.castShadow = true;
                child.receiveShadow = true;

            }

        } );

        // automatically center model and adjust camera

        const box = new THREE.Box3().setFromObject( gltf.scene );
        const size = box.getSize( new THREE.Vector3() ).length();
        const center = box.getCenter( new THREE.Vector3() );

        gltf.scene.position.x += ( gltf.scene.position.x - center.x );
        gltf.scene.position.y += ( gltf.scene.position.y - center.y );
        gltf.scene.position.z += ( gltf.scene.position.z - center.z );

        camera.near = size / 100;
        camera.far = size * 100;

        camera.updateProjectionMatrix();

        camera.position.copy( center );
        camera.position.x += size / 2.0;
        camera.position.y += size / 5.0;
        camera.position.z += size / 2.0;
        camera.lookAt( center );

        console.log( camera.position );

        controls.maxDistance = size * 10;
        controls.update();

        scene.add( gltf.scene );

    }, undefined, function ( e ) {

        console.error( e );

    } );

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.gammaOutput = true;
    renderer.gammaFactor = 2.2;
    renderer.shadowMap.enabled = true;
    container.appendChild( renderer.domElement );

    window.addEventListener( 'resize', onWindowResize, false );

    // stats
    stats = new Stats();
    container.appendChild( stats.dom );

}

function onWindowResize() {

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );

}

//

function animate() {

    requestAnimationFrame( animate );

    renderer.render( scene, camera );

    stats.update();

}
3 Likes