Edelweiss: demonstrating some cool graphic effects

Martin Kinkelin (a friend of mine) and I have finished developing the graphic demo (see related posts: 1, 2). It shows a museum scene with a dinosaur (a raptor), four anubis statues sitting on stone bases and two dragons. The dragon model is taken from “The Stanford 3D Scanning Repository”.

Further, a commuting light source is positioned at the top of the room and generates some nice shadow effects. On the two sides (left and right) of the room there are two dragons that look at the opposite direction of each other:



We have implemented the following effects: Bloom, Shadow Maps, Normal Mapping, Parallax Mapping and animated objects. Try to spot them in the demo :D

Curious? Want to check it out? Download the demo from here.

Published on Jan 27th, 2008 — Tags: , , ,
Comments (0)    digg it!    kick it   

Dynamic Shadow Maps

As mentioned in a previous post a friend of mine and I are currently doing a rendering engine in OpenGL that implements a selection of graphic effect. I also mentioned that the next thing that is on the plan is shadow mapping. It’s done! After we met a few afternoons we finally got it working properly and finished the whole project.

But why do we need shadows? Shadows add realism to the game because they are found everywhere in real life and how can you have a light without shadows. :) Without the shadows everything looks like as if it is floating in the air and not as if it is sitting on the ground (this effect is also seen in the pictures at the end of this post).

There are two approaches to create shadows in the games: one is shadow mapping and the second one is shadow volumes. Shadow volumes cost a lot - especially if you have complex objects (that’s also why Doom 3 has very simple meshes); computing the volumes need a lot of CPU and GPU cycles and aren’t therefore much seen in nowadays games. DirectX 10 adds new features to make creating shadow volumes faster, but since we both don’t own a DX10 GFX card we couldn’t test it and haven’t therefore added shadow volumes to the engine. We went with shadow maps.

When creating shadows in games you have to take two things into consideration: the position of the light and the area that is visible by the camera: the player’s field of view.

The first thing that you do, when creating the shadows, is to switch to the position of the light and generate a shadow map. A shadow map is basically a depth map that holds for each pixel a depth information. That information is computed by detecting the nearest point (for each pixel in the shadow map) to the current position. Since we are at the position of the light it will be the closest position to the light source. Keep in mind that creating the shadow map involves to render all the objects; although you can disable shaders and texturing.

To create the shadow map we used a OpenGL FrameBufferObject where a texture was specified as depth component:

glBindTexture(GL_TEXTURE_2D, _textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, _width, _height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
glBindTexture(GL_TEXTURE_2D, 0);

// set the texture as depth attachment.
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
    GL_TEXTURE_2D, _textures[0], NULL);

// required to be set to none.
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

The next step is to switch back to the camera view. Here it is needed to check each pixel’s (that is part of a mesh) depth value (speaking of the distance from the light position) with the value that is found for that pixel in the shadow map. This is done in the pixel shader where the shadow map is passed in as texture. If the value is heigher than the value that is found in the shadow map that pixel will be in the shadow otherwise it is in the light.

The problem that you get with this approach is that you have hard shadows; something that isn’t found in real life. With “hard shadows” I mean that a pixel is or completely in the light or completely in the shadow. To avoid that PCF (Percentage Closer Filtering) is done. PCF checks the neighbor values in the shadow map and if a certain number of them (threshold) are in the light the current point is calculated as not being fully in the shadow. This allows us to similate soft shadows.

The final results look like this:

 

Published on Jan 23rd, 2008 — Tags: , ,
Comments (3)    digg it!    kick it   

Bloom: a little bit of HDR

Another project that we (a friend of mine and I) are currently doing is a rendering engine in OpenGL that implements a selection of graphic effect. The title of the university exercise is “Echtzeitgraphik” and the goal is to implement some effects in a demo like fashion - it needs to be powered by a real-time game engine that needs also to be developed by the groups, which we did by recycling and enhancing the FishSalad engine :P

Right now the engine is featuring normal mapping and parallax mapping:

If you look at the dragon you might be able to see the normal mapping effect. We use a low polygon model and apply a normal map in the pixel shader to make it look like a high polygon model. The parallax mapping effect is visible on the box. The stones look very much 3D although it is a flat texture. The effect is a lot more visible if you move around in the game.

Adding the bloom
What I did the last two days was to implement the bloom effect. This effect is seen in a lot of the current games and was also introduced in Half-Life 2 with the famous Lost Coast level. The bloom effect isn’t a real HDR effect, it’s some kind of faked HDR and simulates looking from a darker standpoint into something very bright. You usually get dazzled by that bright light and the outlines of the object become very blurry.

