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

MaterialPropertyBlock.SetConstantBuffer doesn't seem to work

Discussion in 'General Graphics' started by SLGSimon, Feb 23, 2020.

  1. SLGSimon

    SLGSimon

    Joined:
    Jul 23, 2019
    Posts:
    80
    Unity 2019.2.21f
    I am rendering a bunch of meshes using
    Graphics.DrawMeshInstanced
    with a
    Material
    and a
    MaterialPropertyBlock
    .
    If I use
    SetConstantBuffer
    on a
    MaterialPropertyBlock
    I get all zero values, however if I set it on the material directly it works. Is this some kind of limitation or is it broken?
     
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,864
    Hi!
    AFAIK this should work. Can you please try on 2019.3 and if it doesn't work submit a bug report?
    Thanks!
     
  3. SLGSimon

    SLGSimon

    Joined:
    Jul 23, 2019
    Posts:
    80
    @aleksandrk I don't really have the time to try for a while, so do you know what the implications of setting it on the material before each call to
    Graphics.DrawMeshInstanced
    would be?
     
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,864
    Not from the top of my head :)
     
  5. unity_ZBVlUMxLgI0vig

    unity_ZBVlUMxLgI0vig

    Joined:
    Sep 11, 2020
    Posts:
    6

    Have you been able to fix the issue? I'm also rendering my custom meshes using instancing.

    Here is my code:


    Code (CSharp):
    1. [StructLayout(LayoutKind.Sequential)]
    2. private struct AnimationInfo
    3. {
    4.     public AnimationInfo(int frameCount, float frameDuration)
    5.     {
    6.         this.frameCount = frameCount;
    7.         this.frameDuration = frameDuration;
    8.     }
    9.  
    10.     public int frameCount;
    11.     public float frameDuration;
    12. }
    13.  
    14. ...
    15.  
    16. var animationInfoBuffer = new ComputeBuffer(
    17.     1, UnsafeUtility.SizeOf<AnimationInfo>(),
    18.     ComputeBufferType.Constant, ComputeBufferMode.Immutable
    19. );
    20. animationInfoBuffer.SetData(new[] { new AnimationInfo(frameCount, frameDuration) });
    21. materialInfo.UnityMaterial.SetConstantBuffer(AnimationInfoID, animationInfoBuffer, 0, UnsafeUtility.SizeOf<AnimationInfo>());
    Here is how it is defined in my shader

    Code (CSharp):
    1.  
    2. CBUFFER_START(AnimationInfo)
    3.     int frameCount;
    4.     float frameDuration;
    5. CBUFFER_END
    Though, everything is zero. Setting those values through Material.SetFloat works
     
  6. unity_ZBVlUMxLgI0vig

    unity_ZBVlUMxLgI0vig

    Joined:
    Sep 11, 2020
    Posts:
    6
    I've found out that

    Code (CSharp):
    1. materialInfo.UnityMaterial.HasConstantBuffer("AnimationInfo")
    returns FALSE!!!

    It is defined in my shader but Unity cannot find it.
     
  7. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,864
  8. unity_ZBVlUMxLgI0vig

    unity_ZBVlUMxLgI0vig

    Joined:
    Sep 11, 2020
    Posts:
    6
    @aleksandrk Currently, the project is setup for Android, though I'm running it in the Unity Editor.
     
  9. unity_ZBVlUMxLgI0vig

    unity_ZBVlUMxLgI0vig

    Joined:
    Sep 11, 2020
    Posts:
    6
    I can create a project that reproduces this bug
     
  10. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,864
  11. unity_ZBVlUMxLgI0vig

    unity_ZBVlUMxLgI0vig

    Joined:
    Sep 11, 2020
    Posts:
    6
  12. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,864
    OK, this check is done on the material, so it should return true only after you've executed
    SetConstantBuffer
    on the material you're querying later on.
     
  13. unity_ZBVlUMxLgI0vig

    unity_ZBVlUMxLgI0vig

    Joined:
    Sep 11, 2020
    Posts:
    6
    The thing is that it doesn't find the constant buffer in the shader whatsoever.

    Code (CSharp):
    1.  
    2. Debug.Log(materialInfo.UnityMaterial.HasConstantBuffer("AnimationInfo")); // Returns false
    3. var animationInfoBuffer = new ComputeBuffer(
    4.     1, UnsafeUtility.SizeOf<AnimationInfo>(),
    5.     ComputeBufferType.Constant, ComputeBufferMode.Immutable
    6. );
    7. animationInfoBuffer.SetData(new[] { new AnimationInfo(frameCount, frameDuration) });
    8. materialInfo.UnityMaterial.SetConstantBuffer("AnimationInfo", animationInfoBuffer, 0, UnsafeUtility.SizeOf<AnimationInfo>());
    9.  
    10. Debug.Log(SystemInfo.supportsSetConstantBuffer);    // Returns true

    Code (CSharp):
    1. CBUFFER_START(AnimationInfo)
    2.       int frameCount;
    3.       float frameDuration;
    4. CBUFFER_END
     
  14. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,864
    It's not about the shader. It's about whether or not it's set on the material. The shader may have nothing, but you can still set a constant buffer on a material.