Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Conditional Shader Compilation

Discussion in 'Editor & General Support' started by thesaint1987, Aug 11, 2011.

  1. thesaint1987

    thesaint1987

    Joined:
    Jul 13, 2011
    Posts:
    168
    Hi,

    I have a more complex material shader and want to add some additional switches. I am not sure what happens if I just use the traditional "if()" statement and compare a shader property with it, but I rather think that this would not be optimized away? Instead I am thinking of something like declaring a boolean shader property:

    Properties {
    _UseLambert ("Use Lambert", Boolean) = false,
    _ShowNormals ("Show Normals", Boolean) = false
    }

    And then just use

    #ifdef _UseLambert
    #else
    #endif

    in shader code an Unity would automatically generate different shaders depending on how I set the boolean values (which shall be Toggle-Boxes in the shader editor)?!

    Is the same thing possible somehow already instead of adding a new shader for each possible combination, which can get quite cumbersome (since 2^n)?

    regards
    chris
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    I don't think that boolean is possible, you would likely use a float.

    Also #ifdef will never work independent of the type as ifdef is for compile time properties which are defined through #define, not through runtime properites like Properties which at shader compilation do not even have a value.

    Runtime values would be checked through if (_UseLambert > 0) alike and then impact the code flow within the shader - this removes the need of all permutations. As long as you run on SM3 that should normally go through without problems

    The other alternative is: use 1 shader for each debug / test output you have there and add / remove clones of the object with the shader ... but thats relatively unfriendly to use.
     
  3. thesaint1987

    thesaint1987

    Joined:
    Jul 13, 2011
    Posts:
    168
    So you think that these switches are not too bad for performance? It is always a little hard to find out, at least since I have a pretty good graphic card which is most likely no reference for the target audience...

    BTW does Unity have this "Shader Complexity View" mode like the UDK Editor, where it shows the computational complexity of running shaders in a similar way how Unity currently displays the mipmaps? This would also help a lot...
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    if the gpu is a DX10+ class, an if is not so much of a problem anymore (on older gpus it would be, as they evaluated both side of a branch and just dropped the wrong).

    also I doubt you intend to use it in the game going by the name.


    And no, no way for shader complexity, but you can use Unity with the NVPerfHud for example :)
     
  5. thesaint1987

    thesaint1987

    Joined:
    Jul 13, 2011
    Posts:
    168
    Ok thanks again ;)... I will also try this PerfHud thing!
     
    Last edited: Aug 11, 2011
  6. MrBurns

    MrBurns

    Joined:
    Aug 16, 2011
    Posts:
    378
    This should work like the following:

    #pragma multi_compile CONDITION1 CONDITION2 etc.

    now you can use these conditions for conditional compilation:

    #if defined(CONDITION1)
    #else
    #endif

    and the in script just enable the proper conditions with

    Shader.EnableKeyword("CONDITION1");
    Shader.DisableKeyword("CONDITION2");

    etc.

    this should do what you want!
     
    Last edited: Aug 29, 2011
    IEdge and HiddenMonk like this.
  7. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    I assume that triggers a realtime recompiliation of the shader including a halt on mobiles?
     
  8. MrBurns

    MrBurns

    Joined:
    Aug 16, 2011
    Posts:
    378
    Well actually I have not tested it, but they use this kind of thing in their Water-FX shader, so I suppose it should work quite well?!
     
  9. MrBurns

    MrBurns

    Joined:
    Aug 16, 2011
    Posts:
    378
    I can now half safely verify that this will yield to static multi compilation and not to some realtime recompilation. The reason is that they use these switches in a render function. So it would be pretty odd if this would invoke recompilation in the mid of scene rendering ;)?!
     
  10. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,087
    It's costly using conditionals on mobile. But it also depends if you're using a constant or not with the conditional, or a varying. Using a number is faster. But only just. For example if the shader can early out with half the screen not evaluated, you could save more than the conditional costs.

    The only way to be sure is benchmark this sort of stuff.
     
unityunity