Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Shadow Caster problem with RenderPrimitivesIndexedIndirect

Discussion in 'Shaders' started by WBonX, Dec 3, 2023.

  1. WBonX

    WBonX

    Joined:
    Aug 7, 2018
    Posts:
    46
    I'm using RenderPrimitivesIndexedIndirect to draw a buffer of indexed matrices I access from a buffer of IDs I cull in realtime with a compute shader.

    All works perfectly, I can draw (100)thousands of diffrerent meshes in realtime,

    I'm having troubles using unity internal functions to create the shadows in a custom shadow caster pass.

    The shadows are flickering, like if the shadow casting pass is not drawing always the same, always all or all in the same order? I defined the buffers separately in the two shaders, I guess that's the way, I have no problems in the drawing pass.

    For drawing:
    Code (CSharp):
    1. v2f vert(uint svVertexID: SV_VertexID, uint svInstanceID : SV_InstanceID)
    2.         {
    3.             InitIndirectDrawArgs(0);
    4.             v2f o;
    5.               uint cmdID = GetCommandID(0);
    6.          
    7.               uint instanceID = GetIndirectInstanceID_Base(svInstanceID);
    8.              uint meshID = Visible_ID_Buffer[instanceID];
    9.               int vertexID = GetIndirectVertexID(svVertexID);
    10.             float4 positionOS  = float4(_Positions[ vertexID], 1.0f);
    11.             o.worldPos = mul(_TransformMatrices[meshID]._matrix, float4(positionOS.xyz ,1));
    12. ... }
    In the shadow caster pass:

    Code (CSharp):
    1. struct v2f {
    2.                 V2F_SHADOW_CASTER;
    3.                 //float4 pos : TEXCOORD0;
    4.                 float4 _ShadowCoord : TEXCOORD1;
    5.                 float3 normal : NORMAL;
    6.             };
    7.  
    8. v2f vert(uint svVertexID: SV_VertexID, uint svInstanceID : SV_InstanceID)
    9.             {
    10.                 v2f o;
    11.                 uint cmdID = GetCommandID(0);
    12.               uint instanceID = GetIndirectInstanceID_Base(svInstanceID);
    13.               uint meshID = Visible_ID_Buffer[instanceID];
    14.               int vertexID = GetIndirectVertexID(svVertexID);
    15.               float4 positionOS = float4(_Positions[ vertexID], 1.0f);
    16.                 o.pos = mul(_TransformMatrices[meshID]._matrix, float4(positionOS.xyz ,1));
    17.                 o.pos = mul(UNITY_MATRIX_VP,o.pos);
    18.                o.normal = float3(_Normals[vertexID]);
    19.                //TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
    20.                 return o;
    21.             }
    22. float4 frag(v2f i) : SV_Target
    23.             {
    24.                 //return 0;
    25.                 SHADOW_CASTER_FRAGMENT(i)
    26.             }

    I believe internally unity needs to have set at least unity_ObjectToWorld and unity_WorldToObject, because they are not correctly initialized in indirect calls, same for the other parameters expected by :
    TRANSFER_SHADOW_CASTER_NORMALOFFSET()
    SHADOW_CASTER_FRAGMENT(i)

    I looked into UnityCG.cginc but I could not sort it out.

    Could someone tell what must be set in V2F_SHADOW_CASTER (couldn't fin the definition).

    Is UNITY_MATRIX_VP always the same for a single indirect draw call?

    thanks.
     
  2. WBonX

    WBonX

    Joined:
    Aug 7, 2018
    Posts:
    46
    All done, just forgot the line:
    InitIndirectDrawArgs(0);