Sign in to follow this  

Delayed rendering for sorting

This topic is 4396 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 got my particle system up and running, made some awesome looking smoke (if I do say so myself) but when I added fire to the equation using a 2nd emitter I noticed I had some problems: Although I fixed alpha sorting/blending problems for 1 particle emitter, when a 2nd emitter is in the scene it's particles arent sorted with the particles from the first resulting in some undesirable graphics (see screen shots). After some thinking I decided to make a new class that would store an array of display lists, their depth, and thier texture/blending settings. Each frame instead of rendering I'd create a display list and pass it and the other appropriate values to this class then have the class sort them all by their depth (back to front) and then call the sorted lists and changing texture/blending settings when necessary. It worked :D *BUT* at a poor 12 frames per second, well below the 60+ previously attained. After some profiling I found that the part that was killing me was the display lists, which makes sense since there was 400+, each only rendering a 2 poly tri-strip with billboarding. So my problem is, how can I postpone the rendering of an object till after it is sorted with other objects without using a display list? I want to be able to sort all polys with alpha not just particles and am not too keen on the idea of using function pointers (tho that's the best idea I can come up with atm). Screen Shots: Smoke rendered 2nd (looking good) Smoke rendered 2nd (looking bad) Fire rendered 2nd (looking good) Fire rendered 2nd (looking bad) I like my smoke, please help make it better :) [Edited by - Skiller on November 28, 2005 9:45:09 AM]

Share this post


Link to post
Share on other sites
What is the point in display lists if you create them EVERY frame? You could just pass your particle structure, and draw the particles in immediate mode.

But it's likely that the slowness results from texture binding, not a lot of display lists. I haven't done a particle engine yet, but do you really need texturing? Won't color/material be enough?

Share this post


Link to post
Share on other sites
Quote:
Original post by Seroja
What is the point in display lists if you create them EVERY frame?


Well, display lists are not necessarily static things.
My engine creates display lists every frame based on the visibility pass.
Each display lists contains all renderable objects affected by a set of lights.
There are actually two display lists per light set, one for transparent sorted by Z and one for opaque sorted by shader/texture/instancing. The renderer receives display list groups and renders them.

About the particles,

Why not just use one pool of particles. Each emitter gets its particles from the pool, updates them and puts them in one large particle buffer. Then sort that one buffer by Z and render.
Probably best to use pointer to particles in the intermediate buffer that will be sorted then copy the sorted particle data into a vertex buffer.

Share this post


Link to post
Share on other sites
@Seroja
I was using display lists because they can store the matrix information for billboarding and because they can be used for any polys with alpha. At the moment the only polys using alpha are the particles, but I'll be wanting to add beams and such later on and they'll need to be sorted with the particles. Also the slowness wasn't from constant state/texture changing, I profiled the changes and it was only taking 0.0008 secs a frame, a far cry from the 0.078 secs that the delete lists was taking.

@Red_falcon
Are those shaders fp20 compatible? I'm aiming at GeForce 4 as min requirement and gf4 only has fp20 shader profile :(.

@Scythen
I'm already using pools for my particles to avoid dynamic memory allocation so it would be easy to set up, but as mentioned I would like a more generic solution so that I can use it for beams and other polys with alpha.

I think I'd better change topic name since it not really just for particles ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Skiller
@Seroja
I was using display lists because they can store the matrix information for billboarding and because they can be used for any polys with alpha. At the moment the only polys using alpha are the particles, but I'll be wanting to add beams and such later on and they'll need to be sorted with the particles. Also the slowness wasn't from constant state/texture changing, I profiled the changes and it was only taking 0.0008 secs a frame, a far cry from the 0.078 secs that the delete lists was taking.


Can't these commands be issued in immediate mode? They might be slower to execute, but won't it compensate for the overhead of creating and deleting lists?

And generally, is there any reason to create display lists unless the same list is going to be called multiple times? (Or are you rendering every particle several times?)

Share this post


Link to post
Share on other sites
Quote:
Original post by Seroja
Can't these commands be issued in immediate mode? They might be slower to execute, but won't it compensate for the overhead of creating and deleting lists?


True, but then the problem is that I'd have to store an extra variable to say what type of thing is to be rendered, particle, beam, mesh ect. then have a big if else if list for all the different rendering types since they need to be rendered differently. For this to be managable/readable I'd probably need to use function pointers (this is the way I was thinking of doing it from first post) which when being called 400+ times a frame could incur a drop in speed (tho probably not as much as I fear ;) ).

Quote:
Original post by Seroja
And generally, is there any reason to create display lists unless the same list is going to be called multiple times? (Or are you rendering every particle several times?)


Not really, I was just after a generic way to render different things with minimal effort to implement.
The way I used render particles is create a particle of size 1 with tex coords, put that in a display list. Each particle would set up the matrix rotation/position so it always faced camera, set desired color then scaled it to size and called the display list.
Now I put the setting up of matrix, color, size and call to "prototype" particle into another display list and just pass the resulting GLuint to the sorting/rendering class as mentioned in first post.

Share this post


Link to post
Share on other sites
Quote:
Original post by Skiller
Quote:
Original post by Seroja
Can't these commands be issued in immediate mode? They might be slower to execute, but won't it compensate for the overhead of creating and deleting lists?


True, but then the problem is that I'd have to store an extra variable to say what type of thing is to be rendered, particle, beam, mesh ect. then have a big if else if list for all the different rendering types since they need to be rendered differently. For this to be managable/readable I'd probably need to use function pointers (this is the way I was thinking of doing it from first post) which when being called 400+ times a frame could incur a drop in speed (tho probably not as much as I fear ;) ).

