1

I am trying to make this object cast a shadow. But there are strange shadows on the edges. I think the object is casting a shadow onto another component of "itself"

enter image description here

Is there a way to remove that?

Here is the fiddle: http://jsfiddle.net/paulocoelho/qMqH7/3/

Here is the mandatory code, but just check the fiddle..

var container, stats;
var camera, scene, renderer;
var cube, plane;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

init();

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

    camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, .1, 10000 );
    camera.position.x=50;
    camera.position.y=50;
    camera.position.z=50;
    camera.lookAt(new THREE.Vector3(0,0,0));
    scene = new THREE.Scene();

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

    //var ambientLight = new THREE.AmbientLight(0x000000);
    //scene.add(ambientLight);

    light = new THREE.SpotLight();
    light.position.set(337,400,313);
    light.castShadow = true;
    light.shadowMapWidth = 3000;
    light.shadowMapHeight = 3000;
    // light.shadowCameraVisible = true;
    scene.add(light);

    var geometry = new THREE.PlaneGeometry( 200, 200, 30, 30 );
    geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
    geometry.applyMatrix( new THREE.Matrix4().setPosition( new THREE.Vector3(0,0,0) ) );
    var material = new THREE.MeshLambertMaterial( { color: 0xEEEEEE } );
    plane = new THREE.Mesh( geometry, material );
    plane.receiveShadow = true;
    scene.add( plane );

    var loader = new THREE.OBJMTLLoader();
    loader.addEventListener("load", function (event) {
        cube = event.content;
        for(k in cube.children){
            cube.children[k].castShadow = true;
            cube.children[k].receiveShadow = true;
        }
        scene.add(cube);
        animate();
    }); 
    loader.load ("https://dl.dropboxusercontent.com/u/4334059/VM.obj", "https://dl.dropboxusercontent.com/u/4334059/VM.mtl");
}

function animate() {
    requestAnimationFrame( animate );
    render();
}

function render() {
    cube.rotation.y += 0.01;
    renderer.render( scene, camera );
}
PCoelho
  • 7,850
  • 11
  • 31
  • 36

1 Answers1

3

You need to set all the light parameters to reasonable values. Google each of them if you do not understand what they are for.

light = new THREE.SpotLight( 0xffffff );
light.position.set( 200, 200, -200 );
light.castShadow = true;
light.shadowMapWidth = 1024;    // power of 2
light.shadowMapHeight = 1024;

light.shadowCameraNear = 200;   // keep near and far planes as tight as possible
light.shadowCameraFar = 500;    // shadows not cast past the far plane
light.shadowCameraFov = 20;
light.shadowBias = -0.00022;    // a parameter you can tweak if there are artifacts
light.shadowDarkness = 0.5;

light.shadowCameraVisible = true;
scene.add( light );

Keep your shadow camera as tight as possible.

Also, when setting up a shadow camera, be sure to use OrbitControls or something similar, so you can pull the camera back and see what you are doing.

P.S. Your camera near plane was 0.1 and far plane was 10000. Not good. Keep the near plane at at least 1. Small values of the near plane can lead to depth-sorting precision problems.

Fiddle: http://jsfiddle.net/qMqH7/4/

three.js r.58

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • I actually need the object itself to cast shadows. Not to itself, but to other neighbor elements i have in my real scene. But apparently fiddling with the shadowCameraFar solves the issue for me. And thanks for the Orbit hint, thats good, I did not know that. :) – PCoelho Jul 12 '13 at 18:11