Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: Having Many Lights Calculated in one Shader

Hybrid View

  1. #1
    Newbie Newbie
    Join Date
    Apr 2013
    Posts
    2

    Having Many Lights Calculated in one Shader

    Hi, I have been doing some reading on the subject of tile-based deferred rendering, and I have been thinking about implementing one myself. I've come across one problem though, it seems (from my understanding at least) that your supposed to calculate the lighting for each tile in one shader pass (to reduce the amount of times you sample from the G-Buffer). In my old deferred renderer, I just was drawing fullscreen quads that sampled from the G-Buffer, and I tried having one shader calculate lighting from 7 lights (passed in as uniform arrays) and although on my GPU (GTX 480) this worked well, and saved a lot of fill rate, when I tested it one a laptop (with a GT 540M) it didn't seem to work. I was able to narrow the problem down to the instruction limit of the fragment shader. Having 7 lights made the fs seemed to break the instruction limit, which odiously caused problems. When I limited the shader to 1 light, it worked great. So, to my question how, if you are at all, are you supposed to have the lighting from several lights calculated in the fs without passing the instruction limit?


    If you don't want to read that my question is: How do you calculate lighting for several lights in the fragment shader, without passing the instruction limit?

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    You don't.

    Part of the point of a deferred renderer is that you don't do all the lights at once. You accumulate each light (or small number of lights) per lighting pass. So instead of running a 7 light shader, you run a 1-light shader with 7 different lights, adding the contribution from each on each pass. Or you run 2-light shaders 3 times and a 1-light shader once.

    You also don't need to render a full-screen quad if a particular light doesn't affect everywhere on the screen. Indeed, you could render a sphere that covers the limit of a particular light's range.

  3. #3
    Newbie Newbie
    Join Date
    Apr 2013
    Posts
    2
    Okay, yeah. I am talking about a tile based deferred renderer. The idea is too separate the screen into small tiles to cull the scene for lighting. Here is a good presentation going over it.

    download-software.intel.com/sites/default/files/m/d/4/1/d/8/lauritzen_deferred_shading_siggraph_2010.pdf

    The idea is to batch the lights together for each tile and minimize reading from the G-Buffer. The same type of system was used if Frostbite 2. In this presentation and in other things I've read about tile-based systems, it seems like the idea is to render with multiple lights per shader pass per tile, if that makes sense... Or am I wrong?

  4. #4
    Newbie Newbie
    Join Date
    Jul 2013
    Location
    n/a
    Posts
    1
    Thanks for starting that topic.

  5. #5
    Quote Originally Posted by Alfonse Reinheart View Post
    You don't.

    Part of the point of a deferred renderer is that you don't do all the lights at once. You accumulate each light (or small number of lights) per lighting pass. So instead of running a 7 light shader, you run a 1-light shader with 7 different lights, adding the contribution from each on each pass. Or you run 2-light shaders 3 times and a 1-light shader once.

    You also don't need to render a full-screen quad if a particular light doesn't affect everywhere on the screen. Indeed, you could render a sphere that covers the limit of a particular light's range.
    Isn't the point of deferred rendering to not calculate all the lights per fragment since most fragments behind other fragments will be discarded? Using multiple passes to accumulate light is called Multipass Rendering and can be used together with deferred rendering by first getting the "outer shell" of the scene and then running the multiple passes to accumulate light. For what he's trying to do, I'd say he's trying to group lights and thus have arrays of lights in one shader pass.

    @Spaceman1701: Is your array of lights inside a uniform block? I just did a quick test of 14 lights in one shader pass and it didn't seem to change anything. Of course my lighting computations might be a lot less complex than yours and my hardware might be better, but I think the problem is you're using something like:

    Code :
    struct Light {
        ...
    };
     
    Light lights[7];

    While you could be doing:

    Code :
    struct Light {
        ...
    };
    uniform Lights {
        Light lights[7];
    };

    I tried using an array of Light structs in my own program and it complains about the instruction limit, but it doesn't when I use Uniform Buffer Objects.

  6. #6
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,224
    Quote Originally Posted by Spaceman1701
    ...tile-based deferred rendering, ...have been thinking about implementing... ...it seems... that your supposed to calculate the lighting for each tile in one shader pass (to reduce the amount of times you sample from the G-Buffer).
    One or a small number of shader passes, yes. How many passes depends on how many light sources that you process within each shader iteration. This is determined on things like the max number of lights one shader iteration can process, whether there are different light source types represented in the same tile and how you handle that case, etc.

    Also note that you do this not only to reduce the number of times you sample from the G-buffer, but to reduce the number of times you have to read/additive_blend/write to the lighting buffer.

    In my old deferred renderer, I just was drawing fullscreen quads that sampled from the G-Buffer, and I tried having one shader calculate lighting from 7 lights (passed in as uniform arrays) and although on my GPU (GTX 480) this worked well, and saved a lot of fill rate, when I tested it one a laptop (with a GT 540M) it didn't seem to work. I was able to narrow the problem down to the instruction limit of the fragment shader. Having 7 lights made the fs seemed to break the instruction limit ... So, to my question how, if you are at all, are you supposed to have the lighting from several lights calculated in the fs without passing the instruction limit?
    Typically instruction limits can be avoided merely by telling your shader compiler "not" to unroll loops, and you writing your shader code such that it doesn't have to. Then the number of lights you can handle per shader pass is only limited by the max amount of uniform data you can pull in via the uniform passing method you choose to use. You just have a loop over all of the light sources to be applied in that pass, and on each pass you index the uniform data for the appropriate light source. In other words, you only have the code/instructions in there for applying one light source though you may be applying 20 or so.

    Quote Originally Posted by Alfonse Reinheart View Post
    You also don't need to render a full-screen quad if a particular light doesn't affect everywhere on the screen. Indeed, you could render a sphere that covers the limit of a particular light's range.
    What you're talking about is a basic (v1) deferred renderer where your light source application loop is over light sources. He's talking about tile-based deferred, where the loop is over screen tiles. The light sources have already been binned into those tiles.

  7. #7
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    Quote Originally Posted by Dark Photon View Post
    What you're talking about is a basic (v1) deferred renderer where your light source application loop is over light sources. He's talking about tile-based deferred, where the loop is over screen tiles. The light sources have already been binned into those tiles.
    i actually struggle to find anything specific about how this (v2.0?) deferred rendering technique goes along with shadows on local lights.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •