Oct 152015
 

I realize this effect was done years and years ago by smarter people than me (JT Nimoy, Adam Swaab, among others) but I’m a big nerd for procedural art and wanted to see how I could create the Quorra Heart effect described on Nimoy’s blog here. The effect itself isn’t terribly complicated to do in Houdini, but it took me a while to figure out the best approach (thanks Ray).

Originally I wrote a function in VEX to sample a volume in cross-sections. The volume was just a sphere multiplied against a 3D Perlin noise function. I stepped through the volume grid in a loop, checking to see if the volume’s value was close to the isosurface value I wanted, and then added points where it was. Here’s the code:


float minX = -.5;
float maxX = .5;
float minY = -.5;
float maxY = .5;
float minZ = -.5;
float maxZ = .5;
float interval = 0.004;
float isovalue = 0.001;

int zslices = 15;

// calculate z interval
float zint = abs(minZ - maxZ) / zslices;

for(float x=minX; x<maxX; x+=interval) {
    for(float y=minY; y<maxY; y+=interval) {
        for(float z=minZ; z<maxZ; z+= zint) {
            vector pos;
            pos.x = x;
            pos.y = y;
            pos.z = z;
            //printf("%f",pos);
            float s = volumesample(1,"density",pos);
            if(abs(s) < isovalue) {
                int newpt = addpoint(geoself(), pos);
                setpointattrib(geoself(), "sdfvalue", newpt, s);
            }
        }
    }
}

Nothing too fancy there. Since the volume here is an SDF, I’m establishing a boundary condition around the isosurface value (the value of an SDF volume at the surface is zero) and checking to see if the current voxel is really really close to zero. If it is, I draw a point. That’s it.

This method outlined the shape in an interesting way, but it wasn’t even close to the original effect, and the points weren’t connected to each other which was problematic. I was looking at the problem the wrong way; I didn’t want to sample the volume by planes, I wanted to sample the volume by spheres!

I decided to scrap the VEX approach and do this visually. Houdini’s Cookie SOP can extract curves from the areas where two objects intersect. I just had to create a bunch of densely-packed concentric spheres, extract the intersection curves using the Cookie SOP with the volume converted to a polygon mesh, and then it was done! Very simple effect when it comes down to it.

For the final animation below, I had both concentric spheres and a stacked group of planes intersecting with the volume. The animation is just the Flow parameter of the Flow Noise VOP keyframed from zero to one… this means the animation can loop seamlessly. There’s also a little bit of VOPs work to add color to the intersection points; it’s just a distance lookup between the point’s position and the center of the sphere, fit to a 0-1 range and used to drive a ramp. You could optionally drive the point color based on the point’s distance to the SDF surface by using a Volume Sample From File VOP in a similar manner (the closer your volume sample is to zero, the closer you are to the surface).

Here’s the animation below.

isosurface intersections test 2 from Toadstorm Inc on Vimeo.

I’d like to eventually try to get this working on the GPU in TouchDesigner, but I’m still a total beginner to GLSL so it’ll be a while before I have the chops. If anyone has any tips there I’d love to hear them.