[Remedy animation programmer Henrik Enqvist takes a look at how the team created a believable tweed cloth simulation on the title character's jacket in the Microsoft-published Xbox 360 exclusive horror-thriller Alan Wake.]
The main character in our action thriller is Alan Wake, a writer who gets trapped in a nightmarish scenario where he is forced to fight dark forces while trying to solve the mystery of his missing wife. He is not a well-trained action hero, but rather an everyday guy.
To establish his character our art director wanted him to wear an old tweed jacket with arm patches. As the game takes place in a real-world setting, the tools for giving characters personality are limited, compared to a fantasy game or a space shooter. Therefore the clothes that our characters wear become far more important.
Alan Wake's jacket had to be as believable as possible to maintain the illusion of a thriller atmosphere to the player. The jacket needs to move in the wind and add a nice secondary motion to the character as he rushes through the forest. As a programmer, you immediately start to think about a cloth simulation.
A lot of games before us had already shipped with cloth simulation, but often those methods gave the impression of either silk or rubber -- something that we didn't want. Just recently, some very good third party solutions for cloth simulation have shipped, but at the point when we needed to have a stable solution such tools didn't exist, or didn't serve our needs.
This article will take a look at the challenges we encountered and present the solutions for rolling our own cloth simulation. Even if you are familiar with the methods described here, the way we put things together should make for some interesting reading.
The jacket was modeled together with the rest of the character as a regular skinned mesh. The bones driving the jacket mesh are a separate layer on top of the normal skeleton. The sleeves of the jacket use the normal upper and lower arm setup. Both upper and lower arms are split into one main bone and one twist bone. The upper jacket is driven by look-at constraints and a Verlet simulation drives the lower jacket.
Figure 1. The jacket rig on top of the regular game skeleton.
The jacket bones are parented top-down so that when the upper bones move the lower bones will follow. We were tempted to parent the lower bones straight to the thorax, but that would have caused us to lose motion -- especially the vertical motion in the jacket when the character raises his shoulders.
In the upper jacket, we mimic the motion of real shoulder pads by driving the shoulder bones with look-at constraints towards spots on the upper arms. This way the shoulder pad will follow the upper arm and when the arm is raised the shoulder pad will lift the rest of the bones -- just as a real jacket.
The following bones in the chain are a layer between the upper jacket and the simulated lower jacket. These bones are driven by look-at constraints straight down so that they compensate for the rotation that the shoulders cause. We also added position constraints between the left and the right bone to compensate for the stretching that occurs when the shoulder pads move.
Figure 2. The bones move when character raises his arm.
It might have been a good enough solution to implement the constraints in the animation exporter and bake the results into the animation data, but we still opted for driving the bones in real-time inside the game engine.
This way we could save a few bytes in the animation data and we were also able to easily share animations between characters regardless whether they were wearing jackets or not. Also the shoulder movement generated by in-game IK (e.g. when aiming) became correctly applied when solving the constraints in real-time.
After the upper jacket is solved we take a look at simulating the lower part of the jacket. Most cloth simulations in games have a one-to-one mapping between the vertices in a cloth simulation and the vertices in the rendered mesh.
In our case we wanted to preserve the fidelity of the jacket mesh and not have it held back by any coder-dictated constraints. For example, the silhouette of the pockets and the front part of the jacket would have been lost if we would have settled for a having the same mesh for simulation as for rendering.
Normal maps could have been utilized to give shape to the jacket but we felt that this wasn't enough. Instead we wanted our artists to freely shape the jacket anyway they wanted and then allow them to use the normal maps to add wrinkles or other detail instead of making up for lost geometry.
Our solution to this was to have a low-resolution cloth mesh used for simulating the jacket and then map that to the bones in the skeleton that was used for driving the skinned mesh.
Figure 3. The silhouette of our jacket vs. one that shares vertices with simulation.