Skip to main content
GameDev.net gamedev.net
🔒 Locked

LightMap quality

Started by spek Apr 1, 2007 at 7:09 AM 6 replies 3.6k views
Original Post
spek
spek
Hi, I'm rendering with lightMaps (with the radiosity technique for normalMapping from Valve) for quite some time now. That all works, but I'm not very pleased with the detail quality, and the time needed to create such a lightMap. I have enough detail (enough pixels per surface) for acceptable quality lightMaps, but my scenes are small. For example, now I have 2 chambers from ~10 x 10 metres, and a couple of hallways between them. And there are some pipes and other details inside. But when I build larger / more detailed scenes, I'm afraid the quality is just too low. I know the lightMap detail in old games such Quake 2 and Halflife 1 was low, but then again, their scenes could be relative big. So, I'm looking for some tricks and tips to get more out of my lightMaps. Compiling: When I compile my scene, it will calculate atlas texture coordinates for 1 texture. Yes, all the surfaces are placed on only 1 texture. Don't know if that's a good idea for the detail, but its nice for rendering and stuff since the lightMap texture only needs to be activated once. I know its important to make good usage of the available space inside the texture, so I try to spread out the surfaces as good as possible. Probably this can be done better (gaps between polygons, complex shapes sometimes take too much space), but its not that bad either if I look at the percentage filled. I wonder if I get that much more detail if the lightMap texture was ~100% used anyway. To make it a little bit better, I can give materials an "importance" factor. For example, ceilings ussually don't catch that much light, so they take less space than the average wall in the lightMap. The lightMap itself: When the compiling is done, I generate the lightMap. I can adjust the lightMap resolution, but I ussually take 2048 x 1024. Well, its actually a little bit smaller. The "normalMapping radiosity" technique places 3 lightMaps in one texture next to each other (3 light directions, each with its own lightMap), so 1 lightMap actually has a resolution of 682 x 1024 pixels. I have no idea if that's enough, but I wonder how old games with larger scenes or games such as Halflife2 keep sufficient detail in their lightMaps, because my lightMap certainly lacks detail when the scene gets bigger. And another annyoing things, is that rendering a lightMap with this size, takes me nearly 8 hours! I wonder how the generators in editors such as Valve Hammer do it much faster. I don't use ray-tracing for the generation, I render the world for each patch and measure how much light is incoming. For the radiosity part, I ussually take 3 or 4 passes. The scene is rendered on a low resolution and simple, but it still takes awfull much time! Ok, the scene is also rendered on a FBO with a floating point format (the lightMap is "HDR", not limited to 0..255 values), so that makes the rendering somewhat slower. Another important point is that the final pass is rendered actually 3 times. Like I said, there are 3 lightMaps for the "radiosity normalMapping" technique. Each patch needs to measure the incoming light from 3 different directions. Maybe this could be done smarter. What am I doing wrong compared to other games that make use of lightMaps? Greetings, Ow, excuse if I don't reply in the next days, probably I'm far away from internet! Rick
spek
spek
By the way, I just saw its possible in the HL2 Hammer editor to define how much "pixels" each surface gets:

http://developer.valvesoftware.com/wiki/Image:Intlight_lightmaps.jpg

I guess the blue squares indicate the pixels. Or is it luxels? Anyway, it also says that the BPS file might increase its size when fooling around with the detail settings per surface.

So if I understand it right, the resolution of the lightMap(s ?) can be adjusted. But in that case, how are the surfaces placed in the lightMap texture? I could say that surface X needs 100 pixels/luxels, but there is no guarantee I actually get that detail when this surface is placed in the lightMap when there also many other surfaces with high detailed (or just a small lightmap resolution). Or does each surface has its own texture?

Greetings,
Rick
sebastiansylvan
sebastiansylvan
Use better UV parameterisation?

UVAtlas in DirectX or perhaps the UV parameteriation tools in Blender etc.
Gagyi
Gagyi
I guess halflife uses one global lightmap (for each part of the level of course), and one "detail" lightmap for the closer places.

If not, this would be a good technique.

Another good thing would be doing a pre-lightmap, see, how detailed a triangle (or patch) is, and if it's only white or only black or a simple gradient, give it a much less resolution than the parts beneath trees or pipes.
-----------------------------------"After you finish the first 90% of a project, you have to finish the other 90%." - Michael Abrashstickman.hu <=my game (please tell me your opinion about it)
SimmerD
SimmerD
I use a constant texel density ( texels / square meter ) for all lightmaps, and don't try to fit the whole level on one texture atlas.

I break up the tri index lists into ~2500 triangle chunks, and create a texture atlas for each one. I try to fit the texture atlas into a 128x128 texture, and if it fails, go all the way up to 512x512, in 2x1 and 1x2 scalings. If I fail even that, then I start reducing texel density by 10% until it fits.

