Handling multiple lights with per-pixel lighting

Started by
8 comments, last by b3rs3rk 19 years, 10 months ago
how can be done? now i can handle a single light source, but i want to add more effects to my scene... one solution would be to redraw the scene once for every light, but this will kill performance.. (a BSP with PVS world running at ~200fps on a ATI9000 128) someone knows another solution? [edited by - b3rs3rk on June 6, 2004 4:47:08 AM]
Advertisement
Well, you could write shaders that will do something like 2-4 lights in the one shader (depending on what shader version you want to target), then when you go over that limit you do another pass. For example, if you have a scene with eight lights you could do two passes, processing 4 lights each pass (rather than doing 1 pass for every light).

Of course, if you can write for v3 level shaders you can do theoretically an infinite number of lights in one shader (due to looping and conditional capabilities)....if you have access to the hardware .

- Thomas

- Thomas Cowellwebsite | journal | engine video

Multipass is the obvious solution but has some limitations :
- it''s going to kill performance, especially if you''re vertex-limited,
- since multipass needs to get your hands on the blending stage, you can''t combine (or you can hardly combine) multipass rendering over translucent faces,
- too many passes causes to reach the 8-bit per channel color precision pretty soon, so you will either have to deal with 16-bit per channel color buffers or you will have to accept saturated-like pictures when pixels receives to much light contribution.
@cow_in_the_well: i don''t think i can use any pixel shader, my video card (ati9000) doesn''t support them :°/

i need to find another solution..
quote:Original post by b3rs3rk
@cow_in_the_well: i don''t think i can use any pixel shader, my video card (ati9000) doesn''t support them :°/

i need to find another solution..


Actually you are wrong the main advantaga between Nvidia Mx440 and RADEON 9000 is that RADEON supports pixel and vertex shaders, actually i have the same Video card on my PC , but shader performance is quite slow , download some shader samples from ati demos.

The RAADEON 9000 specification you can find here

specs
ATi Radeon 9000 series do support the ATI_fragment_shader extension which is quite powerful.
Assuming you need 4 operations for each light (ambient+diffuse+specular), you can perform up to 4 light contributions in a each shader. Dealing with translucency and decal texturing you will probably be limited to 3 lights per shader, but then you can tweak a bit (e.g. don''t compute an ambient for each light, use an overall ambient contribution) to save some operations.

The other problem being, do you want to "play" with shaders for your own card ? Or is your software expected to run on everyone''s hardware ? In the former case, it''s ok to simply use ATI_fragment_shader ; but in the latter case you''ll have to deal with multiple rendering paths (don''t mistake with "multiple rendering pass") in order to run on e.g. GeForce.
The Radeon 9000 supports pixel shader version 1.4, and an OpenGL extension that''s ATI specific that has the same power.

To get more than one light per pixel, you typically want to multi-pass. Then do translucent objects last, in their own pass, using a different lighting solution (!).

If you''re doing 200 fps right now, you can have three passes and it''ll still run at faster than 60 fps. Thus, you should be able to easily do three dynamic lights with the code you have now. Chances are, if you do good per-light culling and scissoring, you can do much more than that. Also, you can shoot for 30 fps on your current card -- available machines and cards already would do 60 fps on the high end. That''d give you 6 lights with the code you have now.

Another option is to, per object, draw the brightest two (or so) lights per pixel, and do the less bright lights per-vertex, or even bake them into a spherical harmonic solution.

Last, to do diffuse + specular with infinite lights, without bumps, all you need is two cube maps. One cube map runs in NORMAL_MAP mode and encodes diffuse lighting; the other runs in REFLECTION_MAP mode and encodes specular. You could do something like 5 lights this way, per pixel, on a 9000, because it has six texture units times two phases; do 5 diffuse lights and a color modulate in the first phase; add 5 specular lights times a reflectivity modulate in the second phase.
enum Bool { True, False, FileNotFound };
quote:Original post by vincoof
The other problem being, do you want to "play" with shaders for your own card ? Or is your software expected to run on everyone''s hardware ? In the former case, it''s ok to simply use ATI_fragment_shader ; but in the latter case you''ll have to deal with multiple rendering paths (don''t mistake with "multiple rendering pass") in order to run on e.g. GeForce.


i am in the second case: i need to write a code that can run on various hardware, not only ATIs

"multiple rendering paths " <--- what?!?

quote:Original post by b3rs3rk
"multiple rendering paths " <--- what?!?

You have to write different code for different target platform. This can get difficut sometimes. It depends on how much effort you put into it. A VERY SIMPLE scenario would be to have an if statement like this:
if ( using ATi extensions ) {    Setup ATi shader} else if ( using NV extensions ) {    Setup NV shader} else if ( using ... ) {    Setup ...}Draw Mesh 



You might want to check out famous "material/shader implementation" thread in graphic programing&theory forum, but it might be a bit heavy for you for now.



You should never let your fears become the boundaries of your dreams.

[edited by - _DarkWIng_ on June 6, 2004 2:11:35 PM]
You should never let your fears become the boundaries of your dreams.
aaaaaah! you mean THIS for "multiple rendering paths"..
i''m sorry man, but i''m italian, my english is not so perfect

This topic is closed to new replies.

Advertisement