Not logged in, Join Here! or Log In Below:  
News Articles Search    

 Home / General Programming / Another lighting question Account Manager
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.

February 27, 2005, 03:14 PM

Hey everyone. I thought i was getting this stuff, but i guess i wasnt.

Light is the most mysterious part in the engine for me! I have some questions, which's answer's are essential for my engine.

1. What type of lighting should i use? Or a combination? Lightmapping, vertex-lighting? I dont want anything like ppxl lighting because i want the engine to run on older machines too (and older video cards as well) yet i want the lighting to look good. Vertex lighting alone doesnt really cut it due to tesselation and polycount issues, that's why lightmapping seems to be a good alternative.

2. Say i chose a combination of lightmapping, and vertex lighting, but when i use lightmapping, the light *rays* pass through walls, and if the light moves through a wall, that isnt good for sure. How would i fix it? I was thinking "Thats what the shadows are for" but i wouldnt want to shadow the whole damn 3d world, now would i? Espessialy with my goal of an engine running on older machines.

3. Does anyone here know of any tutorials, examples, links for info on how to do good quality, "all-compatible", fast lighting?

Thank you in advance.



February 27, 2005, 04:19 PM

If you are targeting older machines - forget about dynamic lighting and just use precalculated lightmaps. Using that u can have radiosity, soft shadows and other nice things - only problem is that its not dynamic - oh well..

If u go down the dynamic lighting route - it will be *better* but a lot more work - esp with bumpmaps and shadows...



February 27, 2005, 04:32 PM

Err, no dynamic lighting means no engine, for me =(

Dynamic effects are extremely important. By old machines, I dont really mean machines from early 80s... but still old.


Please, currently, the most important task for me is to get lightmaps to stop shining through walls. How would i do that? Thanks!



February 27, 2005, 04:43 PM

With your definition, Half-LifeČ has no engine ;)


February 27, 2005, 09:19 PM

It's an engine, just not for him.

Anyway, I suggest giving your lights zones of influence, like a particular light only lights up 1 room and the objects it contains.

Although you say it's the lightmaps that shine through walls? Light maps are (normally) precalculated, meaning you can generate them any way you like (including hand painting) so if they look like light is shining through walls it's no-ones fault but yours.


February 27, 2005, 09:28 PM

heh, its not what i mean ;)

Im sure u know what i mean, light mapping... now u got me all confused. lol...
Zones of influence, that sounds.. interesting, but it would take away the flexibility from the user. The point is to allow the user to throw in the light sources, and its the engine's job to make the lights shine properly. Would u happen to have more suggestions?



February 28, 2005, 12:03 AM

If you mean like the user is building a map, and puts light sources in the map, then you just need to have a compilation step to calculate the lightmaps (this is how all the quake and half-life games do it).

If you mean that during the middle of the game you want the user to be able to create arbitrary light sources...well...there's really no solution for that but dynamic lighting.

Note that if you don't wanna do pixel shaders and stuff, you can fake some dynamic lighting (from point sources only) using a texture that has a white circle fading out to a black background. Use this texture as a lightmap, throwing it over each surface with appropriate texture coordinates, and you can arrive at a fair approximation of per-pixel lighting (diffuse only, no specular) by using texture combiners only. If you're ambitious you can even throw in shadow mapping; it will take 2 passes per light, but I think you can even make this work on GeForce 2 class hardware.


February 28, 2005, 08:57 AM

Heh, sometimes, you might need to insert a light source for a dynamic light, before compilation time. Thats what i need. I need the user to be able to walk with a torch, turn on, and off lights in some rooms.. basically have dynamic lighting.

And thats what im doing, i have a large white dot, fading out to black, and it is used as light - map. And i have them manipulated around the source, and surroundings, to create dynamic lights. I just need a way to stop them from shining through walls, and the way should be as elegant as possible.

About shadow mapping, its way too slow with older video cards, i'd rather stick with stencil shadows...

Thanks... looking for more suggestions, please.



February 28, 2005, 09:57 AM

well, just clip them to the plane of each wall then...


February 28, 2005, 10:16 AM

but the light moves, and then the intensity and location may change.


Rui Martins

February 28, 2005, 10:19 AM

Your problem is a little strange!

