I’ve been trying to add shadows to my huge terrain. I’ve been thinking it would be best to add the shadow to the camera so while to camera moves around the shadows are only rendered for whats within the view of the camera.
Here is my attempt:
let root = new THREE.Group();
root.position.set(-3500, 50, -7800); // edge of terrain at -20000, 0, -20000
let light = new THREE.DirectionalLight(0xfffffff, 0.5);
light.position.set(0, 1, 0);
light.castShadow = true;
light.shadow.mapSize.width = 512;
light.shadow.mapSize.height = 512;
light.shadow.camera.near = 0.5;
light.shadow.camera.far = 500
I also did not forget to enable receiveShadows on the terrain and castShadows on the objects on the terrain.
But I only get this:
The shadow camera seems too small. But, if I make the map size beyond 4096, it just slows everything down.
What are my options here? I wanted to have soft shadows from a little angle from the top as if its around afternoon.
Yep, I also did that. Including setting the type of shadows to soft. The terrain consist of 1 big mesh, with about 225k vertices and about 500k+ faces. I know I should optimize this in someway but that would be another question as I have no idea. But for now, I’m having issues with shadows.
Unfortunately I can’t host it on websites like JSFiddle as I cannot include the object data. If you don’t mind, I uploaded it to my website. But I did cut it down to the simplest script with the problem.
Please try to switch to MeshPhongMaterial to see if it helps. Shadow quality with MeshLambertMaterial is poor in any case. It’s not a good choice for rendering shadows.
Besides, there seems to be something wrong with the normal data of your geometries. When I set the intensity of the ambient light to zero so only the directional light illuminates the scene, it looks like so:
Should I just let THREE.JS calculate the normals? Instead of adding them from my assets?
I tried changing all materials from lambert to phong. Removed the ambient light. Tried fixing the normals to no success.
And I got this:
I’m starting to see shadows but I guess the normals issue is causing problems. The data is from DirectX so I tried multiplying the first part of the normals by -1 to make it work for OpenGL/WebGL. Maybe I’m doing ti wrong.
So I decided to just discard all normal data and let THREE.JS calculate all of it. Added the ambient light back to the scene and got this:
Still not very sure about the shadows though. Might be the positioning of the directional light?
I figured that out before, so that line is now gone. I also added my mesh as light.target which made the mesh look better. But is seems like the light is coming from another direction than the frustum. Do you have any idea where to start debugging this? I thought the frustum represented the bouding box for the light?
Thank you! That explains a lot. I have two follow up questions in that case:
how can I move the camera helper upwards aling the z-vactor? Would like to add a plane so that the buildings cast shadows on the ground. It still seams like the shadow camera is located at a point at the plane geometry that I want to cast shadows on.
Is there a similar way to display where the light comes from? Would later on like to connect the sun poistion to longityude and latitude in mapbox