"If Wall Street crashes, does Main Street follow? Not necessarily."
- Ben Bernanke
More pages: 1 ... 4 5 6 7 8 9 10 11 12
Framework 4 (Last updated: October 25, 2019)
Framework 3 (Last updated: February 6, 2017)
Framework 2 (Last updated: October 8, 2006)
Framework (Last updated: October 8, 2006)
Libraries (Last updated: September 16, 2004)
Really old framework (Last updated: September 16, 2004)
Soft coronas
Monday, January 27, 2003 | Permalink

Executable
Source code
SoftCoronas.zip (2.1 MB)

Required:
GL_NV_occlusion_query
GL_ARB_vertex_program
GL_ARB_texture_env_dot3
GL_EXT_texture3D
GL_EXT_texture_edge_clamp
This demo utilizes occlusion queries to create soft coronas. By querying the number of fragments that passes the depth test I can get a good figure on how visible the fire is. The more pixels visible, the stronger corona, quite simple. The effect will be that as you close in on the light you'll get a stronger corona. If you go behind an occluding object the corona softly fades away.

For this demo I have also added a nice tune for the mood, Antissa by E.S. Posthumus (the song is available for download from their site), so make sure you have OpenAL installed and that you have the libvorbis dlls.

Should run on Radeon 8500/GF3 and up.

Volumetric lighting
Sunday, January 12, 2003 | Permalink

Executable
Source code
VolumetricLighting.zip (565 KB)

Required:
Vertex shader 2.0
Pixel shader 1.0
This demo does a volumetric lighting effect for an arbitrary number of light volumes by using a vertex shader. The demo calculates the sum of the distances through the light volumes of the ray from the camera to the vertex. This is a fairly complex calculation, even though I suspect there exist a simplier solution that what I implemented. So in the 128 instruction of vertex shader 1.1 I would at most be able to fit 2 volumes. But with vertex shader 2.0 I can use a loop to support an arbitrary amount of light volumes without going through the instruction barrier and don't need to use different shaders depending on what number of light volumes I use.

The good thing about this technique is of course that it's cheap from a fillrate point of view as it runs in a vertex shader. Fillrate usually is the limiting factor, not so in this demo though. It would be better to do this kind of calculation on fragment level though, but that would make even the 9700 pro beg for mercy.
The backside of this technique is that it requires a decent amount of tesselation to give good results. The original UT level (DM-Fractal) I used had too few polygons so I tesselate it into smaller polygons at load time for better quality.

Should run on Radeon 9500/9700 and Parhelia.

Perlin noise
Wednesday, December 18, 2002 | Permalink

Executable
Source code
PerlinNoise.zip (88 KB)

Required:
GL_ARB_fragment_program
This demos does perlin noise in a fragment program. The output of the demo doesn't look like much, but it isn't nearly as interesting as the fact that you can actually do this kind of stuff in a fragment program. There is a wide range of applications to Perlin noise, especially in graphics. I already have an idea how to use it in a more useful manner.

For doing Perlin noise you use a table of random values on which you apply a band pass filter. In this case the table is obviously a texture. In order to reduce the amount of texture accesses I have instead of just using a single channel texture mirrored the neighbor values in the other channels. So R it this texel, G is the one to the right, B is the one below and A is below right. This way I only need 2 texture accesses instead of 8 for each pixel.
This demo does the 2D noise function, but extending it to the 3D version should be straight-forward, with performance implication of course though. To get some kind of animation in this demo I just let the output be a simple function of the Perlin function and time.

Shadows that rock
Thursday, December 12, 2002 | Permalink

Executable
Source code
ShadowsThatRock.zip (450 KB)

Required:
GL_ARB_fragment_program
WGL_ARB_render_texture/GLX_ATI_render_texture
In this demo I took the idea from the shadows that don't suck demo and made it better, hence the name. I also took the lighting from the Phong demo, and made it better. I also used a more interesting scene. Yes, that's the DM-tutorial level from UT.

For decently large scenes like this a 8bit/channel render target can have some problems with precision. Further, as we only use one channel really we ideally would want a LUMINANCE16 render target. Unfortunately, there's no extension available for rendering to luminance textures, so we'll have to stick with RGBA. Using RGBA16 means a heavy performance hit though. To solve this problem I used a RGBA8 render target but split the result up into the different components. Then I extracted it in the fragment program.

Will run on Radeon 9500/9700 only at this time. No Linux support at this time either. Note that there's a bug in current ATi drivers so you'll need to turn FSAA off for it to work.

2002-12-15:
Updated with better performance and precision. Thanks to davepermen for hints and optimizations.

Depth of field
Tuesday, November 19, 2002 | Permalink

Executable
Source code
DepthOfField.zip (381 KB)

Required:
GL_ARB_fragment_program
GL_SGIS_generate_mipmap
GL_EXT_texture3D
GL_EXT_texture_edge_clamp
WGL_ARB_render_texture/GLX_ATI_render_texture
This demo shows a way to do depth of field with a fragment program. The technique is simple, unfortunately the result follows accordingly. What I've done is render the scene into a texture. At the same time I put the radial distance into the alpha channel. I let the hardware generate the mipmaps with GL_SGIS_generate_mipmap. Then in the fragment shader I can on a per-fragment basis select the LOD. I pass a focus distance to the fragment program and use LOD = const * abs(dist - focusDist).
What I meant with the "result follows accordingly" comment is that it didn't quite look as good as I had hoped. The mipmap lod with a linear filter gives quite a blocky apperance of out-of-focus parts of the scene. For limited blur it works fine though.
Oh, and don't mind the simple texturing and lack of lighting in this demo. Didn't bother to do something serious on that side of things.

