Paper Strips
Seems like paper strips always get stuck in games today, usually in some kind of ventilation system. Anyways, in this demo the
random moving stripes are done by going through a noise texture and use the values to slightly adjust the z coordinate of the
stripes on the GPU. This requires GPU support for vertex texture fetch, which is just a texture loopup in the vertex shader.
The shadows are done with a cubemap on the GPU with the rendering of distance in the red channel. The same cubemap is used to
render the color of the stripes, this way the color of the transparent stripes can be reflected on the floor as well.
Omni Bloom
When you look at an intensive light source your eye will kind of blur the light with the surroundings. This effect can be simulated by
first rendering the light source (billboard texture) and the scene with 0 material to a texture, and then put this result through a
passion filter (Gauss blur). The blurred textured is added to the original scene: scene * (1 + blurresult). A little bit expensive
because of the many texture lookups required to generate a good looking blur.
Clouds
Clouds are basically noise, this atmospheric effect is done by running through a noise texture borrowed from
RenderMonkey. If you have never seen white clouds cleary on a total black sky, this is your chance.
Box Physics
This demo is powered by ODE (Open Dynamic Engine), a physic API made by Russell Smith. Press the left mouse button to shoot on some boxes.
ODE can do so much more than just box physics, check it out here: ODE
Flash light
A flashlight seems simple at first, it could just be a 2D texture mapped onto the final scene, however this would make
geometry far away shine with the same brightness as geometry close to you, clearly this is unnaturally. This demo makes
a flashlight effect by applying a spotlight and projecting a texture onto what is seen from the spotlight point of view.
With the power of pixel shaders the flash texture conforms to the geometry and fades away in distance.
Screen Space Electricity
The electricity is done on a single quad in the scene, with the help of a huge noise volume texture. Each frame,
3 samples are taken from the noise volume using the current time. For each noise sample the distance dx to the
current y-texture coord is calculated, then the glow is calculated as 1-pow(d1,d2,d3, 0.025), and we are ready to
return a color from the pixel shader, something like, (glow*glow)*color*intensity, dependent on what kind of
result you want. The trick lies in the use of a noise volume to make the impressive random electrical effect.
Bad TV Screen
This demo applies a screen space effect to simulate an old TV. First the scene is rendered to a texture,
then 2 noise volume textures are used to manipulate at disturb the rendered texture.
Scene Luminance
When the human eye comes from dark interior into day light, the light surroundings will expands the overall brightening of the scene.
In real life it will take a few minutes for the human eye to fully adjust the pupils to the new conditions; however in a game
environment we can cut this time down to a few seconds to illustrate the effect. This demo adjusts the final scene luminance by
rendering to basic scene to at texture and afterwards calculates the average luminance L of the scene. As the value of L changes
the scene light (gamma) is adjusted, including a small blurring effect. For the luminance I've used the following: 0.3*R+0.59*G+0.11*B,
taken from Game Programming Gems 4.
Depth of Field
A depth of field effect is a pixel blurring simulation, where the amount of blurring depends on the focus point and the depth
of the scene at that particular point. In this demo the focus point is calculated as the collision point of the ray from the
camera towards the view direction. Depending on how far the focus point is located the amount of blur is adjusted. The flow
is simple, first the scene is rendered to a texture and the texture is passed through a fast blur shader. The final scene is
just a linear interpolation of the original scene and the blurred texture, with the help of a spot texture. The influence of the
spot texture depends on the distance from the camera to the focus point.
Relief Mapping
This demo creates the illusion of complex geometry on flat triangles (extreme parallax mapping). The total scene consists
of only 148 polygons. The effect is called relief mapping, which is a matter of ray tracing height maps. The flow is like this:
first the view vector to the pixel in question is calculated, and the vector is transformed into tangent space. Next, the intersection
between the view vector and height map is calculated, this is done in two steps, first a linear search (top to bottom) followed by a
binary search. Once the intersected pixel is found the new coordinates are used in the remaining texture lookups (diffuse and normal map),
and the effect arrives. The drawback is performance, it slows things down dramatically because of the many texture lookups!
GPU Terrain
The moving terrain in this demo is generated on the GPU. The terrain shape conforms according to a noise textures changing
each frame. The noise texture is written to a RGBA32F render target, which is then passed to the vertex shader
and used to set the vertex positions. This is possible by cards supporting shader model 3.0 and up, which includes Vertex Texture
Fetch (VTF). The VTF is needed to do the texture loopup in the vertex shader.
Titles
This demo renders the backbuffer to a texture which is then dividend into a grid of equal sized quads.
The pixel color in the center of each quad is used on that current title. Further, the edge of
each title has a grey color, to improve the title appearance.
Pool Water
The under water movement in this demo is done by applying a volume noise texture on the geometry, followed
by a distortion using the same volume noise. The water surface follows a sin/cos movement. The entire
scene is blurred a bit, no one sees clearly under water anyways.
Bullet Haze
Heat haze is known as the effect where the scene is affected by a heat source, for instance fire or steam.
In this demo a haze effect is created around a moving bullet and reduced in strength as the bullet moves away.
First the entire scene is rendered to a texture with the same dimensions as the backbuffer. Then the bullet position
is projected onto the screen, the projected coordinates are used in a small lens shader on the rendered texture. The centre of the lens
is the projected coordinates. It may not be the best way to make such an effect, but its cheap, the lens
shader is just a few instructions. Press space to fire some bullets.
Fog Shadows
Fog is easily enabled by the fixed function pipeline in DirecX. However, this demo brings fog to the scene
with a custom pixel shader, which enables us to combine fog and shadows effects.
HDR Rendering
One way of utilize high definition rendering (HDR) is when making an intense light effect. HDR textures are floating point
textures which can store color values beyond 1.0. This extra information can be used to do a tone mapping,
which maps the HDR image to a low dynamic range. This mapping determines the brightness of the scene. We could set the
brightness to a default value, but in this demo the brightness is calculated on the GPU by rendering the scene
to a floating point texture and applying a custom shader (bright-pass filter). This texture is then used to lookup the exposure for
the final output. Press 'space key' to toggle the use of floating point render target.
Bump shadows
Bump shadows or horizon mapping as ATI calls it. This demo shows bump maps which casts shadows on themselves.
The effect requires the precomputing of a horizon map for each texture. The horizon maps are 3D volume textures, and in
this demo they consist of 16 slices. The horizon maps stores at what angle (in 16 directions) the horizon
is. The sampling of the horizon map its compared with the light over the surface. If the light is below the horizon
the pixel is in shadow otherview it is not. The code for this effect is taken from RenderMonkey.
CPU Cloth
The cloth physics is implemented as springs between nodes. In this case the nodes are the vertices of the triangles that
makes up the cloth quad. Each node is connected to its neighbours through with spring force equation. A node not on the edge
is connected to 8 other nodes. When a node is moved it applies forces to all its neighbours making the realistically
overall movement. The collision detection between nodes and the sphere is very simple; its just at matter of testing if
the distance from the node point to the sphere centre is less/greater than the radius of the sphere.
Grass
This demo simulates a field of grass. It is done by rendering lot of quads. Each quad
is mapped with a grass texture and rendered with an alpha test. The top two vertices
of each quad are moved using sin in the vertex shader, the two lower vertices are not
moved. I've added some fog with the same color as skybox.
Soap Bubbles
This bubble effect is done by using a simple sin to perturb each vertex position in the direction of its normal.
The pixel shader uses two textures on the buubles, a rainbow map for the color shift and an environment map (skybox) for
the reflection part.
Fire 2
The fire in this demo is created with a standard particle system. The texture of each particle will
change as the particle moves up. This is done using a 3D texture, and interpolate between the different
slices. This way, the whole particle system can be rendered with a single draw call.
Shadows on Particle System
This demo demonstrates GPU cubemap shadows applied on a particle system. The created cubemap shadow is used on the scene,
but also on the triangles of the particle system.
Glass Surface
This demo creates a glass appearance by using the reflection vector as lookup in a cubemap (skybox).
To further improve the effect a 1D spectrum rainbow colour texture is used to add a color shift on the edges.
Cubemap colors
This demo renders the colour of the transparent ball into a cubemap. The size of the cubemap is just 128x128 pixels.
For shadows we render the depth, as for the ball we render the color instead. For this to work the cubemap will have
to be created with the format that can take some colors, for instance A32B32G32R32F.
Parallax Mapping
This demo offsets the texture coordinates according to the camera view with the purpose of giving the surfaces more
depth and appear bumpier compared to regular bump mapping. The idea is to use a height-map, stored in the alpha channel
of the normal map. The height is added to the texture coords in the view direction (tangent space).
The new texture coords are used in the remaining texture lookups. The performance bottleneck is the extra texture
lookup for getting the height.
Shake effect
The shake effect is invoked when a collision with the scene walls is detected, so try move into the walls!
Its done by rendering 8 different camera views on a spherical bound around a focus point and averaging the results.
The focus point is just in front of the camera position.
Light Circumference
Each fire area in this demo has a single billboard light circumference texture blended into the scene
by adjusting its alpha value. As you go behind an occluding object the alpha value will
go to zero. How much alpha will increase or decrease is determined by using GPU occlusion queries.
The number of pixels that passes the occlusion test divided with the area of the occlusion rendered target
gives a good idea of how visible the circumference is. The main drawback is the performance hit of waiting on the GPU query to finish.
Volumetric Lighting
When a light source has the effect of passing through a medium, such as fog or dust it is often called
volumetric lightning. This demo creates the effect in the pixel shader based on the following vectors: a=light-camera
and b=vertex-camera giving the us this magic value: VOL = 1 / |(dot(b,a)/dot(b,b)) * b - a|^2 (uuhh). The final color is
then: base*(attenuation + ambi) + VOL*volumetricColor.
Point Particles
Point sprite particle system. Here the particles are drawn with a single huge
vertex buffer filled in batched and flushed when a certain threshold is reached.
Soft Lightmaps
This demo gives you soft shadows for free; the drawback is that the light source is restricted to
a predefined path and the geometry is static. The idear is simple, make a list of lightmaps
and merge between them. HLSL has a nice linear interpolation (lerp) function to help us out.
Soft GPU Shadow Maps
A standard GPU shadow map with low resolution will give a stair-step alike shadows. In order to avoid this penalty
this demo takes 5 shadow map samples with different coordinates offsets and average them. This will smooth the
edges nicely, but hits performance.
Phong Lightning
The Phong lightning equation in action. Using normal maps for the 3D surface look, and gloss maps
for the specular component. Phong lightning is an approximation of how real light tend to behave. For this
to work it requires us to transform the light vector into TBN space before using the Phong equation:
A+N*L+(R*V)^s. Here A is the ambient factor and N,L,R and V is normal, light, reflection and view vector.
Cubemap Shadows
The shadows in this demo are created on the GPU. It is done by rendering the distance from the omni light position to each pixel
into a cubemap (red channel) from the light point of view. Then, when rendering the scene, we check the distance to the light
(pixel shader) against a lookup in the cubemap. If this is distance is larger than what is stored in the cubemap then something is
in the same line of view that covers the light, hence the pixel is in shadow, else it is lit.
Quake3 Scene Viewer
This is my version of a Quake3 scene viewer. A Quake3 BSP map is rendered with a BSP partition strategy, which is designed
to return a perfect visibility set of faces in the view frustum. The drawback is, that the BSP traversal is expensive,
compared to other methods. Nowadays you should go for another more flexible scene partition method since it is no really
performance hit to render a few triangles to much on modern GPUs. I've sorted the primes in each leaf with respect to the
textures in order to minimize glBindTexture() calls, just to improve the performance. Further, I've added simple collision detection
and gravity. Help on how to parse Q3 maps is done using google, lots of source code out there.
Shadow Volume
Shadow volume cast from 3D model. This implementation calculates the silhouette edges of the copper
and the blades and utilize the stencil buffer to make the shadow in the scene. The ground is a simple terrain
with a light map attached. The silhouette edge calculations are taken from the DirectX SDK sample.
Ocean waves
The waves created in this demo is done with a sin function in the vertex shader. Totaly there is 4608 triangles.
A blue fog with the same color as the skybox is added, just to make the waves blend into the background. The
shader code is strongly based on the ocean demo in FX Composer from Nvidia.
Rain
Rain simulation. A big vertex buffer is filled with rain particles and the drops on the ground. The buffer
is flushed when a threshold is reached. We only create new rain particles close the camera in order
to minimize the amount of particles needed.