Search code examples
javascriptthree.jsshadow

Three.js .obj shadows not working


I am trying to learn Thee.js. And it is pretty straight forward. However for some reason i am unable to get the shadows working. I've set castShadows, recieveShadows, shadowMapEnabled to true on the places i found where to set them however they do not show shadows (anywhere).

What i want to do is that my imported model casts shadows on itself so you can actually make out what the model is.

This is my current code:

var container;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;

init();
animate();

function init(){
    container = document.createElement( "div" );
    document.body.appendChild( container );

    camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
    camera.position.z = 100;

    controls = new THREE.TrackballControls( camera );
    controls.rotateSpeed = 5.0;
    controls.zoomSpeed = 5;
    controls.panSpeed = 0;
    controls.noZoom = false;
    controls.noPan = true;
    controls.staticMoving = true;
    controls.dynamicDampingFactor = 0.3;

    scene = new THREE.Scene();

    var ambient = new THREE.AmbientLight( 0xffffff );
    scene.add( ambient );

    /*var spotLight = new THREE.SpotLight( 0xffffff,1.5, 40 );
    spotLight.position.set( -400, 1200, 300 );
    spotLight.castShadow = true;
    spotLight.shadowDarkness = 0.5;
    spotLight.shadowCameraVisible = true;
    spotLight.target.position = new THREE.Object3D( 10, 10, 10 );
    scene.add( spotLight );*/

    var light = new THREE.DirectionalLight(0xffffff, 2);
    light.position.x = -100;
    light.position.y = 150;
    light.shadowCameraVisible = true;
    light.castShadow = true;

    light.shadowCameraNear = 100; 
    light.shadowCameraFar = 300;
    light.shadowCameraFov = 20;
    light.shadowBias = -0.00022;   
    light.shadowDarkness = 0.5;
    scene.add(light);

    var groundGeo = new THREE.PlaneGeometry(400,400);
    var groundMat = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );

    var ground = new THREE.Mesh(groundGeo,groundMat);
    ground.position.y = -20; 
    ground.rotation.x = -Math.PI/2; 
    ground.doubleSided = true; 
    ground.reciveShadow = true;
    scene.add(ground); 


    var manager = new THREE.LoadingManager();
    manager.onProgress = function( item, loaded, total ){
        console.log( item, loaded, total );
    };

    var loader = new THREE.OBJLoader( manager );

    //var texture = new THREE.Texture();

    var texture = THREE.ImageUtils.loadTexture( "textures/red.jpg" );
    texture.repeat.set( 0.7, 1 );
    texture.wrapS   = texture.wrapT = THREE.RepeatWrapping;
    var material    = new THREE.MeshPhongMaterial({
        ambient     : 0x444444,
        color       : 0x8844AA,
        shininess   : 300, 
        specular    : 0x33AA33,
        shading     : THREE.SmoothShading,
        map     : texture
    });

    loader.load("models/Shooza.obj",function(e){
        var object = e;

        object.traverse( function(child){
            if(child instanceof THREE.Mesh){
                child.material.color.setRGB(0.5,0,0);
                child.castShadow = true;
                child.reciveShadow = false;
                //child.material.map = texture;
            }
        });

        //object.scale = new THREE.Vector3(-100,-100,-100);
        object.scale.set(0.2,0.2,0.2);

        object.position.y -= 2.5;

        object.castShadow = true;
        object.reciveShadow = true;

        scene.add(object);
    });


    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth,window.innerHeight);
    renderer.shadowMapEnabled = true;
    renderer.shadowMapType      = THREE.PCFSoftShadowMap;
    renderer.shadowMapSoft = true;
    container.appendChild( renderer.domElement );

}

function animate(){
    requestAnimationFrame( animate );

    controls.update();
    camera.lookAt(scene.position);
    renderer.render(scene, camera);
}

And this is my current result: http://gyazo.com/931f9103e01a5985508897fb1a5d0b88


Solution

  • I don't know if you really need shadows. You use MeshBasicMaterial. MeshBasicMaterial doesn't calculate any lighting.

    Try to use MeshLambertMaterial or MeshPhongMaterial instead. They do lighting based on the standards of the mesh. And if you activate castShadows and receiveShadows they will also us the shadowMap.

    http://threejs.org/docs/#Reference/Materials/MeshLambertMaterial

    http://threejs.org/docs/#Reference/Materials/MeshPhongMaterial