自定义材质面板是通过对材质面板的UI样式做简单的调整可以使写出来的Shader更加方便易用。
Unity提供了基础类:
1.不同类型的DrawerClass
下面的表格是将MaterialPropertyDrawer内置不同类型的DrawerClass进行了汇总。
类型 | 描述 |
ToggleDrawer | 将float类型数据显示为开关,数值只能是0或者1,0为关闭,1为开启。 |
EnumDrawer | 枚举会将float类型数据显示为下拉列表,可以用于选择混合系数,比较方法等,也可以自定义。 |
KeywordEnumDrawer | 和EnumDrawer类似,也是将float类型数据显示为下拉列表,但是需要先定义shader keyword才能使用。 |
PowerSliderDrawer | 指数对应关系的滑动条,滑动条上的数值不在按照线性关系进行对应。 |
IntRangeDrawer | 将范围型的数据显示为只能设置整数的滑动条。 |
在编写Shader的时候,DrawerClass需要写在对应属性之前的"[ ]"中,类别的后缀称“Drawer”不需要添加,因为Unity在编辑的时候会自动添加。
1.1.Toggle
将float类型的数据以开关的形式在材质属性面板上显示,数值只能设置为0或1“0位关闭/1位开启”。
当开关开启,Shader关键词(keyword)会被Unity默认设置为“Property name” + “ON”,需要注意的是,关键词的所有字母必须大写。
例如: [Toggle] _Invert("Invert color?" , Float) = 0
Shader的关键词会被设置为 _INVERT_ON
除了使用Unity默认的关键词,也可以自定义一个特殊的关键词,
例如:[Toggle(ENABLE_FANCY) ] _Fancy("Fancy ?" , Float) = 0
括号内的名称ENABLE_FANCY即为自定义的Shader关键词。
1.2.Enum
枚举(Enum)将float类型的数据以下拉列表的形式在材质属性面板上显示,Unity 为用户提供了一些内置的枚举类,例如BlendMode、CillMode、ComparaFunction
例如:[Enum(UnityEngine.Rendering.BlendMode) ] _Blend("Blend mode" , Float) = 1
这是Unity内置的所有混合系数的枚举类,默认值为0表示选择第一个混合系数,默认值为1表示选择第二个混合系数,以此类推。最终在材质面板上的显示效果如图:
这些选项就是Shader中可以使用的所有混合系数。
也可以自定义枚举的名称/数值对,但是一个枚举最多只能自定义7个名称/数值对。
例如:[Enum(Off, 0, On, 1) ] _ZWrite("ZWrite" , Float) = 0
定义的枚举为“是否深度写入”,括号内为定义的名称/数值对,序号0对应Off,序号1对应On,中间用符号“ , ”间隔开,默认为序号0,也就是Off。
1.3.KeywordEnum
关键词枚举(KeywordEnum)跟普通的枚举类似,也就是将float类型的数据以 下拉列表的形式在材质属性面板上显示,只不过关键词枚举会有与之对应的Shader关键词,在Shader中通过“ #pragma shader_feature”或“ #pragma multi_compile”指令可以开启或者关闭某一部分Shader代码。
Shader关键词格式为:property name_enum name,属性名称+“下画线”+枚举名称,所有英文必须大写,并且最多支持9个关键词。举个例子:[KeywordEnum(None, Add, Multiply) ] _Overlay("Overlay mode" , Float) = 0
括号内的None, Add, Multiply 是定义的三个枚举名称,中间用“ , ”符号隔开。默认值为0,表示默认使用None。这三个选项所对应的Shader关键词分别为:_OVERLAY_NONE、_OVERLAY_ADD和_OVERLAY_MULTIPLY。
1.4.在编译指令中定义关键词
定义了ToggleDrawer或者KeywordEnumDrawer之后,如果想要正常使用,还需要在编译指令中声明Shader关键词。例如,上面定义的None、Add、Multiply关键词枚举,在编译指令中的代码如下:
#pragma shader_frature _OVERLAY_NONE _OVERLAY_ADD _OVERLAY_MULTIPLY
不同关键词之间需要用空格间隔开。
另外,也可以使用另一种编译指令定义关键词,代码如下:
#pragma multi_compile _OVERLAY_NONE _OVERLAY_ADD _OVERLAY_MULTIPLY
虽然表面上看似通过一个Shader文件实现了不同种情况,但是Unity会自动将不同情况编译成不同版本的Shader文件,这些不同版本的Shader文件被称为Shader变体(Variants),上述编译指令中包含三个Shader变体。
假设再添加一个指令:
#pragma shader_feature _INVERT_ON
本指令包含Toggle的关闭与开启两种情况,所以Unity最终会编译出2 * 3 = 6 个Shader变体。因此在使用大量shader feature 或 multi compile 指令的时候,无形之中会产生大量的Shader变体文件。
两种不同编译指令之间的区别如下:
- shader_feature:只会为材质使用到的关键词生成变体,没有使用到的关键词不会生成变体,因此无法在运行的时候通过脚本切换效果。
- multi_compile:会为所有关键词生成变体,因此可以在运行的时候通过脚本切换效果。
在Shader文件的属性设置面板中可以查看到本Shader生成的变体数量,如图
通过开启"Skip unused shader_Features"选项可以只查看使用关键词的变体数量,也可以关闭"Skip unused shader_Features"选项查看所有关键词的变体数量。如需确定具体的关键词是哪些,可以单击"Show"查看。
1.5.PowerSlider
指数滑动条(PowerSlider)会将范围型数值的属性显示为非线性对应的滑动条。滑动条上的数值不再按照线性关系进行对应,而是以指数的方式。举个例子:
[PowerSlider(3.0) ] _Brightness("Brightness" , Range(0.01, 1)) = 0
这是一个以3为指数对应关系的滑动条,其中,括号内的数值为指数,在材质属性面板上最终的效果如图:
通过该图不难发现,当数值为0.5的时候,滑动块并没有在滑动条的中间位置,这就是非线性对应。
下面先来看一下y=x3的函数曲线,如图所示,函数中的变量x就是滑动块所在位置,y就是属性的数值。
从曲线上的1号点可以看出,当滑块在0.5位置的时候,属性的数值只有0.1多一点,从曲线上的2号点可以看出,当属性数值为0.5点时候,滑块早就已经到了0.8左右的位置,这就是指数型滑动条的对应关系。
1.6.IntRange
同样也是将数值以滑动条的形式在材质属性面板上显示,只不过数值不再是float类型,只能是整数型数值。
例如:[IntRange] _Alpha("Alpha" , Range(0, 255)) = 100
能在滑块上使用区间[0,255]之间的整数数值。