Search Unity

Draw On Top of Floor and Behind Objects

Discussion in 'Shaders' started by BinaryCats, Apr 16, 2019.

  1. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Hello,

    I am not a graphics guy, my knowledge is limited, but I'm a technical guy so hopefully with your help I can come up with a solution.


    I have a particle effect, which is billboarded:


    However, as you can see, when the effect is close to the ground it intersects the ground, and clips.


    My desired effect would be the star to draw on top of the floor.


    However, this issue gets more complicated, when something in the foreground is drawn.

    My desired effect is somewhat shown here, I wish the star to appear behind the foreground object, but still render on top of the floor

    Is it possible to do this? if so how?

    Many thanks in advance,

    here is a mockup (forgive my art) of how I would like the effect to look
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    There's a few ways to go about this.

    Option 1: Depth offset.
    When working in 3D space with opaque objects, GPUs use a depth buffer to keep track of the closest surface drawn at each pixel. This is used to skip drawing of surfaces that can't be seen due to them being further away than the pixels that were previously drawn. That's why your quad doesn't show when it intersects with the opaque ground. A cheap work around is to use some kind of depth offset. This can be done with a custom shader through various means, or by using the particle offset settings, or by just moving the particle system itself towards the view manually. This can only go so far as, obviously, eventually you'll get closer to the camera than the object you're trying to render behind, and there may be no distance where you're both behind the object and above the floor. Most of the time this is as much as anyone does, plus maybe use soft particles to make the intersection with the ground (and the object) less obvious.

    Option 2: Make everything* transparent!
    Part of the problem here is the rendering order. Generally speaking all opaque objects render first, sorted roughly front to back (so the aforementioned depth buffer can let the GPU skip as many occluded surfaces as possible). Then transparency is drawn back to front. Transparency can't make as effective a use of the depth buffer, which can only store a single depth per pixel, as opaque. So instead objects further away are drawn first so that later objects simply write on top. So one option is to make your foreground object render as part of the transparent queue range after your particle system, and have the particle use a shader with ZTest Always so that it ignores the depth buffer. This will mean the particle effect will render on top of everything that rendered before it, then your object will render over that making sure it's not visible. If you were doing a 2D game, or otherwise using sprites, careful control of the sorting order would be how this would have been done too, so this is just doing the same thing. However making otherwise opaque objects be part of the transparency queue range has other side effects in Unity, like not being able to receive shadows.

    Option 3: Stencils.
    This one requires some custom shader work for both your particles and your object. The object needs to use a shader that writes to the stencil buffer. The particle effect, then uses a shader that checks the stencil and skips rendering where the object previously wrote to it, along with using ZTest Always so it doesn't clip with the ground, or moving it closer to the camera. Both options work since the stencil mask won't care if the particle is closer to the camera than the object or not.
    https://docs.unity3d.com/Manual/SL-Stencil.html
    The one downside to this is it won't work if you're using the deferred rendering path as Unity uses the stencil buffer already, and ignores stencil settings in the shader.
     
    NateReese77 and BinaryCats like this.
  3. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Thank you for your thorough reply