Good Normals for Metaballs

The Problem:

Environment mapping metaballs is cool, but not when your normals are messed up! A lot of people generate normals for their metaballs by looking at the finished mesh and doing a bunch of cross products at each face to make the normals for the vertices. Even when you add and renormalize these, they still look like crap! Check it out:
nasty normals god don't even try env mapping with em

The Solution:

Hey, let's admit it. Every once in awhile math is actually useful, and this is one of those cases. To make the metaballs we defined some function F(x,y,z) that given a point in 3d space returns some value. (this function is usually some variant of summing the distances to the metaball centers) The image we see is just one surface inside that field where the value of the function is constant. Now for the normals what we want is a unit vector that points in a direction perpendicular to the surface. We can generate this by creating a vector composed of the partial derivatives of F. Like so:


this gives us the change along each axis of the function at a given point... exactly what we want for the normal. It's called a gradient and you can apply it to whatever function you are using for your field. In the above images the field was defined as:

where (a,b,c) is the center of a metaball. The gradient of this is:

This gives us the normal at each point in space. If we have multiple metaballs we just add up the results of the function for each one. Here's what the mesh looks like using the new normals.
ahhh much better mmmmmmmmm

For your amusement here are some refractive metaballs. Click to watch the animated gifs.

Conclusion:

If you already knew how to make proper metaball normals, good for you. If not, now you do. Have any questions or comments? Email jimscott@blackpawn.com.