Search Unity

Shader for displaying self-shadow without rendering the actual object.

Discussion in 'Shaders' started by the_gnoblin, Oct 25, 2010.

  1. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    Hello!

    I'd like to show how object is shadowed, but without rendering the actual shader.

    How can this problem be approached?

    thanks
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Can you better explain what you want, perhaps with a reference picture or drawing?
     
  3. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    here it is
     

    Attached Files:

  4. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    Oops.
    By "but without rendering the actual shader" I really meant "but without rendering the actual object"
     
  5. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
  6. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    I've found this 2.x shader in a similar topic.

    Is it possible to convert it to surface shader for 3.0?

    Code (csharp):
    1. Shader "FX/Matte Shadow" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5.    
    6. }
    7.  
    8. Category {
    9.    
    10.     Tags {"Queue"="Geometry+500"}
    11.     LOD 200
    12.     Alphatest Greater 0
    13.     ZWrite Off
    14.     AlphaToMask True
    15.     ColorMask RGB
    16.     Fog { Color [_AddFog] }
    17.     Blend DstColor Zero
    18.    
    19.     SubShader {
    20.        
    21.         Pass { 
    22.             Tags { "LightMode" = "Pixel" }
    23.  
    24. CGPROGRAM
    25. #pragma fragment frag
    26. #pragma vertex vert
    27. #pragma multi_compile_builtin
    28. #pragma fragmentoption ARB_fog_exp2
    29. #pragma fragmentoption ARB_precision_hint_fastest
    30. #include "UnityCG.cginc"
    31. #include "AutoLight.cginc"
    32.  
    33. struct v2f {
    34.     V2F_POS_FOG;
    35.     LIGHTING_COORDS
    36.     float2  uv;
    37.     float3  normal;
    38.     float3  lightDir;
    39. };
    40.  
    41. uniform float4 _MainTex_ST;
    42.  
    43. v2f vert (appdata_base v)
    44. {
    45.     v2f o;
    46.     PositionFog( v.vertex, o.pos, o.fog );
    47.     o.normal = v.normal;
    48.     o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
    49.     o.lightDir = ObjSpaceLightDir( v.vertex );
    50.     TRANSFER_VERTEX_TO_FRAGMENT(o);
    51.     return o;
    52. }
    53.  
    54. uniform sampler2D _MainTex;
    55. uniform float4 _Color;
    56.  
    57. float4 frag (v2f i) : COLOR
    58. {
    59.     half4 c = _Color * 4 * LIGHT_ATTENUATION(i);
    60.     c.a = (1-LIGHT_ATTENUATION(i));
    61.     return c;
    62. }
    63. ENDCG
    64.  
    65.         }
    66.     }
    67. }
    68.  
    69. Fallback "Transparent/Cutout/VertexLit", 2
    70.  
    71. }
    I suppose this is the most important part:
    Code (csharp):
    1. half4 c = _Color * 4 * LIGHT_ATTENUATION(i);
    2.     c.a = (1-LIGHT_ATTENUATION(i));
    3.     return c;
    but I'm not yet sure how to attempt to use LIGHT_ATTENUATION in a surface shader :)
     
  7. jcarpay

    jcarpay

    Joined:
    Aug 15, 2008
    Posts:
    561
    I'm interested in this as well.
     
  8. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    This doesn't work if placed against skybox (probably can be fixed).
    And I think it will work only with forward rendering (because custom lighting model for deferred rendering is not specified). But what is actually important that it works :D.

    Testing and comments are appreciated. Thanks.

    Code (csharp):
    1. Shader "MatteShadowCustModel" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5.     _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    6. }
    7.  
    8. SubShader {
    9.     Tags {"IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    10.     LOD 200
    11.    
    12. CGPROGRAM
    13. #pragma surface surf SimpleLambert alphatest:_Cutoff
    14.  
    15. sampler2D _MainTex;
    16. float4 _Color;
    17.  
    18. struct Input {
    19.     float2 uv_MainTex;
    20. };
    21.  
    22.  half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
    23.           half NdotL = dot (s.Normal, lightDir);
    24.           half4 c;
    25.           c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2); //half3(atten, atten, atten);//
    26.           c.a = s.Alpha;
    27.           return c;
    28.       }
    29.  
    30. void surf (Input IN, inout SurfaceOutput o) {
    31.     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    32.     o.Albedo = c.rgb;
    33.     o.Alpha = 0.25;
    34.    
    35. }
    36. ENDCG
    37. }
    38.  
    39. Fallback "Transparent/Cutout/VertexLit"
    40. }
     
  9. tokyob

    tokyob

    Joined:
    May 17, 2010
    Posts:
    37
  10. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    Yeah, I know about GrabPass.

    I am not sure how performant it is + I also need a shade on the object (not only the shadow produced by it).

    (and I suppose the shader in my previous post is almost what I need)

    thanks).
     
  11. jcarpay

    jcarpay

    Joined:
    Aug 15, 2008
    Posts:
    561
    Nice job!
    It would be great if it worked against a skybox.
    Another thing, disabling the receive shadow option seems to be ignored by the shader.
     
    Last edited: Nov 5, 2010
  12. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    Thanks for the feedback!
    One more interesting thing to check is if this shader can receive a shadow cast by another object.
     
  13. jcarpay

    jcarpay

    Joined:
    Aug 15, 2008
    Posts:
    561
    Yes it does receive shadows casted by other objects. However, it can't stop receiving shadows since disabling the receive shadow option is ignored by this shader.

    Also, would it be possible to have the shader render a true matte, without any shading?
     
    Last edited: Nov 5, 2010
  14. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    > However, it can't stop receiving shadows since disabling the receive shadow option is ignored by this >shader.
    I am going to add an option in shader properties for that.

    > Also, would it be possible to have the shader render a true matte, without any shading?
    I am not sure I understand what you mean ;)
     
  15. jcarpay

    jcarpay

    Joined:
    Aug 15, 2008
    Posts:
    561
    Nevermind, my mistake ;)

    How about getting it to work against a skybox, would that be possible to add?
     
  16. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    Here's a bit simplified version (works the same way).

    Still thinking about skybox.

    Code (csharp):
    1. Shader "MatteShadowCustModel2" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.    
    5.     _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    6. }
    7.  
    8. SubShader {
    9.     Tags {"IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    10.     LOD 200
    11.    
    12. CGPROGRAM
    13. #pragma surface surf SimpleLambert alphatest:_Cutoff
    14.  
    15.  
    16. float4 _Color;
    17.  
    18. struct Input {
    19.     float2 uv_MainTex;
    20. };
    21.  
    22.  half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
    23.          
    24.           half4 c;
    25.           c.rgb = s.Albedo;
    26.           c.a = 0;
    27.          
    28.           return c;
    29.       }
    30.  
    31. void surf (Input IN, inout SurfaceOutput o) {
    32.    
    33.     o.Albedo = _Color.rgb;
    34.     o.Alpha = 0.25;
    35.    
    36. }
    37. ENDCG
    38. }
    39.  
    40. Fallback "Transparent/Cutout/VertexLit"
    41. }
     
  17. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    Ok, I think it may be possible to use this shader with skybox made of an inverted cube.
    I don't know how to make it work with the standard skybox ).

    I also haven't found a way to disable receiving shadows, so this shader (from GrabPass page of the manual) can be used instead:

    Code (csharp):
    1. Shader "Shadow" {
    2.  Properties {
    3.   _MainTex ("Base (RGB)", 2D) = "white" {}
    4.  }
    5.  SubShader {
    6.  
    7.     Tags { "Queue" = "Transparent" }
    8.  
    9.    // Grab the screen behind the object into _GrabTexture, using default values
    10.         GrabPass { }
    11.  
    12.         // Render the object with the texture generated above.
    13.         Pass {
    14.             SetTexture [_GrabTexture] { combine texture }
    15.         }
    16.  
    17.  }
    18.  FallBack "Diffuse"
    19. }
    I haven't tested the performance of it yet.
     
  18. tokyob

    tokyob

    Joined:
    May 17, 2010
    Posts:
    37
    you can have somthing like that with the grabPass and a simple shader: (cf attached file)

    here is the simple code:

    Code (csharp):
    1.  
    2. Shader "matShadow" {
    3.     Properties {
    4.         _Color ("Main Color", Color) = (1,1,1,0)
    5.     }
    6.        
    7.        
    8.     SubShader {
    9.  
    10.         // Grab the screen behind the object into _GrabTexture, using default values
    11.         GrabPass { }
    12.  
    13.         // Render the object with the texture generated above.
    14.         Pass {
    15.         Material {
    16.                 Diffuse [_Color]
    17.  
    18.                }
    19.        
    20.           Lighting On
    21.           SetTexture [_GrabTexture] {
    22.                 Combine texture * primary DOUBLE, texture * primary
    23.               }
    24.        }
    25.        
    26.     }
    27.  
    28.     FallBack "Diffuse"
    29. }
    you can enance it by limiting the effect of ligthning adding some coef to remove the "diffuse effect" keeping only the shadow darkening (but i think you must do it in cg.)
     

    Attached Files:

  19. wimeck

    wimeck

    Joined:
    May 26, 2008
    Posts:
    50
    Hi there,

    So right now object A is invisible, but you see its shadow being projected on object B. Nice!
    But would it also be possible that if object A casts a shadow on object B, you won't see object B itself, but only the shadow which is being cast upon it?

    This link (also mentioned before in this thread) http://forum.unity3d.com/threads/14438-Matte-Shadow?highlight=matte+shadow does what I try to describe, but only for Unity 2.x
     
  20. taoa

    taoa

    Joined:
    Dec 10, 2009
    Posts:
    88
    Why not just using the same shader on object B then? :confused:
     
  21. kraemology

    kraemology

    Joined:
    Oct 20, 2010
    Posts:
    20
    Although no one has posted in this thread for over a month, I've run into an interesting issue, so I figured I'd post it and see if anyone had any thoughts or solutions. The shader currently functions (to a degree anyway), but the shadows severly degrade when additional objects are put into the scene. I've attached an image that illustrates exactly what I'm talking about.

    In the left most image I have 2 planes (one in the distance and one under the sphere). In the middle image the ground plane is hidden and the shadows are a little better. On the far right I have also hidden the plane in the back, which makes the shadows more accurate. Why is this happening? Also, under normal circumstances the sphere is transparent and only the shadows are visible, but I reset the alpha because otherwise the right image would be entirely blank (I'm guessing this is related to the skycube issue people were having).

    Has anyone else run into this issue of shadow degradation? Any help would be appreciated. Thanks in advance
     

    Attached Files:

  22. wannabeartist

    wannabeartist

    Joined:
    Jun 20, 2009
    Posts:
    272
    Anyone working on this anymore?

    I wonder if it's possible to get the shader working with deferred lighting as well?
     
  23. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    I had to do this recently, it was really simple.

    Shadow Matte (only renders shadows falling on the object - make sure renderer has receive shadows on and cast shadows off).

    Code (csharp):
    1. Shader "Custom/Shadow Matte" {
    2.  
    3.  
    4.     SubShader {
    5.    
    6.         Tags {"Queue"="Geometry" "IgnoreProjector"="False" "RenderType"="Geometry"}
    7.        
    8.         Lighting On
    9.         blend One One
    10.        
    11.         Pass {
    12.    
    13.             CGPROGRAM
    14.             #pragma vertex vert
    15.             #pragma fragment frag : Alpha
    16.             #include "UnityCG.cginc"
    17.  
    18.             struct v2f {
    19.                 float4 pos      : SV_POSITION;
    20.             };
    21.        
    22.             struct appdata {
    23.                 float4 vertex    : POSITION;
    24.             };
    25.  
    26.        
    27.             float4 _GrassTex_ST;
    28.             uniform float3x3 _Object2WorldR;
    29.            
    30.             v2f vert (appdata v) {
    31.            
    32.                 v2f o;
    33.                 o.pos      = mul(UNITY_MATRIX_MVP, v.vertex);
    34.                 return o;
    35.             }
    36.            
    37.             fixed4 frag (v2f i) : COLOR {
    38.                 fixed4 color;
    39.                 color.rgb = fixed3(0,0,0);
    40.                 color.a = 0;
    41.                 return color;
    42.             }
    43.            
    44.             ENDCG
    45.    
    46.         }
    47.     }
    48.    
    49.     Fallback "VertexLit"
    50. }
    And a shadow only shader - object itself will be invisible but it will cast a shadow (great for doing really creepy horror game effects). Make sure cast shadows is on - doesn't matter if receive shadows is on as lighting is disabled for this shader so they won't render anyway.

    Code (csharp):
    1. Shader "Custom/Shadow" {
    2.  
    3.  
    4.     SubShader {
    5.    
    6.         Tags {"Queue"="Transparent+1" "IgnoreProjector"="True" "RenderType"="Transparent"}
    7.        
    8.         Lighting Off
    9.         blend One One
    10.        
    11.         Pass {
    12.    
    13.             CGPROGRAM
    14.             #pragma vertex vert
    15.             #pragma fragment frag : Alpha
    16.             #include "UnityCG.cginc"
    17.  
    18.             struct v2f {
    19.                 float4 pos      : SV_POSITION;
    20.             };
    21.        
    22.             struct appdata {
    23.                 float4 vertex    : POSITION;
    24.             };
    25.  
    26.        
    27.             float4 _GrassTex_ST;
    28.             uniform float3x3 _Object2WorldR;
    29.            
    30.             v2f vert (appdata v) {
    31.            
    32.                 v2f o;
    33.                 o.pos      = mul(UNITY_MATRIX_MVP, v.vertex);
    34.                 return o;
    35.             }
    36.            
    37.             fixed4 frag (v2f i) : COLOR {
    38.                 fixed4 color;
    39.                 color.rgb = fixed3(0,0,0);
    40.                 color.a = 0;
    41.                 return color;
    42.             }
    43.            
    44.             ENDCG
    45.    
    46.         }
    47.     }
    48.    
    49.     Fallback "VertexLit"
    50. }
    Disclaimer: Only tested in Unity 3.x with realtime shadows in forward mode. Probably won't work at all with beast or anything like that.
     
    zelderus likes this.
  24. 3DJayC

    3DJayC

    Joined:
    Jul 29, 2014
    Posts:
    33
    Hello!

    I re-up this thread 3 years later!

    I was looking for some kind of shader which simulates Matte shadow...

    I tested this one, It works fine but I'd like to know how can I adjust the shadow opacity?
    Right now it's completly black. (I mean the shadow aera)

    Many thanks.

    JC