Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

THREE.JS Shadow on opposite side of light

Tags:

three.js

webgl

I used THREE.js r49 create 2 cube geometry with a directional light to cast shadow on them and got result as in the following picture.

I noticed that the shadow in the green circle should not be appeared, since the directional light is behind both of the cube. I guess that this is the material issue, I've tried changing various material parameters as well as change the material type itself, but the result still the same. I also tested the same code with r50 and r51 and got the same result.

Could anybody please give me some hint how to get rid of that shadow.

Both cube are creating using CubeGeometry and MeshLambertMaterial as following code.

Result Image

The code:

// ambient
var light = new THREE.AmbientLight( 0xcccccc );
scene.add( light );

// the large cube
var p_geometry = new THREE.CubeGeometry(10, 10, 10);
var p_material  = new THREE.MeshLambertMaterial({ambient: 0x808080, color: 0xcccccc});
var p_mesh  = new THREE.Mesh( p_geometry, p_material );
p_mesh.position.set(0, -5, 0);
p_mesh.castShadow = true;
p_mesh.receiveShadow = true;
scene.add(p_mesh);

// the small cube
var geometry = new THREE.CubeGeometry( 2, 2, 2 );
var material = new THREE.MeshLambertMaterial({ambient: 0x808080, color: Math.random() * 0xffffff});
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set(0, 6, 3);
mesh.castShadow = true;
mesh.receiveShadow = true;

// add small cube as the child of large cube
p_mesh.add(mesh);
p_mesh.quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), 0.25 * Math.PI );

// the light source
var light  = new THREE.DirectionalLight( 0xffffff );
light.castShadow = true;
light.position.set(0, 10, -8);  // set it light source to top-behind the cubes
light.target = p_mesh           // target the light to the large cube
light.shadowCameraNear = 5;
light.shadowCameraFar = 25;
light.shadowCameraRight   =  10;
light.shadowCameraLeft    = -10;
light.shadowCameraTop     =  10;
light.shadowCameraBottom  = -10;
light.shadowCameraVisible = true;
scene.add( light );
like image 824
BoogieBug Avatar asked Sep 26 '12 11:09

BoogieBug


1 Answers

Yes, this is a known, and long-standing, WebGLRenderer issue.

The problem is that the dot product of the face normal and the light direction is not taken into consideration in the shadow calculation. As a consequence, "shadows show through from the back".

As a work-around, you could have a different material for each face, with only certain materials receiving shadows.

three.js r.71

like image 63
WestLangley Avatar answered Nov 02 '22 03:11

WestLangley