SGI Windows NT Toolbox
|Download Files |

This document (dated 12/15/97), hails from http://reality.sgi.com/jamesb/multi.html
-- always reference the above link, for the most current, up-to-date version of this page.


Multi-pass texturing in OpenGL

James Bowman, SGI Inc

Pass 1

Introduction

This short example demonstrates how you can use a combination of OpenGL blend modes and multiple passes to achieve some quite sophisticated texturing effects. It also shows how you can use multi-pass rendering to get more from a very small texture. The example uses a single channel 16 x 16 texture, so the total texture requirement is just 256 bytes, or (256 + 64 + 16 + 4 + 1) = 341 bytes with all mip-maps. Its speed depends on the machine you're using: if you've got the fill-rate, it will run fast.

The code also demonstrates:

  • a method for managing depth-testing when using multi-pass
  • correct use of dithering for multi-pass
  • simple procedural texture mapping
  • use of texture transform
  • diffuse lighting of procedurally-generated textures
  • a method for adding specular highlights

Look at source.

Download sources (if you want to compile it, you'll also need GLUT).

Download Irix executable.

Download Windows 95/Windows NT executable, linked with Microsoft's excellent OpenGL.

How it works

Here's the process visually, using the default settings of 3 noise octaves and full lighting.
Pass 1 Pass 1: just draw the random texture at full scale, with brightness 0.5.
Pass 2 Pass 2: add the same texture at 2.0 scale, randomly rotated, with brightness 0.25.
Pass 3 Pass 3: add the same texture at 4.0 scale, randomly rotated, with brightness 0.125. The texturing stage is over.
Pass 4 Pass 4: Disable texturing, enable lighting, modulate the texture by the diffuse lighting
Pass 4 Pass 5: Enable dither, add specular highlights, and we're done!

User interface

Drag with the left mouse button to spin the cube; pressing shift and dragging up or down with the mouse lets you zoom in or out. The right button gives you a menu for switching the two lights on and off, and for going full-screen.

Various keys do interesting things:
  0-8   
set the number of noise 'octaves' - i.e. how many layers of texture to apply
   D    
drift - slides the texture slowly across the polygons
   F    
toggles trilinear filtering
   L    
toggles lighting (both diffuse and specular)
   O    
toggles the object between a cube and a torus
   S    
toggles specular highlights
   Z    
toggles use of depth buffer

Further reading

If you're interested in procedural texturing, you should check out Texturing and Modeling - A Procedural Approach Ed. David S. Ebert, AP Professional, 1994. ISBN 0-12-228760-6.

Possible extensions, applications

In roughly ascending order of ambitiousness:

  • Try altering the lacunarity and amplitude factors to get a feel for how to achieve different effects.
  • Alter the order or texture transformations in drawObject() to change the way 'drifting' looks. Use nonuniform scales to imitate materials such as wood.
  • Extend the code's use of color. Currently the texture is generated entirely in greyscale. It could start and end at two user-specified colors. For example, blue through white gives an effect resembling clouds.
  • Use multiple specular passes with different values for GL_SPECULAR and GL_SHININESS to build up photorealistic specular highlights.
  • One possible application is to use a noise function such as this to modify a texture you're already using. For example, you can tile a wall or floor with a repeating brick texture, then make it look 'dirty' by darkening it according to a noise function.
  • Use a pixel format that supports an alpha-channel, render noise with an alpha component, and use this channel to attenuate the specular highlights with
    glBlendFunc(GL_DST_ALPHA,GL_ONE);
    By doing this you can use the texture's alpha channel to control how much light the object reflects specularly, giving the effect of a tarnished surface.
  • Use OpenGL's 3D textures to carve objects from solid texture. The storage requirements are not as prohibitive as they might seem: extending the texture above into a third dimension only takes (16 * 16 * 16) = 4096 bytes.