Search Unity

  1. New Unity Live Help updates. Check them out here!

    Dismiss Notice

Reading/Writing to the Stencil Buffer multiple times in the same shader

Discussion in 'Shaders' started by _eternal, Jan 8, 2019.

  1. _eternal

    _eternal

    Joined:
    Nov 25, 2014
    Posts:
    116
    I've got a bit of a specific issue with my player character's shader. I'm trying to combine a couple of different stencil-based effects. Here's what I have:
    • A silhouette effect where certain objects can occlude the player and draw solid black pixels instead. The occluder writes a value to the stencil buffer, and the player checks this value and renders black pixels if necessary.
    • A masking effect where child objects of the player are only rendered if the player itself is visible. This is because some sprites are separate from the base sprite (e.g. eyes, items), but I want the whole character to be able to appear/disappear using a shader effect. This way, the eyes won't render if the base sprite is teleporting out and the top half of their body is cropped.
    Both of these effects work in isolation, but I can't figure out how to combine them (or if this is possible). The Occluder writes the value 4 to the stencil buffer, so I can do something like...

    Code (CSharp):
    1.  
    2. Pass
    3. {
    4.     Stencil
    5.     {
    6.         Ref 4
    7.         Comp Equal
    8.     }
    9.  
    10.     //Simple vert/frag shader to display the silhouette color instead of the sprite color
    11. }
    Below this, the surf shader continues like normal:

    Code (CSharp):
    1. Stencil
    2. {
    3.     Ref 5
    4.     Pass Replace
    5. }
    6.  
    7. CGPROGRAM
    8.     //The rest of the surf shader, which involves drawing the whole sprite and possibly modifying its colors
    9. ENDCG
    When I do this, I think the surf shader overwrites the silhouette drawn in the first pass, because I can't see the silhouette at all. However, if I switch the order around and put the silhouette pass at the end, the Stencil function of the surf shader overwrites the 4s in the buffer, so the silhouette pass never executes.

    I'm pretty new to shaders so I'm not sure if I'm approaching this the right way. I want to write the result of the surf shader to the stencil buffer, but I also want the result to be affected by the silhouette pass.
     
unityunity