6
\$\begingroup\$

How to render metaballs?
I am a Python programmer familiar with the Panda3d and Blender3d APIs. My math kinda sucks, but I know enough to write game logic code and procedural model generation code, as well as importers/exporters for the 3d modeller Blender. So you kind of get my level of experience. So can anyone explain or link to a tutorial which explains what needs to be done, without advanced math or with mentioning what math concepts are needed?

This is what I want to achieve:

http://www.youtube.com/watch?v=dEipENLes10
http://www.dailymotion.com/video/xn3xfn_mercury-meltdown-psp-un-trailer-pour-mercury-meltdown_videogames?search_algo=2

Though with probably more metaballs on screen at the same time.

\$\endgroup\$
5
  • 7
    \$\begingroup\$ Yousa looking fora spicy metaball or a smootha metaball? \$\endgroup\$
    – Tim Holt
    Commented Aug 16, 2012 at 23:21
  • \$\begingroup\$ "The uploader has not made this video available in your country." That might just be because I'm at work and sometimes our stuff goes through India..., but consider the Indian users. \$\endgroup\$
    – House
    Commented Aug 16, 2012 at 23:45
  • \$\begingroup\$ For what it's worth, it's also not available in the US, so the audience is rather severely limited... :P \$\endgroup\$ Commented Aug 16, 2012 at 23:48
  • \$\begingroup\$ dailymotion.com/video/… \$\endgroup\$
    – user17402
    Commented Aug 16, 2012 at 23:49
  • 1
    \$\begingroup\$ Mercury was definitely using marching cubes to do its rendering (Although when the blobs were the size of a particle we just rendered a sphere). \$\endgroup\$
    – Goz
    Commented Mar 5, 2013 at 8:53

3 Answers 3

7
\$\begingroup\$

One option is to use Marching Cubes. There are plenty of tutorials and example code in the Internet such as this. Implementing this is not very easy, but doable.

Thanks to the increased power of computers and especially GPUs, raycasting has also become a fast enough solution for rendering metaballs and other surfaces. Check for example this tutorial. This should be easier to implement. The downside is that it might not fit to the rest of the 3D engine as well as polygonizing the metaballs.

\$\endgroup\$
1
\$\begingroup\$

Unfortunately, 'without advanced math' is a fairly high bar to set for this particular tutorial, because the topic is inherently fairly advanced; metaballs are just a more colloquial way of talking about a particular type of isosurface visualization. The simplest way to conceptualize it may be to imagine taking everything down a dimension; imagine that you're working on a plane (or technically the surface of a sphere) rather than in space, and consider a classic heightmap; then the coastline of the terrain represents one isosurface: it's the set of all the points on the map where the height (the elevation above sea level) is zero. Now, suppose that you had a bunch of elevation data and you were asked to draw coastlines. One approach would be to (somehow) find one spot along a coast and then 'follow that coastline' until you get back to your original point — but that requires you to find that first point, and when you complete your loop you can't be sure whether you've missed anything (imagine tracing the coast of England and entirely missing Ireland in the process).

Instead, you might try an approach where you scan over your map pixel by pixel, looking for spots where you have two adjacent points, one above water and one below, and then carefully drawing a line that cuts between the two, somehow making it match up from pixel to pixel. The generalization of this idea from two to three dimensions is commonly known as the marching cubes method, and it's the most common algorithm for rendering isosurfaces; things are somewhat more complicated in the 3d case than in 2d (since you effectively have 256 cases, one for each of the 28 possible assignments of 'above surface' and 'below surface' to the vertices of a voxel), but the core ideas are the same. Note that even pretty low resolutions on your grid can give good results for this; the demo you linked to is probably running the Marching Cubes algorithm on a 32x32x32 (or likely even 16x16x16) grid and it looks perfectly reasonable doing so.

This leaves open the question of just what your heightfield is, of course — I don't have time to go into that side of things right now (although some searching should find you a handful of different potential functions), but I'll try and flesh this answer out a bit later to give some of the details on that front too.

Of course, because you're essentially dealing with n3 pieces of data (the values on an n x n x n grid) then even fairly low grid resolutions can get expensive pretty fast. With the right potential function, though, you can use interval arithmetic to bound the values of your potential function on larger chunks of space and cut down on the number of actual calculations you have to do; essentially, this is applying octree-style spatial partitioning to the metaball problem.

\$\endgroup\$
5
  • \$\begingroup\$ Correct me if I'm wrong, but Ireland's coastline isn't connected to England's coastline. \$\endgroup\$
    – Pharap
    Commented Jan 18, 2015 at 11:31
  • 1
    \$\begingroup\$ @Pharap That was exactly my point - if you're trying to get the coastline of all of the British Isles, then starting in e.g. Brighton and 'walking' the coast will miss an awful lot of it. If you didn't know that there was another island you'd have no idea that you weren't done. \$\endgroup\$ Commented Jan 22, 2015 at 2:30
  • \$\begingroup\$ You said England's coastline, not the British Isles' coastline. England's coastline excludes Scotland, Wales and Ireland. \$\endgroup\$
    – Pharap
    Commented Jan 22, 2015 at 7:58
  • \$\begingroup\$ @Pharap Mea culpa; I'll try and revise the example - what I was trying to get at was that it was like trying to get all of the British Isles, but only getting England itself because that's where you started. A slightly less complicated case might make things easier to grok. :/ \$\endgroup\$ Commented Jan 22, 2015 at 8:19
  • \$\begingroup\$ It's understandable why you made the mistake, a lot of people (even the ones from England and other places in Britain) think England == Britain and use the two interchangeably. Normally you'd only end up upsetting the other residents of Britain who aren't English, but in this case it's more a matter of the analogy's correctness which is a far larger concern. Clean that up and I'll upvote, delete my comments and pretend it was always that way. \$\endgroup\$
    – Pharap
    Commented Jan 22, 2015 at 14:00
0
\$\begingroup\$

There is another quite impressive solution for this problem using GPU based raycasting approach together with Depth Peeling and Bezier Clipping algorithms.

Implementation is not straightforward but performance is worth it. Please check the white-paper.

Not sure if Python is good idea for such problem since is more related to shader programming.

If you still interesting we can collaborate together to solve this problem. I suggest to use tooling like Godot, Unity or Unreal

\$\endgroup\$

You must log in to answer this question.