Particles & Deferred Shading

Started by
4 comments, last by MessiahAndrw 14 years, 11 months ago
I'm trying to work out the best way to integrate particle rendering into my deferred shading rendering engine. My particles are 2d point sprites. My idea is to render particles in groups called 'sheets'. Assume I've already rendered the opaque objects onto my primary render target, and I have a depth-sorted list of particles waiting to be rendered. I'll have a second render target (the size of the screen) - an intermediate target that the lights render the particles on to, before they are rendered ontop of the scene (the primary render target). To render a sheet you build a list of particles to render on that sheet. You create this list by iterating through the list of unrendered particles (starting from the furthest away). If the unrendered particle does not collide with any other particles in the list you just created (a point particle is just a Bounding Box with a size, though it has to check it against EVERY particle already added to the list) you add it to the sheet. When you finally reach an overlapping particle, you render that batch into your G-buffer, perform lighting (rendering to our immediate target), then render the immediate target on top of the screen (using what ever blending you'd like - additive, alpha, subtractive). Then clear the list and repeat for a new sheet until all particles have been rendered. In the best case, all on screen particles can be rendered in 1 sheet, with a worst case of O(N^2) complexity in checking against all others). I know this isn't the most efficient particle rendering idea ever, but it's consistent in a deferred rendering environment. Some optimisation ideas: - Use a sheet-space quadtree (or a self-balancing 2d binary tree) for checking against other particles, rather than one by one. - Have a maximum number of particles in a batch (e.g. 500), so you don't get too many particles to check against. - To reduce the number of batches, if you hit an overlapping particle, continue going through the list (through store the overlapping particle in a separate list so you still check others against this) fitting as many non-overlapping particles as you can on a single sheet (perhaps with a timeout).
Advertisement
I believe I do not understand what you are after. Here is an attempt to lay out my thoughts on your question. With DX9 hardware you have to split geometry into at least a opaque and a transparent rendering call. Only the opaque objects will get the Deferred lighting treatment. To my knowledge there is no sensible way to layer several depth layers in a way that you can use this to render transparent objects with the Deferred lights. So you have to setup a second lighting system that covers transparent objects. Usually this lighting system uses much less lights.
If you want to attach lights to particles, so that they light the environment, you render the lights first and then later the particles.

So the lighting in that case is just "overlayed" over the particles. See the following URL for a screenshot:

http://diaryofagraphicsprogrammer.blogspot.com/2009/05/deferred-lighting-particle-system.html
I was meaning lights affecting the particles.

To rephrase, my idea was to split the particles into non-overlapping groups, and then light each group with the same lights that effect the scene. Then overlay the lighted group onto the scene.

There isn't a reason why you couldn't do this for transparent convex geometry also (all you need is a screen-space BB).

I like the idea of having a single lighting system for all transparent and opaque objects. Even doing forward multi-pass lighting on alpha blended (not additive) particles introduces the same problems if they overlap.

You could render these sheets front to back to create a shadow map.

[Edited by - MessiahAndrw on May 23, 2009 10:25:19 PM]
You might also want to look into depth peeling and two ShaderX7 articles that describe how use depth layers with the DX10 MRT to achieve several depth layers that can help you to do this. Obviously this requires DX10 hardware as a min standard.
This may deserve a thread of its own, but with regard to the deferred lighting of a particle system, it seems like DX9 level hardware could cut a few corners with a paraboloid map or two. What if you kind of "wrapped a sphere" around the particle system, then lit the sphere. Then instead of doing several blend-passes, over what may very well be empty space, the lighting values stored in the paraboloid maps could be used to light the particle system. This wouldn't work for lights which were inside the system, but those seem like they would be special "shine through" cases anyway. Falloff could be strange too.
Quote:Original post by wolf
You might also want to look into depth peeling and two ShaderX7 articles that describe how use depth layers with the DX10 MRT to achieve several depth layers that can help you to do this. Obviously this requires DX10 hardware as a min standard.


Thanks. I looked into depth peeling (I saw an nVidia publication it a while ago and reread it after you mentioned it).

The advantages of depth peeling over my system (which I'll call depth sheets) are:
- No need to depth sort the transparent items.
- No need to group them into non-overlapping bounding boxes (probably save a lot of CPU processing power).
- Transparent parts which concave over itself on the same mesh will render correctly.
- Since you're not splitting it up into groups, you can render everything (in the case of particles) in a single batch .

The advantages of my system:
- You don't need multiple render targets.
- You don't need DX10 or nVidia specific OpenGL extensions.
- You're not limited to just 4 (or however many RTs you have) layers, nor light/shade unused RTs.
- You don't need to perform multiple passes (though you potentially have a higher batch count).

There are a few other optimisations I thought of, including unlit groups of particles can directly be drawn to the screen (still in order) and other optimisations for fitting as many particles as possible onto a single sheet (improving batch count).

Anyway, still not convinced otherwise yet, I will try implementing depth sheets and see how it goes for performance.

This topic is closed to new replies.

Advertisement