Search Unity

Applying two shaders to an object based on a mask

Discussion in 'Shaders' started by LiquidDarkness, Jun 10, 2019.

  1. LiquidDarkness

    LiquidDarkness

    Joined:
    Apr 19, 2013
    Posts:
    20
    Hi, I hope this is the right place to post, I've never really used a forum before.

    Basically, I've been creating a fog-of-war-type effect by rendering my terrain (pre-modelled mesh, not Unity Terrain) with two cameras: one Main Cam, and a second camera that only renders the terrain and nothing else.
    The second camera renders using a replacement shader that makes the terrain look holographic (tiled grid texture with transparency and some animated colour effects).
    My main camera takes the render texture result from the second (replacement) camera and uses Graphics.Blit to composite the two renders together. This composite shader simply lerps between the original render and the holographic render based on the grayscale interpretation of the holographic render sample (black is where nothing was rendered, anything above should show the hologram).

    This produced an image where everything is rendered normally, but with the hologram overlaying it (due to transparency in the shader, it simply overlays rather than replacing it completely).
    This is where the mask comes in. During the game, a grayscale mask is generated and altered that both the terrain's original shader, and the hologram shader use. The initial shader uses the mask to fade out the terrain where the mask is black, and the hologram shader fades away where the mask is white, therefore providing a final image of a hologram fading into the solid geometry.

    I appreciate this may be a rather hacky way of achieving this effect, but after a lot of thinking and researching, it was the best I could come up with.

    The problem now is that I am having many issues with depth order of the hologram. Initially it was drawing over everything else as it was being composited, so I passed both camera's depth buffers to the composite shader too and compared them to help decide if anything was above the terrain. However I'm still having problems with the hologram flickering angrily when intersecting solid geometry and the camera is being moved closer/further away, as well as a small amount of delay when moving the camera around, almost as if the hologram is 'catching up' with where it's meant to be.

    If anyone can suggest a better way of me producing this effect, or a way to solve my depth sorting issues, I'd be very grateful. Please let me know if there's any other information I should provide.

    Thank you!!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Sounds like your replacement shader pass is rendering after the main camera is doing it's post process compositing. I'm not sure where or how you're rendering the replacement shader pass, but it is likely a frame late. You can try using the Frame Debugger to see if the replacement shader camera is rendering before or after it does the post process compositing.

    However:
    If you want the effect to sort with the objects in the main camera, why not just render your effect in the main camera? You could render the objects you want to appear as holograms again manually with the second material, either by using command buffers or just making copies of your mesh renderers. Or use a projector? Or do it as a post process that uses the main camera's depth texture to extract the world position and maybe stencils to limit what objects it applies to? Or a custom "terrain" shader that does both the normal ground rendering and the hologram either as two passes or a single combined pass.

    Lots of ways to do this.