Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

I put a shadowCollector pass in my shader,but why does it cant recieves shadow,why?

Discussion in 'Shaders' started by Lulucifer, Nov 25, 2012.

  1. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    I put a shadowCollector pass in my shader,but why does it cant recieves shadow,why?
    what happens,
     
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I'd need to see your code to be sure.
     
  3. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Code (csharp):
    1.  
    2. Shader "Tut/Shadow/Collector_0" {
    3. Properties {
    4.     _MainTex ("Base (RGB)", 2D) = "white" {}
    5. }
    6.  
    7. SubShader {
    8.     //pass to render object
    9.     pass{
    10.         CGPROGRAM
    11.         #pragma vertex vert
    12.         #pragma fragment frag
    13.         #include "UnityCG.cginc"
    14.  
    15.         struct vertOut {
    16.             float4 oPos:SV_POSITION;
    17.         };
    18.         vertOut vert(appdata_base v)
    19.         {
    20.             vertOut o;
    21.             float4 pos=mul(UNITY_MATRIX_MVP,v.vertex);
    22.             o.oPos=pos;
    23.             return o;
    24.         }
    25.         float4 frag(vertOut i):COLOR
    26.         {
    27.             float4 c;
    28.             c=float4(0,1,0,1);
    29.             return c;
    30.         }
    31.         ENDCG
    32.     }
    33.  
    34.     // Pass to render object as a shadow collector
    35.     Pass {
    36.        Name "ShadowCollector"
    37.        Tags { "LightMode" = "ShadowCollector" }
    38.  
    39.        Fog {Mode Off}
    40.        ZWrite On ZTest Less
    41.  
    42.         CGPROGRAM
    43.         // Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct appdata members vertex)
    44.         #pragma exclude_renderers xbox360
    45.         #pragma vertex vert
    46.         #pragma fragment frag
    47.         #pragma fragmentoption ARB_precision_hint_fastest
    48.        
    49.         #define SHADOW_COLLECTOR_PASS
    50.         #include "UnityCG.cginc"
    51.        
    52.         struct appdata {
    53.             float4 vertex;
    54.         };
    55.        
    56.         struct v2f {
    57.             V2F_SHADOW_COLLECTOR;
    58.         };
    59.        
    60.         v2f vert (appdata v)
    61.         {
    62.             v2f o;
    63.             TRANSFER_SHADOW_COLLECTOR(o)
    64.             return o;
    65.         }
    66.        
    67.         half4 frag (v2f i) : COLOR
    68.         {
    69.             SHADOW_COLLECTOR_FRAGMENT(i)
    70.         }
    71.         ENDCG
    72.     }//endpass
    73.     }
    74. }
    75.  
     
  4. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    //here is the screen shot in the game view,the green one
    $ScreenShot.png
     
    Last edited: Nov 25, 2012
  5. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
  6. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    I cant find answers there,there is only a shader cast shadow by Fallback "Diffuse"
     
  7. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    From the built-in shaders, linked here

    http://forum.unity3d.com/threads/2085-Builtin-Unity-shaders-source

    you can find that you need 2 passes to get shadows fully working. One for casting one for recieving.

    The code for that is here:
    Code (csharp):
    1.  
    2.     // Pass to render object as a shadow caster
    3.     Pass {
    4.         Name "ShadowCaster"
    5.         Tags { "LightMode" = "ShadowCaster" }
    6.        
    7.         Fog {Mode Off}
    8.         ZWrite On ZTest LEqual Cull Off
    9.         Offset 1, 1
    10.  
    11.         CGPROGRAM
    12.         #pragma vertex vert
    13.         #pragma fragment frag
    14.         #pragma multi_compile_shadowcaster
    15.         #pragma fragmentoption ARB_precision_hint_fastest
    16.         #include "UnityCG.cginc"
    17.  
    18.         struct v2f {
    19.             V2F_SHADOW_CASTER;
    20.         };
    21.  
    22.         v2f vert( appdata_base v )
    23.         {
    24.             v2f o;
    25.             TRANSFER_SHADOW_CASTER(o)
    26.             return o;
    27.         }
    28.  
    29.         float4 frag( v2f i ) : COLOR
    30.         {
    31.             SHADOW_CASTER_FRAGMENT(i)
    32.         }
    33.         ENDCG
    34.  
    35.     }
    36.    
    37.     // Pass to render object as a shadow collector
    38.     Pass {
    39.         Name "ShadowCollector"
    40.         Tags { "LightMode" = "ShadowCollector" }
    41.        
    42.         Fog {Mode Off}
    43.         ZWrite On ZTest LEqual
    44.  
    45.         CGPROGRAM
    46.         #pragma vertex vert
    47.         #pragma fragment frag
    48.         #pragma fragmentoption ARB_precision_hint_fastest
    49.         #pragma multi_compile_shadowcollector
    50.  
    51.         #define SHADOW_COLLECTOR_PASS
    52.         #include "UnityCG.cginc"
    53.  
    54.         struct appdata {
    55.             float4 vertex : POSITION;
    56.         };
    57.  
    58.         struct v2f {
    59.             V2F_SHADOW_COLLECTOR;
    60.         };
    61.  
    62.         v2f vert (appdata v)
    63.         {
    64.             v2f o;
    65.             TRANSFER_SHADOW_COLLECTOR(o)
    66.             return o;
    67.         }
    68.  
    69.         fixed4 frag (v2f i) : COLOR
    70.         {
    71.             SHADOW_COLLECTOR_FRAGMENT(i)
    72.         }
    73.         ENDCG
    74.  
    75.     }
    76.  
    But you will still not get shadows appearing on your shader without adding in the attenuation/shadow value to your shader, the code for which is in the linked thread I posted earlier.

    Adding it to your code gets you this:
    Code (csharp):
    1.  
    2. Pass{
    3.         CGPROGRAM
    4.         #pragma vertex vert
    5.         #pragma fragment frag
    6.        
    7.         #pragma multi_compile_fwdbase // NEEDED FOR SHADOWS.
    8.        
    9.         #include "UnityCG.cginc"
    10.  
    11.         struct vertOut {
    12.             float4 oPos:SV_POSITION;
    13.             LIGHTING_COORDS(0,1) // NEEDED FOR SHADOWS.
    14.         };
    15.        
    16.         vertOut vert(appdata_base v)
    17.         {
    18.             vertOut o;
    19.             float4 pos=mul(UNITY_MATRIX_MVP,v.vertex);
    20.             o.oPos=pos;
    21.             TRANSFER_VERTEX_TO_FRAGMENT(o); // NEEDED FOR SHADOWS.
    22.             return o;
    23.         }
    24.        
    25.         float4 frag(vertOut i):COLOR
    26.         {
    27.             fixed atten = LIGHT_ATTENUATION(i);// NEEDED FOR SHADOWS.
    28.             float4 c;
    29.             c = float4(0,1,0,1) * atten;
    30.             return c;
    31.         }
    32.         ENDCG
    33.         }
    34.  
    You'll need to add an extra pass for Forward Add, but I'll leave that up to you.
     
  8. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Thanks farfarer,the object applys this shader cast a pretty shadow,but it seems ' LIGHT_ATTENUATION(i)' just returns a constant value in the pass fwdadd,in the pass fwdbase,it seems just return 1.0:(
    here is the two screen shots,the sphere with texture
    $fwdadd.png $fwdbase.png

    Add here is the two pass render object
    Code (csharp):
    1.  
    2.     //pass to render object
    3.     pass{
    4.         CGPROGRAM
    5.         #pragma vertex vert
    6.         #pragma fragment frag
    7.         #pragma multi_compile_fwdbase
    8.         #include "UnityCG.cginc"
    9.         #include "AutoLight.cginc"
    10.        
    11.         sampler2D _MainTex;
    12.        
    13.         struct vertOut {
    14.             float4 pos:SV_POSITION;
    15.             float4 uv;
    16.             LIGHTING_COORDS(0,1)
    17.         };
    18.         vertOut vert(appdata_base v)
    19.         {
    20.             vertOut o;
    21.             o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
    22.             o.uv=v.texcoord;
    23.             TRANSFER_VERTEX_TO_FRAGMENT(o);
    24.             return o;
    25.         }
    26.         float4 frag(vertOut i):COLOR
    27.         {
    28.            
    29.             fixed atten=LIGHT_ATTENUATION(i);
    30.             float4 c;
    31.             c=tex2D(_MainTex,i.uv.xy);
    32.             c=c*atten;
    33.             return c;
    34.         }
    35.         ENDCG
    36.         }//endpass
    37.        
    38.         pass{
    39.         CGPROGRAM
    40.         #pragma vertex vert
    41.         #pragma fragment frag
    42.         #pragma multi_compile_fwdadd
    43.         #include "UnityCG.cginc"
    44.         #include "AutoLight.cginc"
    45.        
    46.         sampler2D _MainTex;
    47.        
    48.         struct vertOut {
    49.             float4 pos:SV_POSITION;
    50.             float4 uv;
    51.             LIGHTING_COORDS(0,1)
    52.         };
    53.         vertOut vert(appdata_base v)
    54.         {
    55.             vertOut o;
    56.             o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
    57.             o.uv=v.texcoord;
    58.             TRANSFER_VERTEX_TO_FRAGMENT(o);
    59.             return o;
    60.         }
    61.         float4 frag(vertOut i):COLOR
    62.         {
    63.            
    64.             fixed atten=LIGHT_ATTENUATION(i);
    65.             float4 c;
    66.             c=tex2D(_MainTex,i.uv.xy);
    67.             c=c*atten;
    68.             return c;
    69.         }
    70.         ENDCG
    71.     }
    72.  
     
    Last edited: Nov 26, 2012
  9. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    In your vertOut struct, you'll need to set the numbers in LIGHTING_COORDS(#,#) to be the next two available texcoords, taking into account any you've added.

    So for your code, you'd have:

    struct vertOut {
    float4 pos : SV_POSITION;
    float4 uv : TEXCOORD0;
    LIGHTING_COORDS(1,2)
    };

    or if you had two UVs, you'd have:

    struct vertOut {
    float4 pos : SV_POSITION;
    float4 uv : TEXCOORD0;
    float4 uv2 : TEXCOORD1;
    LIGHTING_COORDS(2,3)
    };

    or if you had two UVs and light direction, you'd have:

    struct vertOut {
    float4 pos : SV_POSITION;
    float4 uv : TEXCOORD0;
    float4 uv2 : TEXCOORD1;
    float3 lightDir : TEXCOORD2;
    LIGHTING_COORDS(3,4)
    };
     
    a436t4ataf likes this.
  10. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    I did have tried the texcoord numbers,it result the same thing
    Code (csharp):
    1.  
    2. pass{
    3.         CGPROGRAM
    4.         #pragma vertex vert
    5.         #pragma fragment frag
    6.         #pragma multi_compile_fwdbase
    7.         #include "UnityCG.cginc"
    8.         #include "AutoLight.cginc"
    9.        
    10.         sampler2D _MainTex;
    11.        
    12.         struct vertOut {
    13.             float4 pos:SV_POSITION;
    14.             float4 uv:TEXCOORD0;
    15.             LIGHTING_COORDS(1,2)
    16.         };
    17.         vertOut vert(appdata_base v)
    18.         {
    19.             vertOut o;
    20.             o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
    21.             o.uv=v.texcoord;
    22.             TRANSFER_VERTEX_TO_FRAGMENT(o);
    23.             return o;
    24.         }
    25.         float4 frag(vertOut i):COLOR
    26.         {
    27.            
    28.             fixed atten=LIGHT_ATTENUATION(i);
    29.             float4 c;
    30.             c=tex2D(_MainTex,i.uv.xy);
    31.             c=c*atten;
    32.             return c;
    33.         }
    34.         ENDCG
    35.         }//endpass
    36.        
    37.         pass{
    38.         CGPROGRAM
    39.         #pragma vertex vert
    40.         #pragma fragment frag
    41.         #pragma multi_compile_fwdadd
    42.         #include "UnityCG.cginc"
    43.         #include "AutoLight.cginc"
    44.        
    45.         sampler2D _MainTex;
    46.        
    47.         struct vertOut {
    48.             float4 pos:SV_POSITION;
    49.             float4 uv:TEXCOORD0;
    50.             LIGHTING_COORDS(1,2)
    51.         };
    52.         vertOut vert(appdata_base v)
    53.         {
    54.             vertOut o;
    55.             o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
    56.             o.uv=v.texcoord;
    57.             TRANSFER_VERTEX_TO_FRAGMENT(o);
    58.             return o;
    59.         }
    60.         float4 frag(vertOut i):COLOR
    61.         {
    62.            
    63.             fixed atten=LIGHT_ATTENUATION(i);
    64.             float4 c;
    65.             c=tex2D(_MainTex,i.uv.xy);
    66.             c=c*atten;
    67.             return c;
    68.         }
    69.         ENDCG
    70.     }
    71.  
     
  11. gavi

    gavi

    Joined:
    Mar 30, 2013
    Posts:
    10
    It does seem to work in Unity v4_3, but you need to add the tags to the Pass / Passes:
    Tags { "LightMode" = "ForwardBase" }
    etc.

    For one important directional light in Forward rendering:

    Shader "Custom/ShadowsInFwdRenderingVertFrag" {
    Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}//Needed by the Diffuse Fallback
    }
    SubShader {
    Tags { "RenderType"="Opaque" }
    //LOD 200


    Pass{
    Tags { "LightMode" = "ForwardBase" }
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #pragma multi_compile_fwdbase
    #include "UnityCG.cginc"
    #include "AutoLight.cginc"

    struct vertOut {
    float4 pos : SV_POSITION;
    LIGHTING_COORDS(0,1) // NEEDED FOR SHADOWS.
    };

    vertOut vert(appdata_base v)
    {
    vertOut o;
    o.pos= mul(UNITY_MATRIX_MVP, v.vertex);
    TRANSFER_VERTEX_TO_FRAGMENT(o); // NEEDED FOR SHADOWS.
    return o;
    }

    float4 frag(vertOut i):COLOR
    {
    fixed atten = LIGHT_ATTENUATION(i);// NEEDED FOR SHADOWS.
    float4 c;
    c = float4(0,1,0,1) * atten;
    return c;
    }
    ENDCG
    }//Pass



    // Pass to render object as a shadow caster
    Pass {
    Name "ShadowCaster"
    Tags { "LightMode" = "ShadowCaster" }

    Fog {Mode Off}
    ZWrite On ZTest LEqual Cull Off
    Offset 1, 1

    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #pragma multi_compile_shadowcaster
    #pragma fragmentoption ARB_precision_hint_fastest
    #include "UnityCG.cginc"
    #include "AutoLight.cginc"

    struct v2f {
    V2F_SHADOW_CASTER;
    };

    v2f vert( appdata_base v )
    {
    v2f o;
    TRANSFER_SHADOW_CASTER(o)
    return o;
    }

    float4 frag( v2f i ) : COLOR
    {
    SHADOW_CASTER_FRAGMENT(i)
    }
    ENDCG
    } //Pass



    // Pass to render object as a shadow collector
    Pass {
    Name "ShadowCollector"
    Tags { "LightMode" = "ShadowCollector" }

    Fog {Mode Off}
    ZWrite On ZTest LEqual

    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #pragma fragmentoption ARB_precision_hint_fastest
    #pragma multi_compile_shadowcollector

    #define SHADOW_COLLECTOR_PASS
    #include "UnityCG.cginc"

    struct appdata {
    float4 vertex : POSITION;
    };

    struct v2f {
    V2F_SHADOW_COLLECTOR;
    };

    v2f vert (appdata v)
    {
    v2f o;
    TRANSFER_SHADOW_COLLECTOR(o)
    return o;
    }

    fixed4 frag (v2f i) : COLOR
    {
    SHADOW_COLLECTOR_FRAGMENT(i)
    }
    ENDCG
    }//Pass

    } //SubShader
    FallBack "Diffuse" //note: required for passes: ForwardBase, ShadowCaster, ShadowCollector
    }
     
    a436t4ataf and Alex_May like this.