Retiming ICE caches
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.
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.
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.
Region A
This section deals with handling the data from the “Cache On File” nodes.
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.
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.
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.
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.
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.
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.
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.
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.





















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
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
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
many thanks for your time.
Rob
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
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
An excellent presentation. Clear. Practical. Insightful. Shows a depth of experience. Thank you. I learned a great deal.
this simply works like a charm.
thanks andy
Thanks Sebastian!
Thanks.. Nice
Leave your response!
Subscribe
Subscribe to the RSS Feed Join me on Twitter
Flickr Feed
Categories
Archives
TD Blogs
Photography
Science Blogs
VFX
Twitter Feed
Tags
Recent Comments
Most Commented
Most Viewed