# Marching Cubes using Pixel Bender: Metaballs / LoFi 4D Julia Set

As promised in my previous post, I would elaborate on some of the things done for the demo. So I’m taking a quick break from work to get this post done :)

Marching Cubes

One thing I did was implement a marching cubes algorithm using Pixel Bender, which is a way to triangulate an isosurface in a scalar field. I had started to write up a whole explanation, but realized it was kinda pointless, as it has been covered plenty of times :) If you’re interested, you’re better off reading up about the subject starting here and here.

Pixel Bender

I know there’s plenty of marching cube implementations in ActionScript out there, but I haven’t seen one using Pixel Bender, so I thought I’d give it a try. I’m using it to calculate the values in the scalar field (at least on the marching cube’s grid corners), and to build the pattern ids needed for triangulation. The benefit of using Pixel Bender is that you can put in any kind of calculation that outputs scalar values, some of which you wouldn’t dare to put ActionScript through. The drawback is that it seems to have some precision problems while doing comparisons (or so it seems), so there’s some missing triangles on occasion.

No transforms, no sorting

Something I’ve realized that’s pretty neat about this algorithm is that you don’t actually need sorting. As long as you make sure the grid is aligned to the “camera” at all times, the triangulation occurs back to front and will already be correctly sorted. This of course means you can’t do any rotations on the triangles, but that’s no big deal. You can simply perform the transformation on the grid coordinates, and let the correct values be calculated for those points. Added bonus, you can do any scaling and translations together with the projection matrix in one call to Utils3D.projectVectors, annihilating the need for any calls to Matrix3D.transformVectors. Result: some extra fps.

Metaballs

Metaballs are probably the most iconic example of isosurfaces out there (bar MRI and CT imagery). It was actually my test data for the MC system, but it ended up making a sneaky appearance in the demo (which I still consider a tribute to the undisputed king of ActionScript sticky substances ).

> Metaball demo (click to change textures)

Quaternion Julia Set

Another example I did was to triangulate a quaternion Julia set, which seems pretty popular lately ;) It definitely looks better raytraced, but I couldn’t resist! I’m using the distance estimator function to produce the grid values (see here), and an epsilon distance as the surface’s isovalue. Since things always look less crap with music, I added some for a change.

> Quaternion Julia Set Demo (might take a while to load the mp3)

Source

The marching cubes thingy, as well as the metaballs example source is up for grabs at Google Code . Enjoy! If you make any surfaces with it, I’d love to see them :)

## 11 thoughts on “Marching Cubes using Pixel Bender: Metaballs / LoFi 4D Julia Set”

1. Incredible demo! It’s gonna take me a month just to understand the code, but I’m gonna give it a shot just the same.

2. Thanks for sharing the source David, im starting to study PixelBender and it’s very good to get some great reference to look at :D

3. Beauty at its best!

Nice work David!
damn nice!

4. it sucks!

..

ok, it rocks, as always…. just like the demo with simo… pfff

yet I think that using the marching tetrahedra algorithm instead of the marching cubes would cut the computation time by… well… a signifiant uint. this will need a thourough take, I’ll let you know if I achieve something :)

PS I just noticed that I have unconsciously chosen the same template as you…

5. Your work is inspiring to say the least. This sort of experimentation is why allot of Flash developers got into the industry to begin with! As said by other users, thanks for sharing your exceptional work.

6. Lev says:

thanks for the fabioulous metaballs-example. it seems, that there are great differences for internet explorer (your example does not work at all, but in my changed code, it just requires huge camera translation to make it visible (ie: z=-20000, firefox: z=-1500)

why is this, does anybody know anything about that?