• Advertisement
Sign in to follow this  

Quick GLSL uniform variable question

This topic is 4322 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
youre running in software, check the glsl forums at www.opengl.org this has been discussed a couple of times.

Share this post


Link to post
Share on other sites
So indexing with a precompiled number runs in hardware, but using a user-specified value makes it run in software?

Do you know any links that would show me how to enable multiple lights?

Share this post


Link to post
Share on other sites
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
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
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
I'll give that a shot tomorrow, it seems like a pretty solid solution. Plus, it'll avoid making me work on my Windows machine just to get decent performance. GLSL in Windows is just... painful.

Share this post


Link to post
Share on other sites
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
Sign in to follow this  

  • Advertisement