Computing Shield Shapes
Today I decided to give shields a shot. The question of how to compute the shield mesh has been in my mind for quite some time. At first I thought about not having any shape at all, and simply using a distance offset when raytracing weaponry to simulate shield hits (the result would be an implicitly-expanded mesh). But then I wouldn't be able to do any sort of global graphics effect, which would be a shame...shields definitely lend themselves to cool graphics, and I like cool graphics!
To that end, I spent part of the day trying to compute shield meshes for arbitrary shapes. The first thing that comes to your mind is probably a convex hull, or some smooth and expanded version thereof. I'm sure that would work just fine, but it's a little heavy-handed for my tastes, so I wanted to try a more intuitive solution.
The first attempt was really an obvious one: point-repulsion. Create an expanded sphere that surrounds the ship, then try to collapse it, while applying repulsion forces from the ship's vertices. In theory it sounds pretty great, and intuition tells me that the resulting shape would be lovely and smooth. We could also apply spring forces between edges on the sphere to ensure a nice vertex distribution in the result. Unfortunately, this method failed pretty miserably, mainly due to computation time. It's expensive. To collapse everything nicely, you need a lot of iterations, and each iteration is very expensive without acceleration. Here's the result after only a few iterations:
Smooth, but quite ugly, and doesn't really capture the shape of the ship. To make it better, you'd want to decrease the repulsion force. But then you'd have to integrate very slowly, otherwise you end up missing the vertices and collapsing the shield into the ship, resulting in a shield that won't do a very good job of shielding! I saw this happen a lot with this model. Again, I think it's a fantastic idea in theory, and would probably provide the highest quality of mesh, but it's not feasible for real-time...it just needs too many iterations and a very small integration step.
Next thought: raytrace it. Take the sphere, raytrace to the center of the ship's bounding box, and add some offset to expand the result. This is much faster, since it's not an iterative method. Unfortunately, the results are still mediocre:
Better, since it definitely captures the shape of the ship in only one iteration. Sadly, it's not very smooth. To make it smooth, you could smooth out the mesh with a mass-spring system postprocess, but then you're going back to iterative. However, that's not the main problem - like the last method, this one often results in shields that are collapsed into the ship, especially when the ship is thin and has long pieces sticking out (like engines). We just can't accept degenerate shields, as they'll not only look terrible, but will prevent your shields from doing their job!
Ok, third time's the charm, right? Right!!!
This one's fast, smooth, non-iterative, and, most importantly, non-degenerate! Great! What's the algorithm? Well...can't give all the Limit Theory implementation away! But, if you look very carefully at the shield vertex distribution, you can probably guess it 😉