Search Unity

Stealth Shader

Discussion in 'Shaders' started by gamesurgeon, Jan 20, 2011.

  1. gamesurgeon

    gamesurgeon

    Joined:
    Oct 11, 2009
    Posts:
    427
    Hello, I am making a game that involves a character going into stealth. When in stealth, the character is semi-transparent, but is undetected by AI, yada, yada, yada.

    I was having problems with Unity's transparent shader, so I looked around and found a great shader from the community at: http://www.unifycommunity.com/wiki/index.php?title=AlphaVertexLitZ

    Unfortunately, I am having two problems:

    1) This shader does not take Unity's Depth of Field camera shader into account.

    2) At times, my character's hood is more transparent than my character's face (depending on the angle), which allows the player to see my character's face.

    I have attached two images that better describe my situation. If anyone knows how to fix this, I am willing to pay for the help.

    Thank you in advance!
     

    Attached Files:

    • $DOF.PNG
      $DOF.PNG
      File size:
      536.6 KB
      Views:
      2,229
    • $Head.png
      $Head.png
      File size:
      521.6 KB
      Views:
      2,078
  2. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Do you have multiple meshes/submeshes? If not, it can only be because of ColorMask 0 not working, which a couple people told me was a problem, on Windows – I don't know if this bug has been fixed yet. If so, then put your hood into an earlier queue than your head.

    Also, this method is inefficient if you're just going to have the same alpha value over the whole mesh, like the wiki shows (not the best example). Do you actually need the alpha channel UV mapped, or will a single value suffice?

    Unfortunately, I don't know how to help you with depth of field.
     
  3. gamesurgeon

    gamesurgeon

    Joined:
    Oct 11, 2009
    Posts:
    427
    Hey Jessy, thanks for responding!

    I do have multiple meshes -- I believe 4: cape, body, face, swords. I must admit I am a tad bit lost, but I think I will only need one single value. The entire character just needs to be semi-transparent -- I'm not trying to do anything *too* fancy!

    Out of curiosity, would you (or anyone else) know if it's Unity's D.O.F. shader that would need tweaking, or the transparent shader that would need tweaking?

    Thanks for all the help. I sincerely appreciate you taking your time to help out!
     
  4. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    In that case, you need to use two materials on each. It shouldn't be any slower; you'll still use the same number of passes; you just need to utilize different queues, and a shader can only be in one.

    Make a single material from this shader, and use that material on each of the meshes:
    Code (csharp):
    1. Shader "Transparent/VertexLit with Z/ZWrite" {
    2.    
    3. SubShader {
    4.     Tags {"Queue" = "Transparent-1"}
    5.     Pass {ColorMask 0} 
    6. }
    7.  
    8. }
    Then, make a different material for each mesh, using this shader:
    Code (csharp):
    1. Shader "Transparent/VertexLit with Z/RGB" {
    2.    
    3. Properties {
    4.     _Color ("Color  (A = Opacity)", Color) = (1,1,1,1)
    5.     _MainTex ("Texture", 2D) = "white"
    6. }
    7.  
    8. SubShader {
    9.     Tags {"RenderType"="Transparent" Queue = Transparent}
    10.     ZWrite Off
    11.     Blend SrcAlpha OneMinusSrcAlpha
    12.     ColorMask RGB
    13.        
    14.     Lighting On
    15.     Material {
    16.         Diffuse [_Color]
    17.         Ambient [_Color]
    18.     }
    19.  
    20.     Pass {
    21.         SetTexture [_MainTex] {Combine texture * primary Double, primary}
    22.     }
    23. }
    24.  
    25. }
    I also modified the second shader to use the alpha of "Color". Just use an RGB texture now instead of texture alpha.

    I'm sure somebody else might. ;)
     
  5. gamesurgeon

    gamesurgeon

    Joined:
    Oct 11, 2009
    Posts:
    427
    Wow!

    Thank you SO much, Jessy. You really helped me out there. I definitely owe you one!

    If anyone else has a clue regarding the D.O.F. shader, feel free to chime in :)

    Again, thank you a lot, Jessy. That was very, very, very helpful!
     
  6. gamesurgeon

    gamesurgeon

    Joined:
    Oct 11, 2009
    Posts:
    427
    I was browsing through the DepthOfField.js script I am using for my camera (Unity Pro only), and I came across this:

    // we use the alpha channel for storing the COC
    // which also means, that unfortunately, alpha based
    // image effects such as sun shafts, bloom or glow
    // won't work if placed *after* the DOF image effect

    Does this mean that my alpha shader is happening AFTER the DepthOfField script is run? If so, is there a way to change this?
     
  7. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    I don't know. Find out if depth of field has anything to do with rendering queues or the alpha already written to the screen. We can easily modify those shaders to deal with either.
     
  8. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    The depth of field shader uses the Z buffer to determine what to blur. Because it is a postprocess, it can only "see" the front-most depth for any given pixel. Because your character is drawn with Z writing enabled, those pixels are considered in focus. If your character did not write to the Z buffer, his pixels would be considered part of the background, and blurred heavily.

    What you want in this situation is actually to composite your character after the DOF effect. This would mean writing an image effect that came afterwards, and rendered your character in a separate buffer. That would probably work quite well, assuming your character is always in focus, but it means learning about image effects and compositing with shaders.
     
  9. gamesurgeon

    gamesurgeon

    Joined:
    Oct 11, 2009
    Posts:
    427
    Wow, that sounds a little too complex for me (as I said before, I barely know syntax for shaders!)

    Jessy, is there a way to combine the Vertex Lit with RGB with a bump map? My character has a normal map for his armor, which I would like to use. If it is complicated, though, then I'd rather not fix what is not broken.

    Thanks for the help guys!
     
  10. MarkPixel

    MarkPixel

    Joined:
    Apr 15, 2010
    Posts:
    39
    hey gamesurgeon,

    maybe this shader can help you.

    It's a Diff-Tex, NormMap, Alpha-Slider, pretty easy.

    Please give a response, if it fits your need - i'm quite new into coding. But for me this one helped.
    Would be great to hear if it works for chars as well.
     

    Attached Files:

    Last edited: Jan 23, 2011
  11. gamesurgeon

    gamesurgeon

    Joined:
    Oct 11, 2009
    Posts:
    427
    Thanks a bunch MarkPixel! That works! I just need to adjust it to work with my code.

    Again, thank you very much!
     
  12. MarkPixel

    MarkPixel

    Joined:
    Apr 15, 2010
    Posts:
    39
  13. QuantumCalzone

    QuantumCalzone

    Joined:
    Jan 9, 2010
    Posts:
    262
    Very cool!
     
  14. Rs

    Rs

    Joined:
    Aug 14, 2012
    Posts:
    74
  15. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    You sort of answered your own question in the post there;
    ZWrite Off

    That means your shader doesn't write to your zbuffer, so Unity won't know it's in the Z buffer in order to blur it.

    You can try adding a pass before (or after - if you want to see bits of your character through other bits of your character) your current pass that reads;
    Code (csharp):
    1.  
    2. Pass {
    3. ColorMask 0
    4. }
    5.  
    That pass will write to the ZBuffer but nothing else.

    Then change the

    Tags { "RenderType"="Transparent" "Queue"="Transparent" }

    to

    Tags { "RenderType"="TransparentCutout" "Queue"="Transparent" }
     
    Last edited: Apr 15, 2013
  16. Rs

    Rs

    Joined:
    Aug 14, 2012
    Posts:
    74
    Hi Farfarer,
    thank you very much for your answer. Unfortunately the Cutout doesn't work for me. I really need the alpha to be smooth and based on UV mapping. I tried also to add the pass you suggest but I had really weird "shuttered" transparencies.
    The shader I shared in the post is not the only one doing this. Most of the Transparent built in shaders do the same thing.
    Any futher ideas?
     
  17. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Anything transparent will not write to the ZBuffer and therefore will not be blurred by DOF accurately as it uses the depth buffer to do so.

    Does the Unity DOF use a replacement shader for that stuff? If so, you might need to add your own passes to it to render things correctly.