gyula
gyula
Here is How I am doing it in my Getic 3D
For a pre-established lumel (luxels) squared size
(Us,Vs)4x4 - 16x16 (units (meters, inches) whatevwe the map
has for 1.00)and preestablished maxim light map image (seee BSP compiler Settgins)
32x32 or 16x16(Du,Dv) RGB I calculate the maxim extend of
a polygon. Eg. For 4x4 lumel size and 16x16 bitmap light map size
I get an extend or 64 units/meters.
Before building the BSP I split each polygon if it's extends
exceeds 64 units. This aligns huge polygons to
have a proper light map size. 3dThen...I follow someting very
similar to this
http://www.flipcode.com/articles/article_lightmapping.shtml
for
each polygons set. YOu can see each light map size after you build a BSP
then (Main Meu->(View or Tools)->Texture Meter-> @Lx)

spek
spek
Hi, thanks for the answers!

Better usage of the available lightMap space is important indeed. Therefore I can select which materials have a "large" scale on the lightMap, and which ones have a low scale. It could be even better if I could adjust the scale per polygon, but the problem is that the scene models are made in Lightwave. So each time I make a change in the model and import a newer version of the model, all these settings are gone. Unless I can find an option in Lightwave to store this factor somehow...

Anyhow, no matter how good the priorities are given, the pixel count is not unlimited of course. So the bigger the map is, the lower the detail. Unless there are multiple (detailed) lightMaps, that are loaded once they are needed. But I wonder if (modern) games are really doing that (something like Gagyi
says). For example, how many/big lightMaps textures would a game like Halflife2 use for 1 scene?

I like the "SimmerD" solution. Because then I have a better guess on how many pixels a polygon will actually use. But splitting up into chunks will be hard though. My scene is already splitted into sectors for PVS, for each material, and for the cubeMaps. And calling a lot of different lightMap textures also takes speed.


By the way, do large textures make the rendering slower (maybe because all the data must be going through the card)? For example, if I render a mesh with a 512 x 512 texture instead of 2048 x 2048, would it be faster? In that case, does the format also matters?


Ow, and does anyone know how lightMap generators for games such as Quake/Halflife are so fast? I know its not super-quality, but man, my generator also needs 20 minutes for making a crappy lightMap. Maybe thats my fault, but Lightwave for example, also needs 8 hours for a bigger (pretty good quality) lightMap. In the days I made maps for Quake2 or Halflife1, it was a manner of minutes. On an old computer that is.


greetings,
Rick
VladR
VladR
Quote:
Original post by spek
Ow, and does anyone know how lightMap generators for games such as Quake/Halflife are so fast? I know its not super-quality, but man, my generator also needs 20 minutes for making a crappy lightMap. Maybe thats my fault, but Lightwave for example, also needs 8 hours for a bigger (pretty good quality) lightMap. In the days I made maps for Quake2 or Halflife1, it was a manner of minutes. On an old computer that is.

While I dont exactly know how is the radiosity calculated in those games, Im sure that I havent spotted static shadows breaking over boundaries of multiple objects (eg. through half of some broken brick) as was the case with Unreal Tournament 2003, where you could clearly see the shadows from objects correctly mapped over multiple walls/objects, even going through half-broken brick.
Which leads me to assumption that they cheated the shadows somehow.
Why ?
Because visibility computation (involved when you take into account shadows) takes most of the time in radiosity computation.
So, if they didn
t have to deal with physically-correct shadows through radiosity (those shadows really didnt look like that), they were involved just in Form-Factor computation.
About a year ago, I made a radiosity test where the scene had 30079 patches and I made 30079 passes (no visibility computation, i.e. Fij = 1.0f ). That
s over 9.04M Form-factors computed during 576 seconds (on AMD XP2500). Which is 1.57M form-factors per second.
I remember huge texels on walls when playing Quake 2, something like 10x10 (at most, but probably much less) texels per square meter (sqm). So, if you had a regular smaller room/corridor, say 10x5x6 meters, thats 280 sqm - which is 28.000 patches. There might be 5 lights in this room. With progressive radiosity, you need to make 28.000 x 5 = 140.000 form-factors (FFs) calculations to take include for each light. Lets say you want some indirect lighting too, so you make about 1000 passes, so we must do 28.000x1000 = 28M FFs. On AMD XP2500, this would take 18 seconds.
Rest assured, that you dont need 1000 passes in regular scenes, unless the light is placed right above some static object which is near some wall or other object (otherwise, theres not much visible indirect illumination visible when lightmaps are multiplied by diffuse textures).
So, with 100 passes thats less than 2 seconds.
Don
t get me wrong, indirect illumination has great impact. But definitely not with the resolution of the lightmaps that Quake 2 has.
Lets say you implement an easy speed-up interpolation hack where you calculate just every second patch, thus you calculate just 25% of previous amount of FFs. This would get us under 0.5s for our above example.
During the HL1-era, there were at least 750 MHz CPUs available. That
s not that much slower than my 1800 MHz AMD in floating-point calculations. Surely not a 10:1 ratio. Plus, there were no obvious optimizations (in my above example) included, so maybe if I spent some more time with it, I could get not jus 1.5M FFs, but maybe even 3M FFs per second (maybe making some obvius cache-coherency rearranging or some other optimizations).

Therefore, its obvious that their lightmap computations didnt take much time even on much slower CPUs.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.