Search Unity

Player Silhouette Shader ignore certain objects

Discussion in 'Shaders' started by MidgardDev, Mar 31, 2015.

  1. MidgardDev

    MidgardDev

    Joined:
    Dec 11, 2012
    Posts:
    47
    Hi there everyone!

    Recently I found a problem in my game where as it's in isometric view, if you standed behind an object, the camera couldn't see the player, so I researched a bit and ended up with a shader that would show the player's silhouette when any geometry would be obstructing the view on him.

    Everything is working really nice, the only problem is that I have some objects that are a children of the player mesh that are getting in the way of that shader, so as they ARE part of the player's transform (but not of the mesh), I would like these objects to not "obstruct" the view.

    Here's a few images:

    Front player view (no problems):




    Perspective player view, the jetpack, that is a children of the player's transform mesh, obstructs the view and shows a part of the player's silhouette:




    This is the code for the shader I'm using (I must say I have no idea on shader programming, so any help or advice would be useful!):
    Code (CSharp):
    1.  
    2.     Shader "Outlined/Silhouetted Diffuse" {
    3.         Properties {
    4.             _Color ("Main Color", Color) = (.5,.5,.5,1)
    5.             _OutlineColor ("Outline Color", Color) = (0,0,0,1)
    6.             _Outline ("Outline width", Range (0.0, 0.03)) = .005
    7.             _MainTex ("Base (RGB)", 2D) = "white" { }
    8.         }
    9.    
    10.     CGINCLUDE
    11.     #include "UnityCG.cginc"
    12.    
    13.     struct appdata {
    14.         float4 vertex : POSITION;
    15.         float3 normal : NORMAL;
    16.     };
    17.    
    18.     struct v2f {
    19.         float4 pos : POSITION;
    20.         float4 color : COLOR;
    21.     };
    22.    
    23.     uniform float _Outline;
    24.     uniform float4 _OutlineColor;
    25.    
    26.     v2f vert(appdata v) {
    27.         // just make a copy of incoming vertex data but scaled according to normal direction
    28.         v2f o;
    29.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    30.    
    31.         float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
    32.         float2 offset = TransformViewToProjection(norm.xy);
    33.    
    34.         o.pos.xy += offset * o.pos.z * _Outline;
    35.         o.color = _OutlineColor;
    36.         return o;
    37.     }
    38.     ENDCG
    39.    
    40.         SubShader {
    41.             Tags { "Queue" = "Transparent" }
    42.    
    43.             // note that a vertex shader is specified here but its using the one above
    44.             Pass {
    45.                 Name "OUTLINE"
    46.                 Tags { "LightMode" = "Always" }
    47.                 Cull Off
    48.                 ZWrite Off
    49.                 ZTest Always
    50.                 ColorMask RGB // alpha not used
    51.    
    52.                 // you can choose what kind of blending mode you want for the outline
    53.                 Blend SrcAlpha OneMinusSrcAlpha // Normal
    54.                 //Blend One One // Additive
    55.                 //Blend One OneMinusDstColor // Soft Additive
    56.                 //Blend DstColor Zero // Multiplicative
    57.                 //Blend DstColor SrcColor // 2x Multiplicative
    58.    
    59.     CGPROGRAM
    60.     #pragma vertex vert
    61.     #pragma fragment frag
    62.    
    63.     half4 frag(v2f i) :COLOR {
    64.         return i.color;
    65.     }
    66.     ENDCG
    67.             }
    68.    
    69.             Pass {
    70.                 Name "BASE"
    71.                 ZWrite On
    72.                 ZTest LEqual
    73.                 Blend SrcAlpha OneMinusSrcAlpha
    74.                 Material {
    75.                     Diffuse [_Color]
    76.                     Ambient [_Color]
    77.                 }
    78.                 Lighting On
    79.                 SetTexture [_MainTex] {
    80.                     ConstantColor [_Color]
    81.                     Combine texture * constant
    82.                 }
    83.                 SetTexture [_MainTex] {
    84.                     Combine previous * primary DOUBLE
    85.                 }
    86.             }
    87.         }
    88.    
    89.         SubShader {
    90.             Tags { "Queue" = "Transparent" }
    91.    
    92.             Pass {
    93.                 Name "OUTLINE"
    94.                 Tags { "LightMode" = "Always" }
    95.                 Cull Front
    96.                 ZWrite Off
    97.                 ZTest Always
    98.                 ColorMask RGB
    99.    
    100.                 // you can choose what kind of blending mode you want for the outline
    101.                 Blend SrcAlpha OneMinusSrcAlpha // Normal
    102.                 //Blend One One // Additive
    103.                 //Blend One OneMinusDstColor // Soft Additive
    104.                 //Blend DstColor Zero // Multiplicative
    105.                 //Blend DstColor SrcColor // 2x Multiplicative
    106.    
    107.                 CGPROGRAM
    108.                 #pragma vertex vert
    109.                 #pragma exclude_renderers gles xbox360 ps3
    110.                 ENDCG
    111.                 SetTexture [_MainTex] { combine primary }
    112.             }
    113.    
    114.             Pass {
    115.                 Name "BASE"
    116.                 ZWrite On
    117.                 ZTest LEqual
    118.                 Blend SrcAlpha OneMinusSrcAlpha
    119.                 Material {
    120.                     Diffuse [_Color]
    121.                     Ambient [_Color]
    122.                 }
    123.                 Lighting On
    124.                 SetTexture [_MainTex] {
    125.                     ConstantColor [_Color]
    126.                     Combine texture * constant
    127.                 }
    128.                 SetTexture [_MainTex] {
    129.                     Combine previous * primary DOUBLE
    130.                 }
    131.             }
    132.         }
    133.    
    134.         Fallback "Diffuse"
    135.     }
    And so, what I tried is to search if shaders could ignore layers or gameobject tags, but that's a Unity only runtime feature, so what I have also tried is to make the player camera ignore a layer where I then put in the objects I want to NOT draw the player's silhouette. But they end up by not rendering (of course, they're not in the culling mask..) so that's everything.

    Again, any help, advice or explanation would be really helpful!

    Thanks for everything beforehand ^^