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.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Making shader_feature depend on another shader_feature

Discussion in 'Shaders' started by TheDeveloper10, Oct 9, 2021.

  1. TheDeveloper10

    TheDeveloper10

    Joined:
    Feb 1, 2017
    Posts:
    4
    I just created a shader that takes around 10min. to compile each time a single change is made(it has like 12 shader_features). Some of the shader_features:

    #pragma shader_feature ENABLED_NORMAL
    #pragma shader_feature ENABLED_NORMAL_STRENGTH
    #pragma shader_feature ENABLED_NORMAL_AFFECTS_RIM
    #pragma shader_feature ENABLED_RIM_LIGHT

    In this case both ENABLED_NORMAL_STRENGTH and ENABLED_NORMAL_AFFECTS_RIM depend on ENABLED_NORMAL - if ENABLED_NORMAL exist then they can exist otherwise they won't be used. I tried to do the following:

    #pragma shader_feature ENABLED_NORMAL
    #ifdef ENABLED_NORMAL
    #pragma shader_feature ENABLED_NORMAL_STRENGTH
    #pragma shader_feature ENABLED_NORMAL_AFFECTS_RIM
    #endif
    #pragma shader_feature ENABLED_RIM_LIGHT

    but it looks like it slows the compilation even more. Why is it happening? Can you please help? Thank you in advance!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,248
    The usual solution to this is to not make them separate shader feature lines.
    Code (csharp):
    1. #pragma shader_feature _ ENABLED_NORMAL ENABLED_NORMAL_STRENGTH ENABLED_NORMAL_AFFECTS_RIM ENABLED_NORMAL_STRENGTH_AFFECTS_RIM
    If you’re using a custom shader editor, you can choose the option you need from the options the user has selected. If you’re not using a custom editor, you’d need to use a
    [KeywordEnum()]
    material property drawer, as well as modify the keyword names slightly to conform to how that feature functions.
    https://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html

    The other thing to think about is if having this many variants is actually helpful or not. It may be faster to not have unique variants for everything. Using just a basic
    if() {}
    in your shader code to enable and disable features can end up being faster in real usage than having hundreds of keywords on modern GPUs.
     
    TheDeveloper10 likes this.
  3. TheDeveloper10

    TheDeveloper10

    Joined:
    Feb 1, 2017
    Posts:
    4
    I am pretty sure I can make this idea work quite well with a custom editor. Thank you, you just saved me so much time!
     
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,856
    and
    produce exactly the same set of variants.
    Pragma directives cannot depend on other pragma directives, so
    #ifdef ENABLED_NORMAL
    is ignored.
     
  5. awardell

    awardell

    Joined:
    Feb 5, 2014
    Posts:
    71
    Hypothetically, what would determine this? I'd imagine that if you had lots of materials rendering with different variants, that would likely be slower than just causing branches with
    if() {}
    . But if your materials were all using the same variant or your objects were sharing a material, then variants would be faster. Even if you had hundreds of variants, it would only use a few. Am I accurate in my thinking?
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,248
    Basically, yeah.
     
  7. BOXOPHOBIC

    BOXOPHOBIC

    Joined:
    Jul 17, 2015
    Posts:
    481
    I would say yes when it comes to SRP Batcher (batching object by shader), having one variant should be faster than having many shader variants.
     
    awardell likes this.