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

Feature request: MaterialPropertyBlock.SetBuffer() (Any workarounds?)

Discussion in 'General Graphics' started by NavyFish, Aug 3, 2015.

  1. NavyFish

    NavyFish

    Joined:
    Aug 16, 2013
    Posts:
    28
    TLDR: Can the team implement MaterialPropertyBlock.SetBuffer() function in the near future?


    MaterialPropertyBlocks are great for batching by allowing you to re-use a single material for multiple meshes, changing the material slightly from one mesh to the next. Unfortunately it does not support the "SetBuffer" method.

    My use case is as follows: I have a single "Dummy" mesh, which is a rectangular grid of vertices w/ indices configured to draw as a plane. I procedurally generate a heighfield using a Compute Shader, storing the resultant vertex heights in a ComputeBuffer. This is done for many patches of terrain - often the scene will display 100+ patches of terrain.

    When rendering, each patch draws the single static "Dummy" mesh, and a custom vertex shader adjusts the position of the mesh's vertices according to the outputs of the heightfield generation step stored in that patch's ComputeBuffer. One such ComputeBuffer exists for each terrain patch. I use "DrawMesh()" to draw the patch.

    I'd like to be able to use a single material, and simply swap-out the appropriate ComputeBuffer for each separate patch. This would be done via a MaterialPropertyBlock (i.e. block.SetBuffer(positionsComputeBuffer) ). Unfrotunately, this is not supported by MaterialPropertyBlocks.

    Is there any chance we could see this feature implemented in a future version of Unity?

    Also, can anyone suggest a work-around? I've had to resort to storing a separate Material per terrain patch - the only difference between the materials is a unique ComputeBuffer for each. As a result, each terrain patch is drawn with a separate batch. I'm unable to profile the performance gains of using a shared material (if any at all), but can only imagine it would be an improvement (going from 100 batches per frame to 1).

    Thanks for your time and feedback!
     
    Last edited: Oct 25, 2015
  2. NavyFish

    NavyFish

    Joined:
    Aug 16, 2013
    Posts:
    28
    Nothing?

    Here's the TLDR: Is there a way to batch / re-use a single material when the only difference between multiple meshes is a ComputeBuffer property (i.e. material.SetBuffer(anotherComputeBuffer)?

    If the changing property is a float / color / vector, etc, you can use a single Material and indicate small changes using MaterialPropertyBlocks. But doing so for a ComputeBuffer isn't presently an option.

    From my knowledge of OpenGL VAOs, this change of state is effectively just the change of a pointer and so should be no harder than changing a float/vector value. Can't speak to DirectX, though.

    Any way, thoughts as to a work-around? I want to use a single material on a single mesh, and draw it multiple times using DrawMesh(...), with the only change of state being the material pointing to a different compute buffer for each instance.
     
  3. NavyFish

    NavyFish

    Joined:
    Aug 16, 2013
    Posts:
    28
    @Aras Had to do it, sorry. Any chance of seeing a MaterialPropertyBlock.SetBuffer() function in the near future?
     
  4. NavyFish

    NavyFish

    Joined:
    Aug 16, 2013
    Posts:
    28
    Shameless bump on this topic. TLDR: Can the team implement MaterialPropertyBlock.SetBuffer() function in the near future?
     
  5. joergzdarsky

    joergzdarsky

    Joined:
    Sep 25, 2013
    Posts:
    56
    Agreed to NavyFish, MaterialPropertyBlock.SetBuffer() would be extremly helpfull for those who like to create procedural content and work with ComputeShaders and ComputeBuffers.

    So please have MaterialPropertyBlock support Buffers!!

    @Aras, please....
     
  6. Zuntatos

    Zuntatos

    Joined:
    Nov 18, 2012
    Posts:
    612
    An equivalent as CommandBuffer.SetBuffer would be appreciated as well I suppose.
     
  7. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
  8. joergzdarsky

    joergzdarsky

    Joined:
    Sep 25, 2013
    Posts:
    56
    @Aras , please.... it would be so helpfull for all of us DX11 users that want to take use indeep of the ComputeBuffer features...
     
  9. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    "@Aras? :D"
    Quoting again... :) Aras?
     
  10. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    MaterialPropertyBlock.SetBuffer should be coming to a 5.4 build soon...
     
  11. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    We have summoned him! :D
    Sounds good for people using it. Would this work for DX10-level hardware, or not?
    If not, then time for me to buy a new computer... ;)