Split shadows on collada objects

I have a scene with two collada objects and directional light. The first collage is almost a plane, and the second is from several boxes.

It seems that when the scene is depicted, some of the β€œside” shadows are indeed removed, although the shadows laid on the ground display quite well.

Here is a screenshot of the shadows .

When I looked for the answer, I realized that this could be a problem with my collage, so I added a base cube to the scene (large, first of all), but it looks like it has the same problem.

Does anyone have a clue or already know this problem?

I use the latest atm (r71) revision of the three. js tested on Google Chrome and Mozilla Firefox (MacOS). I'm already trying to set up almost all of the shadow attributes of the directional light, except for those related to shadowCascade (which I do not use). I also tested to adjust the rendering attributes associated with the shadow.

Here is my lighting setup:

var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 ); directionalLight.target.position = THREE.Vector3(0, 0, 0); directionalLight.position.set( 250, 500, 250 ); directionalLight.castShadow = true; directionalLight.shadowCameraNear = 100; directionalLight.shadowCameraFar = 1000; directionalLight.shadowMapWidth = 2048; directionalLight.shadowMapHeight = 2048; directionalLight.shadowBias = 0.0001; directionalLight.shadowDarkness = 0.5; directionalLight.shadowCameraLeft = -300; directionalLight.shadowCameraRight = 300; directionalLight.shadowCameraTop = 300; directionalLight.shadowCameraBottom = -300; directionalLight.shadowCameraVisible = true; 

My collada objects are very large, so my borders are shadowCamera.

My rendering setting:

 renderer = new THREE.WebGLRenderer( {antialias: true} ); renderer.setClearColor(0x222222); renderer.shadowMapEnabled = true; renderer.shadowMapSoft = true; renderer.shadowMapType = THREE.PCFSoftShadowMap; renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); 

Here's another view of the scene (mostly showing the setting of my light).

EDIT: here's a snippet:

 var container; var camera, scene, renderer, controls; var particleLight; scene = new THREE.Scene(); 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.set( 300, 100, 0 ); // Controls controls = new THREE.OrbitControls( camera ); // Cube var geometry = new THREE.BoxGeometry( 100, 100, 100 ); var material = new THREE.MeshLambertMaterial(); var cube = new THREE.Mesh( geometry, material ); cube.position.y = 50; cube.rotation.y = 0.8; cube.castShadow = true; cube.receiveShadow = true; scene.add( cube ); // Plane var planeGeometry = new THREE.PlaneBufferGeometry( 300, 300, 300 ); var plane = new THREE.Mesh( planeGeometry, material ); plane.position.set( 0, 0, 0 ); plane.rotation.x = -1.6; plane.castShadow = true; plane.receiveShadow = true; scene.add( plane ); // Light var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 ); directionalLight.target.position = THREE.Vector3(0, 0, 0); directionalLight.position.set( 250, 500, 250 ); directionalLight.castShadow = true; directionalLight.shadowCameraNear = 100; directionalLight.shadowCameraFar = 1000; directionalLight.shadowMapWidth = 2048; directionalLight.shadowMapHeight = 2048; directionalLight.shadowBias = 0.0001; directionalLight.shadowDarkness = 0.5; directionalLight.shadowCameraLeft = -300; directionalLight.shadowCameraRight = 300; directionalLight.shadowCameraTop = 300; directionalLight.shadowCameraBottom = -300; directionalLight.shadowCameraVisible = true; scene.add( directionalLight ); scene.add( new THREE.AmbientLight( 0x555555 ) ); renderer = new THREE.WebGLRenderer( {antialias: true} ); renderer.setClearColor(0x222222); renderer.shadowMapEnabled = true; renderer.shadowMapSoft = true; renderer.shadowMapType = THREE.PCFSoftShadowMap; renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); window.addEventListener( 'resize', onWindowResize, false ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function animate() { requestAnimationFrame( animate ); render(); } var clock = new THREE.Clock(); function render() { var timer = Date.now() * 0.0005; camera.lookAt(new THREE.Vector3(0, 0, 0)); renderer.render( scene, camera ); } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script> <script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script> 

Thanks in advance.

+5
source share
1 answer

You get self-shadowing because the beams of directional light are exactly parallel to some facets of your geometry. Move the directional light to a slightly different place. For instance,

 directionalLight.position.set( 250, 500, 200 ); 

Usually light.shadow.bias used to fix problems with self-shadowing, but it will not be effective if the light beam and face are parallel, as in your case.

Also, set shadow.bias as negative to facilitate artifacts on other faces.

 directionalLight.shadow.bias = - 0.01; 

This, unfortunately, will lead, as usual, to another artifact: "Peter Paning."

These types of compromises are common. You just need to find an acceptable compromise. (Perhaps set the offset depending on the position of the camera.)

three.js r.75

+2
source

All Articles