XNA Creators Club Online
Page 1 of 1 (20 items)
Sort Posts: Previous Next

Help needed! Fast Alpha blending for Particles

Last post 05-09-2008 1:54 AM by Rim van Wersch. 19 replies.
  • 05-08-2008 9:05 AM

    Help needed! Fast Alpha blending for Particles

    Hi everyone,

    Just a little problem I've been facing during the development of my game. I'm currently working on the particle system, however, I'm facing some performance issues, particularly in the rendering of particles.

    When particles are not rendering, I get performance of up to 62 fps, however, upon rendering particles my framerate drops to about 30 fps. My suspicions are because I'm excessively calling the DrawIndexedPrimitives function (called once for every particle) and my reason for doing this (instead of hardware instancing) is because I need to sort my particles, according to distance from camera, to achieve alpha blending (source and inverse source) for smoke and other non-additive types of particles. This prevents me from rendering my particles in batches (without further sorting) due to different particles having different textures, etc.

    To proof that my suspicions were right (and that it wasnt the updating or sorting of the particles that was causing the problem), I recompiled the program after commenting out the rendering code for particles which led to a fps of 62.

    Any help regarding this issue is greatly appreciated!

  • 05-08-2008 9:18 AM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    You're right on the money with the cause of your problems, one draw call per particle is about as horrendous as it gets for performance, don't do it at any cost. Why do your particles need sorting?
  • 05-08-2008 11:32 AM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    Make sure you actually need sorting ( sometimes it work fine even with alpha blending).

    Render all particles with a single draw call - to accomodate different textures simply use something like texture atlas.

  • 05-08-2008 11:37 AM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    My understanding of the complete 3d pipeline is somewhat limited...

    but from what I've read, it seems that pixels have depth values in the depth buffer, and when the pixels of a geometry are nearer to the camera than the pixels of another, the pixels further away are not drawn. This is not good as a alpha blended quad (such as a billboard for particles) has many regions that you should be able to "see" through (since the underlying pixels aren't drawn all I see is the clear color of the GraphicsDevice).

    Therefore, to solve this, I rendered opaque geometry first (unsorted), followed by transparent billboards (sorted) with depth buffer writing disabled (so that the above wouldn't occur). Because my depth buffer writing is disabled, billboards drawn first appear at the bottom and billboards drawn last appear right on top. Therefore, in order for my particles to render in the correct depth order, I go through the extra step of sorting the particles and rendering them in the sorted order.

    I'm aware of other methods (such as alpha testing and the clip() function in shaders) however, quality is greatly compromised as these methods cannot render pixels that are semi-transparent...
  • 05-08-2008 11:38 AM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    Have you seen the 3D particle sample? I'm able to get around 1000 particles with fairly little overhead. Each particle has alpha blending.
    XNA QuickStart Engine | My site
    "I'll be whatever I want to do!", Philip J. Fry
  • 05-08-2008 11:41 AM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    If I'm not mistakened the 3D particle sample uses additive blending (doesn't need sorting but makes particles look "bright"), I'll take a look though...

    The effect I'm trying to achieve is rendering particles with the source blend being source alpha and the destination being inverse source alpha.
  • 05-08-2008 11:55 AM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    I believe there are a few different types of particles in the sample, certain types use blending, while others use additive. The sample should let you cycle through different types.
    XNA QuickStart Engine | My site
    "I'll be whatever I want to do!", Philip J. Fry
  • 05-08-2008 12:09 PM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    Apparently, the 3D particle sample is using source and inverse source blending (my mistake) however, particles are not being sorted. This will lead to an incorrect draw order of particles (not obvious because of the nature of smoke in the demo). The particles in my game are very solid, and the draw order is important in the rendering of particles.

    By simply switching the particle sprite in the 3D particle sample the depth sorting problem can be easily observed...

    As you can see from the screenshot, the big particles should be rendered above the small particles (its more obvious when running from the program).

    Here are more obvious screenshots (from my game itself), as you can see the unsorted particles look terribly wrong, compared to the correctly sorted ones.

    Unsorted Particles:


    Sorted Particles:


  • 05-08-2008 12:21 PM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    What if you sort all the particles, and then draw them all at once, in the same draw call?

    Cool looking particles, btw.
    Eli Tayrien - XNA Framework Developer
  • 05-08-2008 12:40 PM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    I thought of that, however because different particles may have different textures (and I have to sort all particles regardless of emitter, because of the case in which 2 emitters are close to each other) I'm not sure how I would go about writing code for drawing all the particles within the same draw call.

    p.s. Thanks for the compliment, the particles were very much inspired by the legend of zelda, the windwaker (which is an awesome game imo)
  • 05-08-2008 12:54 PM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    Given these three requirements:
    • Correct sorting
    • Different textures for each particle
    • Fast

    you pretty much just get to pick any two :-)

    If you want to sort and also want to switch textures a lot, you will inevitably need a large number of draw calls, and if you use a lot of draw calls, your performance will be poor.

    Most games either just don't worry about sorting (or perhaps sort within each different particle system, but don't bother to sort particles using one textures relative to particles of a different type), and tweak their particles so the resulting problems aren't too noticable, or in some cases they use additive blending which makes sorting irrelevant. I believe the magic effects in Zelda were entirely additive, for instance (again, you have to design your effects specifically with that in mind to make additive blending look good).

    If you absolutely need both sorting and varied particle textures, you're going to have to put up with not-so-great performance, which will limit how many particles you can draw at a time. You might be able to use some kind of shader trickery to switch texture within a shader rather than requiring a separate draw call, but that's going to make your shader more expensive, so regardless of whether you do this via shaders or multiple draw calls, it's going to cost you.
    XNA Framework Developer - blog - homepage
  • 05-08-2008 1:29 PM In reply to

    Re: Help needed! Fast Alpha blending for Particles

    Shawn Hargreaves:

    If you absolutely need both sorting and varied particle textures, you're going to have to put up with not-so-great performance, which will limit how many particles you can draw at a time. You might be able to use some kind of shader trickery to switch texture within a shader rather than requiring a separate draw call, but that's going to make your shader more expensive, so regardless of whether you do this via shaders or multiple draw calls, it's going to cost you.

    Another option might be to use a simple 'texture atlas', by putting multiple sprite textures in one big texture (so four 128x128 textures could be combined in one 256x256 or 128x512 one). You could then offset the UV parameters of the particles in the shader based on some index you bake into the particle vertex, so they use the correct texture. For example, when using a 128x512 atlas, you'd scale the the original particle's V coordinate by 0.25 and add vertex.index * 0.25 to it, where the index is a number between 0 and 3. This maps the original UV to the appropriate 'subtexture' in the atlas.

    This approach allows you to render multiple types of particles without swapping the texture, so it's well suited for batching and it shouldn't get in the way of depth sorting. I don't think it's too expensive, since it only requires a few muls and you could do with a ubyte or whatever for the index, so it shouldn't consume too much bandwidth either. The only downside is that creating the particles becomes a bit more complex.

    I believe the magic effects in Zelda were entirely additive, for instance

    I'm not sure. I've looked at them closely to blatantly rip them off myself a while back and as I recall the 'puffs' were all opaque and at least didn't look additively blended, which gave them their cartoony feel. But I learned not to argue with folks who potentially worked on the stuff themselves Smile

  • 05-08-2008 1:45 PM In reply to

    Re: Help needed! Fast Alpha blending for Particles