US5L4——ToggleDrawer

本章代码关键字

1
[Toggle]        // 将float数据以开关的形式在材质属性面板上显示

自带Shader材质属性绘制类

通过之前的学习,我们知道通过继承 MaterialPropertyDrawer​(材质属性绘制器)实现的类,可以自定义 Shader 属性在 Inspector 窗口的外观

而自带 Shader 材质属性绘制类指的就是 Unity 内部实现好的继承自 MaterialPropertyDrawer​(材质属性绘制器)的绘制类
可以让我们在 Shader 属性语句块中直接使用,让属性在Inspector窗口中具备特殊样式,方便我们进行材质球参数设置

ToggleDrawer

作用:将 float​ 数据以开关的形式在材质属性面板上显示,数值只能设置为 0 或 1,0 为关闭,1 为开启

使用场景:

  1. 开启或关闭某个特效(比如是否启用边缘)
  2. 切换某些功能(比如是否使用纹理颜色)
  3. 控制条件分支逻辑

等等

用法:在属性语句块中声明属性时,在属性前加上 [Toggle]​ 或 [Toggle(自定义关键词名)]

1
[Toggle] _属性名("属性名", Float) = 01

使用示例(使用 if​ 语句在运行时动态切换分支逻辑):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Shader "TeachShader/Lesson130"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[Toggle] _ShowTex("ShowTex", Float) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;
fixed _ShowTex;

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = fixed4(0, 0, 0, 0);

if (_ShowTex == 1)
{
col = tex2D(_MainTex, i.uv);
}
else
{
col = fixed4(1, 1, 1, 1);
}

// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}

显示效果:

image

ToggleDrawer 关联关键字

ToggleDrawer​ 可以和关键字编译指令结合使用,达到在材质面板中通过 Toggle​ 禁用启用关键字的效果,从而切换功能或者特效等
它可以让开发者在材质球的 Inspector 窗口中通过简单的复选框启用或者禁用关键字

ToggleDrawer​ 控制关键字的启用或禁用,需要执行以下两个步骤:

  1. ToggleDrawer​ 和关键词绑定

    当我们使用 Toggle​ 定义一个 Float​ 属性时,Unity 会自动根据属性值设置全局关键词

    举例:[Toggle] _ShowTex("ShowTex", Float) = 0或1

    默认生成的全局关键词为 _SHOWTEX_ON​(勾选时为 1 时激活),我们也可以利用 Toggle​ 自定义关键词名 [Toggle(自定义关键词名)]

  2. 关键词连接

    可以使用 #pragma shader_feature​ 或 #pragma multi_compile​ 来关联关键词
    当我们在材质面板切换 Toggle​ 时,Unity 会启用或禁用对应的关键词,触发对应的 Shader 变体

    注意:编译指令声明的关键词必须与 ToggleDrawer​ 的关键词一致,才能正确切换功能

    1
    2
    3
    4
    5
    Properties
    {
    _MainTex ("Texture", 2D) = "white" {}
    [Toggle] _ShowTex("ShowTex", Float) = 1 // 默认会有一个关键字 _SHOWTEX_ON
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    // make fog work
    #pragma multi_compile_fog
    // 如果_ShowTex在材质面板被激活,则这里声明的关键字也会被激活
    #pragma shader_feature _SHOWTEX_ON
    //...
    ENDCG
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    fixed4 frag (v2f i) : SV_Target
    {
    // sample the texture
    fixed4 col = fixed4(0, 0, 0, 0);

    #if defined(_SHOWTEX_ON)
    col = tex2D(_MainTex, i.uv);
    #else
    col = fixed4(1,1,1,1);
    #endif

    // apply fog
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
    }

    使用自定义关键词的情况:

    1
    2
    3
    4
    5
    Properties
    {
    _MainTex ("Texture", 2D) = "white" {}
    [Toggle(_CUSTOM_KEYWORD)] _ShowTex("ShowTex", Float) = 1
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    // make fog work
    #pragma multi_compile_fog

    #pragma shader_feature _CUSTOM_KEYWORD
    // ...
    ENDCG
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    fixed4 frag (v2f i) : SV_Target
    {
    // sample the texture
    fixed4 col = fixed4(0, 0, 0, 0);

    #if defined(_CUSTOM_KEYWORD)
    col = tex2D(_MainTex, i.uv);
    #else
    col = fixed4(1,1,1,1);
    #endif

    // apply fog
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
    }

使用示例(使用不同的 Shader 变体去执行不同分支逻辑):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Shader "TeachShader/Lesson130"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[Toggle] _ShowTex("ShowTex", Float) = 1 // 默认会有一个关键字 _SHOWTEX_ON
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog

#pragma shader_feature _SHOWTEX_ON

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;
fixed _ShowTex;

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = fixed4(0, 0, 0, 0);

#if defined(_SHOWTEX_ON)
col = tex2D(_MainTex, i.uv);
#else
col = fixed4(1, 1, 1, 1);
#endif

// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}

显示效果:

image