Use Predefined Preprocessor Symbols for shaders.

I´d like to optimize the shaders in my project for different platforms. In C#, I make a lot use of preprocessor symbols, and I´m wondering if theres any way to use them in shader code. What I´d like to do is something like

 #if UNITY_IOS
         //some specific stuff here
    #else
        //regular stuff here
    #endif

I have figured out that it is possible to exclude a build target from the shader and use a fallback to get to an alternative version of it, but since the project is quiet big and has a lot of shaders, it would be quiet messy to always create multiple files of every shader. Most times, i just want to change one line of code, since some console versions of unity don´t support unlit shaders while unlit is necessary for the performance on mobile, so I really just need to do something like

       #if UNITY_Console
              Lighting On
        #else
             Lighting Off
        #endif

in every shader of the project.,

For anyone who stumbles upon this, like I did, here’s a potential solution.

SL-MultipleProgramVariants

In short you can add a line like this to the shader

#pragma multi_compile FANCY_STUFF_OFF FANCY_STUFF_ON

which will cause two(or more) version of the shader to be created with appropriate symbols/keywords defined. You can then select the symbol/keyword you need from C#

material.EnableKeyword("FANCY_STUFF_ON"); // for a single material
Shader.EnableKeyword("FANCY_STUFF_ON"); // globally, for all materials

This is not an exact equivalent of C#'s preprocessors symbols, since variant selection happens at runtime, but it is close enough for all practical purposes. If you want to squeeze out even more performance you can use #pragme shader_feature which apparently will not include unused variants in the build… how exactly it does that, I’m not sure, haven’t tested it myself.