Home » Featured, ICE, XSI

Retiming ICE caches

2 October 2009 5,474 views 9 Comments

The ICE tree Implementation

The image below shows the exact setup that I used to retime my particles for the Sky Sports “Super Sunday” ident.

ICERetime_MainTree


You can ignore the nodes at the beginning and end of the ICE tree (extending from ports 1 and 4). Their purpose was to force the loading of a custom particle ID that was used to set the particle instance shapes (the forced loading of attributes was covered in a previous post).

Port 2 of the ICE tree evaluates the nodes that load the cache and evaluate the interpolation of the important parameters. In case you’re wondering, I had to split the retime compound into two parts, A and B, since the Cache On File nodes don’t allow you to promote the File Path parameters to a parent compound.

Port 3 deals with calculating the correct PointVelocity attribute to make sure that motion blur is rendered correctly.

The discussion that follows examines each part of the ICE tree shown in the above screenshot. Make sure you refer back to this image so you can understand how it all fits together.

The Retime Curve

To control the speed ramping, I use a custom parameter to import the animation from the master retime curve for that particular shot. (The master retime curve was generated during the edit from Final Cut Pro.) This is shown in the ICE tree as the Get Data node pulling the parameter this_model.CacheTimeWarp.WarpCurve. It’s always essential to use the this_model keyword, as it means that your ICE tree can be easily duplicated, moved to another model, and reused.

From the value of the retime curve, I calculate which frames need to be loaded in for interpolation, as well as how far to interpolate between them. The details on how this is done follow.

The “Retime Particle Part A” Compound

This compound simply calculates which frames we need to load in for interpolation.

For example, if we have a retime curve value of 12.7, then we need to load frames 12 and 13 and interpolate 70% between the two. These upper and lower values are calculated using the Floor and Ceiling Ice nodes.

ICERetime_PartA


The “Retime Particle Part B” Compound

This compound deals with the loading and interpolation of the particle data. I’m going to break the explanation down into smaller parts (marked with letters A-E) to make it easier to follow.

ICERetime_Interpolate


Region A

This section deals with handling the data from the “Cache On File” nodes.

ICERetime_RegionA


When you load data using a Cache On File node, it automatically overwrites any data that might already exist, but it leaves other data untouched. This means that if we want to interpolate between two cache files, we need to load one, store the data in temporary attributes, and then load the other file. With all the data loaded, we can then interpolate between the current values and those stored in the temporary attributes.

This is exactly what is happening here. You can see that we first trigger the execution of Cache A to load the data from the first frame. The “Store Particle Data” compound stores relevant data in some temporary attributes, and then we trigger the execution of Cache B to load the data for the next frame.

ICERetime_StoreData


Inside the “Store Particle Data” node we go through most of the common attributes and store them in temporary attributes. These values will be used for interpolation later. You may need to add more attributes to this list if you’re using some of your own custom attributes in your cached ICE tree.

You’ll have noticed that after we execute Cache B, there are three nodes plugged into Port 4 of the ICE tree. These do a quick check to see if the particle existed in the previous frame; if it doesn’t we delete it. To figure this out, I’m doing an extremely simplistic check to see if the previous particle position was at [0, 0, 0]. If it was, then I take this to mean that the particle wasn’t in existence and has only just been birthed.

ICERetime_CompareVector


If you don’t put this check in, you’ll have problems with particles appearing to being born from the origin and streaking across to the emission location in a single frame (or more if you’ve slowed the cache down). This technique will solve this problem as long as you never want to have your particles located exactly at the origin, which in practice is fine in 99% situations. If it ever does cause a problem, then you can either move the point cloud itself away from the origin, thereby giving an offset in position, or you can use a custom attribute to do the detection.

Region B

This is where we start doing the interpolation.

ICERetime_RegionB


The first thing we need to do is to calculate how far we are in between the two frames, i.e. are we closer to the beginning of the frame, or to the end? This is easy to figure out as I’ve given the compound the lower frame value (the Frame A input) and the actual frame value (the Current Frame input). All we need to do is subtract the first from the second.

As an example, if our Current Frame input is 12.7, then the Frame A input will be 12. The frame fraction will be equal to: 12.7 – 12 = 0.7. So we are 70% between frames 12 and 13. We use this value for all the linear interpolation that follows.

The first two attributes that get interpolated are position and orientation. Luckily, the Linear Interpolate ICE node knows how to handle interpolations of orientations. It uses a mathematical tool known as a SLERP (Spherical Linear intERPolation) for interpolation between orientations expressed as quaternions. You don’t need to worry about how it works.

Region C

