PDA

View Full Version : Do we need spotlights anymore ?



nobodii
06-30-2002, 08:06 AM
I was just wondering about something ..
Does Doom3 use spotlights ? (i mean with a specific code path dedicated to spotlights)
I think its useless, all you need is a point light, and some geometry to project the needed shadows (actually, not to project light).. its even better as you can deal with arbitrary shaped spotlights ..
And that sounds more like a "unified model".
Dont you guys think so ?

dorbie
06-30-2002, 08:42 AM
All OpenGL lighting is per vertex. If spotlights were per pixel they'd be more useful, (although they still need an additional parameter to soften the edge).
There's a difference between what you can do in code and what a user or artist can use to describe lights. Spotlights have been very popular and useful in describing scene lighting, but they could be implemented as a subset of other general approaches. Nobody used the basic OpenGL lighting path for anything interesting these days. Almost anything fancy, from bump mapping to per pixel lighting to shadows requires hand coding your lighting and pretty much ignoring what OpenGL provides for lights. This is deliberate. Instead of providing fragment lighting support in functions (Which SGI had a spec for and it could be implemented today) implementors have provided a toolbox to let you construct your own lighting. It's much more difficult but it's proven popular and is infinitely more flexible.

dorbie
06-30-2002, 08:52 AM
If anyone's interested, these are the SGI fragment lighting extensions. I wrote some code that used these, it was pretty easy to implement bumpmapped fragment lighting without any hand coding of your whole lighting equation.
http://oss.sgi.com/projects/ogl-sample/registry/EXT/fragment_lighting.txt
http://oss.sgi.com/projects/ogl-sample/registry/EXT/coordinate_frame.txt
http://oss.sgi.com/projects/ogl-sample/registry/EXT/light_texture.txt
http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_perturb_normal.txt

Not sure about the peturb normal one, I think it may be rolled into the light texture extension. I don't see the extra cutoff parameter to soften the spotlight in fragment lighting and can't find the extension for it.


[This message has been edited by dorbie (edited 06-30-2002).]

