[TUTORIAL] Understanding lightmaps

Shmitz

Old Hat
aa
Nov 12, 2007
1,128
746
The goal of this tutorial is to provide a basic understanding of lightmaps, how they work, and how one can minimize their load on texture memory.

You can find the map and associated assets here: Tutorial Map and Model

Lightmaps are an often forgotten part of map optimization. It's true that they are less important than other methods of optimizing performance, but a mapper who pays attention to his/her lightmaps can make a significant difference in their size, which not only has a positive impact on performance but decreases the size of the bsp.

What is a lightmap?
A lightmap is a grayscale image created for a brush face that creates the light shading on that face. Without lightmaps, everything would be fullbright. When the lightmap is overlayed on top of the brush face, it shows us how well (or poorly) lit that face is, if it has shadows cast across it, etc.

Because they are images, they take up a considerable amount of space, both as data in the bsp and in memory as you're playing the map. The first thing we want to do is find out just how much space. To do that we need to compile the map.

We don't need any fancy compile options, just use the "Normal" compile options for bsp, vis, and rad. When it completes, look in the summary table for "LDR lightdata", as shown in this image:
lightmap_lightdata1.jpg


It's a tutorial map, so it's going to be a pretty small amount. As we look at actual differences, keep in mind that in a real map these differences will be multiplied greatly.

Lightmap Scale
The first thing we want to consider is lightmap scale, which is a face property that can be found here:
lightmap_scale00.jpg


The number represents how much of a face gets condensed into a single pixel of the lightmap image. Higher scaling will result in a smaller image with less definition. Lower scaling will result in a larger image with more definition.
lightmap_scale04.jpg


The thing to pay attention to when determining scale is how much definition is actually required for that face. If we look at the two walls that are in the shade, they both look almost identical.

lightmap_scale01.jpg


Since the lower scale of 16 does not bring much of an advantage, both walls should be using 64. Visual detail will not be lost, but lightdata will greatly decrease. Consider the following image:

lightmap_scale03.jpg


We can see that when a shadow falls across a surface, a lower lightmap is better. The top rectangles should probably all be using 16 at least, if not 8. However, the bottom rectangles are all very flat with little to no shading across them. They should all be using 64.

Eliminating Excess
Another way to decrease lightdata is to remove lightmaps from significantly large hidden areas. You can see the columns standing along each wall. These columns are func_detail, which means the face of the wall they are in front of is not cut by them. The area of the wall that is hidden is getting unneeded lightmap data generated for it. If we cut the wall and make the hidden portion of it nodraw, we can remove a considerable amount of lightdata. Look at the visgroups tool on the right side of Hammer:

lightmap_visgroups1.jpg


Uncheck "Wall A" to hide that group and check "Wall B" to make that group visible. Wall B in this case has the areas behind the columns cut and made nodraw. If we compile again and look at the lightdata, we will see that we have just removed 101080 from the map.

lightmap_wall01.jpg


We also gain another advantage from doing this. This method also removes the shadow leak and makes the place where the column meets the wall more seamless.

lightmap_wall02.jpg


Hidden Detail Faces
It is important to note that while the compiler will compute lightmap data for world geometry that is behind detail brushes, it is actually smart enough to NOT do this for other detail brushes. An easy example is steps, which you can see a set of in the middle of the map. There are two methods of creating steps: A series of rectangular brushes, each higher than the previous (visgroup Steps A), or a nodraw triangular brush covered by triangular step brushes (visgroup Steps B).
lightmap_steps1.jpg


In A, each step has a lot of surface area covered by the brush in front of it (the orange lines). In B, no parts of the textured surfaces (blue lines) are hidden behind anything. Yet if we compile each one separately and compare lightdata, we will find that they are identical in size. This indicates that the covered areas are not having lightdata calculated for them.

Lightmaps are Rectangles and Pixels
Yes, we said this earlier, but we should consider the implications of this and how it relates to the shape of your face. A face can be nearly any valid polygon. A lightmap, however, will always be rectangular. Find the flat hovering square brush in the example map. This is visgroup Square A. If we switch to visgroup Square B, we'll see a triangular brush with exactly half the surface area of A. Yet if we compile them and look at the lightdata, it is again exactly the same.

Lightmaps also can't be a fraction of a pixel in dimensions. If your lightmap scale is 16 and the brush is 17 units wide, it's going to be the same size as if you brush were 32 units wide. It's important to note this in view of the section on eliminating excess. If the area you are trying to cut out is small or irregularly shaped, you may actually be increasing your lightdata rather than decreasing it.

lightmap_shape01.jpg


The blue lines represent the actual lightmap shape. In the case of Strip A and Strip B, it's important to note that in Strip B it does not apply the same lightmap to both strips. It creates two separate lightmaps, one for each face.

Using Props
Props are vertex lit, and so their contribution to bsp size and memory usage is the size of the model and skin. If you have brushwork that is repeated many times throughout the level, you may consider turning it into a prop. Not only is it easier to render the same mesh multiple times, but it eliminates all of the lightmap data required for those brushes.

Even if you are not a modeler, creating basic shapes is not difficult, and already existing Valve textures can be used for the model's skin (as it would be if it were still brushwork). In this example we use the I-beams scattered around the map.

