In that case let’s have a look into the Unity’s code snippet:
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
// Do stuff
#else
// Dont' do stuff
#endif
That’s clear enough, if one of FOG_LINEAR, FOG_EXP or FOG_EXP2 is defined, it will make extra computations. Now let’s say I want change FogMode in runtime of my application. Magically it will also work.
That leads me to conclusion Unity compiles “three” versions of shader (one per each FogMode) and loads them then necessary in runtime? Does it REALLY true?
If it IS, that is great for performance, but how it is done? I mean there are ton of directives, it will lead to enormous different combinations in the end?
Could you lighten me up, whats the trick there? or Does the trick there?
Technically 4, one for each fog type and one for no fog. Unity does attempt to be smart and will only compile and load shader variants that exist in the project, but if you use no fog in one scene, linear fog in another, and exp fog in a third all three variants will be loaded all the time.
It’s very good for performance, especially on older (ie: mobile) hardware as it means only the calculations that are needed are ever done. But it does mean it’s possible to significantly bloat the size of your project if you’re not mindful of the variants you are using. For example the Standard Shader can account for nearly 600 megabytes by itself if you really are using every variant possible (which is really hard since that’s many thousands of variants).
Note that there are two forms of this, one for things set on the materials where you might have both options in the scene, and one for things which are generally set globally. It’s quite easy to blow up the shader compiler if you start providing too many options, as each option basically doubles the number of shaders which need to be created. I’ve easily hit hundreds of variants and have shaders which can take many minutes to compile when they’re changed. During development, I usually comment out the features I’m not working with to make the compile time workable…