Zelimir Fedoran
email zelimir.fedoran@gmail.com

Aqua Game Engine

Posted on
September 21st, 2009
, , , ,


I started working on “Aqua” about 4 months ago shortly after my spring semester had ended. The original intent was to create a game for Microsoft’s Dream Build Play competition. However, I soon re-focused on learning about game engine architecture instead. I realized that I wanted to create the prettiest game ever and in order to do so I had a lot to learn. I developed a thirst for real-time rendering during my previous research on GPGPU and I wanted to know more. Thus, Aqua turned into a learning playground for exciting new real-time rendering techniques.

Debug Primitives

One of my biggest problems while working on bubble bound was correct object alignment. I stayed up all night trying to line up and rotate models correctly by guessing affine transformation matrix values. Therefore, the first thing on my agenda was to implement some basic primitives such as: boxes, spheres, axis, and grids. These primitives have really helped visualize and define scale, rotation, position, and bounding volumes in a virtual world. Second on my list, was to abstract matrix transforms away from the user through simple interfaces.


Particle System

The GPGPU research I did in the spring helped me quickly put together a robust particle engine. Standard hardware instancing is not supported on the Xbox 360 under XNA. However, my particle engine supports hardware instancing by using shaders that access textures/rendertargets for particle positions and velocities. This allows for massive amounts of particles without using almost any CPU time.


Deferred Rendering

In current games, many objects need to be lit and shaded by multiple light sources. This remains an expensive task, and even today there is no perfect or best way of approaching the problem. Lately, there has been a lot of talk about deferred rendering amongst the game development community. It is not a new idea but has only recently become viable through faster graphics hardware. In order to understand what deferred rendering is and why it is gaining popularity, lets look at some common lighting methods.

The Single-Pass lighting model is a common approach to the lighting problem. Every object in the scene is rendered normally and the light from each light source, affecting the object, is calculated by a single shader. The problem with this approach is that shaders have instruction length limits and therefore an object can typically only be lit by a few light sources. For example, the BasicEffect shader in XNA only provides 3 directional light sources.

Another lighting model is the Multi-Pass approach. Here, shader programs are run multiple times on individual geometry. The advantage is that many lights can affect a single piece of geometry. However, the Multi-Pass approach causes high amounts of draw calls where the number of draw calls is equal to (the number of objects * the number of lights).

Deferred Rendering, approaches the problem differently. First, all the objects in the scene render geometry information to multiple off screen render targets. After this, the geometry information is combined to create a lit rendering of the scene as a 2D post process. A typical deferred renderer will write out at least the depth and normals of each object. Rendering to multiple render targets every frame is expensive but it does have some benefits. One major benefit is that now hundreds of lights can be added to scenes because the number of draw calls is reduced to (number of objects + number of lights).

I based my deferred rendering engine on the following Killzone 2 paper: available here


Collision Detection

Aqua has basic object to terrain collision detection. This is done by splitting the terrain model into an octree structure. Once the octree has been created checking for collisions comes down to traversing the tree nodes and finding the smallest bounding volumes which intersect with the object. Then each polygon in the tree node can be checked for a collision. I am considering adding a Sweep and Prune algorithm to handle object to object collisions in the future.


Parallel Split Shadow Maps

This technique caught my attention because it allows higher quality shadows close to the viewer and also requires less memory than a traditional shadow map. It does this by splitting the shadow amongst several view projections. Unfortunately, it is not as fast as I would like it to be since it requires the scene to be drawn several times on DX9 hardware, once for each split projection.