Shader Keywords or Shader properties?

I am writing a custom material editor for a custom shader which has several options.

So for instance, let’s say one of those option is for border on or off.

(a) I could use the #pragma multi_compile Border_On Border_Off which would result in two versions of the shader. #if Bevel_On … do something #endif

(b) I could add a property to the shader like _BevelFlag (float) and somewhere in the Shader add … if (_BevelFlag = 0) do something…

My question is which is more efficient? If I have only one flag, I guess having two versions of the shader isn’t too bad but what if I have several options. Won’t I potentially end up with lots of permutations of that shader?

What are the pros and cons of using the Shader Keywords / Do’s and Don’ts ?

Thanks

An if inside a shader is generally fairly slow, because of the parallel nature of the GPU. So a compiler directive if can speed up the resulting shaders. In many cases a hardcoded value also results in faster code than using a value that can be adjusted outside the shader. So, compiler directives generally create faster shaders at the expensive of making more variations of that shader. I guess it’s up to you to decide how to balance shader optimization and shader variation count. (Compile time also.)

Also note that objects with the same shader can be batched together, but objects with different shaders can’t. So if you take the optimization to the extreme and give every object its own shader, batching will be disabled completely. That way you might actually end up reducing the overall speed. There is no general rule, but for a complex if in a shader it might well be worthwhile to put it in a #if. For simpler differences, you probably want to keep the batching option.