I attended this lecture on Friday, 22 February 2008, at the Game Developer’s Conference 2008, presented by Tiago Sousa, a Graphics Programmer with Crytek. I did unfortunately arrive late, as this was my second choice for the morning. The lecturer was a no-show for the lecture I originally planned to attend. So, there may be some key information missing here that was presented in the first fifteen minutes.
The portion of the lecture that was in progress as I arrived was detailing some of the special effects related to water simulation and rendering. Crytek spent quite a bit of time working on underwater rendering, and include some sophisticated effects including light scattering, caustics, and god rays. The underwater lighting environment is extremely complex and dynamic, and all of these features are crucial to producing realism.
In terms of exterior water effects, the game does feature simulation of refraction, which provides the expected distorted view of underwater geometry when viewed from the outside. The game did feature a rolling wave effect, implemented in this game as an animated decal. Sousa discussed some of Crytek’s future plans to enhance water surface effects. They are looking into implementing rolling waves using some form of geometry manipulation, and various related dynamic water surface features including surface interaction with the shoreline (water eroding the shoreline perhaps, washing away shells or small objects built as part of the shoreline model?), other game objects affecting the water surface, and water splashes.
The next portion of the lecture focused on Crytek’s approach to rendering frozen surfaces. They sought to render, for example, frost on rocks, and snow accumulation on objects. They were unable to find much prior art on rendering these things in real time, and so they found they were doing more invention of technique than with some of the other effects. They prototyped a few systems before they arrived at their final implementation of frozen object rendering. Approach #1 was to use custom assets, e.g., have both a frozen and non-frozen version of all relevant assets. This, of course, was going to be expensive and might not produce a consistent look. Approach #2 was to introduce procedural frozen surface shaders that would reuse assets, and allow artists to tweak a number of shader settings per object. This approach initially failed because the artists were spending too much time tweaking parameters, and the results were not always…up the visual quality production goals. Approach #3 was a mix of custom assets and procedural shaders, which produced perhaps better results than approach 2, but still too much work, with the need to tweak parameters for some objects and custom build assets for others. They settled, eventually, on approach #4, which was an all new set of procedural shaders with a focus on making things visually interesting, designed to minimize work for the artists and using real world images as references. The reference images featured all of the details they were looking for: snow accumulation, frost, and frozen water droplets. They were unable to enable every object to look both good and realistic, but they did minimize the amount of work required by artists, achieved results for all objects that were visually interesting, and achieved believable results only under some lighting conditions.
There was some detail on the methodology implemented in the frozen shader. For snow accumulation, the snow layer was blended in based on the ratio of the z components of the objects’ world space and object space normal vectors. The examples shown in the lecture were quite compelling, with snow accumulating more heavily on flat horizontal surfaces in which the world and object normals were nearly vertical, and less on surfaces with normals not so vertical. Frozen water droplets were implemented as 2 layers with texture coordinate offets, and using Perlin noise to vary the blending. Glittering, seen on frosty surfaces, was implemented as a 2D texture with random noise vectors.
Sousa then moved on to discuss various post effects, including camera and object motion blur for both low dynamic range (LDR) and high dynamic range (HDR) rendering. The general goals were: minimize aliasing for high spec hardware; never sacrifice quality over speed; and, make effects subtle (avoiding the in-your-face light bloom and lens flare effects that have plagued games of the past). For motion blur, camera and object they ended up implementing separate LDR and HDR versions.
For camera motion blur, it was desirable to avoid bluring geometry nearby the player, e.g., they did not want to blur the first person weapon. To deal with this, a velocity mask was built using the depth buffer, and was used to mask out the geometry very near the player. Quality was maximized by using iterative sampling, with a pair of buffers that were ping-ponged to enabling accumulation during iteration. The first pass would use 8 samples. The next pass would use the blurred results from the first pass, and again 8 samples, giving effectively 8*8 = 64 samples. The third pass would use the blurred second pass results and an additional 8 samples, for effectively 512 samples. They implemented a number of optimizations. For example, if no camera movement, then no camera motion blur was applied, and they also would estimate the required sample count per pass, and used less than 8 sometimes.
For object motion, various limitations in Direct3D 9 related to hardware skinning limits, vertex constant register limits, etc., led Crytek to make a decision to implement object motion blur only for Direct3D 10 capable systems. The motion blur was implemented via per-pixel velocity and edge dilation, using separate horizontal and vertical offsets. As with camera motion blur, results were accumulated over several passes to maximize quality of the output, with several samples per pass along the velocity direction.
All in all, the effects in CRYSIS are compelling…certainly visually interesting as per their goals, but ultimately elegant in their simplicity.