Search Unity

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.