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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Hybrid renderer. Using float4x4 material property.

Discussion in 'Graphics for ECS' started by sdvoynikov, Aug 10, 2020.

  1. sdvoynikov

    sdvoynikov

    Joined:
    Nov 24, 2012
    Posts:
    7
    Hey there!

    Got an issue with passing matrices to shader via material property. For example:

    Code (CSharp):
    1.  
    2. [MaterialProperty("_Test", MaterialPropertyFormat.Float4x4)]
    3. public struct TestProperty : IComponentData {
    4.     public float4x4 Value;
    5. }
    Shader
    Code (CSharp):
    1.  
    2. CBUFFER_START(UnityPerMaterial)
    3. float4x4 _Test;
    4. CBUFFER_END
    5.  
    6.  
    7. #if defined( UNITY_DOTS_INSTANCING_ENABLED)
    8. UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
    9.     UNITY_DOTS_INSTANCED_PROP(float4x4, _TestColors)
    10. UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
    11.  
    12. #define _Test         UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4x4, Metadata__Test)
    13. #endif
    Everything works fine, i can read this matrix in shader but have an annoying error in console:
    Material <...> with Shader <...> doesn't have a matrix property '_Test'

    Shader have no option to declare matrix property, but in HybridV2RenderSystem.cs:2340 written:

    Code (CSharp):
    1.  
    2. private MaterialPropertyDefaultValue DefaultValueFromMaterial(
    3.             Material material, int nameID, int sizeBytes)
    4.         {
    5.             MaterialPropertyDefaultValue propertyDefaultValue = default;
    6.  
    7.             switch (sizeBytes)
    8.             {
    9.                //...............skipped
    10.                 case 64:
    11.                     propertyDefaultValue = new MaterialPropertyDefaultValue((float4x4)material.GetMatrix(nameID));
    12.                     break;
    13.             }
    14.  
    15.             return propertyDefaultValue;
    16.         }
    so they try to get value from material, which is not exists. I tried to SetMatrix() to this matireal at the very beginning, but had no success. Any suggestions?
     
  2. cultureulterior

    cultureulterior

    Joined:
    Mar 15, 2015
    Posts:
    68
    Yes, this is a known, but not documented bug. 4x4s are not supported. You're about the 6th person who has had to find this by themselves, because Unity haven't had time to document this bug.
     
  3. sdvoynikov

    sdvoynikov

    Joined:
    Nov 24, 2012
    Posts:
    7
    But it works, the only issue - this exception spam in console. It needs just make a check there if property exists, before get its value. Is there any way to provide a pull request to unity team?
     
  4. lukasleder

    lukasleder

    Joined:
    Sep 7, 2017
    Posts:
    16
    Are there any updates on this issue? I stumbled on it now as well and can't get it to work with Hybrid Renderer 10.0
     
    apkdev likes this.
  5. Srokaaa

    Srokaaa

    Joined:
    Sep 18, 2018
    Posts:
    169
  6. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    333
    I can confirm that this is a bug. The float4x4 support in Hybrid Renderer itself should work and has been tested, but the rest of Unity does not support matrix properties on shaders correctly. Using four float4s as already suggested is a good workaround.
     
    apkdev likes this.
  7. lukasleder

    lukasleder

    Joined:
    Sep 7, 2017
    Posts:
    16
    I managed to "fix" the error by applying a value to the matrices when the material gets initialized.
    I can confirm that my properties are found by the Hybrid V2 Render System and are marked as "PerEntitiyOverride" etc.

    I assume that they are therefore also present in the global compute buffer set by the Hybrid Render System.
    I'm having problems with these values being filled by the "MaterialPropertyAttribute" though. Sadly I can't use floats, as I'm already on a very tight budget regarding the component datas in my systems (I need 16 4x4 matrices, but I'm currently testing with 1).

    I'm still a little confused if the Attribute works with 4x4 matrices, I couldn't really wrap my head around your message, so the Renderer supports matrices but unity doesn't and it won't work?
     
  8. lukasleder

    lukasleder

    Joined:
    Sep 7, 2017
    Posts:
    16
    I just got it working with float4x4 matrices, i have been struggling with one thing though.
    The byte layout of my matrices differs from the unity mathematics library and the float4x4 on the GPU.
    This caused my float4x4[0].w actually being float4x4[3].x on the GPU, the dimensions are flipped.

    Thankfully I tested through this and found it, they seem to work without any issues now.

    My progress was the following for future reference.

    Create a shader with
    UNITY_DOTS_INSTANCING_ENABLED etc. like described in the original post but with the matrix outside of the CBUFFER, as it breaks srp batcher compatibility.

    Create a [MaterialProperty] struct like in the original post and assign the values with the rows and columns switched.

    Have a script that calls the SetMatrix on the material before the Hybrid Renderer is rendering the object.
     
    JussiKnuuttila likes this.