Jump to content
  • Advertisement
Sign in to follow this  
Nairou

Calculating scissor region for deferred lighting

This topic is 2634 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've been implementing deferred shading, and have finally got it working. However, as expected, performance is terrible when the number of lights increases, as every light is currently being rendered as a full-screen quad.

I'd like to limit the the rendering of each light using a scissor region, but I'm having trouble understanding how to calculate the screen-space region affected by the light. I've been trying to follow this tutorial, which is the only source I can find that talks about using scissor testing for deferred shading, but it isn't the easiest to understand.

Does anyone have better references or explanations on how to calculate the region to scissor for a given light? I'm also open to other techniques besides scissor tests, but since I'm already using scissor testing, it seemed a good fit.

Share this post


Link to post
Share on other sites
Advertisement
I too am interested in a good resource for this, although I think I have a good idea of how to acheive it. Currently I am only using a simple radius check in the frag. However, since doing 3d picking I think I've realized a different approach. If you take the view_matrix (camera_matrix) and the projection_matrix and find the corners of affect like this:

vec4 top_right_light_position = projection_matrix * view_matrix * vec4(light_position.x + light_radius, light_position.y + light_radius, light_posiion.z + light_radius, light_position.w);
vec4 botom_left_light_position = projection_matrix * view_matrix * vec4(light_position.x - light_radius, light_position.y - light_radius, light_posiion.z - light_radius, light_position.w);

You then know the bounds for the rectangle by using x, y, of each corner and can define a scissor rectangle. Although I'm sure there's a much better way to do this, and I haven't yet tested this. Just figured I'd give you some inspiration to get the wheels turning.

Share this post


Link to post
Share on other sites
You can just use a sphere / cube to approximate the light's area of effect. Set the radius of the sphere to encompass the radius of the light (probably in the vertex shader). I'm not sure how that compares to using scissor testing, but it should be faster than a fullscreen quad.

Share this post


Link to post
Share on other sites
The fullscreen quad is the worst of course...

But with the radius check and what you're saying the vertex and fragment shaders still touch every pixel for lighting.

The scissor op removes those pixels that are not needed.

It's significantly faster I think.

Share this post


Link to post
Share on other sites
What I have read is really nice, is to chop the screen up into multiple scissor tests. Take the screen chopped into a 2x2 grid say. And you figure out which lights are present in each on screen grid. So you have to do some BSP type tests or something. Once you know each of those, you draw a quad over each grid, and not the fullscreen (the scissor test you dont need it now), and send all your lights in that grid to the shader at once. It does the lighting for all lights, instead of doing 1 light and blending with the main scene, then the 2nd light and blending with the main scene.

For their method though do what the other guy said and just draw a 3D box around the x,y,z of your light, at a specific size big enough to cover how far the light distance shines, and it will project onto the screen as the quad you want. Still wont need scissor testing as the pixels that the box projects to on screen are the only pixels that will be drawn and shaded anyway.

Share this post


Link to post
Share on other sites
It is really similiar to shadow volumes so you search for that name too I guess.

Basically you draw an enclosed model that will completely surround the light (it can be cube or a rough sphere). After while rendering this volume you use stencil operetors to find which pixels will be illuminated (or will be shadowed for shadow volumes)