If you are using a lightmap, you can decide where you apply that lightmap.
But this seems to be your question!
"which polys should I 'project' my light map on ?"

Which makes me believe that you don't use any occlusion solution, portals or similar. that is what you should research.

if the "torch" is confined to rooms, you just need to know which polys belong to your current room. You will probably have to handle the case of switching between adjacent rooms.

To know where to place the lightmap, just find the closest point between the emiting point light (the "Torch") and the specific wall (poly).
Note the light map, may span several consecutive polys depending on light radius (fall of distance).


February 28, 2005, 01:53 PM

My problem isnt strange at all. Ok, you are thinking of a scenario too simple.

Ok, imagine a small 3-sided pyramid, and u are looking right that edge of it, so u can see 2 sides at once. Imagine a point light appearing by one side, say left side, the problem is, u can see the lightmap appear on the right side as well, when the light source comes too close to a left side. Thats not good. I need a solution for it.
Thanks for a reply tho..



February 28, 2005, 02:30 PM

First thing to realize when doing dynamic lighting for older machines is that there WILL be tradeoffs.

In your example with the pyramid, why can't you use the side of the pyramid to clip the lighmap?


February 28, 2005, 04:21 PM

what do u mean *side* of the pyramid? I clip textures according to distance of my light sources to world geometry...



February 28, 2005, 05:21 PM

You said "u can see the lightmap appear on the right side as well, when the light source comes too close to a left side". So clip your lightmap when it gets close to the pyramid so that it doesn't light the right side.


February 28, 2005, 06:40 PM

It sounds like you're either not attentuating by the light source's distance to the plane, or you're not doing the dot-product with the normal and the light source direction.


February 28, 2005, 09:09 PM

Wait... You mean it's lighting up backfaces? Like you are lighting things the light is on the wrong side of?

Rui Martins

March 01, 2005, 08:27 AM

OK, if using a 3 sided pyramid, you will always have problems, because it's faces are not Vertical. It's a "Trade off", that you really can't get away of.

What I haven't understood, is if your problem is the fact that
"both pyrami d faces are lit",
or if it's the
"joining at an oblique angle that doesn't match between the 2 lightmaps".

I believe it's the first case, in which case you fall into the case of not occluding correctly.
As someone suggested, you are probably missing the DotProduct between the Light-To-Surface vector with the face Normal.
If the face is not "facing" the light, then NO light will (should) show on it.

Probably a screen grab would avoid wasting all this time explaining, and would make the problem case obvious to us.


March 01, 2005, 02:58 PM

YES! Thank you! I didnt think of that at all when writing this! lol... so in simple words i should just check whether the normal is pointing in the way the light source is. Ok! Thanks!

lol, i was soo stupid not to do that. Should be a snap to make tho. THanks everyone!



March 01, 2005, 10:37 PM

Or depending upon when you are calculatint the lightmap, the fastest way might to transform all the coords to that of the Light, then check the order of points to find backfacing.

This should be faster if you are doing all the polygons at once, yet slower if you are doing it poly by poly


March 04, 2005, 05:31 AM

Hey everyone, im back again. I tried the solution that you suggested, but it doesnt work... in most cases. Let me give u examples:

Say, i have a floor (a 2 polygon plane) and a wall in between. On one side of the wall, there is a light source, quite close to the wall, and quite intensive. On the other side, its the camera. Now, while the light does not shine through the wall anymore, it *does* shine on the floor, and that extends far beyond the wall, in camera's direction. Basicaly, the floor is also iluminated on the player's side. That stops me from having doors sliding open, and letting the light in (just one of the cool effects), which leads me to another question, what if i want to drop light mapping, and implement per-pixel lighting. And i want to do the same thing, have a wall, and a floor and stuff, how would i stop a per-pixel light from doing that? How would i be able to slide open a door, and have the light shine, more and more until the door is open?

I just cant understand this...


Rui Martins

March 04, 2005, 06:45 AM

Say, i have a floor (a 2 polygon plane) and a wall in between. On one side of the wall, there is a light source, quite close to the wall, and quite intensive. On the other side, its the camera. Now, while the light does not shine through the wall anymore, it *does* shine on the floor, and that extends far beyond the wall, in camera's direction

