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

A bug in UnityInstancing.hlsl?

Discussion in 'Shaders' started by GuardHei, Nov 13, 2021.

  1. GuardHei

    GuardHei

    Joined:
    Feb 10, 2018
    Posts:
    89
    I'm writing my own scriptable render pipeline recently, and realize a weird thing in UnityInstancing.hlsl.

    Normally, before UnityInstancing tries to redefine certain matrix macros to match the instancing requirement, it will always try to undefine the macros first to avoid conflicts, like this

    Code (CSharp):
    1. #if defined(UNITY_DOTS_INSTANCING_ENABLED)
    2.         #undef UNITY_MATRIX_M
    3.         #undef UNITY_MATRIX_I_M
    4.         #undef UNITY_PREV_MATRIX_M
    5.         #undef UNITY_PREV_MATRIX_I_M
    6.         #ifdef MODIFY_MATRIX_FOR_CAMERA_RELATIVE_RENDERING
    7.             #define UNITY_MATRIX_M        ApplyCameraTranslationToMatrix(LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_ObjectToWorld)))
    8.             #define UNITY_MATRIX_I_M      ApplyCameraTranslationToInverseMatrix(LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_WorldToObject)))
    9.             #define UNITY_PREV_MATRIX_M   ApplyCameraTranslationToMatrix(LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_MatrixPreviousM)))
    10.             #define UNITY_PREV_MATRIX_I_M ApplyCameraTranslationToInverseMatrix(LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_MatrixPreviousMI)))
    11.         #else
    12.             #define UNITY_MATRIX_M        LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_ObjectToWorld))
    13.             #define UNITY_MATRIX_I_M      LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_WorldToObject))
    14.             #define UNITY_PREV_MATRIX_M   LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_MatrixPreviousM))
    15.             #define UNITY_PREV_MATRIX_I_M LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_MatrixPreviousMI))
    16.         #endif
    17.     #else
    You can see there're a bunch of undef at the top of lines.

    Now the problem is that for whatever reasons, Unity forgets to do such a thing for UNITY_PREV_MATRIX_M and UNITY_PREV_MATRIX_I_M for one branching condition. (Starting from line 384 of the file UnityInstancing.hlsl)

    The code goes
    Code (CSharp):
    1. #ifndef UNITY_DONT_INSTANCE_OBJECT_MATRICES
    2.         #undef UNITY_MATRIX_M
    3.         #undef UNITY_MATRIX_I_M
    4.  
    5.         // Use #if instead of preprocessor concatenation to avoid really hard to debug
    6.         // preprocessing issues in some cases.
    7.         #if UNITY_WORLDTOOBJECTARRAY_CB == 0
    8.             #define UNITY_BUILTINS_WITH_WORLDTOOBJECTARRAY unity_Builtins0
    9.         #else
    10.             #define UNITY_BUILTINS_WITH_WORLDTOOBJECTARRAY unity_Builtins1
    11.         #endif
    12.  
    13.         #ifdef MODIFY_MATRIX_FOR_CAMERA_RELATIVE_RENDERING
    14.             #define UNITY_MATRIX_M         ApplyCameraTranslationToMatrix(UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_ObjectToWorldArray))
    15.             #define UNITY_MATRIX_I_M       ApplyCameraTranslationToInverseMatrix(UNITY_ACCESS_INSTANCED_PROP(UNITY_BUILTINS_WITH_WORLDTOOBJECTARRAY, unity_WorldToObjectArray))
    16.             #define UNITY_PREV_MATRIX_M    ApplyCameraTranslationToMatrix(UNITY_ACCESS_INSTANCED_PROP(unity_Builtins3, unity_PrevObjectToWorldArray))
    17.             #define UNITY_PREV_MATRIX_I_M  ApplyCameraTranslationToInverseMatrix(UNITY_ACCESS_INSTANCED_PROP(unity_Builtins3, unity_PrevWorldToObjectArray))
    18.         #else
    19.             #define UNITY_MATRIX_M         UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_ObjectToWorldArray)
    20.             #define UNITY_MATRIX_I_M       UNITY_ACCESS_INSTANCED_PROP(UNITY_BUILTINS_WITH_WORLDTOOBJECTARRAY, unity_WorldToObjectArray)
    21.             #define UNITY_PREV_MATRIX_M    UNITY_ACCESS_INSTANCED_PROP(unity_Builtins3, unity_PrevObjectToWorldArray)
    22.             #define UNITY_PREV_MATRIX_I_M  UNITY_ACCESS_INSTANCED_PROP(unity_Builtins3, unity_PrevWorldToObjectArray)
    23.         #endif
    24.     #endif
    Apparently the guy whoever wrote it only remember to undef UNITY_MATRIX_M and its inverse, but forgot to undef the other two which are useful to instancing motion vector pass.

    I'm not sure why this is the case here? Is it intentional or is it just a bug? Is there a better workaround out there? rn I just copy paste the entire file and edit it, but this is "ugly" to me.

    btw, I'm using 2022.1a7 if this may help