Using multicompile with includes

Hi,

Has anyone had any success mixing multi-compile with cginc includes? Its not working for me, but frustratingly if i comment out the multi-compile line and replace it with a simple define the exact same code works great.

For example

#pragma multi_compile SKINNERMODE_MATRIX, SKINNERMODE_MATRIXPACKED

#ifdef SKINNERMODE_MATRIXPACKED
            #include "Assets/GPUSkinner/Shaders/FrameworkIncludes/SkinnerLib_MatrixPacked_F4.cginc"  
#endif
      
#ifdef SKINNERMODE_MATRIX
            #include "Assets/GPUSkinner/Shaders/FrameworkIncludes/SkinnerLib_MatrixM44_M44.cginc"          
#endif

fails with various ā€˜pipe’ errors e.g ā€˜Error waiting for read external process: The pipe has been ended.’

whilst

#define SKINNERMODE_MATRIXPACKED

#ifdef SKINNERMODE_MATRIXPACKED
            #include "Assets/GPUSkinner/Shaders/FrameworkIncludes/SkinnerLib_MatrixPacked_F4.cginc"  
#endif
      
#ifdef SKINNERMODE_MATRIX
            #include "Assets/GPUSkinner/Shaders/FrameworkIncludes/SkinnerLib_MatrixM44_M44.cginc"          
#endif

works fine.

I’ve tried numerous variations, tried adding all the includes and then checking the defines in the cginc files themselves etc and it just never works. Starting to think multi-compile is some how special compared to just using a define and is thus doing something different.

Yet if i leave the multi-compile line in and then add a define for the first value in the multi-compile then Unity complains that the same value has been defined twice, so there shouldn’t be any difference between them

Anyone got any ideas?

sounds like obscure syntax, were there no results for multicompile and includes example shaders, when searching codewords for unity codes from pastebin etc?

IIRC you can also use #if instead of #ifdef with multi_compile – tried that too?

Yep, searched the internet no luck.

I started using ifdef when I found checking for Unity defines such as UNITY_COMPILER_HLSL2GLSL would fail, at least I think it was that, something made me switch to ifdef.

Tried switching back to plain #if, no luck, though I get different errors, unmatched #endif.

I just don’t understand. As I said replace the multi-compile with a simple define and everything works great. So it must be something special with multi-compile. Tried in 4.3.4 and 4.5.0 no luck. So frustrating as it means i’ll have to hand code dozens of shaders ;(

FYI
In Unity 4.3.4 using pragma multi-compile I get the error ā€˜Shader compilation produced no results (compiler crashed?)’.
In Unity 4.5.0 I get various pipe and file errors.

In all cases commenting out multi-compile and using define works great.

could be faster work wise to just make 2 materials and switch them, it’s maybe 1 draw call of difference. hope there is an answer to this though.

My code was just an example to show the problem. Its not an issue about materials, drawcalls or switching.

I have 5 different input modes for supplying the data (I just showed two in the example) each with two or three different algorithms that work on the data, all of which would need to work for standard Unity shader types (diffuse, specular, bumpdiffuse, bumpspec, reflection … etc), so the actual permutations become pretty big. Using multi-compile was an attempt to reduce the sheer number of shader versions i’d have to write by hand.

Interestingly #pragma’s don’t seem to work when included from a .cginc file. When I put the #pragma surface directive inside a .cginc file Unity complained that it could not find a surface function reference (not exact wording). My guess is that a pass for #pragma’s is done before processing #include I find this inconsistent and was also inconvenient in my case.

did you try testing multicompile with the built in .cginc to see if there is the same error, if it’s affected by file path? Unity - Manual: Built-in shader include files
sounds too advanced for me, i am curious about what code constructs you are arranging, multi compiles with different cginc’s sounds like alot of code being permutated.

That’s true, i’ve found the same thing, i’d even go as far as suggesting that no pragma’s may exist in include files, since none that I’ve happened to try have worked (e.g. only_renderers or exclude_renderers).

I don’t think file path has any bearing though.
For now I guess i’ll just have to accept that multi-compile simply doesn’t work correctly when trying to use its defines to decide which includes to add.

If you can reproduce this in a very simple setup (just color shader, two includes, two multi_compile options) then I’d say submit a bug report… you can also try this workaround —which, based on your observations, should work— to ā€œjust get on with itā€:

#pragma multi_compile MC_ONE MC_TWO

#if MC_ONE
  #define INC_ONE 1
#elif MC_TWO
  #define INC_TWO 1
#endif

#if INC_ONE
  #include "one.cginc"
#elif INC_TWO
  #include "two.cginc"
#endif

Yeah I will submit a bug when I get a chance.

Nice try with that workaround, but it was one of the many things I tried before posting here :wink:

OMG I’ve fixed it! At least I think so, it all compiles without warnings now.

My mistake?

The bloody comma in between the names defined in #pragma multicompile!

1 Like

I’ll be damned if I could understand any shader theory that was going around in this thread (pretty new to the stuff) but the fact that the answer was a mistake like this tickles me lol.

Nice work anyways would be cool to see some screens of the results?