Well your main problem is that you don't know the restrictions of how to build a correct level.

Your bed room floor is not the same as the one in your living room !
They might even be made of the same material but they are not the same.
Basicly in games, we need to have convex shapes, which makes our life a lot simpler. a Box room is a convex shape, if we don't count the Doors and windows.

So basicly, what you need to correct is to have two floors, one for each room. 4 polys instead of 2.
Note: They share the same mathematical plane, but are distinct areas of it, this means they share the same normal, but the vertexes are different although in the same plane.

Hope you get it. I really don't know how to explain better something as obvious as this, at least to me.

Try to research BSPs and how quake levels for example are defined (Brushes with CSG operations). You can and probably should also research "Portals".

Michael G.

March 22, 2005, 07:05 PM

Listen buddy, Vast,

The lighting you're talking about is just per-vertex or per-pixel based off of lambert's cosine law... and maybe you're taking antenuation into affect. What you really *want* to do though, is shadow calculations.

Basically you have to somehow "trace" a ray from the light source to the surface in question. In raytracing it's very straightforward, when a surface is hit, it spawns a ray to the light and checks for intersection. Very simple, unfortunately we aren't dealing with raytracing and that occlusion check (I suspect) would be darn painful to do per-pixel. Anyway, there are other ways; here's the run-down.

Lightmaps (static):
You precompute those darn visibility/occlusion tests from the surface to the light on a regular grid like interval. It's stored in a texture and can be slapped across the surface later (modulate or modulate2x or whatever you choose!)

Stencil shadows:
Hmm, take the geometry from the scene, extrude it away from the light source and perform a stencil test across the frame using said new polyhedrons. Downside... it can be a pain to generate the geometry and you'd really want to be partitioning your level space well (performace hit) think q3 shadows, Carmack's reverse (a variant of straight stencil shadows, unless I'm wrong). Anyway, this is the method I know the least about.

Lightmaps (dynamic):
Each frame (or however often pleases you) render the depth buffer from the light's point of view (if it's an omni light, you'll have to do the 6 sided cube or some tweaky vertex shader method (parabolic or spherical perspection distortion). When you render the scene, transform those z values into the camera space... there's an extention to compare z values, if they're less in the scene than from the light, then they're in shadow. You'll usually do something like render the scene using only backfaces from the light's point of view for this... then the percision/light bleeding isn't (very) noticable since it's on the dark side. Note, only works for closed objects... Don't have any fins hanging out there. btw, there's some other extension that will filter the results so you have bilinear filtering of the shadows (instead of blockiness) I want to say something like gpu gems has some cool article on blurring/softening the shadowmap in realtime as well (good results, but slow.)

This would be *my* option of choice, but i think for this, or the pixel shader occlusion test you'll need fairly new hardware to decently run it. Check into stencil shadows, you might have some luck there, although you have to do geometry processing.

Maybe you could strategically tesselate your objects and get by with vertex shadow calculations, that could run in realtime and wouldn't be too much of a pain (I wouldn't think). Man... I really need to actually code again someday...
Good luck on your project. Shadows are 'da bomb.


Michael G.

March 22, 2005, 07:14 PM

Btw, everyone is talking about level creation and map processing/partitioning and rooms because when you're doing shadow/lighting calculations having your level partitioned can speed things up by limiting what geometry it has to take into account for each light. In many cases, especially if you have a quick falloff you can get around without shadow calculations and just clip lighting to the immediate room. Although that wouldn't allow your nifty opening door example ;-)

For anything more than the simplest scenes you'll want some sort of partitioning going on for any shadow types (except maybe static lightmaps, which you can probably brute-force and clog up the video card's arteries with textures without hell and the program freezing over...)



March 22, 2005, 07:56 PM

Heh, thanks for your reply Michael. I kept myself busy for a while with this, and then desided to implement everything i could, and sort of "drop" old hardware. Now, I implemented stencil shadows, which work great! (especially for the opening door effect =) OMG cant stop watching it =) )

Also, I went ahead, and implemented dot3 bump mapping (along with per pixel attenuation). It still doesnt work right in some places, but I just have to tweak the way I calculate the tangents.

I also added luminance map (glowing texture map) and specular highlights (if the card supports shaders).

