Hello, I have two transparent characters against a transparent floor that the user can view at any distance/angle.
Thing is, when rotating or moving the camera, said objects overlap on each other. It is my understanding from this question that this is due the way the objects are sorted, based on their distance from the camera. Alas, I believe none of the solutions suggested would fix the issue in my case; would you happen to know a way to fix it or make the issue more bearable?
You can order them manually by adjusting the queue in the material.
Edit: Ah, the issue is between the people. There are a few options.
Only draw the geometry that is at the front. Can be done easily be first drawing z-only for all people and then drawing color only. Easiest and removes the visual popping.
For multiple layers you can look at order independent transparency. Can be a lot trickier.
I apologize, I still struggle a lot understanding shaders. How could I first draw z-only? Would that be with a Tag within the subshader or a Blend type? My current shader is a humongous extension of the current Unity standard shader with lots of passes; I just kept on pasting code from the forums that seemed to do what I needed. It works but I am not sure if it is redundant.
Here it is just in case:
Order Independent Transparency (OIT) is the search term you’re looking for.
To do accurate per pixel transparency sorting is extremely expensive to do on modern graphics cards, though it is possible. To do it in Unity would require essentially not using any of Unity’s built in shaders, and possible not use any of Unity’s built in renderer components. Pretty much no one does this outside of some tech demos and specific applications, these days it’s probably cheaper to “just” do GPU based raytracing … but that’s even more work to implement.
There are approximated OIT techniques that have gained a lot of popularity. They aren’t perfectly accurate, but they’re usually good enough that with out knowing they weren’t accurate you wouldn’t be able to tell the difference. Weighted Blended Transparency is one that a few people have released free basic implementations of, like here:
Another option is to abuse alpha to coverage / alpha to mask and MSAA, but it requires more than just turning it on (which is fairly easy, just make a new shader and add AlphaToMask On) as you need to manually control the mask bits so overlaps show. It also make transparency aliasing worse as it works by abusing MSAA samples.
The “Pre-Z” option @jvo3dc is suggesting can solve the issue, but it’ll also make your objects not look transparent as you won’t be able to see them through each other.
The easiest solution would be just use a blend mode that does’t require sorting, like additive.
Here’s an example of the alpha to coverage hack. You must have 4x MSAA anti-aliasing turned on for this to work. Only two objects will overlap, after that it’s fully opaque, but both objects will individually be ~80% opaque unless they overlap. For your example above you’ll need each character to be using materials with a different “Object” setting, but leave the ground using the material it currently has.
I tried both implementations, the “ZWrite On” during the first pass and the alpha coverage hack (Really interesting stuff!). The thing is that I also need to display the vertices color which, along the alpha values, vary constantly each frame and I wasn’t able to integrate this into your solutions
Nevertheless, @bgolus , the link that you provided in your first post mentioned this GitHub project that seems rather frail and hacky but gives great results! Somehow I was able to add vertex color without breaking it.
Also, thank you for dropping the “OIT” term too, I learned a lot from googling it!