How to create Compute Shader variants?

With normal shaders we can create multi compile shaders and enable or disable keywords to activate a certain variant of the shader for a particular draw call. Is there a way to do the same with compute shaders? The ComputeShader class has no EnableKeyword method. HLSL suggests to use interface and concrete classes and through polymorphic behaviour different functions can be run. Without any of these two we need to have an actual if-else block in shader code meaning more instructions and less performance .

So is there a way to do any of these two approaches with compute shaders?

You can’t use dynamic shader linking in Unity as far as know but you can compile multiple compute shader variants. The downside is that you have to manually declare every single one. There is no “mluti_compile”, “shader_feature” or EnableKeyword. You have to handle everything yourself. Here’s how you do it:

// compute shader
// 1st variant (kernel index 0)
#pragma kernel Main KEYWORD1
// 2nd variant (kernel index 1)
#pragma kernel Main KEYWORD1 KEYWORD2

[numthreads]
void Main() { ... }

// C#
// use variant 1
shader.Dispatch(0, ...);
// use variant 2
shader.Dispatch(1, ...);

It gets crazy if you have lot of variants but I didn’t find anything better.

2 Likes

At least it’s better than nothing when there are two or three keywords. Thank you so much for the help michal.

It’s better than nothing, but it’s a pain with many defines/keywords. I have posted a feature request. Please upvote if you feel the same.
https://feedback.unity3d.com/suggestions/multi-compile-for-computeshader

1 Like

Here you can follow a direct chat with @ (graphic engineer @ unity), and the (semi)automatic solution I made about this.

Upvote if you need it too : https://feedback.unity3d.com/suggestions/multi-compile-for-computeshader

3 Likes