Sooo…consider the image below (click to enlarge) it’s from GSB 2. A ship has blown apart (no bright fire pixels yet, just clouds of smoke) and there are smoke plumes. So far so good right?
Sadly no. The problem is, that ship was in the distance, and behind all the other ships, but if you are really eagle eyed you will notice the smoke plumes get drawn above the ships next to it, and this is a HIDEOUS RENDERING ARTIFACT. For complex reasons to do with the way I build up lightmaps and composite them back, I can’t just draw the smoke cloud after I draw that far-off ship, and then let other stuff render over it. I do some nonsense with multiple render targets that means despite using a ton of transparency and ruling out a conventional Z-Buffer system, I have to render some things out of order. So those smoke plumes are actually rendered last, just before I do my (slight in this screenshot) bloom effect. This lets me have them work sensibly when it comes to obscuring lights behind them, and avoids other artifacts.
The problem is…I need a way when drawing them to prevent them appearing in front of far off objects. Thankfully I have z-positions for everything, so in theory this could be done, although reading up on it, it seems like a conventional z-buffer is not going to cut it, due to it being all translucent smoke particles. So… right now I’m considering the experiment or the day is for me to create my own z-buffer, fill it with the ships (and asteroids) and their z-positions, and then manually compare the z-positions in a special shader I can use for drawing the smoke plumes. In my head, I know that even if this works perfectly, it won’t work perfectly…because there is nothing to stop a smoke plume going ‘through’ a ship. But hey… we can live with that, as long as ones in the background don’t get obviously drawn on top of things in the foreground. Because GSB 2 uses a lot of parallax, it looks slightly 3D-ish, and I don’t want to ruin that effect.
This probably will all go wrong, it’s one of the many experiments you go through when you have an unusual game and your own graphics engine. In my head it seems easy. Create new offscreen render target (yikes…performance), render all of the items I want to sort to it (yikes…performance), using their z-position as the value written to it (it could be a simple and small 8bit format), then set that as a texture I can read from my smoke-plume shader, pass in the Z value to the shader and compare the two, setting alpha to be 0 if the pixel should be obscured. Job done right?
Place yer bets!