Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Shadows for CG Shader

Discussion in 'Unity 5 Pre-order Beta' started by Phantomx, Feb 19, 2015.

  1. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    Hey,
    How do you receive shadows with a custom CG shader in unity 5? I looked at the built-in shaders like Legacy/VertexLit it does cast shadows on a surface shader, but is not receiving any and doesn't have SHADOWCOLLECTOR pass.

    Thanks!
     
  2. Jde

    Jde

    Joined:
    Oct 2, 2011
    Posts:
    139
    You need to use these in your CG shader...

    #pragma multi_compile_fwdbase
    #include "UnityCG.cginc"
    #include "AutoLight.cginc"
    LIGHTING_COORDS(x,x)
    TRANSFER_VERTEX_TO_FRAGMENT(x)
    LIGHT_ATTENUATION(x)

    Here's where you put them...

    Code (CSharp):
    1. Shader "Albedo With Shadows"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Base (RGB)", 2D) = "white" {}
    6.     }
    7.  
    8.     SubShader
    9.     {
    10.         Tags { "RenderType" = "Opaque" }
    11.      
    12.         Pass
    13.         {
    14.             Tags { "LightMode" = "ForwardBase" }
    15.          
    16.             CGPROGRAM
    17.  
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.             #pragma multi_compile_fwdbase
    21.          
    22.             #include "UnityCG.cginc"
    23.             #include "AutoLight.cginc"
    24.  
    25.             sampler2D _MainTex;
    26.  
    27.             struct v2f_full
    28.             {
    29.                 float4 pos : SV_POSITION;
    30.                 float2 uv : TEXCOORD0;
    31.                 LIGHTING_COORDS(1,2)
    32.             };
    33.  
    34.             float4 _MainTex_ST;
    35.          
    36.             v2f_full vert (appdata_full v)
    37.             {
    38.                 v2f_full o;
    39.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    40.                 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    41.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    42.                 return o;
    43.             }      
    44.          
    45.             fixed4 frag (v2f_full i) : COLOR0
    46.             {
    47.                 fixed4 tex = tex2D (_MainTex, i.uv);
    48.                 tex.rgb *= LIGHT_ATTENUATION(i);
    49.                 return tex;
    50.             }
    51.          
    52.             ENDCG
    53.         }
    54.     }
    55. Fallback "Legacy Shaders/VertexLit"
    56. }
     
    seattlebluesky likes this.
  3. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    Thanks for the help, this does work if I want basic lighting, but how to do it for a custom lighting? Also this is not working with the light color.

    Basically I have this shader and I want it to receive shadows.

    Code (CSharp):
    1.  
    2. Shader "Mobile/DS (CG)" {
    3. Properties
    4. {
    5.     _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
    6.     _Shininess("SpecPower",Range(0.1,1)) = 0.5
    7.     _SpecColor("Spec Color",Color) = (1,1,1,1)
    8. }
    9.  
    10. SubShader
    11. {  
    12.     Pass{
    13.    
    14.         Tags{
    15.             "LightMode" = "ForwardBase"
    16.             "Queue"="Geometry"
    17.             "IgnoreProjector"="False"
    18.             "RenderType"="Opaque"
    19.         }
    20.        
    21.         CGPROGRAM
    22.         #pragma vertex vert
    23.         #pragma fragment frag
    24.         #pragma fragmentoption ARB_precision_hint_fastest
    25.  
    26.         #include "unityCG.cginc"
    27.        
    28.        
    29.     sampler2D _MainTex;
    30.         fixed4 _MainTex_ST;
    31.         float _Shininess;
    32.         fixed4 _SpecColor;
    33.        
    34.         uniform fixed4 _LightColor0;
    35.  
    36.         struct vertexInput{
    37.             half2 texcoord     : TEXCOORD0;
    38.             half2 texcoord1 : TEXCOORD1;
    39.             float4 vertex     : POSITION;
    40.             float3 normal     : NORMAL;
    41.         };
    42.        
    43.         struct vertexOutput{
    44.             float4 pos         : SV_POSITION;
    45.             half2 uv         : TEXCOORD0;
    46.             half3 normalDir : TEXCOORD2;
    47.             half3 viewDir     : TEXCOORD3;
    48.             half3 lightDir     : TEXCOORD4;
    49.         };
    50.        
    51.        
    52.         vertexOutput vert(vertexInput v) {
    53.             vertexOutput o;
    54.            
    55.             o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
    56.             o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    57.  
    58.             //Directions
    59.             o.normalDir =         normalize( mul(float4(v.normal,0.0), _World2Object).xyz);
    60.             o.viewDir     =         normalize(WorldSpaceViewDir(v.vertex));
    61.             o.lightDir     =         normalize(ObjSpaceLightDir(v.vertex));
    62.            
    63.             return o;
    64.            
    65.         }
    66.        
    67.         fixed4 frag(vertexOutput i):COLOR
    68.         {
    69.             fixed4 tex = tex2D(_MainTex, i.uv);
    70.            
    71.             //LIGHTING
    72.             float atten = 2.0;
    73.             fixed3 NdotL = max( 0.0 ,dot(i.normalDir,i.lightDir) * 0.5 + 0.5);
    74.             fixed3 NdotH = max(0.0, dot(i.normalDir,normalize(i.lightDir + i.viewDir)));
    75.            
    76.             fixed3 diff = atten * _LightColor0.rgb * NdotL;
    77.             fixed3 spec = atten * _LightColor0.rgb * _SpecColor * pow(NdotH,_Shininess * 128.0);
    78.            
    79.             fixed3 finalLight = diff + UNITY_LIGHTMODEL_AMBIENT.rgb;
    80.            
    81.             fixed4 c;
    82.             c.rgb     = tex.rgb * finalLight + (spec * tex.a);
    83.             c.a     = tex.a;
    84.  
    85.             return c;
    86.         }
    87.        
    88.         ENDCG
    89.     }
    90. }
    91. FallBack "Diffuse"
    92. }
     
  4. Jde

    Jde

    Joined:
    Oct 2, 2011
    Posts:
    139
    Not sure what you mean exactly by custom lighting. Do you mean this line?...
    Code (CSharp):
    1. fixed3 NdotL = max( 0.0 ,dot(i.normalDir,i.lightDir) * 0.5 + 0.5);
    Looks like that's fudging the lighting towards the light direction. You'll probably need to add the shadows in there like this...
    Code (CSharp):
    1. fixed3 NdotL = min(max( 0.0 ,dot(i.normalDir,i.lightDir) * 0.5 + 0.5), (LIGHT_ATTENUATION(i) * 0.5 + 0.5));
    As for light colour, that works ok for me. The _LightColor0 comes through fine.
     
  5. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    This was more like an exemple, I mean if I want to do BRDF or stuff like that. So I just multiplied c.rgb * LIGHT_ATTENUATION(i) at the end and it's working. shadows are way darker than on a surface shader but I can work with that if there's no alternative.

    Thanks!
     
  6. Jde

    Jde

    Joined:
    Oct 2, 2011
    Posts:
    139
    You'll need to add the ambient lighting after the shadows, that's probably why it's darker. Using UNITY_LIGHTMODEL_AMBIENT will work but the better way is to use ShadeSH9(worldSpaceNormal).
     
  7. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    Got it thanks!