ICE: Fast volume emission using signed distance fields. And bunnies.

Softimage ICE is fast, no doubt. But, there are more than a few occasions when even ICE grinds to a halt. Dealing with stupid numbers of particles is usually not so much of an issue (as long as you have the memory). But, when all those particles have to interact with geometry, more often than not things aren’t so smooth.

One issue that users may have to deal with very regularly is emitting particles from a geometry volume. The built-in node does a fine job, making sure each particle is born nicely within the limits of the volume. But this accuracy comes at quite a cost. Emitting just a few hundred-thousand points from a polygon cube will leave you yawning. Push that number up into the millions and you’ll wonder if your computer will ever come back…

Fortunately, it’s possible to cut some corners. Literally.

Visualizing Bunny's SDF

One quick way to find out if any point in space is inside a volume is by the use of a signed distance field (SDF). You’ll find better definitions out there, but in this context and very simply put, the value at any point in space around an object (the field) is equal to the distance from this point to the closest point on the surface of our emitting geometry. The scalar value is then given a + or – sign to describe whether it is located outside or inside the object. By sampling a bunch of points around our geometry we can quickly decide if they’re inside the volume and if so they’re probably worth keeping.

This brings up the next great bottleneck of ICE – closest location searches. Locations are probably one of the most useful things in ICE, but finding the closest location on a mesh to any given particle is not fast. And if you have many million particles who need to find locations, things slow way down. Unfortunately, in order to generate that SDF, it’s necessary to search for the closest location on our emitter mesh. But we can be careful about how many particles do this search.

Reading ICE scalar attributes from the mesh to particles

In this example, I’m strictly limiting the geometry location lookups to the points of a regular voxel grid (based around the excellent voxel building algorithm of Guillaume Laforge, that’s part of his Open Source ICE Meshbuilder. Thanks for sharing!). Having found the closest surface locations to grid points, the voxels now represent our SDF around the geometry. Each point having an inside or outside designation. Owing to the regular structure of the voxels, it’s quite easy to linearly interpolate between the values stored on the cells, simply using known point positions of the voxel corners. Now all that remains is to cast enough samples into the field, find their interpolated SDF value and filter out those that are outside of the geometry. The remaining points are the emitted particles. Kinda brute force, but with some optimizations, it’s pretty quick after all.

Mesh normals to particles

Probably the coolest thing about this stuff is that taking advantage of ICE locations, not only can the SDF be interpolated across the voxel grid, but pretty much any attribute that was on the mesh. And at much less cost than doing per-particle location searches.

The speed and accuracy of this solution is mostly dependent on the resolution of the voxel grid. Bump that up too high and things will probably not be much better than before. If you need accuracy, then stick with the factory emitter (which even has some very cool caching features, so subsequent playbacks are nowhere near as slow). Clearly this is a compromise of speed over accuracy, but sometimes that’s ok. It’s often better to get things done a little rough, than not at all.

The below addon includes a simple example SDF volume emitter and voxel setup. It supports transfer of ICE attributes from the emitter geometry to the particles, but is optimized for normals, CAV and vertex properties.

SDF Emitter Addon for Softimage 2010

29.7.2010 – Updated to version 1.02.
22.3.2010 – Updated to version 1.01.

Got a chance to use this in production so I discovered and fixed a few small but important bugs in the command implementation. Also, made default voxel size 10% of emitter’s bounding box. This makes it easier to work with very large or very small objects. Remove previously installed addon before updating.

Example scenes

(Barely tested, so use at your own risk! You may need to restart Softimage after installing the addon)

Links:
Guillaume Laforge
Geometric Data Structures for Computer Graphics
Trilinear interpolation
Interpolation methods
The Stanford 3D Scanning Repository. Thanks for the bunny!

This entry was written by Ciaran Moloney , posted on Wednesday March 03 2010at 03:03 am , filed under ICE and tagged , , , . Bookmark the permalink . Post a comment below or leave a trackback: Trackback URL.

6 Responses to “ICE: Fast volume emission using signed distance fields. And bunnies.”

  • AndyN says:

    Nice job Ciaran. With tools like this it’s getting more like Houdini every day. Look forward to playing with this.

    Cheers

    Andy

  • Steven Caron says:

    thanks for bringing a better understanding of SDFs to us and another tool to solve production problems

  • admin says:

    Thanks. I hope someone can find this useful. I’ve quite a few more ideas on voxel workflows – it opens lots of doors.
    Regarding Houdini, I guess were’re approaching such a level of versatility. But, we need more built in tools like this. It would be awesome if there were a voxel primitive of some sort, which was totally exposed for ICE and for rendering etc.

  • benp says:

    Great! Thanks for sharing, Ciaran!
    Luckily for me, I’m pretty sure the addon and nodes are working correctly under xsi 7.01.

  • Ahmidou says:

    Thanks Ciaran. I just faced the limitations of the stadard volume emiter. I had to wait about 5 mins for it’s initialisation for only 300000 particles……

  • That’s great Ahmidou. I’m happy you’ve found this useful!

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>