How to get good shadow on big map

hello ,

when pointLight or directionalLight are near object ( around less than 800/1000) , i can get good shadow , but when source of light is far from 1000 shadow are not enough correct . so i ve put a second light(1) (a directionalLight which is at 600 ) between sun ( a pointLight which is at 6000 ) and me . i can get a better result but because it isn’t impossible to set a distance to a DirectionalLight , my back scene( opposite of sun ) is too sunny and it’s not what i want ( around sun the sky and ground should sunny , at the opposite the sky and the ground should dark ) .
so i ve changed directionalLight for a PointLight to be able to set a distance and get a correct ambiance light for the ground and the sky … but because the neart Light(1) is now a PointLight the shadow are not in the correct way at the left and the right of my position .

question : what is the best way to manage a light on big map ( around 5000*3000 ) to get , sunny near sun , dark in the opposite , and good shadow near around me .

thank .

(1) the far Light do a circle around me at 6000 , and the near Light is at 0.05 *distance between sun and me . i’ve done something like that
var farLight = new THREE.PointLight(0xffffff,1);
farLight.castShadow=false;
scene.add(farLight);
var nearLightForShadow = new THREE.DirectionalLight(0xffffff,1);
nearLightForShadow.castShadow=true;

   nearLightForShadow.shadow.mapSize.width=2048;
   nearLightForShadow.shadow.mapSize.height=2048;
  
    nearLightForShadow.shadow.camera.near=1;
   nearLightForShadow.shadow.camera.far=1200;
 
  nearLightForShadow.shadow.camera.left = -200;
  nearLightForShadow.shadow.camera.bottom = -200;
    nearLightForShadow.shadow.camera.top = 200;
    nearLightForShadow.shadow.camera.right = 200;
            scene.add(nearLightForShadow);    

between = new THREE.Vector3();

sun.init(); // sun is an object which give position in the sky according date and position on earth (lat /long )
between.set(0,0,0);
between.addScaledVector( new THREE.Vector3( farLight.position.x-camera.position.x ,
farLight.position.y-camera.position.y ,
farLight.position.z-camera.position.z ) , 0.05);

farLight.position.set(sun.getX() , sun.getY() ,sun.getZ());
between.addVectors(between,camera.position);
     nearLightForShadow.position.set(between.x,between.y,between.);
nearLightForShadow.target.position.set(camera.position.x,camera.position.y,camera.position.z-2);

You can try using cascading shadow maps - see this example:

https://threejs.org/examples/#webgl_shadowmap_csm

hello ,

i ’ m trying to use THREE.CSM() but i does get this error message .

Uncaught TypeError: this.mainFrustum.split is not a function

and in CSM.js there is

initCascades() {

		const camera = this.camera;
		camera.updateProjectionMatrix();
		this.mainFrustum.setFromProjectionMatrix( camera.projectionMatrix, this.maxFar );
		this.mainFrustum.split( this.breaks, this.frustums );

	}

EDIT: in fact my main problem come from background which is a demi sphere with a texture (diffuse ) , so i ve removed it (*) and now i can use my own CSM ( THREE.csm don’t work or i dont know how to use it ) with only 2 source of light . Work very well .

(*) now i use a color for the background which change according hour of the day , move from r:0.133 ,g:0.133 , b:0.2 for the night to r : 0.666 ,g :0.666, b :1 for the day . i 've got a good result for the skybox .

thank for the concept of CSM

1 Like