Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved Manipulating Vertex positions does not change Shadows

Discussion in 'Shaders' started by DimitriX89, Sep 1, 2022.

  1. DimitriX89

    DimitriX89

    Joined:
    Jun 3, 2015
    Posts:
    550
    I have a following custom shader which affects object vertices
    Code (CSharp):
    1. Shader "Custom/SquashTestShader"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.  
    7.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    8.  
    9.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    10.         _Metallic ("Metallic", Range(0,1)) = 0.0
    11.         _SquashMult ("Squash/Stretch", Range(0,10)) = 0.5
    12.  
    13.     }
    14.     SubShader
    15.     {
    16.         Tags { "RenderType"="Opaque" }
    17.         LOD 200
    18.  
    19.         CGPROGRAM
    20.         // Physically based Standard lighting model, and enable shadows on all light types
    21.         #pragma surface surf Standard fullforwardshadows  vertex:vert
    22.  
    23.         // Use shader model 3.0 target, to get nicer looking lighting
    24.        // #pragma target 3.0
    25.      
    26.  
    27.         sampler2D _MainTex;
    28.  
    29.         struct Input
    30.         {
    31.             float2 uv_MainTex;
    32.             float3 worldPos;
    33.         };
    34.  
    35.         half _Glossiness;
    36.         half _Metallic;
    37.         fixed4 _Color;
    38.         float4x4 _MatrixStraight;
    39.         float4x4 _MatrixInverse;
    40.         float _SquashMult;
    41.        
    42.         void vert (inout appdata_full v) {
    43.           float3 GlobalPos = mul (_Object2World, float4 (v.vertex.xyz,1));
    44.           float3 LocalPos = mul(_MatrixInverse,float4 (GlobalPos.xyz,1)).xyz * float3 (1/_SquashMult,1/_SquashMult,_SquashMult);
    45.           v.vertex.xyz = mul(_World2Object, mul(_MatrixStraight,float4 (LocalPos,1))  ).xyz;
    46.         }
    47.  
    48.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    49.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    50.         // #pragma instancing_options assumeuniformscaling
    51.         UNITY_INSTANCING_BUFFER_START(Props)
    52.             // put more per-instance properties here
    53.         UNITY_INSTANCING_BUFFER_END(Props)
    54.  
    55.         void surf (Input IN, inout SurfaceOutputStandard o)
    56.         {
    57.             // Albedo comes from a texture tinted by color
    58.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    59.             o.Albedo = c.rgb;
    60.             // Metallic and smoothness come from slider variables
    61.             o.Metallic = _Metallic;
    62.             o.Smoothness = _Glossiness;
    63.             o.Alpha = c.a;
    64.         }
    65.         ENDCG
    66.     }
    67.     FallBack "Diffuse"
    68. }
    69.  
    When used, the shadows are calculated for original shape of the object (cube in this case)

    What is required for proper shadow support?
     
  2. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,496
    By default, the surface shader doesn't recompile the SHADOWCASTER pass using your custom vertex program, it uses whatever exists in your Fallback shader.

    To make it use your vert program, add
    addshadow
    to the end of your
    #pragma surface
    line
     
    chriscode and DimitriX89 like this.
  3. DimitriX89

    DimitriX89

    Joined:
    Jun 3, 2015
    Posts:
    550
    Thanks, that's exactly what I needed. Also, I'd like someone to verify if the math is right for the effect itself.
    Code (CSharp):
    1.         void vert (inout appdata_full v) {
    2.           float3 GlobalPos = mul (_Object2World, float4 (v.vertex.xyz,1));
    3.           float3 LocalPos = mul(_MatrixInverse,float4 (GlobalPos.xyz,1)).xyz * float3 (1/_SquashMult,1/_SquashMult,_SquashMult);
    4.           v.vertex.xyz = mul(_World2Object, mul(_MatrixStraight,float4 (LocalPos,1))  ).xyz;
    5.         }
    My idea was to make squash and stretch transformation, relative to an external dummy object. First, I convert the vertex positions to world space. Second, I calculate coordinates relative to the dummy, and apply squash/stretch along Z axis. Finally, I convert to world coordinates again, then back to object space. The matrices come from Material.SetMatrix of a C# script. Seems to work on a cube, but could I've miss something?
     
  4. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,496
    If it works it works!
     
  5. NextRealm

    NextRealm

    Joined:
    Mar 17, 2022
    Posts:
    6
    I encountered the same shadow problem in shader graph, I want to know how to set to achieve the effect of the code, thx!
     
  6. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,496
    ShaderGraph should already automatically copy any vertex modifications you do in the graph to all shader passes, including the ShadowCaster passes.
    Do you mean your shader isn't casting shadows in general perhaps? In which case "Cast Shadows" might be unchecked in the "Graph Settings" tab of the shader. Or the Renderer for the object your material is on has its Shadow mode set to "None". Or your material is set as transparent.
     
  7. NextRealm

    NextRealm

    Joined:
    Mar 17, 2022
    Posts:
    6
    Thank you for the response, the issue has been resolved:)