3D Graphics (2 / 2)

Older 3D graphics experiments. Most recent and interesting stuff is on the first page.

  Old - Some content is 10+ years old, not representing my current thoughts  


Machine Learning

Image Recognition

Some of my code is available on my GitHub Account

Old OpenGL Demos

Some of my very first 3D projects. Some of them are quite fun to look at / play with. Nothing special of course, but reminds me of the good old days before pixel shaders and GPUs...


Demo showing a portal-like effect realized through environment mapping with a moving asteroid field in the background.

Critical Velocity

This one races along a long sine wave track with flares on the sides. It was ported to MacOS by my friend Malte Harder.


A terrain engine with simple walk, slide and jump physics. The trees are billboards, the terrain is textured by a randomly distributed set of tiling textures.


Interactive demo with collision detection. The scene is a fractal landscape surrounded by animated water.


That's actually a Direct3D demo, but still pretty old. The demo shows a flashlight effect realized with projective textures.

Sky Cam

Camera on a Bezier spline moves through an environment mapped scene loaded from a Wavefront OBJ file with a sky background.

Motion Blur

This is an old OpenGL project I did around the time where 3Dfx's VSA-100 with the T-Buffer was introduced. It's a simple multipass motion blur effect. The demo shows various objects in motion and has controls for adjusting the amount of blur.

The sampling artifacts visible on the "trail" are usually not noticeable in motion. Obviously it looks better in general when seen in motion.
Some more of the same, but this time with a few more samples. It's probably not practical for anything but very simple scenes. The code was written with a TNT1 in mind, with today's pixel shaders and offscreen buffers there are certainly better ways to do it.

Shadow Map

This demo renders a scene shadowing everything on everything illuminated by colored spotlights. Direct3D9 and Cg are used for rendering. Shadowing is done by using hardware shadow mapping. To avoid the jagged / aliased look of the shadows, the depth map lookup is done with a four sample rotated grid (RGAA). More samples could be taken with a higher pixel shader profile than the currently used 1.1, or more could be accumulated in the already used destination alpha. The lighting part of the demo is a simple per-vertex spotlight plus a projector texture. The RGAA shadowing needs three passes per light (depth map generation, shadow sampling, ambient + spotlight), while the 'normal' version can merge the 2nd and 3rd pass. Win32 related code is done with Shiny.

When judging the performance, keep in mind that the shown model has nearly 70K triangles, 10MB of texture data distributed over 50 individual textures and is rendered with 4x FSAA. Rendering without FSAA, RGAA shadow map sampling and a more moderate 10K triangles / 2MB texture data model results in FPS easily above 150 on a GF3.
Notice the smooth self-shadowing. The light comes from two spotlights. They move on splines while looking at another spline. Looks very nice in motion.
Again, cool anti-aliased self-shadowing. Here you can see that the lights are colored, one is slightly red, the other one is a bit blue. Creates a very real looking daylight kind of illumination.
And once again the same thing.

D3D9 / .NET Demo

I wrote this small demo in C# to evaluate managed D3D9. It displays a fancy version of Rubik's Cube. The faces of the cube are glossmapped and have a reflection cubemap applied to them. The lights are using per-pixel attenuation. I managed to squeeze the entire setup including the two lights into a single ps 1.1 pass. It's 'Color0 = (Mask * (Color + Lighting) + (1 - Mask) * Reflection) * (Light1 + Light2 + Ambient) * 2'. That takes up all 8 instruction slots plus all four TMUs. It's quite tricky to compute both lights additive cause there are only two temp registers, so I was forced to store an intermediate result in the alpha component. The vertex shader needs 34 instructions.

Needless to say that the reflection looks way cooler when the cube is spinning...

Direct3D Based Quake2 Renderer

The purpose of this engine was to render Quake2 levels enhanced with all the eye candy that is possible years after the original. The renderer is not based on the original engine and is completely custom. The lightmaps were replaced with various custom realtime per-pixel lighting algorithms. I also wrote a custom ellipsoid based collison and physics code (based on this). The level data is loaded from Wavefront OBJ files. These files are generated out of Quake2 BSP files by a custom converter that also performs various pre-processing steps. The lighting system supports colored lights, as well as blinking, pulsating and strobe ones. Even moving lights on splines and flares with proper occlusion behavior are supported. The engine features an realtime in-engine light editor which allows lighting the levels in a point-and-click way.

My favourite map Q2DM8 never looked better (Compare to old renderer on old hardware). All lighting here is realtime with lots of attenuated point lightsources. The bumpmapping is per-pixel normalized to get the crisp and sharp illumination effects on the low tessellated Quake2 levels.
Another render from the same map, lighting same as above. Notice how a low frequency texture was added to break the tiling of the low resolution Quake2 textures.
Some early pictures, running on GeForce 1. The upper left one shows point lights without attenuation, the lower right one is a multipass implementation of colored, attenuated diffuse pointlights.
I simply like that map. The detailed dot3 illumination adds a lot. I tried to replace the cubemap with a faster pixel shader normalization, but that just removed a lot of the detail from the scenes.
Some more nice views and a little bit of colored lighting. The lights in the upper right image are moving on splines. One can set them with a simple build in path editor.
Upper two are running on GF1 / GF2, the lower two on GF3. One has to use a lot of passes and destination alpha to get the entire lighting equation implemented on a GF1 / GF2 card.

Simple Ray Tracer

