Retiming ICE caches
Motion Blur
If you’re planning on using an optical flow method to generate your motion blur (although it’s not generally recommended with particles) then you don’t need to worry about any of the following discussion. Otherwise you need to ensure that the particle velocity is correct to generate the right amount of motion blur. That’s true whether you’re using motion vectors or rendering motion blur in-camera.
You may already know that Mental Ray uses the PointVelocity ICE attribute to create motion blur. When we load the simulation cache, we’re usually loading a particle velocity with it. The problem arises when we have a particle velocity of, say, 1 m/s that we simulated at 100 fps, but we load the cache at a different frame rate, let’s say at 25 fps for this example. As a result, the particle will appear to be moving at 4 m/s. Since the renderer is still looking at the same PointVelocity value (i.e. 1 m/s), it will be rendered with a motion blur trail one quarter of the correct length.
An easier way to think about it, is that we just need to blur a proportion (usually 50%) of the distance that a particle has moved in one frame. So to calculate the correct velocity, we just take the position of the particle from the previous frame, and subtract it from the current position, and divide it by the Simulation Step.
This is a very easy thing to do in ICE, and I’ll show you how to do it later in this article.
Can’t we use the Mixer?
Wooaah there! Isn’t there an easy way to do particle retiming? Can’t we just cache out the simulation and load it into the Mixer as a clip and use the Warp curve to retime the simulation?
Yes. Absolutely right. Except it doesn’t work.
There’s a bug in XSI which means that interpolation isn’t being done correctly by the Mixer. If you create a simple particle system and slow it right down using the warp curve in the Mixer, you’ll notice that the particle don’t move smoothly.
As a result I had to come up with my own way of doing it. Heck, it’s more fun doing it yourself anyway!
Technical Detail
Before we get onto the ICE tree implementation, I want to briefly discuss linear interpolation, as it forms the backbone of the retime operation. If you’re already familiar with what it does and it’s uses, then feel free to skip this section and move onto the next page.
Linear Interpolation
Linear interpolation is one of those things that every TD should know inside-out. You use it all the time in a variety of different areas.
One simple application of linear interpolation is cross fading between two images. Let’s say we want to crossfade between image A and image B. To specify the amount of crossfade we’ll use a number, we’ll call it t, that goes between 0 and 1. The linear interpolation formula that does the cross fade is this:
Output Image = (Image A) x (1 - t) + (Image B) x t
When t = 0 we get Image A, when t = 1 we get Image B. When t = 0.5 we get a 50/50 mix between the two.
If we give t a different value at every pixel, then we can mix between all the pixels independently. Since t has a different value at each pixel, we could make a black and white image to represent all the different values across the image. If you did that, you’d recognise it straight away. This is just an alpha channel for blending Image B over the top of Image A.
We can also use linear interpolation to blend between positions:
Output position = (Position A) x (1 - t) + (Position B) x t
As t goes from 0 to 1, the output position moves in a straight line from Position A to Position B.
When we retime simulations, more often than not we need to evaluate the cached simulation at non-integer frames. If we are trying to evaluate our cached simulation at, say, frame 12.7, the particles will be 70% between their positions at frame 12 and frame 13, and in this case, t = 0.7. We also need to calculate the interpolated rotation, size, color, and any other attributes that might be altering across the simulation.
Continued on the next page…










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
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