Shuriken – World Particle Collision

November 18, 2012 in Technology

With Unity 4.0 we are adding support for world particle collsion detection. It’s quite awesome and very fast.

We spent a lot of time optimizing world particle collisions and also did more than a few optimizations to Shuriken in general. Especially on mobile devices Shuriken got a very big performance boost.

Multithreading

Shuriken is multithreaded and so is collision detection.

Batching

The reason why particle world collision becomes slow is due to the sheer number of raycasts and complexity of the raycasts performed. We have done several optimizations to minimize this cost.

We added support for batching raycasts. So we first find all PhysX shapes that touch all particles in a particle system, perform very fast cache localized early out culling of raycasts against those shapes on a per particle basis. Only then do we perform any per collider raycasts. This dramatically increases performance because at any one time, very few particles actually need the full collision check.

One side-effect of this approach is that creating small colliders that are axis aligned will give you a performance boost. For example if you have a corridor. It’s a good idea to separate the walls and the floor into separate colliders.This way when particles are simply flying through the corridor without colliding, Shuriken can quickly skip expensive computations. In almost all particle effects, most particles are not colliding during any single frame. Thus it always makes sense to create colliders with slim bounding volumes.

Approximate mode

Yet when you create scenes with massive amounts of particles, for example performing 50,000 raycasts every frame, it can quickly become a bottleneck. Thus we added support for an approximate collision detection mode. It allows you to define an upper limit on the amount of raycasts performed each frame. This gives you complete control over the maximum time spent on raycast collision. Naturally this comes at the cost of particle collision accuracy. In some cases, particles might fall through surfaces or collide with non-existing geometry. In many cases, some particles falling through is invisible to the user since they will just disappear. Especially with a high particle density this becomes unnoticeable. A framerate drop due to lots of particle collision detection on the other hand can be very noticeable.

In order to reduce quality degradation we store previous collisions in a cache, essentially in a voxel grid defined by space and velocity. Each grid has a single plane in the cache which is then reused for all particles that travel through this voxel. If the number of particles exceeds the budget, some particles will perform only cheap voxel lookups and reuse information in the cache. An almost free raycast.

In the particle system you can choose High Quality (always performs full raycasts), Medium Quality (gets a portion of the raycast budget every frame) and Low quality (gets a portion of the budget every couple of frames). Generally speaking any effects that are chaotic in nature work extremely well with low and medium quality mode. Such as smoke, sparks, dust, and precipitation. Low and medium quality only casts against static geometry. And the cache will usually converge fairly quickly, at which point very few raycasts need to be performed while giving very good looking results.

Related posts

Comments (16)

Subscribe to comments
  1. business mover

    January 30, 2013 at 6:42 am / 

    I believe that is one of the such a lot important information for me. And i am glad studying your article. But want to observation on few basic issues, The website taste is ideal, the articles is in reality great : D. Excellent task, cheers

  2. Naked_Chicken

    January 26, 2013 at 3:16 pm / 

    Ah, yes… reading :P Sorry about the duplicate post. I don’t suppose there is an eta on that later release is there? I only ask because I found a possible (but not elegant in any way) solution to a problem in my game, but particle collision would be a much better solution. I’m only wondering if I should implement the ugly solution I came up with or wait a bit for an update.

  3. Jesper Mortensen

    November 28, 2012 at 12:48 am / 

    @NAKED_CHICKEN

    Look at the comment 2 entries above yours (“Collision message” == “Collision event”).

  4. Naked_Chicken

    November 27, 2012 at 5:01 pm / 

    Is there a way to tell the object that it has been hit by particles? The legacy World Particle Collider had the Send Collision Message option, something like that would be awesome.

  5. thienhaflash

    November 22, 2012 at 5:51 am / 

    These kinds of tech-details posts are awesome. Keep up the good work ! Unity3d rules !

  6. Jesper Mortensen

    November 22, 2012 at 12:04 am / 

    > The one thing I can’t find is scripting access to the collision events.
    Collision events – along with a richer set of script bindings – didn’t make it into 4.0. The primary purpose of Shuriken was to make an awesome tool for artists to create effects, because that is it’s primary use case. A more complete scripting API will follow in another release.

  7. Joachim Ante

    November 21, 2012 at 2:00 pm / 

    >What about “particles along spline”?
    You can use velocity over time to do exactly that. You have explicit control with a randomness range over the velocity. This lets you move particles on an exact path.

  8. Cascho

    November 20, 2012 at 11:25 am / 

    What about “particles along spline”?
    Really need particles to move on a predefined path… eg for simulating air or water in a multidimensional pipe …

  9. Dad

    November 20, 2012 at 8:17 am / 

    Second vote for something like this:
    > Cool! It would be nice if you added Physics.BatchRaycast(Ray[], out RaycastHit[]).

    I also have some situations where I have to cast a batch of rays and any help in making that faster would be much appreciated!

  10. CrippleAlex

    November 20, 2012 at 12:36 am / 

    Well done, thats awesome :)

  11. SumX

    November 19, 2012 at 5:59 pm / 

    Keep up the good work!… soon Unity will rule the world!

  12. Ray

    November 19, 2012 at 5:27 pm / 

    The one thing I can’t find is scripting access to the collision events. That my particles can collide with the world is quiet nice, but how can I make them do certain things once they impacted? That, I feel, should be explained somewhere. Does anyone know?

  13. Jashan

    November 19, 2012 at 12:58 pm / 

    This sounds really nice. Great to get these little “feature details” … so I’ve really got to play with Shuriken a little more ;-)

  14. Ippokratis

    November 19, 2012 at 11:34 am / 

    Hi,
    Nice feature.
    A sample project would be much appreciated.

  15. Georges Paz

    November 19, 2012 at 11:22 am / 

    You guys are really sick. Keep it up the momentum. Don’t stop the greatness! :D

  16. romeo_ftv

    November 19, 2012 at 8:21 am / 

    Cool! It would be nice if you added Physics.BatchRaycast(Ray[], out RaycastHit[]).

Comments are closed.