io7m | single-page | multi-page | archive (zip, signature)
2. Blender implementationGlow maps
PreviousUp

OpenGL implementation
Preamble
The OpenGL implementation is written in Java and OpenGL, using LWJGL for the underlying OpenGL bindings. It does not use any Java-specific or LWJGL-specific features and should be directly translatable to any language with OpenGL access. The program uses the deprecated immediate mode for rendering solely because to do otherwise would require more in the way of supporting code.
The program consists of two classes: GlowMap.java and Utilities.java.
Implementation
Obviously, in OpenGL, there is no such thing as a "separate layer". However, it's easy to get the required separation by rendering in multiple passes using framebuffer objects. The general approach is as follows:
  1. Render the lit scene, including emissive objects, to a texture T0.
  2. Render only emissive objects to a texture T1.
  3. Blur the texture T1 with a GLSL shader, writing the result to a texture T2.
  4. Render a screen-aligned quad, textured with texture T0.
  5. Render a screen-aligned quad, textured with texture T2, possibly with a lower level of opacity depending on the desired effect.
Given that the typical gaussian blur shader requires two rendering passes, the entire procedure requires five rather inexpensive passes and is therefore easily achievable in real-time on modern graphics hardware. For simplicity, the technique here is shown in 2D but the process is exactly the same for three-dimensional objects.
The procedure for rendering is therefore:
  1. Load the necessary shading programs.
  2. Create a framebuffer, Fs, in which to hold the scene.
  3. Create a framebuffer, FbH, in which to hold the horizontal pass of the blur shader.
  4. Create a framebuffer, FbV, in which to hold the vertical pass of the blur shader.
  1. Switch to framebuffer Fs and render only the emissive objects in the scene.
  2. Switch to framebuffer FbH and render a full-screen, screen-aligned rectangle textured using the texture that backs framebuffer Fs, and using the horizontal pass of the two-pass gaussian blur shader.
  3. Switch to framebuffer FbV and render a full-screen, screen-aligned rectangle textured using the texture that backs framebuffer FbH, and using the vertical pass of the two-pass gaussian blur shader.
  4. Switch to the default framebuffer (so that rendering will be visible on the screen) and render everything in the scene.
  5. Enable normal alpha compositing with glBlendFunc.
  6. With the default framebuffer still active, render a full-screen, screen-aligned rectangle textured using the texture that backs framebuffer FbV.
The provided demonstration program, GlowMap.java, is able to show each rendering pass (although the two passes of the gaussian blur shader are combined into one). Use the 'R' key on the keyboard to switch between rendering passes.

PreviousUp
2. Blender implementationGlow maps