Efficient particle rendering

Started by
1 comment, last by Steve132 15 years, 5 months ago
Hi, I'm trying to figure out the best way how to to draw the particles. I'm mainly interested in how to get the particles from an application to a vertex shader. The simplest way, and in my opinion the slowest one, is to create a dynamic vertex buffer, create a vertex structure containing all the important information for a particle and simply every frame lock the vertex buffer and copy all the particles into it. But as far as I konow, locking the vertex buffer is a very slow operation, so I've been thinking about different options. One of them is to create a floating point vertex texture which would be filled with all the important information and you would just read it's pixels in a vertex shader. But you've got to lock the texture every frame and fill it with all the data. Another way is to use some kind of a hardware instancing, but I don't know how much useful is it for the particles. Do you have any experience?
Advertisement
Hardware instancing is great for particles, actually. Very quick. Dynamic VB's also really aren't so bad, as long as you use the WRITEONLY flag and use PIX to make sure you're not stalling the pipeline too much. Shader constant instancing also isn't a bad option for hardware that doesn't support hardware instancing.

Humus has a particles sample that's a bit older, but gives a good demonstration of the techniques available in D3D9. In D3D10 you have more options obviously.
If you want the ABSOLUTE fastest method of rendering particles, I would suggest two techniques, both of which can, but do not have to be, used together.


1) Calculating the particles

Using Pixel Buffer Objects as uber-buffers, set up rendering so that the inputs per-particle are stored in a series of texture maps, where each pixel on the texture map is one particle.

Then, set up a render target framebuffer for the x,y,z output of each particle. If you have to update other things between frames than just position, then set up multiple render targets for each quantity you have to output.

Put your particle code in a fragment shader.

Then, bind your inputs as textures, then render from the inputs per particle to the output texture...that texture will now have the x y z position of every particle...
setup the texture as a source for a vertex array using pbo...this is called render to vertex array.

2) Rendering the particles.

Assuming you have the particles set up as a vertex array target, where each vertex is the xyz position of one particle, do a render using GL_POINTS with the point sprites extension enabled...that way you can get proper screen-oriented particles using only one vertex per particle.



Assuming you ha


This topic is closed to new replies.

Advertisement