Shadow Mesh Generation

This is a technical test that I am currently working on in Unity. I started it for a Creators Jam in the winter of 2021 and have since updated it to work better and faster. It uses a marching squares algorithm to contour the shadow off of a surface with raycasts and uses tyhat to create an interactable mesh. I have recently added multithreading to the triangulation marching squares algorithm, reducing the time to generate a mesh from ~0.9314 seconds to only ~0.127

Features/Things I built:

  • Raycasting
  • Mesh Generation
  • Marching Squares Algorithm
  • Multithreading

Shadow detection and Marching Squares

The system first starts by sending a ray out from the camera to a point on the surface its facing. Using the normal vector from the point the raycast hits, the function creates a 2D grid of points and checks each of them to see if they are shadowed. It accomplished that using simple raycasts to any nearby light sources. Next, once each of the points have been given values, they are triangulated using the Marching Squares algorithm. In addition to the current square, points are also created and given triangles for the opposite face and any side squares, if on the edge. Once all the points have been triangulated, those points are put together into a mesh to create the shadow, which can then be instantiated

Optimizing and Multithreading

The primary issue with the system as it was first built is how long it takes to create the mesh. It wouldn't be suitable as a game mechanic if there was a full second wait each time. After some testing I determined the two largest time sinks. The first was node creation, as it used both raycasts to each light, as well as an expensive physics function to see if the point is actually on the surface, as well as some inefficient looping creating unneccisary function calls. The second and bigger issue was the actual triangulation, due to how many points that were needed to be calculated. I was able to optimize the looping for the first issue, but couldn't take out the expensive calls. I could, however, reduce lag by implementing multithreading. After playing with rudimentary threads, I settles on using Unity's Job system, which allowed me to move almost all of the triangulation calculations out of the main thread. Doing so increased performance sevenfold, with the game handling much more smoothly.

scroll-up