Deferred shading: advanteges and disadvanteges and is it really faster

Started by
12 comments, last by IYP 9 years ago

Im now using forward rendering I was thinking if deferred rendering may help my app's performance im already first processing the depth and then use forward shading (only nearest fragments get shaded so the number of fragments processed is equal or less than whole number of pixels) so in my method the calculation cost depends on n*p (p:number of pixels and n:number of lights), so is the calculation cost in deferred rendering exept you rasterize the scene several more times ,you calculate vertex shader several time too and etc. (especially when using transparent objects) and you also use a lot of memory so should I change my app (in which every thing is dynamic) to use deferred rendering or im better off with the forward rendering.

Advertisement
Depth pre-pass only helps improve performance in forward rendering if your rendering order is absolutely terrible. Typically you render opaque objects via matching shaders, then by matching textures, then by depth (nearest-to-farthest).
In other words, for sorting via < and == (not shown for brevity):
// If objects have the same shader and texture, render the closer one first.
bool CRenderable::operator < ( const CRenderable &_rOther ) const {
    if ( ui32Shader < _rOther.ui32Shader ) { return true; }
    if ( ui32Texture0 < _rOther.ui32Texture0 ) { return true; }
    return fDist < _rOther.fDist;
}

If you are worried about performance (why else would you post asking which is faster?) then you have to sort anyway to reduce the number of heavy state changes, not to mention sorting back-to-front for alpha draws. You’re making your forward render slower and giving deferred rendering an advantage literally because you are using a depth pre-pass.
In other words (numbers used as an example only):
#1: Typical Deferred vs. Typical Forward -> 1.0ms vs. 1.0ms
#2: Typical Deferred vs. Depth–pre-pass Forward -> 1.0ms vs. 1.1ms

This is worth mentioning for 2 reasons:
#1: You still need a forward pass anyway for translucent objects.
#2: Most likely the correct answer to your question is Forward+, not deferred.



Deferred is typically faster than forward because as you know each light is evaluated at most once per pixel, without the need to submit extra geometry (caveat: Google “deferred shading vs. deferred lighting”). You can use tiling to do advanced culling and improve performance as well. Just as with forward rendering, your cookie-cutter deferred rendering can be heavily improved, and if you don’t take the time to do it then it won’t really be fair to weight the costs and benefits of each.

The disadvantage of deferred is that handling multiple materials is a nuisance. Since the lighting passes don’t know which pixels belonged to which models/materials, if you want to handle more than 1 material you need to have yet another buffer to mark them (stencil buffer or material-index buffer, etc.) Then of course shading becomes more complex. It also doesn’t play well with MSAA, so you will want to do anti-aliasing yourself (though post-processed–based anti-aliasing techniques are actually just filters, not true anti-aliasing).



Forward+ addresses the performance problems of forward rendering and the disadvantages of deferred rendering (see link above).
The main disadvantage is that it requires compute shaders, but these are common-enough these days even iOS has them.
MJP lists other disadvantages here, and it is up to you to decide which among everything said here applies to you and how much.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Depth–pre-pass actually increased my performance like 5.5 mili seconds. you see here is the point I don't get. (in my case all objects in the scene are lit by all lights other wise ill run a light culling algorithim either on cpu or compute shader)

Deferred is typically faster than forward because as you know each light is evaluated at most once per pixel,

my forward rendering does the same (due to Depth–pre-pass) so there is no advantage here and my forward rendering also does not shade the pixels in shadows while in deferred rendering, because in calculation of each G buffer we don't have access to other G buffers we don't do the same (well it can be done but still wouldn't give any advantage to deferred rendering) so there are actually no deference except several rastrizing in deferred rendering. so is there any other advantages for deferred rendering?

Are you actually under your performance aim currently with forward rendering, with the quality you want to achieve? (For example >16ms per frame)

If not I wouldn't move to deferred, unless your existing approach holds you back on other/ new functionality you need/ want to have.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Depth–pre-pass actually increased my performance like 5.5 mili seconds.

I already explained what that means in terms of how your current implementation is working. It means you just don’t have a very good forward-rendering pipeline.
By rendering opaque objects front-to-back (forcing certain things such as terrain to be drawn last also) you can basically (not perfectly) eliminate overdraw (the result of depth pre-pass), and use that same pass to also apply several lights (as many as you can fit in a single pass). You’ll only have overdraw in perhaps 2% of the total pixels on the screen, but you will have saved an entire geometry pass.

So there is virtually no reason to do an entire pass just for depth. I’ve tested it on many cards in many scenes and no matter the complexity, with a proper draw-sorting algorithm (render-queue), it is never faster to use depth pre-pass except in very extreme edge cases (none of which I have ever encountered).



Deferred is typically faster than forward because as you know each light is evaluated at most once per pixel,


my forward rendering does the same (due to Depth–pre-pass) so there is no advantage here and my forward rendering

You seem to have left out an important part of the quote…

Deferred is typically faster than forward because as you know each light is evaluated at most once per pixel, without the need to submit extra geometry

Just because there was a comma it doesn’t mean there was a fully contained idea there.


also does not shade the pixels in shadows while in deferred rendering, because in calculation of each G buffer we don't have access to other G buffers we don't do the same (well it can be done but still wouldn't give any advantage to deferred rendering) so there are actually no deference except several rastrizing in deferred rendering.

I don’t know what you are trying to say here.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

im actually already using the depth pass to calculate the radiosity (1366*768*24 sampled secondary lights) and what do you mean by "without the need to submit extra geometry" im not submitting any extera geometry in my depth pass and coz my scene is dynamic and user can add objects I cant sort the objects.

The fact that you're doing a depth pass at all means you are submitting extra geometry. You have to draw each object twice, right? Once for the depth pass, and once for the lighting.

And I don't understand why a dynamic scene means you can't sort your objects. Pretty much every 3d game in existence has "dynamic scenes", and sorts their objects.

I should also redraw objects several times while using deferred rendering. so how is it a disadvantage for my forward rendering? and if I sort ill have to sort objects every time user adds an other object .

Depth–pre-pass actually increased my performance like 5.5 mili seconds.

I already explained what that means in terms of how your current implementation is working. It means you just don’t have a very good forward-rendering pipeline.
By rendering opaque objects front-to-back (forcing certain things such as terrain to be drawn last also) you can basically (not perfectly) eliminate overdraw (the result of depth pre-pass), and use that same pass to also apply several lights (as many as you can fit in a single pass). You’ll only have overdraw in perhaps 2% of the total pixels on the screen, but you will have saved an entire geometry pass.

So there is virtually no reason to do an entire pass just for depth. I’ve tested it on many cards in many scenes and no matter the complexity, with a proper draw-sorting algorithm (render-queue), it is never faster to use depth pre-pass except in very extreme edge cases (none of which I have ever encountered).

L Spiro, in your first response you suggest sorting by shader then texture... in this response you're suggesting sorting front to back. So what exactly are you suggesting since the two seem to clash with each other? I'm not following.

I should also redraw objects several times while using deferred rendering. so how is it a disadvantage for my forward rendering? and if I sort ill have to sort objects every time user adds an other object .

Why are you redrawing objects for deferred?

-potential energy is easily made kinetic-

well for deferred rendering I have to redraw the scene into several textures (G buffer) so I have to redraw scene for every pass (1 pass for normal 1 for material and etc.)

This topic is closed to new replies.

Advertisement