Faster Deferred Rendering

Started by
9 comments, last by 3TATUK2 10 years, 6 months ago

Does anyone know any tip/tricks for speeding up deferred renderer gbuffer population?

This is what I've come up with so far:

A) only usetwo buffers: RGB diffuse, RGBA16F normal+depth in alpha

B) attach DEPTH_COMPONENT32F to FBO

C) reconstruct world position in screen-quad pass from normal buffer depth saved in alpha {texture2D().w}

I drop from 240 FPS using forward rendering to 150 FPS with this deferred... Is that appropriate overhead? Or am I missing something?

Also, with 60 lights, I drop below 60 FPS, even though I see these youtube demos of deferred rendering with hundreds of lights?

I'm still doing the lighting in the geometry pass ... Is it somehow possible to do the lights in the screen-quad pass?

Advertisement

Doing the lights in the screen-quad pass is actually the whole point of deferred rendering, otherwise it's really just little more than a somewhat more complex forward renderer. The idea is that you move the more complex lighting equation to the screen-quad pass so that only pixels that actually appear on-screen need those complex equations. Of course, that assumes that your lighting is sufficiently complex to counterbalance the overhead of writing out your gbuffer; deferred isn't suitable for every lighting scenario, after all.

The trick is in knowing that you don't actually need to draw a fullscreen quad per-light. Instead you only draw the area of the screen that will actually be affected by the light, which - for most lights in your scene - will hopefully be rather small (otherwise with 60+ lights you're going to get quite an intense glare on everything).

There are a few ways of doing this, and I'm just going to mention one, which is to use a light volume; see e.g. here for one further explanation of this method. In short, you draw a bounding volume for each light with additive blending, and that gives you the desired end result. (Note that this method breaks if the viewpoint is inside the light volume, and one quick-n-dirty way of resolving this is to just draw a fullscreen quad for those lights. I'd use a simpler shape than a sphere too; an icosahedron is a decent fit.)

If you're not bothered about shadows you can make this faster by using instancing to draw all of your lights in a single call, which is quite efficient.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

What's the "solution" to determining a light volume for spotlights? Which can essentially extend indefinitely :)

Also, can you go more into depth about how to do these screen space lights? Any page/example maybe?

I mean say you have a light, it's position, and you calculate it's screen-space light volume resolution... Now what?

I tried the tutorial at this page...

http://ogldev.atspace.co.uk/www/tutorial36/tutorial36.html

I get everything compiling and running but real weird results, would be very nice to have a more simplistic step-by-step guide which doesn't use a bunch of glue code

Try reconstructing the position from the depth buffer, it gives you more precision and will save you one component.

Use 16+16 bit ints / float format for normals. You'll need to use some compression here. I prefer to use integers since float values may some time turn out NaNs.

Use R11B11G10_float format for storing HDR values, if possible.

Look into tiled deferred lighting. It works in the screen space and takes some effort to build up, but it will save you some memory reads in the lighting stage and some additive blending.

Cheers!

i already reconstruct position from depth,

I'm trying to figure out how to pack 2x16bit values into 1x32bit value and unpack, all the examples i've found result in garbage...

[deleted]


i already reconstruct position from depth,

Of course you do, but you also store your depth twice. You state that you use a RGBA16 for normals and _depth_ which is unnecessary in many cases since the depth buffer (used to z-buffering) has the depth values already.

Cheers!

thanks, how can i compress the normal into 2x16 bit floats? :)

http://aras-p.info/texts/CompactNormalStorage.html

..and for depth, storing linear depth is sometimes useful, you get better precision and projection matrice tricks support (infinite, clipping, etc...).

This topic is closed to new replies.

Advertisement