Advertisement Jump to content
Sign in to follow this  

Lightmap generation with Radiosity

This topic is 3442 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, ich wrote my first Lightmap generator for some weeks. It was my first one, so it is not very efficient. I created a small texture (sizes from 2x2 to 16x16 pixels) for each triangle and optimized it by making these all sub-lightmaps unique - that is to say that I did not create a new light map when I have this one already (e.g. a complete black lighted triangle). Then I summeraized all these lightmaps to multiple big lightmaps (with 1024x1024 pixels). And I just used simple shadows (with picking-/ intersection- functions). Now I want to write a better lightmap generator using Radiosity. In "Quake III Arena" levels the lightmaps have just a size of 128x128 pixels and use ~ 10 to 20 pieces of it. My question is: what is a good and efficient method to calculate the texture area for each triangle on the lightmaps? In Quake III the lightmaps are computed for each "Quad" so multiple triangles builds on Quad. How can I learn more about lightmap generation??? Thanks for your help.

Share this post

Link to post
Share on other sites
I've never done anything like this, but you could try looking into the Half-Life or Quake compile tools. I know that the Half-Life community has produced highly improved versions of the original tools, so it's very likely that they improved the original lightmap generating code as well.

Share this post

Link to post
Share on other sites
I'm currently playing with light map generation/radiosity as well. At the moment I use the following method to generate the light map atlas:

First, for each face I calculate the set of all adjacent faces.

Then, for each face find the major normal axis. I based this on this article, although I use all 6 axii (+x, -x, +y, -y, +z, -z). For the light map coordinates of each vertex of a face convert the vertex position in world space into light map coordinates, see article. Also, apply the scaling factor as shown in the article
For Example: face normal is on the +x axis: use (v.z, -v.y) as the texture coordinates vor vertex v. For -x the coordinates become (-v.z, -v.y).
At this point, you have all faces sorted into one of 6 sets, one set for each major axis. Each vertex of the faces should now also have preliminary lightmap coordinates based on their vertex position. Although the texture coordinates may not be valid at this point, the relative sizes of the occupied texture space resembles the relative size of the faces.
Note: if you share vertices between faces (easier to calculate adjacency), be sure to clone vertices that are used on different axii!

3. Create non-overlapping clusters of faces in each axis-group. Clustering is quite useful to remove as many seems between faces as possible by putting neighbouring faces tightly together on the texture atlas. This step is actually not very difficult if you have adjacency lists available. This step is done for each axis-related set of faces.

- You have a set of faces R that contains all faces not yet put in a cluster. This initially contains all faces for the current axis face group
- You have a queue Q that contains the list of faces that still need to be considered for the current cluster
- You have a list L that contains all faces in the current cluster.

The algorithm goes like this:

while(R is not empty) {
face first = any face in R
C = new list
while(Q is not empty)
face f = Q.dequeue()
for each face a adjacent to f
if R.contains(a)

store C as a new cluster somewhere

When the algorithm terminates, you have a bunch of clusters, each consisting of a list of adjacent faces that won't overlap. You should calculate the bounding rectangle of the faces' texture coordinates and probably sort the clusters by decreasing size.

3. Pack clusters in texture
I used the algorithm found here to pack the clusters into one or more textures. Works nicely.

There are several issues not handled here (dealing with faces or clusters too large for a texture), but this should get you started.

Edit: as an example, here's the result of the procedure described above when applied to a typical teapot mesh:
Free Image Hosting at

Clusters have green borders, faces are red with white borders. You see that some clusters waste quite some space, that's where possible improvements are. Besides that you at least have something to start with. Optimizing the face atlas can always be done later without much influence on the rest of the radiosity processor.

And here's a second (though useless) example: mapping a terrain with 524k triangles to a single light 1024x1024 map:
Free Image Hosting at With the terrain in memory, atlas generation took about 15 seconds: 3.5 seconds for finding the adjacency, 7.5 seconds for determining major axii and clustering and about 4 seconds for packing the atlas. Implemented on .NET 3.5, running on a Intel E6750 dual core machine.

[Edited by - VizOne on August 21, 2009 2:10:04 AM]

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!