Demoniak3D Mandelbrot Fractal Demo
Demoniak3D Mandelbrot Fractal Demo
Win32 Exe + Source Codes
zip package - (2833k)
Release date: January 25, 2006
Update: September 22, 2006
Last update: January 18, 2008
For any bug report or feedback, please send an email to feedback [AT] ozone3d [DOT] net and add "[DEMO FEEDBACK]" to the subject.
- Operating System: Windows XP SP1 or SP2
- Processor: Pentium 4 or AMD Athlon XP and up processor
- Memory: 512M RAM and up
- Graphics Controller: ATI Radeon 9500 and up (with the latest Catalyst drivers) or GeForce FX 5200 and up (with the latest Forceware drivers)
- Resolution: 1024x768 - 32 bits/pixel
This set of demos is the implementation of concepts described in the tutorial Mandelbrot Set: Color of Infinity
The most interesting demos are those which exploit GPGPU techniques to render the fractal. These demos are located in the following files:
: use mouse left click to zoom in and mouse right click to zoom out. You can increase and decrease the number of iterations
with numpad [+] and [-] keys. That's all!
Both demos uses FBO
(Frame Buffer Object) in conjuction with Floating Point Textures
in full resolution (IEEE 754 floating point value)
Currently on my gf7800gt (with 81.98 WHQL drivers) the floating point textures are only supported for NPOTD
(Non Power Of Two Dimension)
Textures. I got this fundamental information in the NV_float_buffer.txt file, line 519-520: Floating-point textures are only supported
for the TEXTURE_RECTANGLE_NV target.
. You can download NV_float_buffer.txt here:
Ok, there is no particular problem except for textures coordinates: with NPOTD textures (GL_TEXTURE_RECTANGLE_NV), texture coordinates
are not normalized as for normal 2D textures. With normal 2D textures, textures coordinates vary from 0.0 to 1.0 (for both u and v).
With NPOTD textures, coordinates vary from 0.0 to texture_width (for u) and from 0.0 to texture_height. So in shaders, there is an uniform
variable called tex_size
which the goal is to re-normalize texture coordinates. With nVidia, tex_size
holds texture dimensions
(tex_size.x = 1000.0; tex_size.x = 800.0
) and with ATI, tex_size
is equal to 1.0.
ATI does not support NPOTD textures but support POTD floating point textures. So we are restricted to power of two dim for render to
texture size: 512x512 or 1024x1024. The chosen size is 512x512 for ATI demo.
At the GLSL shader level, we have to use a new texture sampler called samplerRect
to acces to NPOTD textures.
Since ATI does not support NPOTD textures, the GLSL compiler of ATI does not recognize this sampler! Then, two versions of the interator
and the viewer shaders are provided, one for nVidia and the other for ATI...
Another difference is the floating point value precision. With nVidia floating point textures, we can have a real 32-bits IEEE 754 floating
value for each texel componant (R, G, B and A). ATI, in the other hand, offers only a partial floating point precision of 24-bits per texel
component. We can see the difference when zooming: we reach faster a pixelised rendering on ATI than on nVidia:
As Nathan Reed said it in the tutorial, one of the biggest limitation with current GPU is floating point precision.
But one day maybe, nVidia and ATI will ship us GPU that will be able to deal with 64-bits floating point textures...
A word about GPGPU. GPGPU
stands for General Programming on GPU. It is now possible to perform simulations of complex
phenomenons using the incredible power of current GPUs.
The official site of GPGPU is: www.gpgpu.org
GPGPU programming is based on four concepts:
- GPGPU concept 1: Arrays = textures
- GPGPU concept 2: Kernels = shaders
- GPGPU concept 3: Computing = drawing
- GPGPU concept 4: Feedback
Each of these concepts is used in the stream processing demos (look at the source code). For a thoroughly explanation of these concepts, see the following links:
To end up, here is, for OpenGL coders, an overview of the underlying implementation of lua functions that deal with FBO:
GLuint fbo = 0;
// Create our FBO.
glGenFramebuffersEXT( 1, (GLuint *)&fbo );
// Bind our FBO.
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, (GLuint)fbo );
// We assume that rtt0_tex and rtt1_tex are two valid texture name.
// Attach textures to FBO.
// Set render destination buffer (rtt0_tex).
glDrawBuffer( GL_COLOR_ATTACHMENT0_EXT );
// Bind MandelbrotInitializerShader and
// render to rtt0_tex.
// Set render destination buffer (rtt1_tex).
glDrawBuffer( GL_COLOR_ATTACHMENT1_EXT );
// Now bind rtt0_tex, bind MandelbrotIteratorShader_NVIDIA
// and render to rtt1_tex.
// Restore rendering to window frame buffer.
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
// Now bind rtt1_tex, active MandelbrotViewerShader_NVIDIA
//and render to window.
One of the things that gave me pains, has been texture définition (with glTexImage2D) on nVidia hardware. With nVidia hardware, we have
to pass a NULL pointer for the last parameter of glTexImage2D(): if we try to initialize data, FBO does not work! Maybe a bug in nVidia
Forceware drivers or in my engine, I don't know...
Last thing: when using floating point textures, we must disable texture filtering (use GL_NEAREST)
and not use texture edge (use GL_CLAMP_TO_EDGE)...Author Profile
|Author:||Jérôme 'JeGX' Guinot|
|Contact:||jegx [at] ozone3d [dot] net|