Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Part of shader being ignored by realtime shadows

Discussion in 'Shaders' started by CptBonex, Nov 19, 2014.

  1. CptBonex

    CptBonex

    Joined:
    Dec 14, 2013
    Posts:
    15
    I have made a shader that draws a copy of the object with a offset on the x-axis. The problem that I have is that the copy gets ignored by the realtime shadows in unity. I guess there is some thing that I have missed to add but I cant find what. Anyone knows how to solve this?

    Code (CSharp):
    1. Shader "TestShader" {
    2.  
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.     }
    6.    
    7.     SubShader {
    8.    
    9.         Tags { "RenderType"="Opaque"}
    10.         LOD 200
    11.         Cull Off
    12.         ZWrite On
    13.         ZTest LEqual
    14.  
    15.             CGPROGRAM
    16.             #pragma surface surf Lambert addshadow
    17.            
    18.             sampler2D _MainTex;
    19.            
    20.             struct Input {
    21.                 float2 uv_MainTex;
    22.             };
    23.            
    24.             void surf (Input IN, inout SurfaceOutput o) {
    25.                 fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
    26.                 o.Albedo = c.rgb;
    27.             }
    28.             ENDCG
    29.  
    30.             CGPROGRAM
    31.             #pragma surface surf Lambert vertex:vert addshadow
    32.            
    33.             sampler2D _MainTex;
    34.            
    35.             struct Input {
    36.                 float2 uv_MainTex;
    37.             };
    38.            
    39.             void vert (inout appdata_full v) {
    40.                   v.vertex.x += 2;
    41.             }
    42.  
    43.             void surf (Input IN, inout SurfaceOutput o) {
    44.                 fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
    45.                 o.Albedo = c.rgb;
    46.             }
    47.             ENDCG
    48.     }
    49.     FallBack "VertexLit"
    50. }


    The right one is the second CGPROGRAM that gets ignored.

    See how the shadows of the original ball is displayed above the copy even when the copy is in front of the original.
     
  2. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    I have just test your shader in a scene and got it to work if you remove the first pass of your shader (the non-vert displaced one).

    You basically have defined two shaders in one and it looks like Unity just uses the first one that is defined when rendering the shadows, in this case the non-vertex displaced one which is why the shadow does not move.

    There are ways of making a shader with more than one pass or subshader if that is what your trying to do although I am not sure if you can set which one to use when rendering the shadows.

    If not just split the shader into two files.
     
    Last edited: Nov 20, 2014
  3. CptBonex

    CptBonex

    Joined:
    Dec 14, 2013
    Posts:
    15
    Yes thats what I have noticed to. Only the first one gets shadows.
    The thing is that if I try to make it a fragment shader the shader that I am gonna make out of this will be huge and I dont think the effect is wort the time. How would I split the shader into 2 files? I am kind of a noob when I comes to shaders.
     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    You'll have to write a custom shadow caster/receiver subshader that has two passes in it, one of which does the duplication.

    I'm guessing Unity's rendering the scene for shadows and it simply uses the first shadow caster/receiver shaders it finds in your shader. Yours has two, and it's simply getting the first one and using that (the one for your undisplaced sphere).
     
  5. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    By split into to files I just mean make two separate shaders but I am not clear on what effect your trying to achieve.

    Perhaps it maybe best to download all of Unitys default shaders and have a look at that. There are some good examples on how to construct complicated shaders with multiple passes and shadow caster/receivers.

    I have just noticed that many of the "Nature/Tree" shaders have displacement vert shaders and a shadow caster pass which maybe similar to what you are trying to achieve.??
     
  6. CptBonex

    CptBonex

    Joined:
    Dec 14, 2013
    Posts:
    15
    Thanks to both of you. I will read up more on shader creation and have a look around in the default shaders. I found out that TreeCreatorLeavesFastOptimized has shadow caster/receiver in it. The shader I am trying to make is a grass shader like the one in Viva Pinata. I have created one that looks good with realtime shadows disabled. But I really want it to be able to recieve shadows.

    This is how it looks so far when shadows are disabled