Sun and shadow with mesh subdivision

with No Comments

Suppose you have a bunch of buildings and want to analyze the shadows cast on one building by all the other buildings. Let’s say you have a triangle mesh describing a flat wall. It could be a very simple mesh with two triangles. Another building somewhere else casts a shadow on the wall. How does the shadow on the wall interact with the wall’s mesh structure?

You could divide space into two volumes, the part of space exposed to sunlight and the part of space not exposed to sunlight. In this case, the shadow line on the wall shows the intersection of the wall with the boundary surface between the two volumes of space. The intersection line would be a polyline and you could use this to remesh the wall into a mesh compatible with the shadow line. But this method could get pretty complicated with a lot of other meshes casting shadows.

An alternative approach is to pick a face and check whether each vertex is in the light or shadow. This check can be done with a ray cast towards the sun. If all vertices of a face agree about whether they are in the sun or the shadow, the whole face is considered to be in the light or in the shadow. If the vertices split the vote, then that face gets subdivided. Check for sun or shadow on the new vertices, and continue to subdivide as necessary. Adjust the mesh to preserve triangularity. Repeat the process until a desired resolution is obtained. Here’s how the light / shadow boundary appears after a few steps of subdivision:

forblog

This way, one can selectively increase resolution where it’s needed, on the light / shadow boundary. That’s the basic idea, on top of which one can add a few simple tweaks, such as an initial subdivision stage for the original mesh in order to detect shadows from objects with a specified feature size.

Here is an example, displayed using libigl‘s viewer, of light / shadow division for a mesh representing the ground.
The first image is in the sun, the second in the shade. The sun is directly overhead.

ground_light

ground_shadow

Leave a Reply