   Generating a lightMap
  Another question for today:)I need to write a lightMap generator, for the first time. I know how it works globally, but there are some things where I need your advice.First of all, I think there are 2 ways to 'fill' the lightMap texture:1: a. Loop through all pixels in the lightMap (pixels that are inside a polygon)b. Convert the 2D texture point to a 3D world positionc. Figure out to which polygon that pixel belongs for additional info(normal or something). Might not be nessesary, but in my case it is.d. Check out which lights can affect this pixel3. Fire a ray to those lights and check if there's nothing between them2:a. Loop through all lights.b. Fire a dozen rays into the worldc. Track each ray, and check where they hitd. When it hits, convert 3D world position to a 2D texcoord in the lightMape. Eventually, bounce the ray (radiosity?)...but won't their be a risk that some pixels are skipped, if we don't fire enough rays? We could fire millions, but that might slow-down the process too much...Several problems show up for me now. First of all, I don't know how to calculate a 3D world position from a given texcoord, or vice-versa. And how to implement bouncing rays for radiosity? The second sequence easily allows to bounce, but since the rays might get scattered too much, I'm afraid a lot of pixels will be skipped that are litten indirectly.What sequence do they normally use for generating lightMaps (with radiosity)?Greetings,Rick   
  The second approach you mention is commonly used in Shadow MappingYou fire the "rays" from the light source to the objectsThis is commonly used in games nowadays :) and can be used to produce softer shadows than stencil shadows.Usually the shadowmap will be 256x256 or larger (1024x1024)This is *a lot* more rays than ~12 (try 1 million "rays")Since it's rendered on the videocard (depth buffer stuff, check the link I gave above) it's rather blazingly fast.The first mentioned way sounds closer to the other way to work with lightmaps.You take the lightmap surfaces, and you check for incoming light.You described it as checking which lights are visible.  In actuality, you'd want to do that for the First bounce.  This accomplishes (in reverse) what the section above does.If you want multiple bounces though, you *really* should be sampling the scene *all* around the section in question (ie, cast rays in a hemispherical fashion out from the surface to see what it "sees" that's how light probes work, right?  You let light in from a range of angles.)Anyway, you're basically rendering the scene (you can use the hemicube style if you like)this article shows the method in a most descriptive visual manner.Some research has been done in speeding up the computations by rendering using hemispheres *instead* of hemicubes on hardware (used to be the other way around, 'cause we can't *really* do a hemispherical projection)They use a vertex shader to project the coordinates onto the spherical lens shape.If you google it, you'll see what the precision problem was with this method (but it's still very good)HTH,-Michael g.p.s. There are more ways than Shadowmaps, shadow volumes, and radiosity to calculate lighting.  In terms of global illumination, the math starts to get ugly in some of the other methods, but you can check them out here (global illumination on wikipedia)p.p.s. Paul Nettle (fluid studios) has written up something cpu driven, closer to what you're talking about.  He uses raytracing and beam tree subdivision to speed up the calculations.May have source code as well (can't remember)   ;  Thanks! I'm reading your first link now, and I like it. I prefer the "1+1 potatoes = 2 potatoes" way of explaining things, if you know what I mean :) Well, I have plenty stuff to read now.Greetings,Rick;  There's one thing I wonder. I was thinking about raycasting all the time, but it seems that radiosity gets his result by rendering the scene from hemicubes/spheres, and measuring the pixel values.Sounds logically, but how to do this fast? I know the entire thing is already a slow process, but reading all those pixels for each hemicube that needs to be rendered (not interpolated)... I'm using OpenGL, does that mean I need to read the entire screen with glReadPixels or something?Another thing that comes to my mind is HDR lighting. I'm using HDR, so maybe it would be nice if the lightMaps contain bigger data as well. I guess when rendering to a floating point buffer, and storing it in floating point textures, i can simply use bigger values than 1.0 (and no normalization is used), right? Only bad thing is that the lightMap texture takes even more time to be generated probably. And it takes more memory when loading it into the game. Now my lightMap is already big, since I'm trying to do the Halflife2 "Radiosity Normal Mapping" thing. If I understand this technique right, there are 3 lightMaps inside one. I have no idea how big the Halflife2 lightmaps are. But I guess I need something like- resolution of 1 lightMap  682 x 1024- resolution of 3 lightMaps 2048 x 1024- size of RGB 16 floating texture: 12 MB12 MB... does this sound reasonable? I have no idea. Maybe I could compress it. Render the whole thing as floating point stuff, but finally save it as an ordinary 32 bit texture. Then I measure the difference between the lowest and highest brightness. This difference is used to calculate a scale factor. Now the alpha channel contains a value that must be multiplied with this scale to come on the total value. Something like:  lightValue.rgba = tex2D( lightMap, texcoord );  color.rgb  = lightValue.rgb * lightValue.a * hdrScale;A little bit less accurate, but I think it should work. It saves 4 MB. By the way, is the usage of floating point textures in a shader slower than using 'normal' textures? I'm asking this because I need to do extra math now, but maybe it will be compensated.What do you think? Is this a proper way to implement HDR for the lightMaps?Greetings,Rick   ;Quote:here's one thing I wonder. I was thinking about raycasting all the time, but it seems that radiosity gets his result by rendering the scene from hemicubes/spheres, and measuring the pixel values.Sounds logically, but how to do this fast? I know the entire thing is already a slow process, but reading all those pixels for each hemicube that needs to be rendered (not interpolated)... I'm using OpenGL, does that mean I need to read the entire screen with glReadPixels or something?I believe it was this paper (coombe) that had information about the whole spherical projection stuff in a pixel shader.You'll also (I believe) find that you'll want to do the multiplication pass just as a modulated texture (very fast in hardware) and then generate a mipmap chain - in the end (1x1 pixel) you have the average rgb intensity.I'm not sure whether floating point textures support mip-mip generation though, or how fast it is.  I don't think it's too slow to create your own mip-map generation codepath though.  You might look into that :)Sorry I can't comment on practical usage in texture memory and the HL2 lightmap resolution.  My question is, for the 16mb map, how much level area is that covering?  I might be misunderstanding the method you plan to apply and hl2's method.I understood that there was some sort of radiosity lightmap (which would be of considerable resolution, 1x1 texel for every 8x8 or 32x32 texture pixels I would imagine.)  You've already mentioned the 3 lightmap thing (for each axis, to support bumpmapped lightmapping)Please understand that the hemicube/hemisphere resolution is independant of the final lightmap texture.  If you look at hugo elias' site (linked in my first post) you'll see that, for each texel of the lightmap, you actually have to probe many points (64x64 or so, again, sorry, not sure on practical considerations) but that 64x64 is sampled down to one value, which is stored in the lightmap.HL2 (if I recall correctly) also used lightmap "probes" in level areas.  These were for the dynamic objects (ie, entities, players, moving objects, etc.) and these *would* be directly using the (not hemicube, but) full cube, so the resolution would matter.However, if you look at ATI's CubeMapGen you'll find that you really don't need *that* high of a final resoltion for the texture.  Something like 32x32x6 is generally good enough (so long as you *originally* used something at least 128x128x6 or so, and blurred + sampled down)  I would recommend *using* ATI's CubeMapGen if possible.  Otherwise, well, look at the page linked - I've messed with it, and yes, the seams *are* that bad.Commenting on your 12mb size and hdr scaling question.  I would remind you that your target audience *probably* has at least 128mb or memory (again, just keep in mind how much of the scene the 12mb represents).  The idea of scaling lightmap related textures is not new (and not uncommon) but is usually used in the final step.  When generating the multiple bounces for the lightmap, you'll probably want to keep all the accuracy you can.-Michael g.   ;  I know the resolution for making the hemicube samples has nothing to do with the final result resolution itself. I was wondering how large lightMaps ussually are for games as HL2. I can remember that you could often see the low resolution of a lightmap in old games, since it was somewhat "blocky". I didn't really notice this in HL2. Which is pretty good, since the levels are pretty big relative. Most of my scenes are much smaller. Think a little bit of Resident Evil 1, where each the world was divided into chambers. Most of the chambers weren't that big, although there were also longer hallways or bigger open area's though. Same thing for me. I should make the lightmap as small as possible I think, until the lack of detail becomes a pain in the eye. Maybe an option to stretch it down for older cards with less memory. Anyway, I'd like to compare the sizes with a game such as HL2, just for my information. I have no clue if 682 x 1024 is big or small, comparing to other modern games.By the time I finish this game (I hope it ever comes so far!), common video-cards probably have at least 256 MB I suppose. So yes, 12 MB is not that much of a problem. But with all the trauma's from programming on microcontrollers, I'm always carefull with my resources :) And smaller lightMap means more space for other things and faster loading times of course.By the way, I think's its a smart idea to let the video-card scale down the texture like you said. Should be a lot faster than reading all the pixels with the CPU I guess. Thanks for the tip!Thanks for helping again!Rick   ;  I'm starting with an implementation now. But the first thing that shoots to my mind, are those "patches". If I understand it right, each patch holds a couple of numbers like its emmision value, and how much light it has received so far (measured with a hemicube). But...First of all, what exactly are those patches? Let's say I have a list of polygons. The lightMap UV coordinates are given, and each polygon has it's own position somewhere on that texture. Now I need to divide that polygon into patches. With some math I could "put points" on that polygon, and store it somewhere on a list. But what to do with it? The patches should be used when rendering the scene for a certain hemicube. But how to connect these patches with a surface? I mean, i can do whatever i want with those patches, but they need to be used while rendering somehow. Maybe with a texture? Maybe I could copy the original lightMap, and use it as a texture for the entire scene. After measuring the results from 1 hemicube, the result is put into the corresponding data to that pixel (isn't that the "pointer texture" where one of the papers is talking about?). When finishing a pass, I should use all values to re-draw the entire texture, then upload it again to the video-card for the next pass. Correct, or am I talking rubbish here?Another thing are the lightSources. The measurement is an avarege of everything you can see through a patch. But... lightSources are not visible of course. I could represent them with a very bright sphere or something (like you see in the paper), but is there not a risk this sphere gets lost when downscaling the whole thing (or when a lightSource is very far away)?Greetings,Rick   ;  Answering your questions would be easier and faster to do via an instant messenger, but if we feel the community would benefit from this continued discussion I can continue to reply on here.Please let me know.As for your questions about patches and point light sources, please look again at Hugo Elias's web page (linked in my first post) and see his work on the issue.Please *then* come to the conclusion that radiosity is supposed to be representive of actual, physical phenomena and decide to use ambiently lit spheres for "point" light sources since the falloff of light and perspective for the sphere are equal (inverse square law) :)Btw, you're on the right track.  You may want to decide to disregard the thought of point light sources in your radiosity solution though...With spheres you don't risk losing the information to downscaling - unless your sphere is *very* bright, what happens is, with distance, it's affect on the scene lessens, the fadeout will be gradual (and realistic/physically based)-Michael g.   ;  As for UV coordinates for the lightmap, Yann Lombard has commented extensively on this, and you'll find some great links here on triple buffer it links back to discussion on gamedev.net for the most part.Hmm... I was sure Yann talked *a lot* about uv mapping and discontinuities.... Search around, you might find it, or I might find it.  It involved the cornell box example.Yeah, quake 2 made some assumptions because it always had floor and ceiling objects, that it'd map stuff straight down (uv coordinates) for faces below a certain angle threshold.  It helped to eliminate lightmapping artefacts.You can code up a nieve uv mapper for them, but at some point in time, to eliminate border discontinuities, you'll need to pad the edges of each non-connected face correctly.(this paper should get you started thinking.  There are better documents which detail how *exactly* to work out edge problems.  I'll try to find the one I'm thinking of.  This should help you know how you can choose to build/segment the lightmap though.)-Michael g.   ;  First of all, I really appreciate your help! Rate++It's difficult for me to explain, but the real problem is that I don't know how to render the scene for the passes. My technical english is limited, so that makes it harder to understand those papers.I understand that you should render half 'cubeMaps', disable shading, fog etc. All surfaces should be rendered with their patches. The patch decides how much light is coming from the patch at that moment. Right? But how to render these polygons with those patches? I guess I use textures for that. All polygons start with black textures, unless they are emitting light. So far so good. I render the scene from the view of a certain patch, and measure the incoming light for that patch. I can do this by downscaling and reading the pixel values. The CPU then stores that value into the corresponding patch, which is probably a record in an array or something. When the pass is done, all my patch records have been updated. Before starting the next pass, I need to update all textures that are used for those polygons. So each patch should be linked with a polygon's pixel. After that, the texture is re-loaded, and the next pass can begin. Is that correct?If not, how to render the scene then? And if it's correct, how to link these patches with textures? Like I said, I already have atlas texture coordinates for the whole scene. So maybe I could use those coordinates to make another texture that is used for rendering the patch values? But maybe it's a problem that the patch sizes are not really equel. Some surfaces have relative small space on the texture, while others are far more detailed.Another mathematical problem is how to decide the patch coordinates/normal when using those given texcoords? I can loop through the lightMap, create a patch for each pixel that lies inside a polygon. I know to which polygon the pixel/patch belong then, but then I need to know the actual 3D position for that UV point...[edit]Or maybe each patch has a texture on itself? And the scene is not rendered with the actual polygons of the scene itself, but the quads/triangles from those patches? Could be somewhat easier maybe... But in the end I still need to know to which pixel in the resulting lightMap each patch belongs I guess.Greetings,Rick   