# 2D particles with a perspective camera?

I'm working on a 2D pixel art Unity game. I have multiple layers of scrolling so I need to use a perspective camera, the problem is though that it seems to mess up using particles as when the screen scrolls the particles move in perspective, when I need them to stay just in the x and y. Is there way to achieve this? I don't particularly want to go through every particle in real time and zero out their Z value, but maybe that's the only way?

• Can you add some images of the types of particle effects you're using, and the artifact you're trying to avoid? There might be ways to fix it using emitter settings or shaders, but we'll have to see your setup because particle systems can be used in so many different ways. Mar 10, 2015 at 18:09
• It's literally the standard emitter you get when you create a particle object, I'm just using that as a tester, I put that in the scene then run my game, and scroll the screen around, and the particles move in perspective (some moving left and right faster than ones behind them), which is not what I need. I need them just to be 2D, not use their Z value.
– Phil
Mar 10, 2015 at 23:38

There are three main approaches you can try:

1. Modify your particle emitter settings:

Ensure the particles are spawned at the same Z position. In Unity, this will be in the Shape section of the particle system inspector. For a sphere, hemisphere, or cone, set the radius to zero. For a box, set the Z extent to zero. If using a mesh as the emission surface, choose a flat mesh.

Ensure the particles do not stray from the Z plane they start in. In Unity you can do this with the "Limit Velocity over Lifetime" section. Check the "Separate Axis" box, and set the Z velocity limit to 0 and the space to World. Set the X and Y limits generously high (greater than or equal to your maximum speed) so that you don't slow the particles in the directions you want preserved. Watch out when using forces or collisions with the particles, as these might bump them out of plane.

2. Use a shader to flatten particles during rendering:

Write a custom vertex & fragment shader for your particles. Create a material using this shader and assign it in the Renderer section of the particle system inspector. In the vertex shader, set the z-coordinate of each vertex to some fixed value (either a constant or a shader parameter) before multiplying it by the projection matrix. (There are plenty of sources that explain how to write vertex shaders for Unity, so I won't clutter this answer with every step)

Note that, as far as I can tell, Unity pre-transforms particle vertices into camera space before submitting them to the GPU, so the z-value you use is relative to the camera. This may be a platform-specific batching behaviour, or dependent on quality settings, so be sure to test in your intended output format to double-check that it behaves as expected.

3. Render your particles (alone) with an orthographic camera.

Put your particles into their own layer. Set your main (perspective) camera to ignore this layer. Create a second camera, parented to your main camera. This one should render after the main camera, see only the particles layer, perform no clearing, and be set to Orthographic. Adjust its size so that the particles line up correctly. If your camera ever gets closer or further from the scene, you'll need to adjust the orthographic camera's size to match. (This will only work if all your particle sources sit in a single plane - otherwise the particles may be offset from their source when the source parallaxes and the particles don't)

Of these options, number 1 (emitter settings) is quickest to set up, and 2 (custom shader) is the most robust/flexible. I'd only recommend 3 (separate camera) if you need more flexible emission options than 1 allows, but aren't comfortable writing shaders (or are targeting a platform that lacks programmable vertex shaders)