- Home /
Multiple calls to Graphics.DrawMeshInstancedIndirect - only draws last call
I'm trying to render large chunks of tiles using Graphics.DrawMeshInstancedIndirect. When I call it multiple times in the same frame it only seems to register the last call, like so:
Link to gif it it's broken here
Relevant code is below:
public class DoDraw : MonoBehaviour
{
BufferData[] data_ = new BufferData[2];
[SerializeField]
bool[] toDraw_ = new bool[2];
[SerializeField]
Material mat_;
[SerializeField]
int numToDraw_ = 2;
private void Start()
{
data_[0] = new BufferData(Vector3.zero, Color.white, 10);
data_[1] = new BufferData(Vector3.right * 11, Color.blue, 10);
}
private void Update()
{
for( int i = 0; i < 2; ++i )
{
if (toDraw_[i])
data_[i].Draw(mat_);
}
}
}
class BufferData
{
ComputeBuffer argsBuffer_;
ComputeBuffer posBuffer_;
ComputeBuffer colorsBuffer_;
Bounds bounds_;
public BufferData(Vector3 pos, Color color, int size )
{
bounds_ = new Bounds(pos, pos + Vector3.one * size);
int count = size * size;
argsBuffer_ = new ComputeBuffer(1, sizeof(int) * 5, ComputeBufferType.IndirectArguments);
argsBuffer_.SetData(new int[] { 6, count, 0, 0, 0 });
Vector3[] posData = new Vector3[count];
for (int x = 0; x < size; ++x)
{
for (int y = 0; y < size; ++y)
{
int i = y * size + x;
posData[i] = pos + new Vector3(x, y, 0);
}
}
posBuffer_ = new ComputeBuffer(count, sizeof(float) * 3);
posBuffer_.SetData(posData);
Color[] colorData = new Color[count];
for (int i = 0; i < count; ++i)
colorData[i] = color;
colorsBuffer_ = new ComputeBuffer(count, sizeof(float) * 4);
colorsBuffer_.SetData(colorData);
}
public void Draw(Material mat)
{
mat.SetBuffer("posBuffer_", posBuffer_);
mat.SetBuffer("colorBuffer_", colorsBuffer_);
Graphics.DrawMeshInstancedIndirect(StaticQuadMesh.GetMesh(), 0, mat, bounds_, argsBuffer_);
}
}
This example is small and pointless, but it gives a good idea of what I want to do with much larger chunks of tiles. Am I misunderstanding something about how this works?
Answer by Sarkahn · Jun 16, 2017 at 08:17 AM
Edit - After filing a bug report and asking about this on the forums I was able to get some clarification. The suggestion was to use MaterialPropertyBlock to set compute buffers for each call via MaterialPropertyBlock.SetBuffer.
As to why it's needed, I was pointed to this snippet from the docs for Graphics.DrawMesh (which I never saw because it's not a part of the docs for DrawMeshInstancedIndirect for some reason):
Because DrawMesh does not draw mesh immediately, modifying material properties between calls to this function won't make the meshes pick up them. If you want to draw series of meshes with the same material, but slightly different properties (e.g. change color of each mesh), use MaterialPropertyBlock parameter.
However there's a bug right now preventing MaterialPropertyBlock.SetBuffer from working with Graphics.DrawMeshInstanced indirect:
It's been fixed in the beta version 2017.2.0a2.
Your answer
Follow this Question
Related Questions
GPU Instancing (Dynamic Batching) Not Working on Oculus Quest 2 (Android). Works fine in-editor. 0 Answers
Will this script that does drawmeshinstancedprocedural actually work? 0 Answers
find out graphic chip of Android Device 1 Answer
Thread Crash UnityGfxDeviceWorker on MacOS 0 Answers
CPU GraphicsFence synchronization 0 Answers