The question was on how to achieve this effect. The bloom effect is a post-processing effect that means that you apply it when the scene has been already rendered. As I found out there are a few easy steps to perform the bloom effect. The theory looks very easy, but implementing it is another story:

  1. You render your scene into a texture: best is using the so called Frame Buffer Objects (FBO) because that avoids copying the data from the back buffer to a texture. FBOs allow you to directly render the scene into a texture.
  2. You use a pixel shader that extracts the more interesting parts of the scene, by darkening the darker parts and brightening the brighter parts. That’s done via a threshold. That result is rendered in another texture - it’s time to use a FBO that allows you to target multiple textures.
  3. Next you use a gaussian blur (in a pixel shader again) to blur the texture in one direction. The bigger the kernel, the better it looks like and the slower because you need to do a lot of texture lookups. The result is again rendered into a texture.
  4. The next step is to use the gaussian blur again. But this time in the other direction. As input the result of the previous step is taken. The result of this step is rendered in another texture and is a two way blurred image.
  5. The final step involves another pixel shader that merges the original scene with the blurred scene by doing an additional overblending (adding the both together). The brighter parts will brighten the original texture and generate a nice bloom effect.

Now if you do this on a 1280×1024 texture you can imagine how many texture lookups that are. But it is running quite fast on my older graphic card: it’s impressive how powerful even older graphic cards are… very impressive. I wonder how much this thing would fly on a 128 shader units card, like the Geforce 8800 GTS, GTX or Ultra. :D

The final result is shown in the image underneath:

Next on the plan for this little engine is shadow mapping. :)

Published on Dec 16th, 2007 — Tags: , , , ,
Comments (2)    digg it!    kick it   

Starting with game development

Ever wanted to start with game development? What technology could you use? There are several around. In the last months we have heard very much about XNA and XNA 2.0. But there are also other libraries around that are very interesting: two of them are DirectX or OpenGL.

For university a friend of mine and I had to write a small game named FishSalad. It’s a simple game and we had to write it in OpenGL. DirectX was theoretically allowed but everybody looked weird at you, if you considered using it (university life). I don’t regret having done the class and having written the game in OpenGL. The API has an easy to use model (it’s ideal to start with) and makes it easy to switch to DirectX afterwards: the calls are very similar. It’s always the same hardware in the end…

There are some very good OpenGL tutorial sites around. I like the collection of tutorials at NeHe’s site. It has all the important lessons from how to start with OpenGL (and C/C++) until how to write shaders, cool looking fogs and particle systems. Another interesting read is the OpenGL documentation: the so called Red Book.

DirectX on the other hand is also interesting if you want to program a game for Windows. There’s plenty of information on MSDN and there are a lot tutorial websites around. If you have time (and the required hardware) you should have a look at DirectX 10. The geometry shaders look very powerful and interesting.

If you want to start with XNA you should have a look at the link section at the XNA Development website. XNA Development itself has also some interesting and easy to understand tutorials. What makes XNA very interesting is the way how everybody can write small games in a few hours. Very cool!

As for techniques I really wonder when people start to implement relief mapping. It looks awesome and would be the next step after bump mapping. Anybody willing and having some free time?

Published on Sep 9th, 2007 — Tags: , , , ,
Comments (0)    digg it!    kick it   

Fish Salad: Become the king of the ocean!

fishsalad_xp.png

This term a friend of mine, Martin Kinkelin, and I programmed an OpenGL based game for university. The aim of the game is to become the king of the ocean. You start as a little fish and eat other (smaller) fishes. As you eat, you grow and are able to eat bigger fishes. This goes on until you have reached a certain size to be called the “king of the ocean”.

How to play?
Use the arrow keys or A, S, D, W to control the fish. Try to collide with smaller fishes to eat them and try to avoid collisions with bigger fishes. Before starting each level the game tells you what kind of fishes should be avoided in the upcoming level. All other fishes can be eaten!

Special effects
We have implemented pixel and vertex shaders. The caustics are implemented in the pixel shader. They are displayed on each fish and the ocean ground. Side note: To display the shaders you need a decent video card!
The game includes also per-pixel-fog and motion blur. You can see the motion blur, if you collide with a bigger fish. It is shown as long as your fish blinks (in that time you are invincible).

Other points of interest
All models in the game are stored in a custom written format. We have written a converter to translate .obj files to our .fsm format. The model-configuration is found in the Models directory and stored as xml file. That allowed us to easily customize the models behaviour. The levels are also stored in the game.config file, which is found in the same directory as the game’s .exe. Feel free to add your own levels ;)
We are also using quaternions to rotate stuff in the 3D space. That’s gives us better results and is faster when rotations are concatenated. To make the game even more performant SSE intrinsics are being used :)

If have had some problems with the game under Vista. That’s due to the buggy nVidia drivers for my mobile GeForce 6800. I haven’t had any problems under Windows XP. The game works well in Vista on my girlfriend’s computer. She has a GeForce 7xxx. Martin has an older Radeon card and Windows XP and it works also great there!

I hope you enjoy the game!

Download the game from here.

Note: If you get an error while starting the game, try to download and install the latest MSXML package from here.

Published on Jun 25th, 2007 — Tags: , , ,
Comments (3)    digg it!    kick it