Search Unity

Shader Properties : no bool support?

Discussion in 'Shaders' started by ronan-thibaudau, Nov 7, 2012.

  1. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    http://docs.unity3d.com/Documentation/Components/SL-Properties.html

    From what i can find there there's no support for bool input for shaders? I know i could workaround this but it will be very unintuitive to users to use a float or something similar to represent a bool. Am i missing something? Why is there not a simple bool one that maps to a checkbox?
     
    zanouk likes this.
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Nope, you'll have to use a float (or a range) to toggle between 1 and 0.
     
  3. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    Properties were designed as graphical wrappers for uniform variables of shaders. There is no support for boolean uniform variables, thus, there are no properties for them.

    Without doubt boolean uniform variables and in particular checkbox properties would be very useful and for some later version of Unity (after 4.0) they will be supported but not now.
     
    Last edited: Nov 7, 2012
    Bifooh7087 likes this.
  4. Elecman

    Elecman

    Joined:
    May 5, 2011
    Posts:
    1,372
    If the bool doesn't change during runtime, you can use a preprocessor directive:
    Code (CSharp):
    1. #pragma multi_compile FEATURE_OFF FEATURE_ON
    In your shader you can then do:
    Code (CSharp):
    1. #if FEATURE_ON
    2. //Some code here.
    3. #endif
    To get the bool on the Inspector as a checkbox, use a MaterialEditor script. More information here:
    http://www.martinpalko.com/muli-compile-unity/
    http://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html
    http://docs.unity3d.com/460/Documentation/Manual/SL-CustomMaterialEditors.html

    Edit:
    Even better, use a material property drawer:
    http://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html
     
    Last edited: Apr 30, 2015
    adamgryu likes this.
  5. i9mobile

    i9mobile

    Joined:
    Aug 8, 2013
    Posts:
    54
    try this on your shader properties:

    [MaterialToggle] _isToggled("isToggle", Float) = 0
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Or use #pragma shader_feature instead of #pragma multi_compile, then only the keywords that are used will be generated. mutli_compile will generate every permutation if it's used or not. However multi_compile can be used on a shader and allow keywords to be changed during runtime.
     
    skullthug likes this.
  7. monotoan

    monotoan

    Joined:
    Feb 13, 2015
    Posts:
    11
  8. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    Why would you use a Float for a boolean instead of Int?
     
  9. i9mobile

    i9mobile

    Joined:
    Aug 8, 2013
    Posts:
    54
    You can use INT on Shader Property, but it will be a float (or half) inside the shader CGPROGRAM, which is the code that will be sent to the graphics card.
    So there is no benefit to use float or int on the Shader Property...
    Shader Property is just a map for values from Unity Engine to send it to Shader CGPROGRAM
     
  10. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    That’s not quite right.

    There are two reasons why you’d use a Float instead of an Int for the property.

    First is because numerical material properties are always floats. Even though the properties have the option to define it as an
    Int
    , Unity ignores that and the property is always a float. Why? No idea! But that’s how it is. Material properties are always floats, unless they’re textures.

    Second, is when you’re using a
    [Toggle]
    material property drawer it doesn’t matter what the value is since it’s never used by the shader. It’s just a placeholder for the inspector to use to allow the user to toggle a keyword on or off.

    But that sounds like what @i9mobile said was mostly correct, and I said it wasn’t right. Well, that’s because inside the
    CGPROGRAM
    you can totally have it be a float, or int, or uint, and it absolutely matters to the shader. Just because the material itself can’t do anything but floats doesn’t mean the shader itself can’t. Unity is smart about looking at how it’s defined in the shader code and converts the value to whatever type is needed when sending it to the GPU. It just doesn’t matter in this particular case because the numerical value isn’t directly being use.
     
  11. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    That's good to know... thanks for the explanation!
     
  12. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    Hey I have another quick question... what is the difference between Float and float?

    I've seen some shaders with:
    Code (CSharp):
    1. _AnimLen("Animation length in seconds", Float) = 0
    and others with:
    Code (CSharp):
    1. _AnimLen("Animation length in seconds", float) = 0
    I had trouble googling it because google is case insensitive and none of my other keywords narrowed the results to an answer.
     
    Kokowolo likes this.
  13. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    The difference is
    Float
    is what the documentation says to use, and
    float
    would produce an error that was probably too cryptic for most people to understand what it meant, so they made it work too.

    Basically, there isn't a difference.
     
    Kmm__, Kokowolo and lclemens like this.
  14. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    Thanks yet again bgolus. I owe you beer.
     
    Kokowolo likes this.