Add multiple materials to an object as "filters"

I would like to be able to add multiple materials to an object as “filters”
So something like:

Material 0: Main texture material
Material 1: Contrast material
Material 2: Brightness material

Where the filters are added in that order. However I find that the materials after the first are hidden. I know I could fix this by adding the filters into a single shader/material. But then I lose the ability to re-order filters, and add multiple of the same filter. Any thoughts?

The only way to do this would be to either very carefully control each material’s render queue, or use multiple renderers and set the sorting order on each, possibly with a custom script as the sorting order isn’t exposed on non-sprites.

Though you could also write a single shader that would let you do multiple simple operations, including multiple of the same. You could setup a structured buffer that is an array with a struct with an integer value for what type of operation you want to do, and a float4 for the color or data to use with that operation, and a for loop with a switch inside it that chooses which operation to do for each element of the structured buffer array.

StructureBuffers are exactly what I am looking for I think.

Another solution I found was using a bunch of blits. Basically grabbing the original texture, blitting it throught shader one, passing that output into shader 2, etc. However I have to do that every frame (this is for video textures), for every filter. I can’t find a lot of info on the performance of blit but I didn’t see a huge drops in frames?

Do you have an input on the performance of the buffer? Is there anything I need to lookout for?

Blits are a perfectly good option too. Shader wise, it’s a little cheaper than using a loop in the shader, but each blit is the same as rendering a full screen transparent quad over the entire view at whatever resolution the render texture you’re rendering to is. If the GPU you’re using has a lot of unused fill rate, then it can probably do a lot of blits without to much of an issue, but there is still an extra cost to each blit. And any GPU that has enough fill rate overhead can probably chew through dynamic loops in a shader without breaking a sweat, so the structured buffer option will probably still be the faster option overall.

The one thing to look out for with structured buffers is some mobile devices have very poor performance with them. Those same devices will choke on multiple blits though, likely even worse so. In that situation either method is going to be painful.

Got it. The buffer is working great. Thanks for the help!