Quote:
Original post by Seroja
And generally, is there any reason to create display lists unless the same list is going to be called multiple times? (Or are you rendering every particle several times?)


Not really, I was just after a generic way to render different things with minimal effort to implement.
The way I used render particles is create a particle of size 1 with tex coords, put that in a display list. Each particle would set up the matrix rotation/position so it always faced camera, set desired color then scaled it to size and called the display list.
Now I put the setting up of matrix, color, size and call to "prototype" particle into another display list and just pass the resulting GLuint to the sorting/rendering class as mentioned in first post.


Well what is wrong with a big switch case? And I think the overhead of calling function pointers won't affect your framerate :P (400 isn't that much, now is it?)

Just create a struct/class for each particle (you probably already have it) and create a function that will set up matrix color etc. according to the content of the struct/class.

Display lists aren't supposed to help you organize your code :D

Share this post


Link to post
Share on other sites
Big switch case statements are not good.
There is almost always a better way.
Every time you add a new type you will have to update all of your related switch statements.

Quote:
Original post by SkillerNot really, I was just after a generic way to render different things with minimal effort to implement.
The way I used render particles is create a particle of size 1 with tex coords, put that in a display list. Each particle would set up the matrix rotation/position so it always faced camera, set desired color then scaled it to size and called the display list.
Now I put the setting up of matrix, color, size and call to "prototype" particle into another display list and just pass the resulting GLuint to the sorting/rendering class as mentioned in first post.


If I understand what your saying here it doesnt sound very efficient.
It would be much better to just set up 4 world space verticies with texture coords and then use a shader to align them with the screen. All the positions can be exactly the same, just offset them in the shader based on the texture coordinates. You could pass a size and rotation (around Z) in a second set of texture coords and to that work on the GPU as well.

If your rendering different primitive types for ribbons and such then its a bit hard to sort them with particles of different types. Its probably not worth the effort since the blend should cover up most of the errors. Just be sure to render all opaque particles first. Trying to sort every particle against every other particle could result in a ridicules number of separate draws.

Share this post


Link to post
Share on other sites
Quote:
Original post by Scythen
It would be much better to just set up 4 world space verticies with texture coords and then use a shader to align them with the screen. All the positions can be exactly the same, just offset them in the shader based on the texture coordinates. You could pass a size and rotation (around Z) in a second set of texture coords and to that work on the GPU as well.


Now there's an idea, was trying to think of ways to speed up that area of code, atm I'm doing 3 glRotatef's which is far from ideal, moving to vertex shader should help heaps, thanks :D.

Quote:
Original post by Scythen
If your rendering different primitive types for ribbons and such then its a bit hard to sort them with particles of different types. Its probably not worth the effort since the blend should cover up most of the errors.


Ribbons?

Quote:
Original post by Scythen
Just be sure to render all opaque particles first. Trying to sort every particle against every other particle could result in a ridicules number of separate draws.


What exaclty do you mean by opaque? Particles with NO blending or certain blend modes like SrcAlpha, InvSrcAlpha?
And what do you mean by separate draws? Each particle would have to be seperate wouldn't it? Or do you mean switching between textures/blend modes?

Share this post


Link to post
Share on other sites
Well… guess ribbon isn’t really a primitive, sorry for the confusion. Particle systems some times use a ribbon object which is really a tri strip or list to draw things like lightning bolts. The polys are connected and appear like a ribbon. These would probably not be sortable like the quads.

By opaque I mean there is no blending. Alpha test is ok but blend requires the correct draw order (far to near). So, if you draw all your non blended geometry first (near to far) then draw your blended geometry (far to near) sorted by Z (at least almost) there shouldn’t be to many visual artifacts and your sorting will be much simpler.

I live in the Direct3D world so a draw to me is when you submit a set of primitives for rendering. OpenGL is a bit different, I guess a D3D draw is similar to the glBegin/glEnd pairs or glCallList. Either way, sorting all particle primitives would cause you to interleave the primitive types and that would make things quite slow Im sure.

Share this post


Link to post
Share on other sites
Well I've slept on it (but only for 6 hours ;)) and I think what I'll do is this (unless someone can come up with improvements or a better idea):

Same as described in first post except:
Each object passed to the sorter/render is passed with a pointer to a renderer profile which atm contains texture, blend settings, and zbuffer writing information. I'll add to this a function pointer to the render function.
I'll have to have each object pass some identifier variable so that the rendering function knows what part of the object/which particle to render.
I'll also have a go at making the particles face the cam in a vertex shader.

Hopefully I get some speed back, but obviously this is still fairly slow so I'll have an option to use "inacurate" sorting and "no sorting" so ppl with slower computers can still play with good fps :)

Another option I'll explore is simply having a fade in/fade out on the particles, this will solve the fire/smoke issue since I'll just render smoke 2nd and have it fade in so you cant see it for x seconds till it's above the fire. But this doesn't really solve the underlying problem :(

Share this post


Link to post
Share on other sites
*) dont use DLs/VBOs for objects of 2 polygons
*) best compromise method
A/ set the state eg smoke material (blending/textures etc)
and draw ALL smoke particles in the scene (freom back to front)
B/ goto A/ but do fire instead

Share this post


Link to post
Share on other sites
Quote:
Original post by zedzeek
*) best compromise method
A/ set the state eg smoke material (blending/textures etc)
and draw ALL smoke particles in the scene (freom back to front)
B/ goto A/ but do fire instead


That's exactly what I had :), and what is causing the problem :(, see the screen shots too see what happens when you do that :(.
But you are right it is probably the best quality you could get at good speeds, as mentioned I'll still use this method as an option for better speed and just have to modify the effect to be less problematic with this.

Share this post


Link to post
Share on other sites

This topic is 4396 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this