This section shows the interpolation of Size, Scale, and Age.

ICERetime_RegionC


Region D

This section shows the interpolation of Color and Force. Note that often the easiest way to deal colors is to convert them to vectors. In a way, it’s a shame that XSI doesn’t just treat them the same.

ICERetime_RegionD


Region E

Finally, this section shows the interpolation of Mass and Velocity. Even though I calculate the velocity later in the tree (outside this compound) to fix the motion blur, I thought there might be situations where it would be helpful to have this value around anyway as it represents the real world simulation velocity that doesn’t alter with the frame rate.

ICERetime_RegionE


Calculating the correct velocity for motion blur

Finally, we need to address the motion blur issue I mentioned earlier. I’ve already said how and why this is done, so it just leaves it for me to show you the ICE tree that does it.

ICERetime_CalcVelocity


Conclusion

So that’s it. You should now know how to retime your particles and deformations in ICE. This solution seemed to work really well on the Sky job that we did and is something I’ll almost certainly be using again at some point. I’ll probably still end up using this method even if Autodesk fix the interpolation bug in the Mixer, because this way gives you so much more control.

Finally, here’s an excerpt of a screen capture of the particle system simulated at 100 fps. Immediately after it, you’ll see the corresponding finished sequence. Notice the difference in speed and duration, as well as the slow down to 100 fps as Wayne Rooney kicks the ball at the end.


A big shout out to Justin, Tom and all the other very talented guys who worked their butts off on this.

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading ... Loading ...

9 Comments »

  • Rob Chapman said:

    Hi Andy , Great Tutorial & very informative. I was going through this because I wanted to slow down an existing simulation by half which was captured at 25fps without having to resimulate at 50fps

    I think ive got it working by plugging the current frame into the warp fcurve input and adjust the fcurve so that the value say at frame 150 = 75 AND Swapping the ceiling & floor around in the ‘Retime Particle A’ compound. what you recon? am I flawed in thinking this works? it looks ok so far :)

    thanks again

  • AndyN (author) said:

    Hi Rob,

    You shouldn’t need to swap the floor and ceiling nodes. By my reckoning, it’ll make the particles interpolate the wrong way round as it goes between the surrounding frames. You know… thinking about it, the fact that you’ve slowed it down by a factor of 2 means that you won’t notice this happening, as you’re only ever seeing it half way through the interpolation (at t=0.5 it doesn’t matter which way round you get there).

    If you try slowing it down by a factor of 10, I’m pretty certain you’ll see the particles interpolating backwards and jumping around as a result. In fact, this is exactly what the Mixer does at the moment, which is the bug I mentioned on page 2. Let me know if this is what happens with your setup.

    Anyway, I’m glad you found the tutorial useful. Thanks for the comment.

    Cheers,

    Andy

  • Rob Chapman said:

    Aha yes you are right. setting a different speed other than 0.5 makes the cache playback all over the place. oh well I’ll just resim at 50fps and keep the compound for speed ramps which im positive will be needed in the future :D

    many thanks for your time.

    Rob

  • Jasper S said:

    Thanks for the tutorial, very well written and explained. Even a complete ICE-noob like me managed to recreate the compound (and learned quite a few things along the way).

    Like Rob above, my aim was to slow down a simulation, no ramping involved. I took out the fcurve node and replaced it with a ‘current frame’ followed by a ‘multiply’ – this seems to work correctly, no jumping around of particles.

    The only thing I’m having problems with is the motion blur fix – the ‘get self.pointposition at previous frame’ node. Is it a ‘get data at previous frame’ node referenced to self.pointposition? I get 0,0,0 value out of that (checked with expose value hack node). I suppose I’m doing something wrong there.

    (As said, I’m new to ICE, so forgive me if this is too easy to answer)

    Jasper

  • AndyN (author) said:

    Hi Jasper,
    Good to hear that you found the tutorial useful.

    Yep, you’re right; the “Get self.pointposition At Previous Frame” is exactly what you said it is. I’ve recently discovered that there are some issues with this node if you’re doing any deletion or cloning of particles, but otherwise it should work okay.

    It’s hard to give advice without seeing your ICE tree and setup. If you want to email me a screen shot, I’ll see if I can help. (I’ll send you my email address in a sec)

    Cheers

    Andy

  • abacus center said:

    An excellent presentation. Clear. Practical. Insightful. Shows a depth of experience. Thank you. I learned a great deal.

  • sebastian said:

    this simply works like a charm.
    thanks andy

  • AndyN (author) said:

    Thanks Sebastian!

  • Siaamak said:

    Thanks.. Nice

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

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

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.

Security Code: