Search Unity

Text Mesh pro SDF shader does not render correctly next to Alpha-supporting shader - need help

Discussion in 'Shaders' started by konstantin_lozev, Apr 8, 2019.

  1. konstantin_lozev

    konstantin_lozev

    Joined:
    May 8, 2015
    Posts:
    99
    I have recently started using Text Mesh Pro in my project, but now I am having an issue with the way TMP objects using the SDF shader render next to other objects that use shaders that support alpha transparency.
    Here is what it looks like: https://i.imgur.com/esONjvg.jpg

    As you can see, in the image there are 2 sections - one using TMP next to a linerenderer with an unlit shader (top) and another using TMP next to a linerenderer using Mobile/Particles/Additive shader (bottom). The upper image renders correctly in the sense that the linerenderer "pierces" the text and the box showing correctly first under both of them and then over both of them. The lower image has the same positioning of the elements, but while the linerenderer "pierces" correctly the box, it stays under the whole text instead of being half under, half over it. This gives a very jarring effect where the right side of the linerenderer renders both over the box and under the text, which is impossible.

    Is that a TMP bug, or is it a general issue of using TMP SDF renderer next to Mobile/Particles/Additive shader. How can this be resolved? Is there another compatible shader that supports alpha transparency but renders correctly?

    Here is the Unity project https://drive.google.com/file/d/1IXCzPzsxsU1TqGMPyX-bwD2Skh_O47m8/view?usp=sharing

    I should add that the situation reverses if most of the linerenderer is positioned in front of the TMP element - then the linerenderer always renders on top of the whole text, even if some part of the line is behind the text.
     

    Attached Files:

    Last edited: Apr 8, 2019
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Not a bug. This is just how transparency works in real time rendering. Efficient and correct sorting of arbitrary transparent geometry is an unsolved problem for real time rendering.

    Opaque geometry uses the depth buffer to ensure proper sorting, but that only works for opaque geometry since the depth buffer only stores a single depth value. Opaque geometry test against the depth buffer and either skip rendering all together, or completely replace the color value for that pixel. Technically transparent objects do the same, but they don't (usually) update the depth buffer at the same time as they're pre sorted per-object. Enabling depth write won't fix the sorting either, it'll just mean either the line or the text will be completely invisible behind the other, depending on the order you rendered in.

    For this particular case, the only easy solution is to not use alpha blending on your text or the line.

    Alternatively manually split the line into two parts, one behind the text and one in front, though that's still not guaranteed to prevent the problem due to Unity liking to batch geometry using the same material, and transparency sorting being spherical bounds based.
     
  3. konstantin_lozev

    konstantin_lozev

    Joined:
    May 8, 2015
    Posts:
    99
    Thanks a lot bgolus, really useful to know that there is no shader trick around it. I think I will go with having 2 linerenderers - one with alpha (with the "blue glow") and the other with the central white solid line. That way only the glow will get occluded and the central white section will be properly overlayed.
    I will also think about splitting the line, probably using raycasts, but the laser pointer can go in so many ways inbetween objects in my scene without intersecting them that it might not be a solution.

    Thanks again!
     
    Last edited: Apr 9, 2019