I’m trying to improve my understanding of passing data to the GPU. Specifically I’m trying to figure out how to keep as much of my data on the GPU as possible, because it rarely changes frame to frame. This is in the context of the indirect or procedural rendering functions (Graphics.RenderMeshIndirect()).
From my understanding, indirect rendering works by loading a whole collection of data onto the GPU, keeping it there, and having a shader render different instances of the same mesh based on an index passed to the shader. Usually this only works well when you can also pass individual data for each instance, hence the collection of data. I’ve seen people use float4 for position data as well as entire float4x4 for full transform data, but that is mostly unimportant. What is however interesting is whether it matters if this is passed to the shader through a StructuredBuffer<float4x4> _MyInstanceDataBuffer or through a uniform float4x4 _MyInstanceDataArray.
Then there’s also the matter of how to pass this data to the shader from Unity. I’ve seen different approaches in the docs. The most current doc for the modern RenderMeshIndirect() function, which uses a RenderParams struct to set parameters, supports both setting the properties on a MatPropBlock as well as on the material itself. Both work. As far as I know, material property blocks are only interesting to the old built-in renderer for batching. In this case I’m neither batching, nor using the built-in renderer. So why then would the documentation for Unity 6 use this? Meanwhile, the docs for the deprecated DrawMeshInstancedIndirect (which has no support for RenderParams) set the properties directly on the material.
Does anyone have any clue how any of this works?