View Full Version : Multiple Lightsources?

11-27-2005, 04:06 AM

I wonder what is the best way to support multiple lightsources in a shader without knowing the exact number at the time of writing?

Of course, I could always compute all 8 OpenGL Lightsources in my Shader but this would be very slow and would result in wrong results when there are less lightsources present.

I thought about a uniform parameter to pass to the shader but this won´t work, even on ShaderModel 3 Hardware.

So which way should I go?


Zulfiqar Malik
11-27-2005, 06:43 AM
I don't know what you are trying to achieve over here, but on pre-SM3.0 capable hardware you usually had to process one light at a time. On SM3.0 hardware i have read some nVidia paper suggesting 4 lights per-shader. Infact, nVidia ported FarCry's lighting shaders to SM3.0 and they did lighting in batches of upto 4 lights per-pass.

11-28-2005, 01:45 AM
When you try to send the number of lights as uniform, what exactly happens???

One idea is to use different shaders for each separate light count - 1, 2, 3, ...

12-03-2005, 08:15 AM
When I send the number of lights as uniforms, I get a compile error in my Fragment Programm (Shader Model 3 Hardware!):

error C5043: profile requires index expression to be compile-time constant

When trying to do something like that in my vertex program, I get another error:

error C5025: lvalue in assignment too complex

Any ideas? Always computing 4 Lightsources is pretty slow, at least for some shaders.

12-04-2005, 12:14 AM
what graphics card do you use? and driver version?

12-04-2005, 10:12 PM
... and what were the exact shader sources producing the errors?

01-12-2006, 04:49 PM
error C5043: profile requires index expression to be compile-time constant
Are you using the default light source uniforms? Last time I tried using them, ATI drivers had a lot of problems. I remember the following giving the same compiler error:

void f(int i)
array[i] = something;

f(0);One way to get around that problem is by using macros.

01-13-2006, 04:01 PM
The way I have been doing this is by including bools at the top of my shader like this:


up to some maximum number of lights. Then I use conditionals to process the contribution from all the active lights. It is probably bad to have the conditionals, but it works.

The other way I would like to try (but haven't yet) is to make a lighting ShaderObject which would just compute lighting and store it in variables such as diffuse, specular, and indirect. Then I would link this to all my ShaderObjects that compute material properties using the already computed lighting data.

So every time I change my lighting environment I would compile the lighting ShaderObject once and link it to all my material ShaderObjects. For this to actually work well, it relies on linking being very fast. I don't know if this is the case, though. I have even heard that some shader compilers just concatenate shader strings and then compile them all at once, effectively linking *before* compiling. Anyone have anymore information on this?

01-14-2006, 05:28 AM
Originally posted by mogumbo:
Anyone have anymore information on this?I've been doing this for all my shaders. I have created a library of "utility" shader objects (lighting, shadows, fog, skinning, parallax, etc) that I compile and link as needed to get a final shader program.

AFAIK, ATI has been compiling before linking since their first implementation, whereas NV added support for this recently (Forceware 80+).

Unfortunately, the NV implementation is currently buggy. It works the first time, but as soon as you try to link a program containing a shader object that has already been linked with another program, the link fails (with an obscure, internal error). I have reported this, but the bug is still present with the latest official drivers.