Hi! I am trying to create GPU instanced particles (no unity particle system involved). Currently I just have a bunch of quads with a texture and I move around in a compute shader. The problem is with transparency. It seems to me that some instances are rendered in wrong order and I think the issue might be in z depth. I tried to play around with writing to depth buffer in frag shader, but it didn’t really help. Below are the screenshots of what is happening and the shader code. If anyone has any idea what is the problem and how to fix it, I would really appreciate it. Thanks!
Most particles use additive blending, so it does not matter what order they are rendered in. In the Pass {} block, of your vertex/fragment shader, put Blend One One.
For certain types of particles, you may need to use different blend modes (eg alpha testing might be appropriate for falling leaves).
If it is not specified, Unity shaders default to ZWrite On. For transparent materials, usually you want ZWrite Off. ZWrite along with ZTest is used for depth sorting of opaque objects, but it is only really useful for opaque objects because the depth buffer can only store one depth value per pixel. For transparent objects you want set turn ZWrite Off and then you’ll either need to use a blend mode that doesn’t care about the render order, like additive (though I’d recommend Blend SrcAlpha One instead of Blend One One), or you’ll need to manually sort the particles in back to front order in the structured buffers.
Yeah, z testing was on, and after I disabled it things changed but not much better. Now, if I look at the particles with cameraZ being negative I - they render properly. But, when cameraZ is positive at certain distances I get the black square artifacts again.
And this same position, but a little further away from the center - artifacts appear again. Plus, particles behind the blue plane are now occluded by it - which is what I expect always, but it only happens when the artifacts appear.
In my shader code I have:
Tags{ “RenderType” = “Transparent”
“Queue” = “Transparent”}
LOD 200
You do not want ZTest Off, you want that on, or more specifically ZWrite GEqual, which is the default if you don’t include it… You want ZWrite Off.
ZTest Off will mean it will render on top of opaque objects, even if they’re behind those surfaces.
ZWrite Off means it won’t write to the depth buffer (aka z buffer), which is still what’s causing your issue
The behavior of the black squares showing or not is due to the render order changing. In the first image the walls are rendering first, and then the particles. In the second image the particles were rendering first, and then the walls. Because ZWrite was still enabled, in the second image the walls aren’t rendering anywhere they’re behind the particles because that’s what the depth buffer along with ZWrite and ZTest are supposed to do to ensure depth sorting.
However the fact the order between the walls and the particles isn’t consistent makes me think the Render Queue on the material itself is overriding the shader (make sure it’s set to 3000 or Use Shader and not 2000 or some other number), or you’re manually rendering the mesh during the opaque queue.