There are 3 posiblities for a pixel depending on which sides of volume (front side or back side relative to camera) are rendered

  • If both sides are rendered (passed the depth test) then this pixel is behind the light and too far away. It won't be illuminated.
    • If back side is not rendered while front side is rendered that pixel is inside the light volume so it will be illuminated.
      • If both sides are not rendered (couldn't passed the depth test or maybe pixel is not on top of them) that it is not illuminated again.
        You use stencil tests to find which pixels are inside the light. First render back side of model by culling front (of course don't render anything to depth buffer or color buffer. just stencil) And set a stencil bit to 1 if depth test fails. After this step stencil bit will be 1 for each pixel that is infront of back side of light volume. After that render front side of light volume and render light if depth test passes and stencil bit is 1. This will ensure that you will be rendering only if your pixel is between two sides of light volume.

        alternatively you can use two sided stencil tests. Increase stencil buffer while rendering front and decrease it while rendering back. If a stencil buffer is 1 in the end it means that only the front side is rendered and pixel will be illuminated. Finally render a full screen quad to render light

Share this post


Link to post
Share on other sites
Thanks for the shadow volume comments. I'm still hoping to find a solution using scissor regions, but I may have to give that a try.

I've started trying to read the "Scissor Optimization" chapter from the Mechanics of Robust Stencil Shadows article on Gamasutra, which deals exactly with the problem I'm having of using scissor regions to limit light rendering. However, I so far haven't been able to follow along very well. The article makes assumptions and pulls in equations that I don't know about, and doesn't really explain what its doing or why the equations are important.

I really want to understand the "why" of what I'm doing, and not just copy/paste math equations, so I'm still searching for solutions...

Share this post


Link to post
Share on other sites
Drawing spheres as we suggested IS scissor testing. Just draw a sphere, where your light is, and the only pixels that will be be lit are the ones that the sphere projects to on screen.

[color="#1C2837"]However, as expected, performance is terrible when the number of lights increases, as every light is currently being rendered as a full-screen quad.[/quote]
[color="#1c2837"]I think you missed the deferred rendering memo. You draw a sphere for each light. When you really need to optimize, you draw portions of your screen with multiple lights at once using scissor tests:

[color="#1c2837"]Assuming 8 lights in your scene:

[color="#1c2837"]1.Draw sphere, sphere projected on screen will basically give you the "scissor pixels" the only ones the light will effect.
[color="#1c2837"]2. Light those pixels and ADD blend them to the scene.
[color="#1c2837"]3. Step 1 for next light.

[color="#1c2837"]8 Blend operations.

[color="#1c2837"]Optimized
[color="#1c2837"]1. Figure out (like that mechanics article, or basic ray tracing) what lights are in what part of your screen image.
[color="#1c2837"]2. Assuming your screen is cut in 4, say 2 lights are in each quadrant. You draw 4 quads, upperleft, upperight, etc. And send to your pixel shader 2 light locations for each quad you draw (the lights that actually are projected on screen and only light/influence those pixels in 1 specific quadrant).
[color="#1c2837"]3. Light those pixels and ADD blend them to scene.
[color="#1c2837"]4. Step 1 for next quadrant.

[color="#1c2837"]4 Blend operations. Because you calculated lighting for 2 lights at once.


[color="#1c2837"]For now just settle with the first version 8 blends.

Share this post


Link to post
Share on other sites

Drawing spheres as we suggested IS scissor testing. Just draw a sphere, where your light is, and the only pixels that will be be lit are the ones that the sphere projects to on screen.

[color="#1C2837"]However, as expected, performance is terrible when the number of lights increases, as every light is currently being rendered as a full-screen quad.

[color="#1c2837"]I think you missed the deferred rendering memo. You draw a sphere for each light. When you really need to optimize, you draw portions of your screen with multiple lights at once using scissor tests:
[/quote]
What you're describing is using stencil testing, right? Correct me if I'm wrong, but isn't that just another method of doing the same thing as screen-space scissor testing? I don't understand why you would need both. Stencil test would show you exactly where to render based on the "shadow" created by the sphere geometry, but requires an extra pass to render the sphere geometry. Scissor test limits rendering to a particular rectangle on the screen, with no extra pass, but requires some fancy math to calculate the extent of the light on the screen. End result should be roughly the same either way.

Share this post


Link to post
Share on other sites
I've started trying to read the &quot;Scissor Optimization&quot; chapter from the <a href='http://www.gamasutra.com/view/feature/2942/the_mechanics_of_robust_stencil_.php?page=6' class='bbc_url' title='External link' rel='nofollow external'>Mechanics of Robust Stencil Shadows</a> article on Gamasutra, which deals exactly with the problem I'm having of using scissor regions to limit light rendering. However, I so far haven't been able to follow along very well. The article makes assumptions and pulls in equations that I don't know about, and doesn't really explain what its doing or why the equations are important.<br /><br />I really want to understand the &quot;why&quot; of what I'm doing, and not just copy/paste math equations, so I'm still searching for solutions...<br />


That article is self-contained. The only assumptions it makes is that you know what a plane is and what a dot product is, and it does not pull in equations from out of nowhere. If you really want to understand how to calculate the proper scissor rectangle for a light source, then that article is the right place to look.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!