High-speed, Off-screen Particles in Unity

Our approach to fill-rate problems with massive numbers of particles filling the screen.

http://technology.blurst.com/off-screen-particle-optimization/

Hope someone finds it useful :slight_smile:

Interesting read, thank you for sharing

Nice. I implemented a downsized particle buffer in a project at work last year for some hardware that was fillrate limited. We used if for all ‘transparent’ objects in the end including distortion objects ect.

You mention that you didn’t have issue with artifacts, I’m guessing that is due to the ‘close’ range that the particles are rendering into. We were not so lucky and it took some crazy up scaling / full res depth buffer sampling tricks to make the scene recombine nicely.

We also didn’t rerender the scene for the depth buffer, we did a downsample of the full res buffer. We could not afford the time to rerender the geometry.

One nice way we found to fix the ‘bad’ edges on upscale was to make the edges a bit ‘softer’ by sampling the full scale depth buffer and the downsampled depth buffer at the texel location and if they were different do a few different combines (multisampling of the depth buffer / heuristic) to make the edges seem softer and match up.

Oh and nice work on the premultiplied alpha. It’s the only way to fly :wink:

Guess I didn’t make that clear enough. That’s what we did too. We rendered a full res depth buffer (since we don’t have access to the depth buffer on the graphics card) and then downsampled it for use by the offscreen particles. We’re using the depth buffer for other effects as well, so we needed it full res. Agreed that it would be too expensive to render another depth buffer at the lower res just for the particles.

Ahh, I read this and it seemed to indicate that you were rerendering part of the scene (with a different clip plane.

What method did you use to downsample the z-buffer? Did you just sample 4 pixels and pick one? If so what kind of heuristic did you use for pixel selection.

We took the pessimistic option and always took the pixel closest to the camera. We found that this was more appropriate given our use cases. But as you are just doing additive particles (and looking a the pictures) it seems like you took the optimistic route of picking the z value furthest from the camera. Some of the pixel bleeding gives it away.

Ah, all of our effects work with a depth buffer that has a reduced far clip plane.

Nothing special :slight_smile: Just point sampling at the center of pixels. I tried doing tests for pixels that were closer and pixels that were further, neither really looked any better or worse for us.

1 Like

Hello,
I tried to implement the technique but I found some difficulties. Could you explain a bit more in detail how to implement it? one of the errors that appear is:

Assets / Test.js (17:27): BCE0005: Unknown identifier: 'PostProcessingHelper.

Where is this class defined? :face_with_spiral_eyes: Is already within Unity?

Nick, I recommend you read through the Unity manual about rendering with Replace Shaders and download the Replacement Shaders example resource and have a look at that before attempting off-screen particles.

There are much simpler example projects (Like the UV texture one) that you can play round and experiment with before jumping straight into off-screen particles and they work out of the box in Unity 3 (Shawn’s code requires a soft massage before it’ll work in stock U3).

You should also read through the GPU Gems 3 article about off-screen particles, they explain some potential issues and fixes with this kind of system that Shawn’s game didn’t have to deal with. It’s a great technique though and kudos to Shawn for the article about using replace shaders for it. His other articles about replacement shaders used in Blush and his other games are also equally awesome.

Cameron thanks for the reply is just what I was looking for! Actually I was hoping use the Shawn’s technique to implement soft particles in the forward rendering. Actually I have already done some testing with replacement shader and I’m pretty close to the solution.

I released a version of this on the asset store for free as part of my Unity 2015 talk, enjoy:

2 Likes

Is there an up to date version of this? the asset store says that it’s no more and I think it was A GREAT case study at least.

Not up to date, but the code is still on my public github…