Search Unity

  1. The 2022.1 beta is now available for testing. To find out what's new, have a look at our 2022.1 beta blog post.
    Dismiss Notice

Adding shadows to custom shader (vert - frag)

Discussion in 'Shaders' started by jcabreur, Oct 18, 2011.

  1. jcabreur

    jcabreur

    Joined:
    Oct 18, 2011
    Posts:
    6
    Hi,

    I am currently trying to use Unity's shadows on a shader (without using surface shader), is it possible?
     
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    It's possible.

    Code (csharp):
    1.  
    2. // after CGPROGRAM;
    3. #include "AutoLight.cginc"
    4.  
    5. // in v2f struct;
    6. LIGHTING_COORDS(0,1) // replace 0 and 1 with the next available TEXCOORDs in your shader, don't put a semicolon at the end of this line.
    7.  
    8. // in vert shader;
    9. TRANSFER_VERTEX_TO_FRAGMENT(o); // Calculates shadow and light attenuation and passes it to the frag shader.
    10.  
    11. //in frag shader;
    12. float atten = LIGHT_ATTENUATION(i); // This is a float for your shadow/attenuation value, multiply your lighting value by this to get shadows. Replace i with whatever you've defined your input struct to be called (e.g. frag(v2f [b]i[/b]) : COLOR { ... ).
    13.  
     
    Last edited: Oct 18, 2011
  3. jcabreur

    jcabreur

    Joined:
    Oct 18, 2011
    Posts:
    6
    Hi Farfarer,

    Thank you for your reply! Your suggestion works fine but I am having problem with the lighting, it looks like Unity is disabling the lights when viewing objects from some angle. Do you have any idea what could be the reason?

     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Uh, what is it you're trying to do in this shader? It looks like you're using strange stuff as a workaround for built-in functions.
     
  5. jcabreur

    jcabreur

    Joined:
    Oct 18, 2011
    Posts:
    6
    Indeed, this is a workaround to keep the built-in shadows functionality while doing everything else myself (post processing-like effects without additional passes and stuff like that).

    Right now I am trying to perform most light calculation per vertex while still using Unity's shadows.Does it makes sense?

    Additionally, in my scene I have only two lights and only one cast shadows (keyLight).
     
  6. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Hmm, give this a go. Will do base pass with ambient + 1 per-pixel light + vertex lights + spherical harmonics. And an additive pass for each light after that.

    Code (csharp):
    1.  
    2. Shader "Test" {
    3.  
    4.     SubShader {
    5.  
    6.         Tags { "RenderType" = "Opaque"}
    7.  
    8.  
    9.  
    10.         // This pass acts the same as the surface shader first pass.
    11.  
    12.         // Calculates per-pixel the most important directional light with shadows,
    13.  
    14.         // then per-vertex the next 4 most important lights,
    15.  
    16.         // then per-vertex spherical harmionics the rest of the lights,
    17.  
    18.         // and the ambient light value.
    19.  
    20.         Pass {
    21.  
    22.             Tags {"LightMode" = "ForwardBase"}
    23.  
    24.  
    25.  
    26.             CGPROGRAM
    27.  
    28.            
    29.  
    30.                 #pragma multi_compile_fwdbase
    31.  
    32.                 #pragma vertex vert
    33.  
    34.                 #pragma fragment frag
    35.  
    36.                 #pragma fragmentoption ARB_precision_hint_fastest
    37.  
    38.                 #include "UnityCG.cginc"
    39.  
    40.                 #include "AutoLight.cginc"
    41.  
    42.  
    43.  
    44.                 struct Input
    45.  
    46.                 {
    47.  
    48.                     float4 pos : SV_POSITION;
    49.  
    50.                     float3 vlight : COLOR;
    51.  
    52.                     float3 lightDir : TEXCOORD1;
    53.  
    54.                     float3 vNormal : TEXCOORD2;
    55.  
    56.                     LIGHTING_COORDS(3,4)
    57.  
    58.                 };
    59.  
    60.  
    61.  
    62.                 Input vert(appdata_full v)
    63.  
    64.                 {
    65.  
    66.                     Input o;
    67.  
    68.                     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    69.  
    70.                    
    71.  
    72.                     // Calc normal and light dir.
    73.  
    74.                     o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
    75.  
    76.                     o.vNormal = normalize(v.normal).xyz;
    77.  
    78.                    
    79.  
    80.                     // Calc spherical harmonics and vertex lights. Ripped from compiled surface shader.
    81.  
    82.                     float3 worldPos = mul(_Object2World, v.vertex).xyz;
    83.  
    84.                     float3 worldNormal = mul((float3x3)_Object2World, SCALED_NORMAL);
    85.  
    86.                     o.vlight = float3(0);
    87.  
    88.                     #ifdef LIGHTMAP_OFF
    89.  
    90.                         float3 shlight = ShadeSH9(float4(worldNormal, 1.0));
    91.  
    92.                         o.vlight = shlight;
    93.  
    94.                         #ifdef VERTEXLIGHT_ON
    95.  
    96.                             o.vlight += Shade4PointLights (
    97.  
    98.                                 unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
    99.  
    100.                                 unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
    101.  
    102.                                 unity_4LightAtten0, worldPos, worldNormal
    103.  
    104.                                 );
    105.  
    106.                         #endif // VERTEXLIGHT_ON
    107.  
    108.                     #endif // LIGHTMAP_OFF
    109.  
    110.                
    111.  
    112.                     TRANSFER_VERTEX_TO_FRAGMENT(o);
    113.  
    114.                     return o;
    115.  
    116.                 }
    117.  
    118.  
    119.  
    120.                 float4 _LightColor0; // Contains the light color for this pass.
    121.  
    122.  
    123.  
    124.                 half4 frag(Input IN) : COLOR
    125.  
    126.                 {
    127.  
    128.                     IN.lightDir = normalize ( IN.lightDir );
    129.  
    130.                     IN.vNormal = normalize ( IN.vNormal );
    131.  
    132.                    
    133.  
    134.                     float atten = LIGHT_ATTENUATION(IN);
    135.  
    136.                     float3 color;
    137.  
    138.                     float NdotL = saturate( dot (IN.vNormal, IN.lightDir ));
    139.  
    140.                     color = UNITY_LIGHTMODEL_AMBIENT.rgb * 2;
    141.  
    142.                     color += IN.vlight;
    143.  
    144.                     color += _LightColor0.rgb * NdotL * ( atten * 2);
    145.  
    146.                     return half4(color, 1.0f);
    147.  
    148.                 }
    149.  
    150.                
    151.  
    152.             ENDCG
    153.  
    154.         }
    155.  
    156.  
    157.  
    158.         // Take this pass out if you don't want extra per-pixel lights.
    159.  
    160.         // Just set the other lights' Render Mode to "Not Important",
    161.  
    162.         // and they will be calculated as Spherical Harmonics or Vertex Lights in the above pass instead.
    163.  
    164.         Pass {
    165.  
    166.             Tags {"LightMode" = "ForwardAdd"}
    167.  
    168.  
    169.  
    170.             CGPROGRAM
    171.  
    172.            
    173.  
    174.                 #pragma multi_compile_fwdadd
    175.  
    176.                 #pragma vertex vert
    177.  
    178.                 #pragma fragment frag
    179.  
    180.                 #pragma fragmentoption ARB_precision_hint_fastest
    181.  
    182.                 #include "UnityCG.cginc"
    183.  
    184.                 #include "AutoLight.cginc"
    185.  
    186.  
    187.  
    188.                 struct Input
    189.  
    190.                 {
    191.  
    192.                     float4 pos : SV_POSITION;
    193.  
    194.                     float3 lightDir : TEXCOORD1;
    195.  
    196.                     float3 vNormal : TEXCOORD2;
    197.  
    198.                 };
    199.  
    200.  
    201.  
    202.                 Input vert(appdata_full v)
    203.  
    204.                 {
    205.  
    206.                     Input o;
    207.  
    208.                     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    209.  
    210.                    
    211.  
    212.                     // Calc normal and light dir.
    213.  
    214.                     o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
    215.  
    216.                     o.vNormal = normalize(v.normal).xyz;
    217.  
    218.                    
    219.  
    220.                     // Don't need any ambient or vertex lights in here as this is just an additive pass for each extra light.
    221.  
    222.                     // Shadows won't work here, either.
    223.  
    224.                    
    225.  
    226.                     return o;
    227.  
    228.                 }
    229.  
    230.  
    231.  
    232.                 float4 _LightColor0; // Contains the light color for this pass.
    233.  
    234.  
    235.  
    236.                 half4 frag(Input IN) : COLOR
    237.  
    238.                 {
    239.  
    240.                     IN.lightDir = normalize ( IN.lightDir );
    241.  
    242.                     IN.vNormal = normalize ( IN.vNormal );
    243.  
    244.                    
    245.  
    246.                     float3 color;
    247.  
    248.                     float NdotL = saturate( dot (IN.vNormal, IN.lightDir ));
    249.  
    250.                     color = _LightColor0.rgb * NdotL;
    251.  
    252.                     return half4(color, 1.0f);
    253.  
    254.                 }
    255.  
    256.                
    257.  
    258.             ENDCG
    259.  
    260.         }
    261.  
    262.     }
    263.  
    264.  
    265.  
    266.     FallBack "Diffuse"
    267.  
    268. }
    269.  
     
    mouurusai likes this.
  7. jcabreur

    jcabreur

    Joined:
    Oct 18, 2011
    Posts:
    6
    Thanks! It looks like is working now.
     
  8. Alberto Martinez

    Alberto Martinez

    Joined:
    Feb 15, 2012
    Posts:
    5
    Im working on a vertex-fragment pixel-lighting spec-bump shader and i can't handle with the attenuation parameter for shadowing, etc.
    I have tested several shaders posted in the forum and they are not working in Unity 3. In fact it should but, when compiling it comments the subsader and jumps to the fallback shader. The warning message says something like you should rewrite as a surface shader, but that's not the idea :p

    In my current solution Im ussing the lighting macros via TRANSFER_VERTEX_TO_FRAGMENT(...);, LIGHTING_COORDS (...,...) and LIGHT_ATTENUATION(...);.

    It seems like atten is returning 1.0 for every pixel.

    Could someone tell me whats the way for getting the scalar needed for cockies, shadows and attenuation?

    Thanks in advance.



    Code (csharp):
    1. Shader "PARADOX/ PDX_blinnPhong" {
    2. Properties {
    3. _MainTex ("Color", 2D) = "white" {}
    4. _BumpMap ("Normal", 2D) = "white" {}
    5. _RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
    6. _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
    7. _SpecColor ("Specular Color", Color) = (0.26,0.19,0.16,0.0)
    8. _SpecPow ("Specular Power", Range(0.15,15.0)) = 2.5
    9. }
    10.  
    11. SubShader {
    12. Tags { "RenderType" = "Opaque" }   
    13.    
    14.     //______________________________________________________________________AMBIENT + RIM PASS
    15.     Pass {
    16.     Name "BASE"
    17.  
    18. CGPROGRAM
    19. #pragma vertex vert
    20. #pragma fragment frag
    21.  
    22. #include "UnityCG.cginc"
    23.  
    24. struct v2f {
    25.     half4 pos: SV_POSITION;
    26.     half3 normal: TEXCOORD0;
    27.     half3 viewDir: TEXCOORD1;    
    28. };
    29.  
    30. v2f vert (appdata_tan v) {
    31.     v2f o;
    32.     o.pos = mul( UNITY_MATRIX_MVP, v.vertex );    
    33.     float4 normal4 = { v.normal.x, v.normal.y, v.normal.z, 1 };
    34.     o.normal = mul(_Object2World, normal4).xyz;
    35.     o.viewDir = WorldSpaceViewDir(v.vertex);    
    36.     return o;
    37. }
    38.  
    39. half4 _RimColor;
    40. half _RimPower;
    41.  
    42. float4 frag( v2f i ) : COLOR {
    43. //
    44. //NORMALIZE
    45. i.normal = normalize ( i.normal );
    46. i.viewDir = normalize ( i.viewDir );
    47.  
    48. //
    49. //RIM + RIM-UP
    50. float rim = 1 - dot ( i.normal ,i.viewDir );
    51. float rimUp = max ( 0, dot ( i.normal ,float3 ( 0, 1, 0 )));
    52. rim = pow ( ( rim * rimUp ), _RimPower );//RIM UP
    53. //rim = pow ( ( rim ), _RimPower );//RIM UP disable
    54.  
    55. //
    56. //AMBIENT
    57. half4 ambient = UNITY_LIGHTMODEL_AMBIENT;
    58.  
    59. //
    60. //RETURN: Ambient, Rim
    61. return ambient + ( rim * _RimColor );
    62. }
    63.  
    64. ENDCG
    65. }
    66.  
    67.     //______________________________________________________________________MAIN LIGHT PASS
    68.     Pass {
    69.     Name "PPLBase"
    70.     Tags {"LightMode" = "ForwardBase"}
    71.     Blend One One
    72.  
    73. CGPROGRAM
    74. #pragma vertex vert
    75. #pragma fragment frag
    76. #pragma multi_compile_fwdbase
    77.  
    78. #include "UnityCG.cginc"
    79. #include "AutoLight.cginc"
    80.  
    81. struct v2f {
    82.     half4 pos : SV_POSITION;
    83.     LIGHTING_COORDS (0,1)    
    84.     half2 texcoord2;//: TEXCOORD0;//TEXTURE
    85.     half2 texcoord3;//: TEXCOORD1;//BUMP    
    86.     half3 viewDir;//: TEXCOORD2;
    87.     half3 lightDir;//: TEXCOORD3;  
    88. };
    89.  
    90. float4 _MainTex_ST;
    91. float4 _BumpMap_ST;
    92.  
    93. v2f vert (appdata_full v) {
    94.     v2f o;
    95.     o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    96.     o.texcoord2 = TRANSFORM_TEX(v.texcoord,_MainTex);
    97.     o.texcoord3 = TRANSFORM_TEX(v.texcoord,_BumpMap);            
    98.     float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
    99.     float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    100.     o.viewDir = ObjSpaceViewDir ( v.vertex );    
    101.     o.viewDir = mul ( rotation  , o.viewDir );
    102.     o.lightDir = ObjSpaceLightDir ( v.vertex );
    103.     o.lightDir = mul ( rotation  , o.lightDir );
    104.     TRANSFER_VERTEX_TO_FRAGMENT(o);
    105.     return o;
    106. }
    107.  
    108. sampler2D _MainTex;
    109. sampler2D _BumpMap;
    110. half4 _SpecColor;
    111. half _SpecPow;
    112. half4 _LightColor0;
    113.  
    114. half4 frag( v2f i ) : COLOR {
    115. //
    116. //LIGHT ATTENUATION
    117. float atten = LIGHT_ATTENUATION(i);
    118.  
    119. //
    120. //NORMALIZE
    121. i.lightDir = normalize ( i.lightDir );
    122. i.viewDir = normalize ( i.viewDir );
    123.  
    124. //
    125. //TEXTURE
    126. float4 mainTexture = tex2D( _MainTex, i.texcoord2 );
    127.  
    128. //
    129. //BUMP
    130. float3 NMN =  UnpackNormal ( tex2D (_BumpMap, i.texcoord3 ));
    131. NMN = normalize ( NMN );
    132.  
    133. //
    134. //DIFFUSE + WRAP
    135. //Diffuse calculation: Angle between normals and light direction.
    136. half diffuse = max ( 0, dot ( NMN, i.lightDir ));// * 0.5 + 0.5;
    137.  
    138. //
    139. //SPECULAR
    140. //Specular calculation: Angle between normals and half view vector (light direction + view direction).
    141. half3 halfView = normalize ( i.lightDir + i.viewDir );
    142. half spec = max (0,  dot ( halfView, NMN ));
    143. spec = pow ( spec, ( _SpecPow * 10 ));
    144. half4 spec4 = { spec, spec, spec, 1 };
    145.  
    146. //
    147. //RETURN: Texture, Bump, Diffuse, Specular
    148. return mainTexture * (( diffuse * _LightColor0 ) + ( spec4 * _LightColor0 * _SpecColor )) * ( atten * 1.5 );
    149. }
    150. ENDCG
    151. }
    152.  
    153.     //______________________________________________________________________SECONDARY LIGHTS PASS
    154.            
    155.     Pass {
    156.     Name "PPLAdd"
    157.     Tags {"LightMode" = "ForwardAdd"}
    158.     Blend One One
    159.  
    160. CGPROGRAM
    161. #pragma vertex vert
    162. #pragma fragment frag
    163. #pragma multi_compile_fwdbase
    164.  
    165. #include "UnityCG.cginc"
    166. #include "AutoLight.cginc"
    167.  
    168. struct v2f {
    169.     half4 pos : SV_POSITION;  
    170.     half2 texcoord2;//: TEXCOORD0;//TEXTURE
    171.     half2 texcoord3;//: TEXCOORD1;//BUMP    
    172.     half3 viewDir;//: TEXCOORD2;//VIEW
    173.     half3 lightDir;//: TEXCOORD3;//LIGHT  
    174. };
    175.  
    176. float4 _MainTex_ST;
    177. float4 _BumpMap_ST;
    178.  
    179. v2f vert (appdata_full v) {
    180.     v2f o;
    181.     o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    182.     o.texcoord2 = TRANSFORM_TEX(v.texcoord,_MainTex);
    183.     o.texcoord3 = TRANSFORM_TEX(v.texcoord,_BumpMap);            
    184.     float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
    185.     float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    186.     o.viewDir = ObjSpaceViewDir ( v.vertex );    
    187.     o.viewDir = mul ( rotation  , o.viewDir );
    188.     o.lightDir = ObjSpaceLightDir ( v.vertex );
    189.     o.lightDir = mul ( rotation  , o.lightDir );
    190.     return o;
    191. }
    192.  
    193. sampler2D _MainTex;
    194. sampler2D _BumpMap;
    195. half4 _SpecColor;
    196. half _SpecPow;
    197. half4 _LightColor0;
    198.  
    199. half4 frag( v2f i ) : COLOR {
    200.  
    201. //
    202. //NORMALIZE
    203. i.lightDir = normalize ( i.lightDir );
    204. i.viewDir = normalize ( i.viewDir );
    205.  
    206. //
    207. //TEXTURE
    208. float4 mainTexture = tex2D( _MainTex, i.texcoord2 );
    209.  
    210. //
    211. //BUMP
    212. float3 NMN =  UnpackNormal ( tex2D (_BumpMap, i.texcoord3 ));
    213. NMN = normalize ( NMN );
    214.  
    215. //
    216. //DIFFUSE + WRAP
    217. //Diffuse calculation: Angle between normals and light direction.
    218. half diffuse = max ( 0, dot ( NMN, i.lightDir ));// * 0.5 + 0.5;
    219.  
    220. //
    221. //SPECULAR
    222. //Specular calculation: Angle between normals and half view vector (light direction + view direction).
    223. half3 halfView = normalize ( i.lightDir + i.viewDir );
    224. half spec = max (0,  dot ( halfView, NMN ));
    225. spec = pow ( spec, ( _SpecPow * 10 ));
    226. half4 spec4 = { spec, spec, spec, 1 };
    227.  
    228. //
    229. //RETURN: Texture, Bump, Diffuse, Specular
    230. return mainTexture * ( diffuse * _LightColor0 ) + ( spec4 * _LightColor0 * _SpecColor );
    231. }
    232. ENDCG
    233. }
    234. }
    235. }
     
  9. Alberto Martinez

    Alberto Martinez

    Joined:
    Feb 15, 2012
    Posts:
    5
    Fixed. Definitely, I do not understand what fallback is doing. I just added it to the shader and now it is working properly. I will keep researching about that. Nevertheless, here is the complete shader.
    Code (csharp):
    1. Shader "PARADOX/ PDX_blinnPhong" {
    2. Properties {
    3. _MainColor ("Main Color", Color) = (0.26,0.19,0.16,0.0)
    4. _MainTex ("Color", 2D) = "white" {}
    5. _BumpMap ("Normal", 2D) = "white" {}
    6. _RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
    7. _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
    8. _SpecColor ("Specular Color", Color) = (0.26,0.19,0.16,0.0)
    9. _SpecPow ("Specular Power", Range(0.15,15.0)) = 2.5
    10. }
    11.  
    12. SubShader {
    13. Tags { "RenderType" = "Opaque" }   
    14.    
    15.     //______________________________________________________________________AMBIENT + RIM PASS
    16.     Pass {
    17.     Name "BASE"
    18.  
    19. CGPROGRAM
    20. #pragma vertex vert
    21. #pragma fragment frag
    22.  
    23. #include "UnityCG.cginc"
    24.  
    25. struct v2f {
    26.     half4 pos: SV_POSITION;
    27.     half3 normal: TEXCOORD0;
    28.     half3 viewDir: TEXCOORD1;    
    29. };
    30.  
    31. v2f vert (appdata_tan v) {
    32.     v2f o;
    33.     o.pos = mul( UNITY_MATRIX_MVP, v.vertex );    
    34.     float4 normal4 = { v.normal.x, v.normal.y, v.normal.z, 1 };
    35.     o.normal = mul(_Object2World, normal4).xyz;
    36.     o.viewDir = WorldSpaceViewDir(v.vertex);    
    37.     return o;
    38. }
    39.  
    40. half4 _RimColor;
    41. half _RimPower;
    42.  
    43. float4 frag( v2f i ) : COLOR {
    44. //
    45. //NORMALIZE
    46. i.normal = normalize ( i.normal );
    47. i.viewDir = normalize ( i.viewDir );
    48.  
    49. //
    50. //RIM + RIM-UP
    51. float rim = 1 - dot ( i.normal ,i.viewDir );
    52. float rimUp = max ( 0, dot ( i.normal ,float3 ( 0, 1, 0 )));
    53. //rim = pow ( ( rim * rimUp ), _RimPower );//RIM UP enable
    54. rim = pow ( ( rim ), _RimPower );//RIM UP disable
    55.  
    56. //
    57. //AMBIENT
    58. half4 ambient = UNITY_LIGHTMODEL_AMBIENT * 2;
    59.  
    60. //
    61. //RETURN: Ambient, Rim
    62. return ambient + ( rim * _RimColor );
    63. }
    64.  
    65. ENDCG
    66. }
    67.  
    68.     //______________________________________________________________________MAIN LIGHT PASS
    69.     Pass {
    70.     Name "PPLBase"
    71.     Tags {"LightMode" = "ForwardBase"}
    72.     Blend One One
    73.  
    74. CGPROGRAM
    75. #pragma vertex vert
    76. #pragma fragment frag
    77. #pragma multi_compile_fwdbase
    78.  
    79. #include "UnityCG.cginc"
    80. #include "AutoLight.cginc"
    81.  
    82. struct v2f {
    83.     half4 pos : SV_POSITION;
    84.     LIGHTING_COORDS (4,5)    
    85.     half2 texcoord2;//: TEXCOORD0;//TEXTURE
    86.     half2 texcoord3;//: TEXCOORD1;//BUMP    
    87.     half3 viewDir;//: TEXCOORD2;
    88.     half3 lightDir;//: TEXCOORD3;  
    89. };
    90.  
    91. float4 _MainTex_ST;
    92. float4 _BumpMap_ST;
    93.  
    94. v2f vert (appdata_full v) {
    95.     v2f o;
    96.     o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    97.     o.texcoord2 = TRANSFORM_TEX(v.texcoord,_MainTex);
    98.     o.texcoord3 = TRANSFORM_TEX(v.texcoord,_BumpMap);            
    99.     float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
    100.     float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    101.     o.viewDir = ObjSpaceViewDir ( v.vertex );    
    102.     o.viewDir = mul ( rotation  , o.viewDir );
    103.     o.lightDir = ObjSpaceLightDir ( v.vertex );
    104.     o.lightDir = mul ( rotation  , o.lightDir );
    105.     TRANSFER_VERTEX_TO_FRAGMENT(o);
    106.     return o;
    107. }
    108.  
    109. sampler2D _MainTex;
    110. sampler2D _BumpMap;
    111. half4 _MainColor;//MAIN COLOR
    112. half4 _SpecColor;
    113. half _SpecPow;
    114. half4 _LightColor0;
    115.  
    116. half4 frag( v2f i ) : COLOR {
    117. //
    118. //LIGHT ATTENUATION
    119. float atten = LIGHT_ATTENUATION(i);
    120.  
    121. //
    122. //NORMALIZE
    123. i.lightDir = normalize ( i.lightDir );
    124. i.viewDir = normalize ( i.viewDir );
    125.  
    126. //
    127. //TEXTURE
    128. float4 mainTexture = tex2D( _MainTex, i.texcoord2 );
    129.  
    130. //
    131. //BUMP
    132. float3 NMN =  UnpackNormal ( tex2D (_BumpMap, i.texcoord3 ));
    133. NMN = normalize ( NMN );
    134.  
    135. //
    136. //DIFFUSE + WRAP
    137. //Diffuse calculation: Angle between normals and light direction.
    138. half diffuse = max ( 0, dot ( NMN, i.lightDir ));// * 0.5 + 0.5;
    139.  
    140. //
    141. //SPECULAR
    142. //Specular calculation: Angle between normals and half view vector (light direction + view direction).
    143. half3 halfView = normalize ( i.lightDir + i.viewDir );
    144. half spec = max (0,  dot ( halfView, NMN ));
    145. spec = pow ( spec, ( _SpecPow * 10 ));
    146. half4 spec4 = { spec, spec, spec, 1 };
    147.  
    148. //
    149. //RETURN: Texture, Bump, Diffuse, Specular
    150. return ( mainTexture * ( diffuse * _LightColor0 ) + ( spec4 * _LightColor0 * _SpecColor )) * _MainColor * ( atten * 2 );
    151. }
    152. ENDCG
    153. }
    154.  
    155.     //______________________________________________________________________SECONDARY LIGHTS PASS
    156.            
    157.     Pass {
    158.     Name "PPLAdd"
    159.     Tags {"LightMode" = "ForwardAdd"}
    160.     Blend One One
    161.  
    162. CGPROGRAM
    163. #pragma vertex vert
    164. #pragma fragment frag
    165. #pragma multi_compile_fwdadd
    166.  
    167. #include "UnityCG.cginc"
    168. #include "AutoLight.cginc"
    169.  
    170. struct v2f {
    171.     half4 pos : SV_POSITION;
    172.     LIGHTING_COORDS (4,5)  
    173.     half2 texcoord2;//: TEXCOORD0;//TEXTURE
    174.     half2 texcoord3;//: TEXCOORD1;//BUMP    
    175.     half3 viewDir;//: TEXCOORD2;//VIEW
    176.     half3 lightDir;//: TEXCOORD3;//LIGHT  
    177. };
    178.  
    179. float4 _MainTex_ST;
    180. float4 _BumpMap_ST;
    181.  
    182. v2f vert (appdata_full v) {
    183.     v2f o;
    184.     o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    185.     o.texcoord2 = TRANSFORM_TEX(v.texcoord,_MainTex);
    186.     o.texcoord3 = TRANSFORM_TEX(v.texcoord,_BumpMap);            
    187.     float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
    188.     float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    189.     o.viewDir = ObjSpaceViewDir ( v.vertex );    
    190.     o.viewDir = mul ( rotation  , o.viewDir );
    191.     o.lightDir = ObjSpaceLightDir ( v.vertex );
    192.     o.lightDir = mul ( rotation  , o.lightDir );
    193.     TRANSFER_VERTEX_TO_FRAGMENT(o);
    194.     return o;
    195. }
    196.  
    197. sampler2D _MainTex;
    198. sampler2D _BumpMap;
    199. half4 _MainColor;//MAIN COLOR
    200. half4 _SpecColor;
    201. half _SpecPow;
    202. half4 _LightColor0;
    203.  
    204. half4 frag( v2f i ) : COLOR {
    205. //
    206. //LIGHT ATTENUATION
    207. float atten = LIGHT_ATTENUATION(i);
    208.  
    209. //
    210. //NORMALIZE
    211. i.lightDir = normalize ( i.lightDir );
    212. i.viewDir = normalize ( i.viewDir );
    213.  
    214. //
    215. //TEXTURE
    216. float4 mainTexture = tex2D( _MainTex, i.texcoord2 );
    217.  
    218. //
    219. //BUMP
    220. float3 NMN =  UnpackNormal ( tex2D (_BumpMap, i.texcoord3 ));
    221. NMN = normalize ( NMN );
    222.  
    223. //
    224. //DIFFUSE + WRAP
    225. //Diffuse calculation: Angle between normals and light direction.
    226. half diffuse = max ( 0, dot ( NMN, i.lightDir ));// * 0.5 + 0.5;
    227.  
    228. //
    229. //SPECULAR
    230. //Specular calculation: Angle between normals and half view vector (light direction + view direction).
    231. half3 halfView = normalize ( i.lightDir + i.viewDir );
    232. half spec = max (0,  dot ( halfView, NMN ));
    233. spec = pow ( spec, ( _SpecPow * 10 ));
    234. half4 spec4 = { spec, spec, spec, 1 };
    235.  
    236. //
    237. //RETURN: Texture, Bump, Diffuse, Specular
    238. return ( mainTexture * ( diffuse * _LightColor0 ) + ( spec4 * _LightColor0 * _SpecColor )) * _MainColor * ( atten * 2 );
    239. }
    240. ENDCG
    241. }
    242. }
    243. FallBack "Diffuse"
    244. }
     
    IgorAherne likes this.
  10. knuckle117

    knuckle117

    Joined:
    Jun 1, 2012
    Posts:
    2
    LOL, spent 1.5 hrs trying to update AngryBots vertex shader EnemySelfIlluminationReflective so it casts shadows too.
    All I needed was actually FallBack "Diffuse" added at the end of shader.

    According to documentation on FallBack, what it does is adding functionality from another shader if shader used is not supported by the hardware.
    http://unity3d.com/support/documentation/Components/SL-Fallback.html

    It seems FallBack also adds functionality from another shader (like shadows) even if shader used is completely supported by the current hardware.
    Wonder if that's a bug :)
     
    Rugbug_Redfern likes this.
  11. Chickenlord

    Chickenlord

    Joined:
    May 13, 2011
    Posts:
    381
    No, it's totally correct. You probably didn't have a receiver/caster pass in your shader so that in order to get shadows it uses these two passes from the fallback shader.
     
  12. vegenarie

    vegenarie

    Joined:
    Jan 5, 2011
    Posts:
    287
    I am trying the code shown to my shader but i receive the following error "incorrect number of arguments to numeric-type constructor (compiling for d3d11)" , the problem is in the line TRANSFER_VERTEX_TO_FRAGMENT(o); . Anyone knows why is that error? what arguments must i pass, i know i must pass at least the pos but thought that was the only that was needed to pass in the output inTRANSFER_VERTEX_TO_FRAGMENT
     
  13. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,196

    When I add LIGHTING_COORDS() it returns a strange error: "unrecognized identifier "'SHADOW_COORDS'" altho that phrase isn't in my code.
    I'm trying to modify the "Nature/Tree Soft Occlusion Leaves" shader so it receives shadows (the built-in version only casts shadows but doesn't receive them).
     
  14. tsangwailam

    tsangwailam

    Joined:
    Jul 30, 2013
    Posts:
    280
    Use SHADOW_COORDS(1), TRANSFER_SHADOW(o),SHADOW_ATTENUATION(i).

    LIGHTING_COORDS, etc is the old way.
     
    HonoraryBob likes this.
  15. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,196
    Thank you. I can try that.
     
unityunity