Search Unity

Turn transparent when behind wall, how to do this ?

Discussion in 'Shaders' started by windmaomao, Dec 4, 2009.

  1. windmaomao

    windmaomao

    Joined:
    Jun 11, 2009
    Posts:
    50
    This might sounds newbie description, but I don't know if this is just the shader thing.

    Ok, I have an player and a wall, when the player is in front of the wall, it's just regular shading. And when the player goes behind the wall, the ghost shape of the player is projected on the wall. I saw this effect in couple of games, the latest one is Torchlight.

    Just curious if anybody knows how this can be achieved by shader. thanks.

    Fang
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    I made this a while ago.

    Code (csharp):
    1. Shader "FX/VertexLit ShowThrough" {
    2.     Properties {
    3.         _Color ("Main Color", Color) = (1,1,1,1)
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.         _OccludeColor ("Occlusion Color", Color) = (0,0,1,1)
    6.     }
    7.     SubShader {
    8.         Tags {"Queue"="Geometry+5"}
    9.         // occluded pass
    10.         Pass {
    11.             ZWrite Off
    12.             Blend One Zero
    13.             ZTest Greater
    14.             Color [_OccludeColor]
    15.         }
    16.         // Vertex lights
    17.         Pass {
    18.             Tags {"LightMode" = "Vertex"}
    19.             ZWrite On
    20.             Lighting On
    21.             SeperateSpecular On
    22.             Material {
    23.                 Diffuse [_Color]
    24.                 Ambient [_Color]
    25.                 // Emission [_PPLAmbient]
    26.             }
    27.             SetTexture [_MainTex] {
    28.                 ConstantColor [_Color]
    29.                 Combine texture * primary DOUBLE, texture * constant
    30.             }
    31.         }
    32.     }
    33.     FallBack "Diffuse", 1
    34. }
     
  3. windmaomao

    windmaomao

    Joined:
    Jun 11, 2009
    Posts:
    50
    hi Daniel,

    thank you very much. Another newbie question, is this supposed to be applied to the wall, right ? And how do I make the switch from show-through to no show-through? I actually just start to read the shaderlib manual.

    Fang
     
  4. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    That shader goes on things that you want to appear through walls. The trick is that it has two Pass blocks, one of which uses ZTest LEqual to only draw in front of things, and one which uses ZTest Greater to only draw when it is behind things. Thus for every pixel, the model will be drawn using one pass or the other, but never both. The Queue = Geometry+5 tag makes sure that objects with this shader wait until everything else is drawn so that they can decide whether they are behind or in front of something.
     
  5. windmaomao

    windmaomao

    Joined:
    Jun 11, 2009
    Posts:
    50
    oh, man, this sounds exactly I wanted, I'll test it tonight. thanks you very much Daniel, you made the task trivial now :)
     
  6. windmaomao

    windmaomao

    Joined:
    Jun 11, 2009
    Posts:
    50
    Thanks Daniel, I just tested, it works perfect, when the object under shader is behind something, it's plotted using a blue color. Awesome. I'm sure this shader can turn into other kool stuff as well.
     
  7. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Daniel, that's really cool. Thanks for giving me ideas!

    Do you have any method to turn objects transparent only when certain meshes go behind them? (e.g. the player character)? I really like this effect in games. Seems like a much more complicated situation, but I've seen it a lot, so perhaps there is a common solution?
     
  8. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    You mean turning a wall transparent when it blocks the camera's view of the player? That can be done with a script that casts a ray at the player and modifies the materials of whatever it hits. I believe there was a script in the Goober demo from way back when that did that. I'm not sure if there's an equivalent script in the Lerpz tutorial.
     
  9. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    I figured that was how it needed to be done. But I hadn't thought of what you posted in this thread, so I didn't know if there was some shader trick I didn't know about, to "automate" this.
     
  10. rylmtn

    rylmtn

    Joined:
    Nov 18, 2017
    Posts:
    1
    I'm new to unity and trying to use this code but I keep getting and error on the first lane saying 'Shader' unexpected symbol. Any tips on how to fix this? or am I just creating the shader wrong?
     
  11. Balikk

    Balikk

    Joined:
    Oct 23, 2014
    Posts:
    49
    Hi @rylmtn ,

    I think you made a little mistake. You created a " C# " script and not a " shader => standard surface shader " to paste this code.
     
  12. ediit

    ediit

    Joined:
    Mar 17, 2018
    Posts:
    8
    I'm trying to use this shader for an object lit by light probes and the model appears black. Does anyone know how to integrate light probe info into this?
     
  13. blafed

    blafed

    Joined:
    Sep 24, 2015
    Posts:
    5
    good solution but i want to make show only outline without filling
     
  14. Max_power1965

    Max_power1965

    Joined:
    Oct 31, 2013
    Posts:
    127
  15. unity_6tCHBIs4NsVEUQ

    unity_6tCHBIs4NsVEUQ

    Joined:
    Nov 12, 2021
    Posts:
    1
    I want to turn the Lighting off to have it be fullbright but when i do that it is not coloured anymore
     
  16. exhuman

    exhuman

    Joined:
    Sep 27, 2019
    Posts:
    5
    If you want to use the shader on 2nd reply for many (semi-) transparent models in the same scene (eg a party of characters going behind a wall at the same time) keep in mind that you are going to run into drawing order problems, since the render queue used is opaque and Unity sorts front-to-back by default in these queues.

    For correct transparency, apart from a suitable blend mode, you also need to use a back-to-front sorting render queue (eg Transparent). But if you try to do this with a separate transparent material, the triangles on the back of your model will mess everything up since they will always render because they will pass the "ZTest Greater" depth test (they are occluded by the geometry of the same mesh in front of them).

    A solution to this situation is to use stencils: have a stencil-only pre-pass in your opaque shader and "flag" the pixels that will need to be transparent:
    Code (CSharp):
    1.  Pass {
    2.          
    3.             ZWrite Off        //we MUST NOT write to depth buffer (else below passes will also render)!
    4.             ZTest Greater    //depth test will succeed when geometry is occluded
    5.             ColorMask 0        //do not write anything on screen!
    6.  
    7.             Stencil
    8.             {
    9.                 Ref 1            //value that will be written to stencil buffer
    10.                 Comp Always        //stencil test will always succeed
    11.                 Pass Replace    //if depth test succeeds write ref value
    12.             }
    13.         }
    When your transparent material renders later on, perform a stencil test against the same reference value:

    Code (CSharp):
    1.  Pass
    2.         {
    3.             ZTest Greater                   //we still need this as depth test will always happen after stencil test
    4.             ZWrite Off                      //do not write anything to z-buffer (else geometry behind ours won't render)
    5.             Blend SrcAlpha OneMinusSrcAlpha //classic transparency blend mode
    6.  
    7.             Stencil
    8.             {
    9.                 Ref 1      
    10.                 Comp Equal  //if stencil buffer for this pixel equals our flag value then stencil test succeeds
    11.                 Pass Keep   //do not do anything if depth + stencil tests succeeds (stencil buffer will be cleared anyway next frame)
    12.             }
    13.             CGPROGRAM
    14.             //your shader here
    15.             ENDCG
    16.         }
    17.  
     
    Last edited: Jul 19, 2023