You can move the focus spot with you + and - keys.

This demo will run on Radeon 9700 only at this time.

Motion blur
Tuesday, November 19, 2002 | Permalink

Executable
Source code
MotionBlur.zip (377 KB)

Required:
WGL_ARB_render_texture/GLX_ATI_render_texture
GL_EXT_blend_color
Motion blur is another of the so called "cinematic" effects. Cinematic seams to be the buzzword of the day, but you don't need all those fancy technologies for creating motion blur though. The solution is simplier than one might think and can be expressed with a simple formula:
NewFrame = OldFrame * a + ThisFrame * (1-a)
The old frame is of course stored in the framebuffer since the last frame, so we just don't need to clear the color buffer and can blend directly. The small difference between two frames in double buffering mode doesn't really matter. We need however render the current scene into a texture.
As with the depth of field demo, no particular effort has been put into lighting and stuff.
You can change the amount of blur with the + and - keys.

Should run on Radeon 8500 and up and the whole GeForce series.

Infinite terrain
Sunday, November 17, 2002 | Permalink

Executable
Source code
InfiniteTerrain.zip (602 KB)

Recommended:
GL_ARB_vertex_buffer_object or GL_ATI_vertex_array_object
This demo shows how to create a highly detailed infinite world which basically requires no storage space. The terrain is based on a mathematical formula, pretty much any continuous function can be used. I'm using a function based on perlin noise, one perlin function defines the large scale detail and on top of that I add another perlin function for finer details.
It's a no brainer to use such a formula for defining your world. The tricky part is to let the user go anywhere in the world and still be able to maintain some level of performance. Evaluating perlin noise functions isn't that quick and even if it would be you would still have to pass all your geometry over the AGP bus every frame. To solve that problem I have splitted the world into blocks. I'm deciding which blocks will be in view in the current frame, then evaluate the blocks as neccesary from the provide formula, then upload them to the graphic card and draw. The next frame it'll repeat the procedure, except that this time there are stored block on the card that it can reuse. As soon as a new block is needed it's evalutated and uploaded. Obviously, you can't just upload new stuff in infinity, you'll have to delete sometime too. I haven't implemented any fancy scheme to decide which blocks to drop and when, instead I just use a fifo and delete the first uploaded block when a certain amount of blocks have been uploaded. For this demo it's good enough.
Another great thing, it's quite easy to do LOD with this approach. Just use an appropriate index buffer for each block depending on distance, quite analogous to mipmapping, except there's no filtering. This simple LOD scheme improves performance (believe it or not) more than 6x.

This demo should run on all graphics cards. Decent performance can only be expected on cards that support GL_ARB_vertex_buffer_object or GL_ATI_vertex_array_object though.

2003-05-01:
Updated with support for the GL_ARB_vertex_buffer_object extension.

Mandelbrot
Monday, November 11, 2002 | Permalink

Executable
Source code
Mandelbrot.zip (88 KB)

Required:
GL_ARB_fragment_program
Aah, I remember the old days. I was 17, sat there at school by the 486 machines with some friends coding on our mandelbrot set viewer in Pascal for DOS. It generally took a minute or two to get our picture, but it was very fun and interesting. You never really got bored by zooming in on interesting parts, waiting for the computer to finish and the zoom again ... ah, those were the days.
Time went by and today we have much more powerful computers. Still it's a quite slow process generally to render mandelbrot sets. So what I'm demonstrating today is the maybe quite original idea of accelerating the process with todays fragment shading hardware. What we see here is a mandelbrot renderer that generates mandelbrot sets at framerates of around 60fps on a Radeon 9700 in 1024x768. In the old days you'd use a custom palette for getting a nice colored setup. I however have let the distance to origin of the end point determine the final color. This way we don't get any banding like you'd get in the old days.

As anyone who have done a mandelbrot renderer should know, for mandelbrots to look really good you need a lot of precision. On the CPU you could use normal 32bit float, but as you start to zoom you'll get pixelation. Even a 64bit float runs out of precision after a while. So in the old days I used full 80bit floats. On a Radeon 9700 you have 24bit precision in the fragment shader pipeline. This means that you can't really zoom a whole lot before the lack of precision gets apparent. Zooming and panning is done with your normal back/forward/up/down/left/right keys.

Will run on Radeon 9500/9700 only at this time.

2002-12-08:
Updated with an improved shader, it now performs one iteration in 3 instructions, previously it took 5 instructions. Thanks to Basic for hints and inspiration. Instead of going with higher performance I went with adding more iterations instead, which resulted in better detail. I also made it more colorful with a dependent texture read into a texture to look up the final color.

2003-05-30:
Updated with a zoom console command to let you define an exact zoom for comparion purposes.
Type "zoom" to get the current (left, top, right, bottom) coordinates.
Type "zoom left, top, right, bottom" to set the zoom. You can cut'n'paste from a previous "zoom" command.

More pages: 1 ... 4 5 6 7 8 9 10 11 12