0

At the moment I've implemented Deferred Rendering using OpenGL its fairly simple just now. However I'm having major performance issues due to using the stencil pass at the moment (at least in the current way I use it). I've mainly been using ogldev.atspace tutorial (only got 2 links per post atm sorry!) as a reference alongside a few dozen tidbits of information from other articles.

It works like:

  1. Gbuffer pass (render geometry and fill normals, diffuse, ambient etc.)
  2. For each light 2a) stencil pass 2b) light pass
  3. Swap to screen

The thing is using the stencil pass in this fashion is incurring huge costs, as I need to swap between light pass mode and stencil mode for every light in the scene. So that's a lot of GL state swaps.

An alternate method without the stencil pass would look like this:

  1. Gbuffer fill
  2. Set light pass
  3. Compute for all lights
  4. Swap to screen

Doing this skips the need to swap all of the OpenGL states (and buffer clears etc.) for each light in the scene.

I've tested/profiled this using CodeXL and basic fps's std::cout'ng. The State Change Functions using the stencil pass method take up 44% of my GL calls (in comparison to 6% for draw and 6% for textures), buffer swaps/clears etc also cost a fair % more. When I go to the second method the GL state changes drop to 2.98% and the others drop a fair margin as well. The FPS also changes drastically for example I have 65~ lights in my scene, dynamically moving. Stencil Pass gives me around 20-30 fps if I'm lucky in release mode (with rendering taking the majority of the total time). The second method gives me 71~ (with the rendering taking the smaller part of the total time).

Now why not just use the second method? Well, it causes serious lighting issues that I don't get with the first. I have no idea how to get rid of them. Here's an example:

2nd non-stencil version (it essentially bleeds and overlaps onto things outside its range): https://i.stack.imgur.com/fIRqG.jpg

1st stencil version (how it should look): https://i.stack.imgur.com/PDlOL.jpg

So my main question is, is there a way to avoid using the stencil pass (and use something similar to the first without the graphical glitch) without completely changing the algorithm to something like tiled deferred rendering?

And if not, is their an alternate deferred rendering method, that isn't too much of a jump from the style of deferred renderer I'm using?

Getting rid of the stencil pass isn't a new problem for me, I was looking for an alternative to this a 6 months or so back when I first implemented it and thought it might be a bit too much of an overhead for what I had in mind. But I couldn't find anything at the time and still can't.

Peter O.
  • 32,158
  • 14
  • 82
  • 96

1 Answers1

0

Another tecnique wich is used in Doom3 for lighting is the following:

http://fabiensanglard.net/doom3/renderer.php

For each light
    render the geometry affected only by 1 light
    accumulate the light result (clamping to 255)

As optimization you can add a scissor test so that you will render only the visible part of the geometry for each light.

The advantage of this over stencil lights is that you can do complex light calculations if you want, or just keep simple lights. And the whole work is GPU, you don't have redundant state changes (you setup 1 shader only, 1 vbo only and you re-draw each time changin only the uniform parameters of the light and the scissor test area). You don't even need a G-Buffer.

CoffeDeveloper
  • 7,961
  • 3
  • 35
  • 69