Write a sprtie shader with ordered multiple effects which can be deactivated

hello, I searching since 2 days how to combine image effect in a dynamic way for a sprite shader.
I discovered we could use shader program variant and keyword to enable or desable shader functionnnality (so image effect in my case), but I also want to order the enable effects. I haven’t find a way to do that.

is it possible to ordered shader functionnality in a shader or in a c# script ?

shader program variant : Unity - Manual: Declaring and using shader keywords in HLSL
enable/desable shader functionnnality : Shader variants and multiple passes - Unity Engine - Unity Discussions

There are fairly complicated and expensive ways to do this that I can think of, and there’s brute force ways using a ton of variants, or you can just leave the effects as separate sprite layers rather than controlling it via the shader which will likely be faster.

So the brute method I can think of is basically have multiple groups of the same effect, then use a KeywordEnum to select between them.

Some bits of shader code:

// properties
[KeywordEnum(Off, One, Two, Three)] _Effect_A_Order ("Effect A Order", Float) = 0
[KeywordEnum(Off, One, Two, Three)] _Effect_B_Order ("Effect B Order", Float) = 0
[KeywordEnum(Off, One, Two, Three)] _Effect_C_Order ("Effect C Order", Float) = 0

// pragmas
#pragma shader_feature _ _EFFECT_A_ORDER_ONE _EFFECT_A_ORDER_TWO _EFFECT_A_ORDER_THREE
#pragma shader_feature _ _EFFECT_B_ORDER_ONE _EFFECT_B_ORDER_TWO _EFFECT_B_ORDER_THREE
#pragma shader_feature _ _EFFECT_C_ORDER_ONE _EFFECT_C_ORDER_TWO _EFFECT_C_ORDER_THREE

// shader code
// group one
#if _EFFECT_A_ORDER_ONE
    // do effect A code
#endif
#if _EFFECT_B_ORDER_ONE
    // do effect B code
#endif
#if _EFFECT_C_ORDER_ONE
    // do effect C code
#endif

// group two
#if _EFFECT_A_ORDER_TWO
    // do effect A code
#endif
#if _EFFECT_B_ORDER_TWO
    // do effect B code
#endif
#if _EFFECT_C_ORDER_TWO
    // do effect C code
#endif

// group three
#if _EFFECT_A_ORDER_THREE
    // do effect A code
#endif
#if _EFFECT_B_ORDER_THREE
    // do effect B code
#endif
#if _EFFECT_C_ORDER_THREE
    // do effect C code
#endif

It can obviously balloon to a pretty huge shader to manage, but does what you want. For your own personal sanity I would try to make each effect it’s own function so you don’t have to write it all out for each group which would be error prone, especially if you want to tweak the effect.

Thanks a lot, I don’t know we can use a enum of keyword. This will work for what I want to do.
I planned to write all the effect functions in a .cginc and include the file, it’s a lot easier to maintain like that.
Otherwise you say about separate sprite layers, I don’t understand what do you mean.
Use different sprites like filters ? Or in a sprite renderer we can use real layers ?

Like filters, mostly. Only really works if your effects are relatively simple and mostly just adding / blending on top of each other. If you’re doing UV distortions or masks, you have to do this in a single shader, or get into much more complex rendering setups with render textures and multiple cameras.

Ok, thanks for your help.