After about a month's work, Paul and I finally have some presentable
results for our new animation technology, DMorph. Before I go into a
long-winded explanation, here's a demo of DMorph in action:
http://plasmacore.googlegroups.com/web/dmorphdemo.zip?gda=goQAa0AAAABu4IqxsQXUD9yENdTBOsDRji4ffCA2sP1g46d8RZeCha_NdAXFUXO5_RKvef59crptxVPdW1gYotyj7-X7wDON&gsc=bkpV-BYAAAA6zKqIuJ5rpLPxzKAPxtzv-vghgYgES8zAzJdW7J9-8w
The cow and dog animations on top are DMorph objects, and on bottom
are the source frames. DMorph is interpolating the source frames on
the bottom to create the animation on top. I also included a regular
morph, just for fun. You'll notice that you can switch into "ugly
mode" by pressing 'u,' which I'll explain later.
DMorph uses a variation on the old-school technique of morphing that
was made popular in movies like Terminator before 3D became
mainstream. Essentially what's happening is a crossfade between two
images that are dynamically warped so that the features in the
crossfade line up. This leads to a very natural, organic, transition
between images. Traditionally this is used to make characters
shapeshift, like turning a man into a werewolf, but Paul and I had the
idea that the effect was much more useful as a way of smoothing out 2D
animation. We used pre-rendered morphs to animate all the objects in
MadStone, and over Christmas break I realised that with just a few
tweaks, the effect could run in real-time. Paul wrote a fantastic
command line/GUI hybrid editor that can morph whole sequences of
images to create complete animations. It's really awesome:
http://plasmacore.googlegroups.com/web/dmorphedit.jpg?gda=tZziNUAAAABu4IqxsQXUD9yENdTBOsDRji4ffCA2sP1g46d8RZeChYyoGbTF9Y51Pst29jKdyBdtxVPdW1gYotyj7-X7wDON&gsc=bkpV-BYAAAA6zKqIuJ5rpLPxzKAPxtzv-vghgYgES8zAzJdW7J9-8w
The benefits of using DMorph are:
1. Animators can get away with creating much less animation
2. All your animations can now have the same frame rate as the rest of
your game
3. You get all the smoothness of vector animation with the carefully
crafted look of pixel art
4. Subtle animations can be created, like trees slowly waving in the
breeze, that would be almost impossible to animate by hand
5. You don't need to spend as much texture memory storing in-betweens
The limitations / drawbacks are:
1. Depending on the number of mesh points in the object, DMorph
objects require significantly more polygon renders than a normal image
2. The artist has to define warp meshes between each pair of frames.
This is quite time consuming
3. Objects that have appearing and disappearing elements don't morph
well (Notice buck's back horn in the demo). Layering can be used to
solve this.
4. Partially transparent objects don't morph well (more on this later)
So far I'm really happy with the results and we intend to use DMorph
heavily in our next WiiWare game. However, there is still one major
improvement we can make, but I think it will require direct support
from Plasmacore:
Try pressing 'u' in the demo to enter ugly mode. This is really just
the same morph animation of Buck, but a lot bigger. You'll notice that
the edges of the object seem to pulse. This is because of a limitation
in the crossfading method we're using. A true crossfade takes a
weighted average of the pixels in the source and target image. This
creates a smooth crossfade that properly supports alpha. However, the
only way to simulate this effect currently in Plasmacore is to draw
two images on top of each other. This creates some problems.
1. The obvious solution, which is to fade one image out as you fade
the other in, results in an image that is 25% transparent in the
middle of the fade.
2. The second most obvious solution is to fade in the target image on
top of the source image without changing the source image's alpha.
This is what we're currently doing, and it's what's causing the
unsightly pulsing of Buck. As the second image gets drawn over the
first image, the alphas of the pixels increase, causing anti-aliased
edges (and any other partially transparent regions) to pulsate. This
solution also has the problem that the target image must be faded in
over the source image, and then held while the source image is faded
out. This makes for a significantly less smooth transition.
I think the solution of this is to create a custom render function for
DMorph. Basically, we'd need to render a quad or triangle with a
texture that is a weighted average of two source colors, including
their alphas. Their source texture coordinates would need to be
different as well. So if A and B are the source colors, W is the
weight, and R is the resultant color, the result would be:
R = WA + (1 - W)B
I *think* this can be done on Wii, DirectX, Mac, and hopefully iPhone,
using custom texture stages. I'm not familiar enough with these APIs
to figure it out though. I think DMorph has the potential to really
enhance our work in 2D, so I think it would be worth figuring out how
to make this improvement.
If anyone is interested in using the beta version of the DMorph source
code or editor, let me know and I'll post it here.
Thanks!
Jacob