Search Unity

Surface Shader: Vertex Displacement - shadows aren't adjusted...

Discussion in 'Shaders' started by lordofduct, Sep 8, 2012.

  1. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    I have a shader that is supposed to warp terrain the further it is away from the camera. The problem is shadows are still based off the un-deformed vertices, which casts against the deformed terrain. Essentially casting a shadow on itself.

    Googling around said I need to use 'addshadow', but it doesn't do anything for me.

    Anyone have any ideas?

    Code (csharp):
    1.  
    2.  
    3. Shader "Cylinder/Diffuse-Cyl" {
    4.     Properties {
    5.         _Color ("Main Color", Color) = (1,1,1,1)
    6.         _MainTex ("Base (RGB)", 2D) = "white" {}
    7.     }
    8.     SubShader {
    9.         Tags { "RenderType"="Opaque" }
    10.         LOD 200
    11.         Cull Back
    12.  
    13.         CGPROGRAM
    14.         #pragma surface surf Lambert vertex:vert addshadow
    15.  
    16.         sampler2D _MainTex;
    17.         fixed4 _Color;
    18.         float CURVE_OFFSET;
    19.  
    20.         void vert(inout appdata_full v)
    21.         {
    22.             if(CURVE_OFFSET != 0)
    23.             {
    24.                 float4 vpos = mul(UNITY_MATRIX_MVP, v.vertex);
    25.                 float l = length(float2(vpos.x, vpos.z));
    26.                 v.vertex.xyz += mul(_World2Object, float4(0,-1,0,0)) * l * l * CURVE_OFFSET;
    27.             }
    28.         }
    29.  
    30.         struct Input {
    31.             float2 uv_MainTex;
    32.         };
    33.  
    34.         void surf (Input IN, inout SurfaceOutput o) {
    35.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    36.             o.Albedo = c.rgb;
    37.             o.Alpha = c.a;
    38.         }
    39.  
    40.         ENDCG
    41.  
    42.     }
    43.  
    44.     Fallback "Diffuse"
    45. }
    46.  
    (note: CURVE_OFFSET is a global value, it's constant through out the game. I usually have it set to 0.001 -> 0.004)
     
    Last edited: Sep 13, 2012
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    No assistance?

    I really would like to know how to make dynamic shadows be calculated off the deformed mesh, and not the original mesh.

    I've been searching around, playing with the shader, and just gambling left and right with no luck.


    Does anyone have resources on how the dynamic shadows are calculated?
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Images of the problem...

    here is what it looks like with out the vertex deformation, everything is correct:



    here is with the deformation, NO SHADOWS, works




    here is with the deformation, shadows included, note the shadowing on the terrain... that is coming from what would be the terrain if it weren't deformed.

     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    One last bump for good measure...
     
  5. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    That seems strange to me. As far as I can tell, specifying a custom vertex function in a surface shader generates appropriate shadow passes. Everything should just work. The standard tree shaders use the same approach, and their shadow passes reflect distortion from wind.

    Does your shader produce correct shadows when used on regular meshes? If so, then perhaps terrain shadows are handled in a special way. In this case, you might have to get input from Unity on whether the terrain shadow pass can be replaced.
     
  6. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    As an aside, you should avoid branching (usually if statements) in shaders whenever possible. It could very well be being optimized out by the compiler in this case, but it's very unlikely that you'll gain any performance on any hardware by enclosing your vertex function in a conditional.
     
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    the mesh is just a basic mesh, it's not a special terrain mesh.

    And the conditional isn't for efficiency, it's for turning it on or off from scripting side in game. Removing it doesn't change anything.
     
  8. iamvideep

    iamvideep

    Joined:
    Oct 27, 2017
    Posts:
    118
    You are making changes to vertex positions, but not updating its normals. Hence you will not get shadows on the modified vertex data.
    do the same for normals:
    v.normal = normalize(v.normal + mul(_World2Object, float4(0,-1,0,0)) * l * l * CURVE_OFFSET);
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Wow... that's a necro of a very old post of mine.

    This game is WAYYYYY in my past.
     
    MadeFromPolygons likes this.
  10. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,982
    Just FYI This was 6 years old when you resurrected it XD
     
  11. iamvideep

    iamvideep

    Joined:
    Oct 27, 2017
    Posts:
    118
    hah, I did see that, but as no answer was posted, I thought to post it so that anyone who is wandering in search for it would find it helpful :)

    Haha, back in those days I was learning computers :p
     
    MadeFromPolygons likes this.