Sign in to follow this  
Foobar of Integers

Quick GLSL uniform variable question

Recommended Posts

I'm working on my per-pixel lighting shader, and I'm trying to get it to support more than one light Normally it always used gl_LightSource[0] for all the calculations. This worked fine, and hardly reduced the framerate (about 60 FPS on a 9700 Mobile) Then I decided to make it so the program can tell the shader which light to use. I added a uniform integer called current_light, and used gl_LightSource[current_light] for the math instead. That was the only change it made, and it reduced the framerate down to below 1 FPS. What happened? Is it bad do index based on that? I tried to use arrays and calculate all the lights in one loop, but GLSL told me that by doing that I had exceeded the hardware limit (32) of floating-point varyings.

Share this post


Link to post
Share on other sites
zedzeek    529
i believe u will have to hard code the number of lights in the shader
eg make one shader for 3 lights another for 4 lights etc
the problem is whilst recent cards are getting more and more flexible all the time theyre still a long way off with the flow control etc of cpus.

though do it easy like me and do one light at a time which is the easiest way esp if youre shadowing

Share this post


Link to post
Share on other sites
Yann L    1802
Are you doing this lookup in a vertex or fragment shader ? In the latter case, this is a limitation of current hardware. In the former case however, you should be fine. Vertex shaders can dynamically index into arrays (it essentially compiles down to an ARL opcode). So try to offload as much as you can to the vertex shader.

Share this post


Link to post
Share on other sites
How would I do the lookup in the vertex shader only? I use gl_LightSource[] in both.

Edit: Ok, never mind that, I just send the fragment shader a gl_LightSourceParameters object. But how?

It won't let me declare it varying because it's an object, but if I leave out the qualifier the lighting stops working...

Edit (Remix): Never mind, I've got it all under control. Screenshots soon

[Edited by - Foobar of Integers on April 23, 2006 8:27:48 PM]

Share this post


Link to post
Share on other sites
Ok, update.

I rewrote a bunch of the fragment shader to fix the couple of glitches it had. However, after trying a few methods I found on google to support multiple lights, it still drops down into software mode. I'm kind of lost here.

More update:

This doesn't seem to be a programming problem, I compiled the code on my Windows box (with the 7800GT) and it handles 3 per-pixel lights at once with no framerate drop from 1 light. Screenie: http://rav.efbnet.com/imagebin/images/1145847473.png

[Edited by - Foobar of Integers on April 23, 2006 9:23:58 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
One other method is to store your light information into a texture, one texel per light, and then use a sampler in GLSL to get that data.

Uniform variables needed: 1

Share this post


Link to post
Share on other sites
taby    1265
Sorry for the AP above.

I also wanted to mention that if you use a sampler, here is a way to calculate the floating point index you need to use in order to get to each individual light. If you do not use this special offsetting method, you will obtain interpolated values, which is definitely not what you want.


step_size = 1.0/num_elements
first_element_float_index = 0.5*step_size
float_index = first_element_float_index + stepsize*int_index

ie:
For a texture with 2 elements:
step_size = 1.0/2 = 0.5
first_element_float_index = 0.5*0.5 = 0.25

So, the first element should be accessed at 0.25, and the 2nd at 0.75

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this