Im drawing a bunch of stuff with DrawMeshInstanced and i want to set a shader property, _BurnAmount, per each instance. Using shadergraph in URP btw.
First i tried MaterialPropertyBlock, i set a float[] with the same name as my float property on the mateiral but uh it didnt do anything.
Im currently using a StructuredBuffer and ComputeBuffer which works okay, except InstanceID seems to like randomly looping back to zero so it deosnt work as intended. Im pretty sure this is because of how unity splits draw calls... kinda... but I am sure that it is because of InstanceID
I would just write a shader so i can actually use the MaterialPropertyBlock for per-instance properties but A: i dunno if that will work in URP B: i dont know how to do that really
any advice would be appreciated thanks
#Material properties per instance
1 messages · Page 1 of 1 (latest)
I don't see any guarantees on the documentation about the consistency of indexing with DrawMeshInstanced (you should use the Render... methods on newer unity versions). One solution that I would consider would be to render using the indirect methods (DrawMeshInstancedIndirect/RenderMeshIndirect) in which case it is totally up to you to keep all the per instance data in sync
Well, RenderMeshInstanced actually seems to support sending custom structs that may contain whatever data you need (though it reduces the allowed max count). It will depend on many factor whether you would actually want to use the simple instanced or indirect render methods.
oh yeah the custom data seems interesting but how would i get that float to the instance's material
i'll look into those though thanks
i'll be honest i had no idea the render... nethods existed ive only ever used drawmeshinstanced lol
Those are the old ones, using Render... is recommended nowadays
i just implemented rendermeshinstanced and the instanceid still seems to loop weirdly ...
I haven't used it myself so little clue and the documentation doesn't specify how to access the data either but I just found this reference implementation which is definitely worth looking into: https://github.com/keijiro/StickShow
always seems to be the same place too which is strange cuz if it was because of other drawcalls it would be a bit inconsistent surely
oh shoot thanks this looks useful
That is not surprising in a sense that the Draw... and Render... methods are pretty much the exact same thing with maybe some little improvements and better naming conventions (in favor of Render...)
alright copied a bit of code from here it seems like the looping has stopped ...
turns out they were doing about the exact same thing as i was originally (splitting to blocks) but they had smaller ones
yep its fixed
tysm man!
Are you sure you didn't hit the limit?
from docs:
You can only render a maximum of 1023 instances at once. The maximum depends on how much data you use for each instance.
i originally thought it was that but no i only had ~780 things being rendered
and the loop happened like halfway
ive split to blocks of 100 instances which seems to have fixed
That's weird. How many blocks will you have in total? If a lot, you could consider using the indirect methods which can render unlimited instances
not sure yet, but i doubt it would be enough to seriously impact anything
i should probably also experiment with the block size to see how big i can make it before strange things occur
Oh, the next line on the documentation:
By default, Unity uses an objectToWorld matrix and a worldToObject matrix for each instance, which means you can render a maximum of 511 instances at once. To remove the worldToObject matrix from the instance data, add #pragma instancing_options assumeuniformscaling to the shader.
well there you go
In case you are wondering, those limits are not totally arbitrary, they are 2^10-1 and 2^9-1 respectively which might have something to do with some technical details
Actually makes even more sense why ^10 was chosen. Matrices (4x4) are made of 16 floats each 4 bytes in size. that comes out 65536 bytes in total which is 2^16. You can basically use ushort (16 bit integer) to index within the buffer. When 2 matrices are stored for each instance, you can only store half as many instances
thats makes sense
i like working with this stuff (draw... render...) its interesting and can make pretty cool stuff
Yeah, it matches very closely what graphics libraries like OpenGL have by default. Unity just abstracts those calls into gameobjects and tries to rejoin them back with different batching/instancing techniques. Using those methods directly is often faster than going through the whole pipeline to only end up in similar calls to the graphics library
yeah wheneevr i make stuff that lets me draw directly i feel a lot free-er than in unity... like if i want to draw a line its just a function rather than a whole gameobject, object ref, whatever
but i guess both are good and having with these funcs are useful
i just wish there was some way to have colliders like render/drawmeshinstanced that would be great
I think the problem with that is how the physics engines like PhysX optimize things. The objects are always placed in some spatial structures that allow very fast collision checks and adding and removing from those every frame would probably be quite slow. With rendering it doesn't add much overhead to just add one more object to the render queue, but with physics you would probably have to do quite some more calculations. Of course you have the ray/box/spherecast methods which can be used bit similar to that every frame
that is true...
some way to separate collision from individual objects at all though would be nice
(other than using weird stuff like tilemap collider that i have done in the past lol)
There is a new low level 2D physics API. ECS physics could also be an option for 3D physics without gameobjects.
The only thing I found was the "2D Physics Low-Level API" in Planned section of the roadmap, is it something different?
Looks really interesting. Weird it is still marked as Planned, usually they update the roadmap when even the beta release is out