Search Unity

  1. The 2022.1 beta is now available for testing. To find out what's new, have a look at our 2022.1 beta blog post.
    Dismiss Notice

Z-sorting of billboard sprites in 3D space? (stop tall sprites intersecting with walls)

Discussion in 'General Graphics' started by Lastair, Jan 11, 2015.

  1. Lastair


    Mar 16, 2012
    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)
  2. brettjcooper


    Oct 4, 2016
    Resurrecting this because I have the the exact same problem, have thought about the exact same possibilities you put forward, and also haven't been able to find anything else by googling. Did you every come up with a solution?