lightmap_modelreplace01.jpg


If we compile and compare, the use of the I-beam models cuts out 32192 bytes of lightdata. The model itself contributes 7709 bytes of data, but we're still at a profit of 24483 bytes removed.
 

Dox

L8: Fancy Shmancy Member
Oct 26, 2007
588
62
Great info, thanks, hopefully I can get my filesize down a bit :)
 

l3eeron

L8: Fancy Shmancy Member
Jan 4, 2008
593
88
I learned alot... great images and explaination. Id thank you twice if I could.
 

TotalMark

L6: Sharp Member
Feb 13, 2008
331
78
The func_detail thing I had no idea about, now I gotta go fix some of my maps!
:lol:
 

YM

LVL100 YM
aa
Dec 5, 2007
7,158
6,079
Does anyone know why the 'lightmap grid' setting in hammer no longer shows a grid? I was really pissed off to find it now only shows three colours, one for normal scale, one for bigger than and one for less than. its now really hard to tell what brush has what scale but before you could see because it had a nice blue grid of the right size on it :(
 

Shmitz

Old Hat
aa
Nov 12, 2007
1,128
746
Does anyone know why the 'lightmap grid' setting in hammer no longer shows a grid? I was really pissed off to find it now only shows three colours, one for normal scale, one for bigger than and one for less than. its now really hard to tell what brush has what scale but before you could see because it had a nice blue grid of the right size on it :(

Maybe you've accidentally toggled some Hammer setting. Mine still shows blue gridlines.
 

YM

LVL100 YM
aa
Dec 5, 2007
7,158
6,079
:O I hate it when I toggle random settings without realising it! damnation!
 

phatal

L6: Sharp Member
Jan 8, 2008
259
21
Shmitz you make some great tutorials. Very easy to follow with great imagery. Big thumbs up. Look forward to your next tutorial. ;) Thanks.
 

Spacemonkeynz

L5: Dapper Member
Jan 31, 2008
234
52
Is there anyway to set the lightmap grid of the whole map to 64 in one go?

I would like to do that, then go through and reduce it where necessary.
 

grazr

Old Man Mutant Ninja Turtle
aa
Mar 4, 2008
5,441
3,814
edit > select all

texture tool; type in 64 to lightmap option.

click apply.

Edit: You can set/apply light map scales without changing the texture underneath. If you have a wall texture and right click to apply a lightmap scale of 64 to a metal texture, it wont effect the texture material itself, it will remain metal (only if you are in lightmap camera mode). Still, you can edit texture appearences on mass scale anyway whilst using multiple materials. It wont revert all your selected faces to the selected material. Handy, that.
 
Last edited:

Altaco

L420: High Member
Jul 3, 2008
484
120
edit > select all

texture tool; type in 64 to lightmap option.

click apply.

Edit: You can set/apply light map scales without changing the texture underneath. If you have a wall texture and right click to apply a lightmap scale of 64 to a metal texture, it wont effect the texture material itself, it will remain metal (only if you are in lightmap camera mode). Still, you can edit texture appearences on mass scale anyway whilst using multiple materials. It wont revert all your selected faces to the selected material. Handy, that.

Oh, thanks, I was wondering about that.
 

Spacemonkeynz

L5: Dapper Member
Jan 31, 2008
234
52
Thanks for that too.

Going through my map atm lowering the lightmap scale where all the shadows are. Lots of work, wish their was an easier way to do it.

I've got TF2 running in windowed mode, so I just spectate through, when I find a face with contrasting shadows, I alt-tab to hammer and change the scale.


What would be awesome if you could edit the lightmaps right in hammer, and see the results.
 

Sgt Frag

L14: Epic Member
May 20, 2008
1,443
710
I never saw this tut but it is well done and has good info. Figured it could use a bump and a little more info (see bottom)

I was aware that changing lightmap scale could shrink file size but never looked into it too closely, just kindof did it as a last minute optimizing technique.

Anyway, after reading this and knowing I needed to do it for Orient I went through yesterday and changed scale from 16 to 24 on about half the building trims and some roofs that didn't get much shadow anyway. Changed alot of the barely seen details and roofs to 32.

That shrank the 44 mb file down by 2.5 MB's and I'll probably get another 2-4 MB in the future. Maybe only 2 MB zipped but it does help with that. Can't say I've noticed framerate changes but haven't looked into it that far.

So anyone looking to shave file size this can have a pretty good impact on that, and I suppose there is tex memory benefits for your graphic card (I've got 512 ram on mine, maybe it's more noticeable on 256).

Also, in game you can use
mat_fullbright 2
and it will render the map in greyscale, just the shadow maps so you can see which faces aren't shading much anyway. That helps decide where you can benefit from this.
mat_luxel 1
will actually show you the lightmap luxels (grid scale of maps)
 

pitto

L3: Member
Feb 17, 2009
109
73
Great tutorial
I did know about the light map stuff before, with the shadows being better, and better shadows taking longer 2 compile, but I didn't know much about the file size and some of the other techniques.
 

Ravidge

Grand Vizier
aa
May 14, 2008
1,544
2,820
Bumping this, because it's a very nice tutorial!