It is always cool when developers reveal technical information about their games, especially when it is a team that has done really good work and you’re likely to pick up some good nuggets of information. One of the most interesting presentations of late was the Capcom MT Framework presentation (in Japanese) from CEDEC 2006 posted by the Japanese site Impress Watch.
For those of us who don’t read or speak Japanese beyond a few sushi terms (“shiraku kudasai”), one can always try to use Altavista’s Babelfish or Google’s language tools to translate an article, often with mixed results. (BTW, note that Babelfish has some languages that Google doesn’t have.) Thankfully, if it is a good article, you often find some nice soul posting a better-quality translation to somewhere.
One place you often find Japanese tech article translations posted to is the Beyond3D forums, and indeed, the previous article had two translations posted: first a rough one and then a more extensive one. It turns out the Capcom presentation covers a number of cool techniques and neat tricks, and I thought I’d highlight the ones I thought were particularly noteworthy (but in no particular order).
Normal-map encoding trick
One clever thing they do (as mentioned on these two slides) is to encode their normal maps so that you can feed either a DXT1 or DXT5 encoded normal map to a shader, and the shader doesn’t have to know. This is neat because it cuts down on shader permutations for very little shader cost. Their trick is for DXT1 to encode X in R and Y in G, with alpha set to 1. For DXT5 they encode X in alpha, Y in G, and set R to 1. Then in the shader, regardless of texture encoding format, they reconstruct the normal as X = R * alpha, Y = G, Z = Sqrt(1 – X^2 – Y^2). The only additional cost over the “normal” way to decode, is the added multiplication.
A DXT5-encoded normal map has much better quality than a DXT1-encoded one, because the alpha component of DXT5 is 8 bits whereas the red component of DXT1 is just 5 bits, but more so because the alpha component of a DXT5 texture is compressed independently from the RGB components (the three of which are compressed dependently for both DXT1 and DXT5) so with DXT5 we avoid co-compression artifacts. Of course, the cost is that the DXT5 texture takes twice the memory of a DXT1 texture (plus, on the PS3, DXT1 has some other benefits over DXT5 that I don’t think I can talk about).
Dynamically adjusted MSAA setting
With Lost Planet they’re aiming at the game running 30fps at 720p, 4xMSAA. However, when the load gets higher and the framerate is dropping or about to drop, they dynamically switch from 4xMSAA to 2xMSAA, or even to no AA. On the XBOX 360 they apparently see around 10% improvement going to 2xMSAA and 20% dropping to no AA. We usually drop in framerate because there’s lots of things happening on screen, which means you are likely not to notice the temporary drop in anti-aliasing (as long as it doesn’t last for too many frames). This is a neat trick and I’m guessing we’ll see lots of people using it in the future.
HDR texture encoding
The approach they’re taking to encode HDR textures is not new, but it is nevertheless interesting to see this is what they use. Given a texel { R, G, B, 1.0 } they select the largest-magnitude component (lets call it C) and then store { R/C, G/C, B/C, 1.0/C } in the texel. This encoding is decoded in the fragment shader by dividing R, G, and B by the value in alpha. Four slides of the presentation talk about this encoding and its results ([1], [2], [3], and [4]).
An alternative approach to encoding HDR textures is to use an RGBE format. In an RGBE encoding alpha containts an exponent E which is used to scale the RGB values in the fragment shader. I guess it would also be possible to encode textures using LogLuv, although that seems a bit expensive.
MSAA trickery
Another thing the Capcom presentation talks about is their use of MSAA trickery, for increased speed. On the consoles, where you have lower-level access to frame buffer formats, etc. you can do wacky stuff like pretending a 1280×720 (720p) no-AA screen is a 640×360 (ordered grid) 4xMSAA screen. This works, because these would have the same pixel dimensions. By drawing e.g. particles to the 640×360 4xMSAA screen instead of the 720p screen you would reduce your fragment shader computation to 1/4 (as the fragment shader is only executed once per pixel for multisampling), while still rendering to the same pixels as you would have if drawing into the 720p buffer. This is a way of trading fidelity for speed (or vice versa) and it is a very nifty trick.
Lots more
There are several other interesting topics touched on in Capcom’s presentation. Their use (and implementation) of motion blur, their choice of shadow solution, how they are doing multi-threading, statistics for amount of textures and polygon counts for characters, etc. All in all, an excellent and very forthcoming presentation!
More Japanese developer goodies
Capcom has overall been very forthcoming in talking about the tech of their games over the years. In the past they had an interesting presentation about Onimusha 3 (for PS2), again posted on Impress Watch. Some of the interesting stuff was the slide on their light scattering implementation and the slides on their in-game interface for the light scattering feature ([1], [2], and [3]).
Staying with Impress Watch just one more time, another presentation (of a Sony game this time) from that site which was worth reading was the Shadow of the Colossus article (English translation). It’s interesting to see how they achieved certain effects on the old PS2.
LogLuv for textures is not that bad, quality wise, even when compressed with DXT5, as long as a narrower dynamic range is used.
I experimented with it encoding logluminance most significant bits in the alpha channel and tweaking the available range between 10-12 stops.
Now 8 bits per pixel HDR textures are nice and everything, but since the game I was working on could do without them I decided it was not worth the hassle :)
Great links from Impress Watch, thanks! I’m quite interested in the topic of parallel rendering, and have had a go at extracting and interpreting those portions of the article. http://meshula.net/wordpress/?p=112
I wish I’d seen your links earlier, it would have made things easier :)