I’m building a football stadium with thousands of moving plane primitives in the stands, that comprise a card stunt system. Each one will be coloured with a single colour, and will basically act like a pixel in an image, and when assembled together, they’ll recreate that image. I also want to be able to change the image, so in a “wave”, cards will gradually flip around and change to a new colour to reveal a new image within a second or two.
…and it works great. Very smooth. I can move them all around independently using matrices and pc.BUFFER_DYNAMIC. Currently however, they’re all the same colour. I’ve found I can change that one colour by adjusting the colour of the material’s diffuse property of the model that they’re all using, but how would I go about doing this on an individual basis for each board, any time I want?
The reason I suspect it’s possible is that the documentation in the first link above uses colour as an example of a property that you can change in this way:
“Each instance of the mesh can have a different limited amount of state (for example, position or color). It’s a technique suitable to drawing objects such as trees or bullets, say”.
Can I do something with the material, or do I have to use a completely different method to render each colour?
I’m hoping there won’t be many different colours per image, so if absolutely necessary I could probably work out a system of swapping out boards that belong to different vertex buffers, but I’d much rather just change the colour properties of each one, just like I’m currently doing with their positions as they animate around independently.
I don’t have the answer to this, I haven’t tried this. But I would very much like to know that myself. Maybe something for @mvaligursky?
If you would like to explore more, here is the default instancing vertex format, a thought would be to create a custom VertexFormat and include one more semantic for coloring per instance (to use later in a custom pixel shader). Still not sure if that’s the way to go!
What Leonidas says. You currently call pc.VertexFormat.defaultInstancingFormat get get default instancing format. You could copy the function above, and add something like this
Other option would be to create a single mesh, and generate quads to it yourself - that’d likely win in the performance as well, and ease of use. This is probably the closest example we have: https://playcanvas.github.io/#graphics/mesh-decals.html
Each decal is a quad positioned where you need it. It already has random color support. Personally, I would go this way for the best solution.
In general terms, you can do this with UV coordinates and one big image. Not sure of the PC version, but you would use instance # to lookup or derive UV coordinates for access into a texture (which could just be one pixel per card).
Thanks for the advice all (sorry, forgot to reply earlier) - I only ever needed a small handful of different colours, so I ended up just making a different vertex buffer per colour, which didn’t have a big performance impact, so it was fine for my purposes. Hopefully these suggestions can help others though.
Note that most of this is no longer needed for engine v2, as the instancing customization is now officially supported. This is the most relevant example: PlayCanvas Examples