Keeping the trend of “things that have been disproportionately helpful” from my last technology posts, today I am going to talk a bit about why curves are awesome. I am a bit late to the party on this one so if you have been working with particle effects during the last five years or at all with animations then chances are this post will not give you a lot of new insights. Sorry!
A little bit more than a year ago, I was working on an effect that needed bubbles – these bubbles were going to grow from nothing to a certain size, wobble a bit by increasing and decreasing their size within a threshold and then finally increase their size again and play a burst animation. The particle system at that time was based around constant ranges for things like velocity, acceleration, growth speed and fade time so it did not support this. All things considered it was not a terribly complex behavior but it was woefully specific – writing a generic system to deal with changing behaviors would take time and go against my principles of not complicating things before we are sure we will need them.
Luckily, I had just watched David Rosen’s talk on Procedural Animation where he, among other things, talk about interpolation curves controlling animation blending and I thought I could use a similar system for the changing size of my bubble particles. For the purposes of this article, a curve is a 2D graph that uses control points to map one value (in Backworlds, it’s usually time) to another one – I could simply use a curve to decide the size of the particle rather than a randomized start size and a set of grow and shrink parameters.
The Backworlds curve has a really simple implementation. It is a template class that takes the max number of control points as a parameter – these are usually pretty few so I opted to go for cache locality and fewer allocations rather than save memory, but the class has an option for using a dynamically allocated buffer as well. Each control point then determines if the values between it and the next control point should be constant, linearly interpolated or calculated with a spline. Since we are usually taking about a few values the curves can read and write to plain text – while this was viable at first I hacked together the editor pictured above in a few hours since we already had functionality for dragging connected points around. As always when it comes to editing content you want to make the distance between data editing and results as small as possible.
The curve editor – or curves themselves – do not support per-node ranges that could improve control of the randomness of values and at some point I might add that and other functionality but again – I do not want to complicate systems before we find use-cases.
The curve is a very simple base object that we replaced most of the particle parameters with – this way, you can control opacity, velocity, rotation, size and some other things as a curve over the lifetime of the particle rather than adhering to constant parameters. The talented folks over at Sucker Punch had a few really good talks about the effects in inFAMOUS: Second Son and the technology behind it that you should check out if you have GDC vault access.
In addition to particles, as in David Rosen’s video we replaced some animation blending parameters with curves – I have mentioned the 12 principles of animation before and having better control over animation blending helps us with anticipation, easing in and out of movement and exaggeration. In addition, a lot of our other procedural effects have some aspect of their systems following the fade in – remain constant – fade out pattern and with curves we can control these without the need to re-implement birth and death durations.
Finally, I am starting to look into some less visible uses of curves. For instance, for the previously mentioned pressure-sensitive tablet input we get a more or less linear set of pressure values but that does not translate to comfortable input. Your pen might be really stiff and never really reaching the values on the far end of the scale, or you might simply want to focus on the mid-range of values – either way, by allowing a controllable curve (with some presets for ease of use) to process the raw input we can accommodate most issues that may arise.
… So a simple curve class can be very versatile. Despite my enthusiasm, we have not implemented it in a lot of places outside of the particle systems yet since I want to avoid a golden hammer situation, but it is a very nice tool to have.