Particles Redux

In the far distant past of last October I showed a little Stage3D accelerated particle system. Displaying a fantastic rate of progress I’ve made the same thing again, but this time it’s better, and uses HaXe.

Get Adobe Flash player

Select a number of particles to create (50,000 or 100,000 is liable to take a while to load up and might even exhaust Flash’s available memory on lower spec machines). Once the particles have been generated you can drag with the left mouse button to change your view.

In terms of feature difference to the old version all that’s new is that any number of particles can be created (oh, also this version is in 3D). As there are limits to how many vertices and indices you can load into Stage3D for a single draw call, the larger particle counts make use of a simple batching system I’ve been building to spread themselves between multiple draw calls. My batch manager is still a little slow, and this example rather foolishly adds new particles one at a time, so you have to wait a little while it constructs the batches at the start.

15th April Update:
I’ve since rewritten how I handle memory in my nascent 3D framework to use the soon to be a “premium” feature of direct memory access. End result is that time to generate 100,000 particles went from 30 seconds to 5. To celebrate I added an option to generate 500,000 particles.

 

I should probably also mention that if you really did want huge numbers of particles active at once in a game you can save substantial memory use by creating just one batch’s worth of vertex data and drawing it several times each frame with varied vertex constants. In this example I’m quite deliberately wasting memory to test out my framework.

 

From a development point of view the big difference is that this is built using HaXe rather than AS3. Explaining HaXe is outside the scope of this little post, but it’s really pretty great and you should check it out. Its major feature is the ability to compile to a variety of languages, but for now I’m just using it as a straight up replacement for AS3 in Flash development as I enjoy the additional features of the language.

For shader work HaXe really stands out thanks to HxSL, which is a quite simple but very effective high level shader language, similar to GLSL for OpenGL or HLSL for DirectX. This means that I can write Stage3D shaders without directly using AGAL.

My HxSL shaders are still converted into AGAL-equivalent bytecode when the project is compiled so I’m still limited by the same restrictions as AGAL itself is: no loops (although HxSL can ‘unwind’ for loops between constant values) and a limit of 200 commands per shader being the main ones. But writing and especially maintaining the shader is vastly easier.

The AGAL code for the original bouncing particles shader. Click to enlarge.

 

The HxSL code for the new bouncing particles shader. Click to enlarge.

The HxSL version actually does slightly more, as it applies a simple billboarding effect to the particles so that they’re always facing the camera. Notice how the HxSL version is at least as readable as the AGAL even without any comments at all and how the comments for the AGAL dwarf the actual code.

5 thoughts on “Particles Redux

    • Hiya,
      I don’t know off-hand how ND2D does its stuff, but I imagine it’s broadly similar:
      For everything that I want rendered I create a RenderItem object, which is a mesh (the 3d geometry) and material (vertex and fragment shaders, texture, relative render order and settings like face culling) bound together.
      The RenderItem is passed to a BatchManager, which looks for an existing batch with the same material as the added RenderItem.
      If it finds one then it simply adds the mesh data in to that batch, so when the batch is rendered it’ll also draw the added RenderItem.
      If it can’t find an existing batch with a matching material, or all matching batches don’t have space in their buffers for the RenderItem’s mesh then it creates a new batch with the correct material.
      I keep the RenderItem around even after it has been incorporated into a batch to store the indices of where it was added in to the vertex/index buffers, so it can be correctly removed from the batch if needed (or even altered in-place, although far faster to alter stuff via vertex shader if at all possible).
      A bitfield is used to record what locations in the batch’s buffers are in use, and meshes are permitted to become fragmented within a batch’s buffer so the available space is used efficiently. That all makes adding RenderItems slightly slower, hence the “preparing particles” delay at the start of this article’s example.

      I haven’t finished implementing this part yet, but it’ll also automatically create a texture atlas (using the “skyline” algorithm to pack the textures) when it finds two materials that are identical except for their texture.

      Hope that’s useful.

  1. Thanks for the post. Very interesting.

    We’re maintaining an as3 codebase and using AGAL (yuck), but if you say that haXe & HxSL can target the flash runtime, I wonder if I can just write my shader code in a separate haXe .swc and link against it?

    • I’d think that is possible, although can’t say I have experience doing it.
      HxSL and HaXe’s handling of Stage3D shaders are fairly wound up together (there’s some macro-based magic going on), so it could be a little fiddly separating them out completely. If it’s possible for your project, having the rendering system as a self-contained HaXe project might make it simpler.

      You might also find the code for HxSL studio useful. It translates HxSL code directly into AGAL and then runs it on a simple model, all in real time. Unfortunately the online version is 404′ing for me, but the source is all available.
      It would be an ugly workflow but you could write shaders in HxSL, have a HaXe project that converts them into AGAL, then use the AGAL directly in your AS3 code.

Leave a Reply

Your email address will not be published.

* Copy this password:

* Type or paste password here:

16,850 Spam Comments Blocked so far by Spam Free Wordpress