Search Unity

Question The Use of FX Alongside Main Shaders

Discussion in 'Shaders' started by BlackSabin, Sep 23, 2022.

  1. BlackSabin

    BlackSabin

    Joined:
    Feb 27, 2021
    Posts:
    75
    I've been using shader graph for a good long while recreating a number of very fun and interesting visual effects. More recently I began trying to code them directly as I find it yields a much deeper control for all of the facets of shaders. Up until now though it has all been play and experimentation, getting myself used to the systems in place rather than coming up with something definitive that I could use for my game. I'm now at the point in my game's design and production that I need to start concerning myself with graphics, and I've come across a rather large design point that I've completely neglected and don't know how to direct myself.

    I have a toon shader that I use for all my materials. My models often use multiple materials to make up for this, no textures (normal maps aside). In several places I want to use a dissolve shader to give them a "teleport" effect, an "aura", snow, and many more. A given object can support more than one material... but when/how would I go about using this teleport effect? Do I need to specifically make it have a toon pass and then assign all the materials on my character to the new dissolve? Or should I have all my materials stem from a shader that has all the separate passes, thus allowing me to turn on/off all these at any time? Would that create needless stress on one's GPU? I'm not fond of needing 4-5 different shaders for each color I'll need...

    Are there best practices concerning these things? How have you done these in your games? I'm worried about starting any of these paths without knowing more and needing to start over later.

    EDIT: I kept referring to "displacement" instead of "dissolve" as I had intended.
     
    Last edited: Sep 23, 2022
  2. kruskal21

    kruskal21

    Joined:
    May 17, 2022
    Posts:
    68
    From my experience, I would recommend writing one shader that includes all of the features you need, especially if there is a signficant amount of shared code between your shaders. You can selectively turn these features on and off using shader keywords. Materials with different set of shader keywords will get compiled with separate shader variants, so there shouldn't be a performance penalty for not using a feature.

    To get started, you can take a look at for example the URP lit shader, which includes many lines like #pragma shader_feature _SOMEFEATURE. These tell the compiler to compile two versions of the shader - one with _SOMEFEATURE defined, and one with it not defined. You can then access this information in your code by
    Code (CSharp):
    1. #if defined(_SOMEFEATURE)
    2.     ...
    3. #else
    4.     ...
    5. #endif
    These if statements will not incur a runtime cost, since they are preprocessor directives that get translated to different variants of a shader, and each variant will only contain one of the branches.

    You can read more about shader keywords here: https://docs.unity3d.com/Manual/shader-keywords.html

    About the passes. I think in your specific case, its perfectly feasible to have toon shading and a dissolve effect in a single pass. You would call clip(float) at some point in your fragment function to create the dissolve effect (make sure to wrap your code in an #if directive that checks for the keyword definition), and then do you usual calculations for toon shading, and return the appropriate color.
     
    BlackSabin likes this.
  3. BlackSabin

    BlackSabin

    Joined:
    Feb 27, 2021
    Posts:
    75
    Thats phenomenal news! I was super concerned about making multiple materials for each effect, and the knowledge that the shader keywords make them separate is really reassuring. Thank you!
     
    kruskal21 likes this.