This basic ray tracing project uses an XML based scene graph file format. Supported primitives are (in)finite cylinders, spheres, planes, AABBs and capsules. Lighting is phong shading. Colored spot, directional and point lights are implemented. Anti-aliasing is jittered/fixed ordered grid adaptive sub-sampling, other sampling schemes supported as well. Other features are shadows, sky boxes and gamma correction. Correct reflections and refraction with Fresnel term and inner-object reflections can be calculated. Rendering is performed adaptively in a separate thread so that intermediate images can be displayed asynchronously. For fast interpolated output of these images DirectDraw7 is used. Editing the XML scene files can be done with a two computer setup where one machine edits the scene and the other automatically previews changes. The Win32 part of the code was written with my Shiny library.

Phong illuminated scene in front of a sky box background. The adaptive anti-aliasing sub-samples the borders of the objects, also the ones that are seen through a reflection.
From left to right: Reflective, refractive and reflective + refractive sphere. The refractive only one looks a bit wierd, but that's probably cause there's hardly such a material in the real world.
Area light source casting soft shadows. The lightsource is sampled by ordered grid jittering. It's rather inefficient compared to i.e. a Poisson disk distribution.
Intersecting reflecting / refracting objects, very time consuming to render cause they cause a lot of discontinuities which needs heavy sub-sampling to look good. Limiting the ray depth to much can quickly result in artifacts for such scenes.
Some old and new test scenes. The refractive spheres use a fast refraction approximation I got from Ray Tracing News.
Rotated grid anti-aliasing in action. I tried lots of different sampling schemes like ordered grid jittering and poisson disk. RGAA looks pretty good with just 9 samples and is very simple to implement. Currently I use Hammersley sampling, but I dislike the fact that it can't easily generate additional samples.
The object AABBs used for intersection acceleration. The pink lines are discontinuities which get stronger sub-sampling.

Indoor Engine

This is a modular engine using Direct3D8 for rendering. The scene is exported from MAX4 and pre-processed by a custom tool. It supports all kind of per-pixel lighting and takes advantage of D3D's pixel and vertex shaders. While the geometric data itself is in a binary format, the scene files are XML based. The shadows are done with shadow volumes. My implementation of them works around the common problems by rendering with Carmack's reverse and using an infinite far plane. Basic particle systems and flares are featured as well. In the context of this engine I researched on an occlusion volume extraction algorithm that can compute a conservative set of axial occluders with user defined precision. This simplifies further visibility computations a lot and makes them depending on the visual complexity of the mesh instead of the triangle count.

Some picture I made while playing around with the attenuation function. I started with a 1D + 2D texture, tried a version with vertex color + 2D texture and settled down on just using a dp3 inside the pixel shader to get the effect I wanted.
Per-pixel attenuation and shadow volumes. In this early version was no bumpmapping. The attenuation was implemented using a 1D and a 2D texture. The flares are point sprites handled by the built in particle engine.
Per-pixel normalized bumpmapping in action. The lights are all attenuated pointlights, either static ones or moving on Hermite splines. Bumpmaps are in tangent space.
Particle systems and a nice realtime statistics display in the upper-left corner. The particles were done using pointsprites. The little statistics graph can be customized, I used it to show a lot more than just the FPS.
Another picture of a particle system. They can be defined as templates in the XML. One system can contain multiple emitters.

PC / XBox Lighting Demo

I wrote this demo as a shadow volume / per-pixel attenuation test for Direct3D. Later this one was ported to the XBox by me. Lights move on Hermite splines and shadows are cast, with self-shadowing of course. The camera can move freely, no near plane clipping artifacts with the shadow volumes.

Demo in action with two lights active. Notice how the shadows correctly overlap and that i.e. the chair shadows on itself.
Here's one without textures. The attenuation is a simple 1D + 2D distance lookup and works well on GF1 class hardware, or even TNT1.

OpenGL Terrain Engine

The engine uses heightmaps for the terrain. The textures are generated procedurally based on terrain height. An octree is used for terrain frustum culling. Shadows are done by raycasting, the sun flare occlusion is also done that way. A detail texture is applied to the terrain. The water is procedurally animated with real geometry waves, a cubemap gives the reflective look.

Sun flare overlay, octree subdivision (higher than usual), entire terrain and surface shot with detail texture.
A nice sky box, lots of mountains from a high altitude, long shadows cast by a low positioned sun and just a bunch of shiny water.
In the upper left are some old pictures, the upper right picture shows the setup dialog. The lower ones are some more recent pictures running on a GF3.
Nice water. You need to see it in motion to really appreciate the effect.

OpenGL Lightmap Renderer

A rather simple OpenGL project. The engine loads Wavefront OBJ models and features very basic octree based collision detection and handling. Simple shadow light maps are generated on startup.

Several images show the octree, one in the lower left shows simple dynamic lightmapping.

3D UI Elements

A small collection of 3D UI classes. The goal was not to do things like an in-engine UI etc., but rather having some ways of displaying online rendering statistics as well as tweaking settings on the fly. The framerate graph is actually just a generic graph control that adapts automatically to ranges. It can also be used to display other statistics like state changes per frame.

A framerate graph and two selection boxes. This is an early version of my shadow map program.
An older version of the graph control. Credits to Jason Allen for porting it to OpenGL and various non Win32 systems.
A mesh / shader viewer using the same controls. I also ported this to OpenGL and GLSL.

Vertex Program

First hardware shader I ever wrote, a simple water wave animation. The code was written for the NV_vertex_program extension. At that time there was no HW support for it and the driver ran it on the CPU.

Most obvious flaw of the shader is the lack of normals.

 © 2002 - 2024 Tim C. Schröder Disclaimer