I downloaded the Beta specifically because I need this:
“Shader uniform array support. Uniform arrays can be set by new array APIs on MaterialPropertyBlock. Maximum array size is 1023. The old way of setting array elements by using number-suffixed names is deprecated.”
I assume the api would be material.SetArray(“name”, array), but that doesn’t work. Is the functionality there and does anyone know how to use it?
Also the above note was from 5.4.0b1, but I am 5.4.10b, which I assume should also have that functionality?
I finally figured it out, the feature is there it was just me being confused. For future reference, you can’t SetFloatArray on a material directly, you have to do it on a MaterialPropertyBlock and then pass that to the renderer of the object. This was a bit confusing since you can do for example SetFloat directly on the material. Anyways, the following should work:
var materialProperty = new MaterialPropertyBlock();
float[ ] floatArray= new float[ ] {0f, 1f};
So we can’t set, say, set a global array of floats? Shader. SetGlobalArray***** (float, vector, etc)
Also, since the material property block applies to the renderer and not the material, we can’t have all renderers that are being renderer with a certain material share the array, right? We’d have to set the array for each renderer, which I assume would.be costly and it would break any dynamic batching. That’s not very useful
I can’t say for sure, but I don’t think that is possible Also yes I think you would have to pass the material proberty to each renderer and that does sound like it should break dynamic batching
You probably have to use a hack like pass the data with setTexture (large overhead) or maybe setBuffer (requires DirectX 11 i think) on the material if the above limitations doesn’t work with you want to do.
Hopefully they will add this method to the material directly soon also!
I am using a global texture (RGBAFloat format) to pass 256 values to my shader. It works, but it would be more efficient to by pass texture sampling and all that other junk in my shader if I could just have an array of vector’s accessible to me directly.
but I haven’t checked if it actually works globally.
Setting arrays permaterials would be definitely welcome though. For large arrays it would increase material asset memory required (on disk), but it’s not that bad I guess?
The maximum array size seems a little arbitrary. Does anyone know if we can have multiple arrays of size 1023 in one shader? Can we query the hardware to discern what limitations there are for the amount of data we pass in to our shader in Unity? I can’t find the info I’m looking for online – nor can I test it conclusively without testing on all GPUs I want to support.
With the latest beta there are also SetFloatArray/SetVectorArray/SetMatrixArray on Material class. I haven’t checked the implementation but I think array values are not serialized with the Material object.
Yes you can have multiple arrays of size 1023 in one shader. This limitation is rather from our internal implementation than the hardware. If you put an array in a constant buffer, you are also limited by the maximum size of a constant buffer, which is 64KB for D3D11 and 16KB for OpenGL.