Search Unity

  1. Unity 2020.2 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Custom ShadowCaster for Indirect Surface Shader

Discussion in 'Shaders' started by m506, Sep 15, 2020.

  1. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    80
    Hi, I have an "Instanced Indirect" surface shader which works fine except it is not casting shadows properly:

    Shader "InstancedIndirect"
    {
    Properties
    {
    _MainTex("Albedo (RGB)", 2D) = "white" {}
    }

    CGINCLUDE

    #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    StructuredBuffer<float4x4> obj2world;
    StructuredBuffer<float4x4> world2obj;
    #endif

    void setup()
    {
    #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    unity_ObjectToWorld = obj2world[unity_InstanceID];
    unity_WorldToObject = world2obj[unity_InstanceID];
    #endif
    }

    ENDCG

    SubShader
    {
    Tags { "Queue" = "Geometry" "RenderType" = "Opaque" "IgnoreProjector" = "True" "DisableBatching" = "True" }

    CGPROGRAM

    //#pragma surface surf Standard addshadow
    #pragma surface surf Standard
    #pragma target 4.5
    #pragma multi_compile_instancing
    #pragma instancing_options procedural:setup

    sampler2D _MainTex;

    struct Input
    {
    float2 uv_MainTex;
    UNITY_VERTEX_INPUT_INSTANCE_ID
    };

    void surf(Input IN, inout SurfaceOutputStandard o)
    {
    o.Albedo = tex2D(_MainTex, IN.uv_MainTex);
    }

    ENDCG

    Pass
    {
    Name "SHADOWCASTER"
    Tags { "LightMode" = "ShadowCaster" }

    CGPROGRAM

    #pragma vertex vert
    #pragma fragment frag
    #pragma multi_compile_shadowcaster
    #pragma fragmentoption ARB_precision_hint_fastest

    #include "UnityCG.cginc"

    struct v2f
    {
    V2F_SHADOW_CASTER;
    };

    v2f vert(appdata_base v)
    {
    v2f o;
    TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
    return o;
    }

    float4 frag(v2f i) : COLOR
    {
    SHADOW_CASTER_FRAGMENT(i)
    }

    ENDCG
    }
    }
    FallBack Off
    }

    Basically, if I do "addshadow" in the pragma section the shadows get batched together for multiple objects and
    they all overlap, as if unity was not instancing them properly. See image below:

    https://imgur.com/a/X9vDbcD

    One thing I am trying now is to add a custom "ShadowCaster" pass into this surface shader, but it is not working at all
    for indirect instanced objects, but because it is working for normal MeshRenderers, I can guess I am in the right direction.

    Can someone please let me know if there's a way to either make Unity batch the shadows properly using "addshadows"
    or to make this custom pass to work? (Using Unity 2019.4.1f1)

    Thank you in advance
     
  2. marwi

    marwi

    Joined:
    Aug 13, 2014
    Posts:
    116
  3. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    80
    Hi, thanks for replying but using materialproperties didn't work for me. The pass below solved the problem (I included only the relevant parts):

    Code (CSharp):
    1. Pass
    2. {
    3.     Name "ShadowCaster"
    4.     Tags { "LightMode" = "ShadowCaster" }
    5.  
    6.     ZWrite On
    7.     ZTest LEqual
    8.  
    9.     CGPROGRAM
    10.  
    11.     #pragma vertex vertShadowCaster
    12.     #pragma fragment fragShadowCaster
    13.  
    14.     StructuredBuffer<float4x4> obj2world;
    15.  
    16.     struct v2f
    17.     {
    18.         float4 vertex : SV_POSITION;
    19.         float2 uv : TEXCOORD0;
    20.     };
    21.  
    22.     v2f vertShadowCaster(appdata_base v, uint i : SV_InstanceID)
    23.     {
    24.         v2f o;
    25.  
    26.         v.vertex = mul(obj2world[i], v.vertex);
    27.         o.vertex = mul(UNITY_MATRIX_VP, v.vertex);
    28.  
    29.         o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    30.  
    31.         return o;
    32.     }
    33.  
    34.     float4 fragShadowCaster(v2f i) : SV_Target
    35.     {      
    36.         return 0;
    37.     }
    38.    
    39.     ENDCG
    40. }
     
unityunity