And it works "ok". Old hardware can get the effects through, without using shaders, newer hardware (starting GeForce 3) could get everything =)

I didnt implement a codepath for ATI yet (since i dont own a card) but since you know so much, perhaps you could suggest something?

Also, lightmapping would be good with stencil shadows, but i desided to implement it all while I was having fun with it.

I really appreciate your feedback though.


Michael G.

March 23, 2005, 10:17 AM


I'm flattered you think I know so much. To tell you the truth, I have almost zero experience with this stuff except from a theoretical standpoint.

I owned nothing more than a voodoo2 for a *long* time, and recently bought a radeon 9800 pro so I could actually start coding some decent stuff.

Unfortunately I work fulltime (as much as I can) doing software testing (fairly non brain-interactive) go to school fulltime, and have some tough responsibilities besides.
Ultimately, what I'm trying to say is, I have wanted to break into 3d programming using vc++ and d3d (kinda like d3d over opengl, anyway, different topic) but haven't *taken* the time to do it. (I have written several software rasterizers and know the concepts rather well.)

*grin* So, I'd like to congratulate you on your progress so far, and let you know, except for the theoretical stuff, my say is genuine 100% bs. :)

I haven't posted on this forum in probably over a year. I just thought it'd be cool to get my kicks once again.

Suggestions? Check around the forums for someone doing similar things, check for pdfs (documents) on stencil shadowing that outlines the differences between nvidia and ati implementation, throw an exe up on the net and say "does this work for you?" Other than that, like I say, I haven't cruised the forums or websites in ages. Check over at if you're working in OpenGL.

Haha, someone who knows the heck what he's talking about can take over now.


Michael G.

March 23, 2005, 10:44 AM


I just re-read your original post. You've got it figured out, like others have said though, you just need to partition your world into some visibility hierarcy. If you're doing an outside world that means something like a quadtree (usually a good option). If you're working indoors, you might look into a sector/portal design, or if you're really into "pure" 3d stuff and like the idea of 3d contiguous space you might look into octrees.

For what you're doing (if it's 1/2 way indoor) the sector/portal idea should work well. Design your world around this idea and for medium to large scenes you'll see a great performance increase. If you're still caught up in the "I don't want the user to have to place anything but pure level data" ie. no hand placement of sectors/portals you might consider doing something like Unreal did (negative CSG) which really lends itself well to automatic sectors/portals placement. But again, now the user has to start with level data created in this CSG editor. And you're no longer working with raw polygons now.
A Quadtree or Octree (or KD-tree? or Beam-tree?) scheme can be applied to the raw input and is a geo-spatial partitioner. It breaks stuff up based most entirely on position.
Because of this, things like 'which geometry to process for lights with quick antenuation' become trival, and you can just blindly include any nearby geometry without thinking about portal clipping and the rest (just perform those stencil shadow calcs.)

When it comes down to it, you're really looking for the best performance, which can sometimes be a rather sticky hybrid of techniques and... shortcuts.
I would recommend shooting not for performance right now, but technique, once you really decide what you want to do/limit yourself to, then you can focus in on some speedups/hacks/etc for performance.

That said, partitioning schemes are not hacks and should be applied as soon as you're wanting to allow slightly larger/more complex worlds.
There are several articles (here I believe) on Portals, which I thought were good. If you go the Quadtree or Octree (or other tree) way, there was an Ask Midnight post some time ago about traversing the Octree which my prove useful. There was also an article which showed how to use the quad/oct tree for visibility determination in the area of geometry processing before even sending it to the video card (to be rendered)(That may have been at Since you're going to be processing this for the stencil shadows it'd probably be in your best interest to pump this into your "extended" rendering pipeline and process what geometry can be clipped from the rendering process altogether.
You may find there's a balance between being 100% accurate with the clipping, or leaving leway and updating the current/previous included tree branches over multiple frames.

Well, enough talking out of my posterior. Heh, I feel like some old fogy, imparting his general, outdated learning (for better or worse) upon the younger generation.

Dang the field of 3d graphics is facinating, I can't wait to be able to hone my focus into my field of interest. Ah well, the daily grind continues. If things work out I'll be able to head up to "U dub" (university of washington) next year.
*ramble ramble ramble*

Back to work,

This thread contains 28 messages.
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.