Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Models using Unity's Standard transparent shader are overlapping themselves

Discussion in 'Shaders' started by Wasplay, Aug 1, 2019.

  1. Wasplay

    Wasplay

    Joined:
    Jun 2, 2018
    Posts:
    46
    Here's two examples :
    Opaque : https://i.imgur.com/iaRX57X.png
    Transparent : https://i.imgur.com/4fUtHVE.png

    Seen from up :
    Opaque : https://i.imgur.com/Sw2itEw.png
    Transparent : https://i.imgur.com/8O1Hv2y.png

    I need to have a shader compatible with Sorting Layers since my game is a mix of 2D and 3D, that's why I'm using the Standard transparent one

    Any way to fix this issue ?
    I've tried to put ZWrite to 1 but this breaks Sorting layers
    I've also read people talking about multi-pass shaders but I don't know what it is
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,366
    Efficient, and correct sorting of 3d transparency in real time rendering is still an unsolved problem.
    https://forum.unity.com/threads/render-mode-transparent-doesnt-work-see-video.357853/#post-2315934

    The addition of needing to sort against 2D layers increases the complexity of the problem here. Sorting layers and order works because sprites do not write to the depth buffer, but for proper sorting of 3d objects you kind of have to write to the depth buffer. Indeed that's what it exists to do to avoid having to sort the individual polygons of a 3d mesh directly.

    The easiest solution is to actually move sprites in the Z plane so that their "real" depth and render order match up. Then you don't have to deal with any special shader stuff, though you may still get some clipping if you're not careful. I've seen some people use the solution of moving 3D objects in the Z plane in large steps to ensure they're in front of or behind the pre-spaced 2D elements.

    The next easiest solution is to not use 3d models in the scene. Render out your 3d models to sprite sheets and use those, or render them to render textures and render those as sprites. Some mobile games do this, like Brawl Stars. This is a lot more expensive to render, but requires far less upkeep once setup.

    Almost all the other techniques out there for getting proper sorting of transparent objects won't work in combination with sprites, and would still require using one of the above methods to get them to sort properly based on their sorting order.


    There's one last option that requires a multi-pass shader. You've seen people talk about multi-pass shaders. Those work by rendering the entire object once to only the depth buffer, then render the entire object again with a normal transparent shader pass. The pass that renders only to depth ensures only the closest surface depths are in the depth buffer when the transparent pass renders. That causes all surfaces that aren't the closest to the camera are skipped.
    https://docs.unity3d.com/Manual/SL-CullAndDepth.html


    This of course leaves the depth buffer filled with values, and means sprites that intersect that 3d object get clipped too. So you could render a third pass that effectively clears the depth buffer meaning subsequent sprites don't get clipped.

    Something like this example, though it's only a small snippet and not a full shader in the post, the zip should have a more complete shader:
    http://aras-p.info/blog/2019/02/01/Infinite-sky-shader-for-Unity/
    The modifications you'd need to make is use ColorMask 0 like the depth only pass in the previous link, and ZTest Always so that it ignores what's already in the depth buffer.
     
    Last edited: Aug 1, 2019
  3. Wasplay

    Wasplay

    Joined:
    Jun 2, 2018
    Posts:
    46
    Thanks a lot.. I though it was easier than that !
    I'll try to use render textures and place them as sprites, it seems like the best solution for my game since it has a lot of dynamic lights

    (EDIT: Changing the sprites' Z axis was a far better idea)
     
    Last edited: Aug 1, 2019