I am working on a project that would have billboarded 2D character and object sprites in 3D space - for example think of Ragnarok Online if you’re familiar, or something like Chrono Trigger except with 3D backgrounds. Using the sprite renderer and a simple script that matches the camera’s X rotation for the billboarding, I am running into an issue with z-sorting.
A tall sprite in front of a tall 3D object will intersect with it, e.g. a character’s head will end up inside a wall. I do understand that this is correct behavior, as that’s how the billboarded quad actually is aligned in the 3D space. However, for my purposes I want the sprite to be sorted as if it was vertical in world space, based on its bottom edge.
I’ve tried/considered:
- simply pushing the quad towards the camera - not workable since the bottom of the quad will then end up in front of things it should be behind like ground foliage, and create other positioning/lighting/shadow issues
- the CG and GLSL billboard shaders available on Wikibooks - neither seem to even work properly to begin with (and even if they did, I figure they’d run into the same issue as they’re so basic)
- setting the camera’s transparency sort mode to orthographic - seemed tangentially promising but did nothing to affect this situation
- considered dynamically setting renderqueues or sorting layers/orders-in-layer - this seems like a very clunky solution that would need constant updating for moving objects, and by my logic would require every single object in the scene to be assigned their own values
- considered creating a perspective-distorted quad that is truly vertical in world space, but results in a rectangle in screen space, using mesh renderer instead of sprite renderer - seems complicated for my weak math, and would possibly clip problematically in new ways since the mesh height would around double, also loses a lot of the sprite renderer’s power creating extra work in other areas
This feels like a problem that should’ve been solved by other people a million times already, but I couldn’t find solutions by googling, maybe because I couldn’t come up with the right terms. I figure this could be done with some kind of shader that writes manually to the z buffer or something, but I’m not very shader literate. Am I missing some feature or easier solution here, or what would you suggest? Help is greatly appreaciated.
(I’m running Unity 4.5.1f3, free version)