PH
06-30-2002, 09:00 AM
Unified means that the lights interact in the same way with all surfaces in the world ( static world and dynamic characters - it's all computed the same way ). That's all Carmack has said. Adding different types of light doesn't mean that lighting isn't unified. It's all in the MacWorld video.

nobodii
06-30-2002, 09:11 AM
Well, actually i wasnt talking about OpenGL lighting, but all those technics that use cubemaps or projected textures to simulate spotlights.
I just wanted to know if that is still usefull when your shadowing system can do the whole thing for you...
The only problem i can see is the hardness of the shadows that may ruin your spotlight effect .. ?

dorbie
06-30-2002, 09:12 AM
Unified means different things to different people. I think what Carmack means when he says unified is he has a single lighting equation for a surface which all lights use accurately, the results are summed in the framebuffer. Shadows are probably optional but work correctly when enabled for any given light source. So I think I'm with you on the unified interpretation.

[This message has been edited by dorbie (edited 06-30-2002).]

PH
06-30-2002, 09:24 AM
Dorbie, yes we agree http://www.opengl.org/discussion_boards/ubb/smile.gif.

And I do think DOOM 3 has spotlights. It's merely an extra term calculated per-pixel. The projected...ahem...shadow/light texture is modulated by this term. Actually, I'm sure DOOM 3 just implements the GL lighting model per-pixel ( with a few tweaks ). What I would like to know, is what Carmack does to avoid clamping when summing lights - any ideas ?

PH
06-30-2002, 09:27 AM
PS: And there are definitely shadows from multiple lights in the scene with the Imp and fireball http://www.opengl.org/discussion_boards/ubb/smile.gif.

nobodii
06-30-2002, 09:53 AM
PH : you mean the only thing that changes is the attenuation map texture, while the equation remains the same ? You could for example bind a texture3d for a point light, and a cubemap for a spotlight (i think you see what i mean), without really changing your vp.
well, I guess this would work .. and still, you can call it 'unified' http://www.opengl.org/discussion_boards/ubb/smile.gif

dorbie
06-30-2002, 10:01 AM
Clamping is not a problem when you are accumulating results in the framebuffer, it can look OK, just watch your totals if it's an issue. Clamping IS a problem when it happens between two passes for example in an emboss bump map where the tops of your bumps can get flattened, or individual terms get clamped before use.

I strongly suspect Carmack uses destination alpha to store shadow_texture(?)*attenuation*cutoff (pick your own combination of attenuators) between passes on systems with limited texture units. So, this could get clamped, but they modulate each other then the light on the second pass so it's not an issue.

The lighting results just accumulate in the destination color, if they clamp they clamp, it will probably give them a realistic looking overexposed look unless there's a huge chroma shift, and even then it'll probably look great.

dorbie
06-30-2002, 10:03 AM
Yes, the lighting equation is identical. It's lighting_result * (attenuation * spotlight cutoff * shadow * whatever else I might modulate the light with). Oh and it works for color too.

[This message has been edited by dorbie (edited 06-30-2002).]

nobodii
06-30-2002, 10:14 AM
Ok, i get your point, but i cant figure what is your "* shadow". I though shadow is when the stencil count != 0 (or whatever init value) ?
Or maybe we're not talking about the same thing ?

PH
06-30-2002, 10:19 AM
There was an interview with Carmack where he said he did some pre-modulation and post-scaling to support an arbitrary number of lights per surface ( at the expense of some precision ).

For example, if I accumulate a series of bright lights, sum( Li ) will eventually exceed 1.0. This is the clamping I was talking about. I've been looking at ways of extending the range ( dynamically ? ) at the expense of precision. Maybe combine it with the base texture color to simplify/optimize shadows from multiple lights on shiny surfaces ).

dorbie
06-30-2002, 10:22 AM
P.S.

PH, darn I just deleted the video. I totally expect multiple shadowed lights, I just haven't seen them in the shots. Any engine accumulating lights that can do shadows for one light should be able to just enable it for all lights, it'd just clear the stencil buffer and have at it with stencil volumes etc for the next light. There are engines now which do stencil shadows or projected shadows of another kind, but it's just a nasty hack. Again this is another aspect of a unified lighting model. The key is that the fragment color added to the framebuffer represents everything about the fragment lighting result for a single light, (of course the stencil test culls the fragment rather than modulating it to zero but the net effect is the same).

[This message has been edited by dorbie (edited 06-30-2002).]

PH
06-30-2002, 10:27 AM
There's a scene in the leaked video where the multiple shadows is _very_ visible. The player hides and a monster walks by, there are two huge shadows there.

Oh, and implementing this for surfaces with colored specular highlights requires rendering to a texture. I had a few posts on this a long time ago and I settled with using a doubled buffered p-buffer ( I'll revisit that work when time permits as it might not be the most optimal ).

dorbie
06-30-2002, 10:36 AM
PH,

Hmmm... I can see that with a fragment light result in a nominal range and the attenuation maps which clamp it would never blow out. This would mean that you want to keep the attenuation maps a bit darker than normal, and boost the result during attenuation modulation. So the clamping he's avoiding is in on an individual light attenuation to allow a light to blow out a surface and look bright, not to avoid all clamping in the framebuffer. He's trying to avoid clamping in the attenuation * cutoff * shadow(?) before he multiplies by fragment light result. To do this it costs him some precision in the attenuation modulation because it's ramped over fewer bits and multiplied later.

It's not the final result he doesn't want to clamp, he's actually trying to make it >1 in places it's the intermediate modulation he needs to stop clamping before it multiplies the result and he can then boost the overall effect. As you ass lights to the framebuffer they will clamp.

Beyond this he MIGHT manage overall levels in the scene, but not to save every destination fragment from a clamp.

Anyhoo, that would be my interpretation. Clamping is not always bad, and can look quite good at times.


[This message has been edited by dorbie (edited 06-30-2002).]

dorbie
06-30-2002, 10:40 AM
PH, if you look at the massive doom3 thread you'll see I predict that on cards with limited texture units some shadow effects will be monochrome. However I don't think specuar highlights are a unique case. Their color can be modulated by the same color as the diffuse term for a point source, it's just that when you only have one component in alpha....

Do the math, L is the same for all terms, and it's L that is attenuated and applies the color, as opposed a diffuse map which isn't applied to specular.


[This message has been edited by dorbie (edited 06-30-2002).]

zeroprey
07-01-2002, 05:00 AM
Originally posted by PH:
Oh, and implementing this for surfaces with colored specular highlights requires rendering to a texture. I had a few posts on this a long time ago and I settled with using a doubled buffered p-buffer ( I'll revisit that work when time permits as it might not be the most optimal ).

I don't really see why you would need the render to texture. An older tutorial:
http://www.ronfrazier.net/apparition/research/advanced_per_pixel_lighting.html

has basicly the entire light equation and can be done on a gf2 without a render to texture. The color of the spec comes from the light color. Maybe I'm misunderstanding you.


[This message has been edited by zeroprey (edited 07-01-2002).]

PH
07-01-2002, 05:14 AM
Trust me http://www.opengl.org/discussion_boards/ubb/smile.gif, specular lighting is not that simple when combined with shadow volumes. If you try and implement a completely general system, you'll see what I mean. It's exactly the same with the interpolation problems with specular lighting - when I brought this issue up ( a post a long time ago ), only Cass Everitt immediately knew what I meant. In short: there are lots of subtle issues with lighting/shadowing, that you need to experience first-hand to accept.

davepermen
07-01-2002, 05:19 AM
so lets all move to ptm. just write out the whole lightingequation and tailorize it, put this into a texture and done.. http://www.opengl.org/discussion_boards/ubb/smile.gif

zeroprey
07-01-2002, 05:38 AM
PH,
I have. Full bumpmap lighting in 5 passes on gf2 with volumetric shadows. It all seems to work fine for me and I still don't see what the problem is. Do you know what the topic was in which you discussed this so I could find it? Either that or maybe explain it to me now.
Maybe you mean a color gloss map instead of just in alpha. I dont see why youd need that though.

PH
07-01-2002, 05:46 AM
Yes, for one light it works. For 2 or more lights on a single specular surface ( that reflects the lights color - some materials do that ) with shadow volumes for _all_ lights, the implementation is not that straight forward.

I don't remember when I posted about this but I _think_ it was in a thread about pbuffers.

PH
07-01-2002, 05:49 AM
Oh, do you have some screenshots of your work that you could post somewhere ? I'd just like to see what other people are doing ( not that I doubt you, just curious ).

zeroprey
07-01-2002, 05:53 AM
PH,
Yeah one surface with spec and however many lights you want that all shadow. You just add them up in the frame buffer. Its 5 passes each light for mine full effects. The only color the spec has is that of the light which is what your saying. I'd show some pics but I'm at work now. Anyways I'll take a look at the pbuffer thread and see if I can see what your saying there.

PH
07-01-2002, 06:10 AM
It really just boils down to requiring two RGB temporaries. You can solve this by drawing your shadow volumes twice, once for diffuse and once for specular. Or you could save the affected stencil region to a texture ( one for each light ) and restore the shadow infomation when time comes to sum specular RGB. If you only have white lights, you can use destination alpha as the second temporary. Note that materials such as metals will have a reflection that is somewhat the color of the material ( so a white light on a gold surface, will have a golden highlight ).

PH
07-01-2002, 06:17 AM
Or you might be able to do some so tricks to avoid rendering to a texture:

Pixel = sum( DiffuseLight*Shadow )*DiffuseMaterial + sum( SpecularLight*Shadow )

The shadow term is required in both sums, so if you dont want to draw you shadows twice, you need a second temporary ( a texture, pbuffer or something else ).

If you could get the DiffuseMaterial into the sum ( without clamping ) then there wouldn't be any problems. I'm looking into this at the moment.

zeroprey
07-01-2002, 06:20 AM
PH,
Since I use the alpha of the diffuse tex I can mul by the diffuse color for the spec calculation too if I wanted. Why would your stencil get overwriten? I just do it once at the beginning and enable stencil test. I do save stuff in the alpha channel such as att and things but this doesnt touch the stencil. I could run through the passes if you want.

PH
07-01-2002, 06:26 AM
The stencil will be overwritten by the next lights shadow volumes as you sum the diffuse contribution. Shadows from two seperate lights that occupy part of the same area ( affecting the same surface for instance ). You need all these _seperate_ shadows in the second sum but you sum all the diffuse light first, then modulate by the surfaces diffuse material, _then_ add all specular contributions ( all the previous shadows terms are required here ). Is that not what you are doing ?

PH
07-01-2002, 06:28 AM
Originally posted by zeroprey:
I could run through the passes if you want.

Sure, that might help in seeing what you are doing.

zeroprey
07-01-2002, 06:47 AM
Nope thats not what I'm doing. I cant remember the passes off the top of my head cuz its been a little while and I dont have the code in front of me. I tryed to write them out. I can write them down when I get home if you want. I'll tell you the jist of it.
shadow to stencil
att*spot->alpha
specpass*alpha->rgb(might be 2passes dont remember)
diffuseshading*alpha->alpha
diffusecolor*alpha->rgb

I dont redo things and split up the dif and spec. You just have to make sure the passes always add to the frame and nothing else.

dorbie
07-01-2002, 06:52 AM
zeroprey, you need the destination color to accumulate the lighting result. So there is no simple way to pass color information between passes in a lighting calculation. When you calculate specular you need to do this. The only thing left right now is destination alpha in the framebuffer or render to texture (which I don't think will be a favoured path).

2 factors should be prominent in your thinking, 1) destination color (the framebuffer) is reserved for total accumulation (except on the first light) and 2) a full lighting calculation with diffuse & specular bump map attenuated etc cannot be done in a single pass on some of the highest end current hardware (GF3 & GF4).

The conclusions follow easily from this. The only other significant point of debate is does the engine support render to texture or render to destination alpha for the first pass. Remember that the first light can use destination color (for simplicity it may not)

from Carmack's latest .plan
Doom needs more than 2 bits of
destination alpha when a card only has four texture units

Hmmm.... I think that's a bit of a giveaway, destination alpha for attenuation storage followed by source * destination alpha on multipass lights it is.

zeroprey
07-01-2002, 06:54 AM
another problem youd get doing it the way you are by doing mul diffusemap last is that in the end the lights cant sum to white. That is unless youve found some trick around that.
Check out that link I gave earlier cuz I just do a reduced version of that. I think I just sacrifice color light maps but I dont remember. Its been almost a year since I've fooled with that part of the code.

dorbie
07-01-2002, 06:55 AM
P.S. Since a smart implementation would render stuff like emission (glowing stuff)during the depth fill pass I think even the first light will be unable to use destination color because it will already have color information from the depth fill pass.

dorbie
07-01-2002, 06:57 AM
zeroprey, w.r.t. your latest comment, I think that's what we're talking about with clamping earlier in this thread.

PH
07-01-2002, 06:58 AM
zeroprey,

Of course the lights can sum to white. If you had the diffusemap inside the sum, everything would eventually be completely white ( that is a completely white surface, which is probably not what you want ).

zeroprey
07-01-2002, 06:59 AM
emission is just ambient really. The ambient pass(havent coded yet) would just be done when you render the depth for the shadows. That would be once per object instead of per light.

dorbie
07-01-2002, 07:05 AM
It can be rendered the same for our purposes. W.r.t. the rest that's what I just said. It is significant because it instantly reserves destination color so NO lights may use it between passes. Not even the first.


[This message has been edited by dorbie (edited 07-01-2002).]

PH
07-01-2002, 07:07 AM
dorbie,

Another big hint from one of his .plan files, is that the GeForce3 requires 2-3 passes depending on the number of color components in a light. You could probably use destination alpha to store the number of lights that affect a certain pixel ( and use that to pre-modulate the diffusemap and bring it into the sum ). This might not work or be efficient but anything is better than rendering to a texture ( I would assume ).

zeroprey
07-01-2002, 07:09 AM
PH,
I dont see how you can get a surface with 0.0 spec to go to white. The diffuse all adds to no more than 1 cuz of the frame buffer. 1*diffusemap wouldnt be 1 unless the diffusemap is one. The only way is if you sum the diffuse each time.

dorbie, yes this is the clamping problem. It was recently discussed on the gdalgoritms group.

[This message has been edited by zeroprey (edited 07-01-2002).]

PH
07-01-2002, 07:11 AM
Originally posted by zeroprey:
PH,
I dont see how you can get a surface with 0.0 spec to go to white. The diffuse all adds to no more than 1 cuz of the frame buffer. 1*diffusemap wouldnt be 1 unless the diffusemap is one. The only way is if you sum the diffuse each time.


Which is exactly why I do it last http://www.opengl.org/discussion_boards/ubb/smile.gif.

Edit:

That is Pixel = sum( DiffuseLight )*DiffuseMap


[This message has been edited by PH (edited 07-01-2002).]

zeroprey
07-01-2002, 07:17 AM
PH,
I dont understand, you want it to be at most the diffuse map? I dont think thats physicly accurate. It should sum to 1 if there are enough lights. Am I wrong? I do believe thats what all the fuss was about on the gdalgorithm group.

dorbie
07-01-2002, 07:19 AM
PH I'm skeptical about that. Maybe he thinks he needs to break the diffuse & specular into separate passes in addition to the destination alpha first pass for the extra color work. It's getting too speculative now, some things we know others.... well you can roll your own lighting anyway so does it really matter? :-)

Zeroprey, it sounds like Carmack has already said he boosts the attenuation result and keeps the map a bit darker. This is like storing an attenuation value >1 in the framebuffer. It's using a post modulate scale to store an extended range variable in the framebuffer and it costs you a bit or two of precision due to the scale. It's very like the source*dest + dest*source in a texture emboss bump map implementation, you need to keep the bump map values down in the framebuffer to avoid clamping but you effectively multiply the result by two during the modulation. I think the motivation is different though. With the bump map you want to avoid clamping during the emboss, here I suspect he wants to avoid clamping of the result to avoud the post clamp modulation of his lighting result (which would look slightly strange).

I think this is quite clever, I hadn't considered this before PH sent me in the right direction in this thread, it should mean that overexposure is very nicely handled in the engine when a light over illuminates a surface.


[This message has been edited by dorbie (edited 07-01-2002).]

PH
07-01-2002, 07:22 AM
Zeroprey,

To be absolutely sure we are talking about the same lighting equation: I'm using the one from the RedBook ( chapter 6 ) which is the GL model. I do this per-pixel, with shadows and colored highlights. This requires two RGB temporaires for multiple lights ( in general ). The diffusematerial term I store in a texture map ( DiffuseMap ).

Dorbie,

Yes, it probably won't work. Besides I'm not trying to copy Carmack, simply looking for more efficient ways to solve the issue I mention previously ( which I thought was the pre-modulation he talked about ).

zeroprey
07-01-2002, 07:25 AM
dorbie,
I havent heard that before. Do you know where you heard that? Seems strange he'd cut his presision in 1/2. I can see cut down on att thing but a x2 at the end doesnt make sense to me.

dorbie
07-01-2002, 07:30 AM
I heard it second hand in this thread from PH :-), but I drew the conclusion it was the attenuation the comment applied to. See the earlier discussion on clamping. This makes some sense to me it might be worth that precision to boost the levels, Remember if the screen is too dark human contrast sensitivity works against you anyway and the user probably cranks his monitor brightness up :-).

