Passing A Few Numbers Frequently to a Shader

In short:
How would you recommend that a small amount of simple numeric data be provided to a shader on a potentially-per-frame basis? Or am I worrying over nothing…?

To explain:
I’m starting work on a little prototype sprite-system, and I’m thinking about how to handle animations.

Now, I could use SequenceNodes to this end–that would work, I daresay. But my instinct is rather to use a single quad on which a shader renders the appropriate frame from within a single texture.

This would seem to then call for informing the shader of the current animation frame–potentially every frame.

Which leads me to my problem: my impression is that it’s generally unwise to call setShaderInput quite so often. Especially as I could potentially have a number of sprites on-screen at once.

Now, I’m aware of the possibility of using a PTA to a list-array, but I’m primarily aware of that feature in the context of large numbers of inputs–would it be a good choice for just one or two numbers?

Are there other options?

And conversely, do I have it entirely wrong about the performance impact of frequent calls to “setShaderInput”…?

Use a PTA for data that changes on a per-frame basis, because updating a PTA is more efficient than calling setShaderInput. This also goes for very small amounts of data, even an individual number.

If you have many sprites that have different versions of that number, you can use one PTA containing data for every sprite, and index into that in the shader based on a sprite index (depends a little on how you are doing sprites). That prevents Panda from having to respecify the inputs to the shader for every individual object.

For huge amounts of data, use a buffer texture.

If you are using instancing with setInstanceCount, you can use a vertex data array with a divisor for per-instance data.

Another tip: use setShaderInputs(input1=..., input2=...) instead of multiple setShaderInput calls if you want to set multiple inputs at once.

Ah, wonderful, and thank you for so comprehensive an answer! :slight_smile:

I’m glad to read that PTAs are indeed more efficient, and still the way to go even with a small number of inputs! :slight_smile:

It’s funny you should mention it, but in searching the forum regarding this matter I found a previous thread of mine in which you gave the same advice.

At the time I think that I overlooked it–I imagine because what I was doing there was well-served simply by using a PTA into a big array.

But I caught it this time, and quickly implemented it into a convenience-function of mine–although as I type this I realise that it somewhat obviates the convenience function, and so I’ve made a note to replace my function with the Panda function when I get around to it! :slight_smile:

1 Like