This is an OpenGL based 3D graphics and physics engine, written in C++. It runs on most Unices, including Mac OS X. Code-wise the program is portable to Windows as well, even though I'm not offering such a port at the moment. It runs on OpenGL 1.4 or later, but some of the more advanced features require an OpenGL 2.0 implementation.
This software has been a project for me to experiment with, and especially to learn from. The software isn't actually used for any specific purpose, but rather acts as a platform for me on which to implement new ideas or effects that I find interesting.
A demonstration of water and HDR rendering.
It's not precalculated and it's dynamic, rendered on a single polygon using shaders. water_hdr_high.mp4 800x600, 5.4Mbps, 125MB, high-profile h264 |
|
Various miscellaneous shaders are implemented, such as ones suited to simulate cars with metallized paint jobs. viper_long_hq.avi 800x600, 8.9Mbps, 114MB |
FLTK (2.0) is used as the user interface. Objects can be loaded and managed with the UI. None of the OpenGL specific code is handled via the FLTK, only the user input is; the graphics engine isn't dependent on FLTK. |
A smaller part of the engine is the physics engine.
It simulates object dynamics in a physically realistic fashion. 3d_physics.avi 800x600, 1.5Mbps, 13MB, 75s, Windows Media Player compliant |
The engine has a Lightwave 3D object (LWO2) loader for importing modelled objects. Support for Lightwave scene files was once partially implemented, but I didn't have use for it, so it's not included. |
The eye (or the camera, if you like) is also a controllable object, as are the light sources. Light sources can represent solid objects at the same time.
For shadowing objects, shadow volumes are supported. Shadow volumes are rendered using shadow polygons that are rendered to stencil buffer, which is then rendered on the screen appropriately. |
The same object shadowing technique was used in Doom 3, for example. Shadowing techniques more suitable for surface self-shadowing are implemented using shaders (see self-shadowing).
For an environment having no singular lights, ambient occlusion needs to be implemented for a realistic lighting of objects. The engine computes vertex specific ambient occlusion coefficients -- optionally in multiple passes -- for any object, and also accounts for indirect lighting from other polygons.
Normal (not ambient) lighting. A spot light above the car provides the light. | |
A flat ambient environment lighting. This type of ambient lighting was used in the car in section 3.5. | |
|
Ambient occlusion computed in 1 (above) and 2 (below) passes. |
Ambient occlusion with indirect light (from other polygons) simulated. |
The shader programs are written in GLSL (OpenGL Shading Language), and some of the techniques, especially the more advanced ones, require a GPU with dynamic branching capabilities. OpenGL 2.0 implementation is preferred.
Translucency and transparency effects are applied to two-layer relief-mapped surfaces. The simulated surfaces consist of a solid bottom layer, similar to the ones simulated previously. Per-pixel lighting, texture mapping, normal mapping and relief mapping techniques can be applied on the solid layer.
The upper layer of the surface represents the upper limit of a material that has an index of refraction (optical density) different than of the environment. The space between the lower and the upper layer thus consists of the optical medium. The index of refraction for the medium can be freely chosen (for example to match that of water (1.34), glass (1.6) or diamond (2.42)). A normal map and a height map is supplied for the upper layer.
The phenomena responsible for the appearance of optically denser materials, such as glass or water, are well known in physics, and are caused by reflection and refraction.
Video captures of the above surface (1024x768 @ 4Mbps):
glass_long.avi 38MB, 80 seconds
Water rendering is one of the many applications of the translucent medium rendering technique.
In the following screen captures, the previously presented rendering techniques are used to render water.
The visual simulation of the water is physically correct.
Water dynamics is implemented in software.
I have also taken a video capture of the water:
water_hq.mp4 1200x900, 7Mbps, 47MB, H.264 encoded |
The translucency/transparency rendering techniques, and the water dynamics, are my design. You can see my master's thesis for more detail about the rendering technique.
Metal rendering is done in 2 layers. The first layer has static-intensity environment reflectivity, and the bottom layer is solid gray. |
|
viper_long_hq.avi 800x600, 8.9Mbps, 114MB Image captures from the video in left. |
The physics engine is fps independent. During each frame update, events are processed in the order they occur in time -- objects are updated after each event, and the remaining frame timeline is kept consistent until no more events need processing. As some physical effects are near-impossible to keep analytical relative to arbitrary advances in time, linear and real object trajectories are intelligently applied in order to produce realistic behaviour and accurate collision detections.
Collisions with arbitrary polygons and other objects are computed. During collisions, both linear and angular momenta are calculated, resulting in rather realistic dynamics. Objects have physical properties, such as mass and moment of inertia, based on which calculations are done. Some more trivial effects are simulated as well, such as the gravity and air friction.
3d_physics.avi 800x600, 1.5Mbps, 13MB, 75s, Windows Media Player compliant |