Hybrid renderer. Using float4x4 material property.

Hey there!

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

[MaterialProperty("_Test", MaterialPropertyFormat.Float4x4)]
public struct TestProperty : IComponentData {
    public float4x4 Value;
}

Shader

CBUFFER_START(UnityPerMaterial)
float4x4 _Test;
CBUFFER_END


#if defined( UNITY_DOTS_INSTANCING_ENABLED)
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
    UNITY_DOTS_INSTANCED_PROP(float4x4, _TestColors)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)

#define _Test         UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4x4, Metadata__Test)
#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:

private MaterialPropertyDefaultValue DefaultValueFromMaterial(
            Material material, int nameID, int sizeBytes)
        {
            MaterialPropertyDefaultValue propertyDefaultValue = default;

            switch (sizeBytes)
            {
               //...............skipped
                case 64:
                    propertyDefaultValue = new MaterialPropertyDefaultValue((float4x4)material.GetMatrix(nameID));
                    break;
            }

            return propertyDefaultValue;
        }

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?

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.

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?

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

1 Like

@lukasleder I just ended up using float4 4 times

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.

1 Like

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?

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.

1 Like