(Post 13 in the thread)

[This message has been edited by dorbie (edited 07-01-2002).]

PH
07-01-2002, 07:36 AM
I was about to start pulling my hair out http://www.opengl.org/discussion_boards/ubb/smile.gif. My comment about storing the number of lights in dst alpha was to support what I wrote in post 13. I have thought about this before but I think I concluded that it wouldn't work ( unless perhaps attenuation and other brightness affecting terms are combined with it too ).

[This message has been edited by PH (edited 07-01-2002).]

davepermen
07-01-2002, 09:02 AM
just wanted to state that i like how dorbie always counts posts and refers to them by number.. (how about the "quote" button? i don't like to count myself you know.. http://www.opengl.org/discussion_boards/ubb/wink.gif)

zeroprey
07-01-2002, 09:04 AM
I took a look at the lighting model in the redbook. You're not doing the whole equation are you? Heres the general equation I do:
amb+sum[ (1-d.d)*spot*lightcolor*((N.L)*diffusemap+((N.H)^n)*s peccolor*gloss) ]

come to think of it now I might need 6 passes for gloss. I dont remember now. I sure hope not.

On a gf3-4 pretty sure I can do it in one pass for a static exponent and 2 passes with a exp texture using the tex combiners(also helps the precision problem). That would be done using the combiner normalization. Has anyone tryed this? How does it compare with the cubemap?

[This message has been edited by zeroprey (edited 07-01-2002).]

PH
07-01-2002, 09:09 AM
Yes, the whole equation. I recently added the ambient term but I might remove that ( though it does make it look more real ). The attenuation is of course different ( it has to be bounded ).

PH
07-01-2002, 09:13 AM
Oh, my spot effect has inner and outer cone angles and raised to an exponent ( currently a fixed value ).

zeroprey
07-01-2002, 09:16 AM
I am impressed then. Does that work on gf1-2 hardware? Could you maybe tell me how many passes and stuff that takes? I hadnt seen attenuated ambeint in the equation before but that certainly fixes the changing at rooms problem I would have had with just a flat per room ambient value.

zeroprey
07-01-2002, 09:18 AM
Is that spot effect created in the combiners or do you just gen a texture for it with those values?

PH
07-01-2002, 09:24 AM
Originally posted by zeroprey:
Is that spot effect created in the combiners or do you just gen a texture for it with those values?

A pre-generated texture ( that depends on inner/outer angles and an exponent ). I _could_ do it with ATI_fragment_shader on Radeon 8500 but that wouldn't be very useful ( and it would be slower ).

PH
07-01-2002, 09:32 AM
Originally posted by zeroprey:
I am impressed then. Does that work on gf1-2 hardware? Could you maybe tell me how many passes and stuff that takes? I hadnt seen attenuated ambeint in the equation before but that certainly fixes the changing at rooms problem I would have had with just a flat per room ambient value.

Well, I'm not trying to impress you http://www.opengl.org/discussion_boards/ubb/smile.gif. You did ask why rendering to a texture was required ( the equation from the Red Book where the DiffuseMap is outside the sum requires this OR some other trick ).

Oh, 5 passes on GeForce1, 3 on GeForce3 and 1 on Radeon 8500 ( I have a "new" shot of this on my site ).

zeroprey
07-01-2002, 10:05 AM
An interesting thing to note: just saw recently on that gdalgorithms list the way they are doing the lighting for Malice. They have 3 buffers a normal buffer, N.H, and N.L. they do a dependent tex read of the normal buffer to make the N.H and N.L with a full screen quad. They then do another quad to do fill in the equation and slap it to the frame buffer. Its a interesting idea I think. Maybe its more applicable for the lower res of xbox. If you have to do the extra buffers might want to look into this.


[This message has been edited by zeroprey (edited 07-01-2002).]

SirKnight
07-01-2002, 05:08 PM
It's exactly the same with the interpolation problems with specular lighting - when I brought this issue up ( a post a long time ago ), only Cass Everitt immediately knew what I meant.


Here is that discussion. http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/003519.html

-SirKnight