4.ToggleDrawer

4.自定义材质面板-自带Shader材质属性绘制类-ToggleDrawer


4.1 知识点

自带Shader材质属性绘制类是什么

通过之前的学习,我们知道通过继承 MaterialPropertyDrawer(材质属性绘制器)实现的类可以自定义 Shader 属性在 Inspector 窗口的外观。而自带 Shader 材质属性绘制类指的就是 Unity 内部实现好的、继承自 MaterialPropertyDrawer 的绘制类,可以让我们在 Shader 属性语句块中直接使用,使属性在 Inspector 窗口中具备特殊样式,从而方便地进行材质球参数设置。

ToggleDrawer类

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

使用场景包括:

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

用法是在属性语句块中声明属性时,在属性前加上 [Toggle] 或 [Toggle(自定义名称)],格式为:[Toggle]_属性名(“属性名”, Float) = 0或1。

创建 Shader 时,使用 [Toggle] 的属性和条件分支语句,尝试动态切换是否使用贴图。例如:

Shader "Unlit/Lesson04_ToggleDrawer"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        // 添加的 Toggle 属性
        [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"

            // ...

            sampler2D _MainTex;
            float4 _MainTex_ST;

            fixed _ShowTex;

            v2f vert(appdata appdata)
            {
                // ...
            }

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

                if(_ShowTex == 1)
                    col = tex2D(_MainTex, v2f.uv);
                else
                    col = fixed4(1,1,1,1);

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

该 Shader 可以动态切换是否使用贴图。


ToggleDrawer关联关键字

ToggleDrawer 可以与关键字编译指令结合使用,从而在材质面板中通过 Toggle 禁用或启用关键字,实现功能或特效的切换。通过简单的复选框,开发者可以在材质球的 Inspector 窗口中启用或者禁用特定的关键字。

使用方式包括:

  • ToggleDrawer 和关键词绑定
    当使用 Toggle 定义一个 Float 属性时,Unity 会自动根据属性值设置全局关键词。例如:[Toggle]_ShowTex(“ShowTex”, Float) = 0或1,默认生成的全局关键词为 _SHOWTEX_ON(当勾选时即属性值为 1 时激活)。我们也可以利用 Toggle 自定义关键词名,如 [Toggle(自定义关键词名)]。

  • 关键词连接
    可以使用 #pragma shader_feature#pragma multi_compile 来关联关键词。当在材质面板切换 Toggle 时,Unity 会启用或禁用对应的关键词,从而触发相应的 Shader 变体。注意,编译指令必须与 ToggleDrawer 的关键词一致,才能正确切换功能。

声明关键字,并且在片元着色器中使用变体分支语句

Shader "Unlit/Lesson04_ToggleDrawer"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        // 默认就会有一个关键字 _SHOWTEX_ON
        // 如果想要用 Toggle 来控制关键字的启用与禁用,那么一定需要去声明对应规则的关键字
        [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

            // 声明对应规则的关键字
            #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 appdata)
            {
                v2f v2f;
                v2f.vertex = UnityObjectToClipPos(appdata.vertex);
                v2f.uv = TRANSFORM_TEX(appdata.uv, _MainTex);
                UNITY_TRANSFER_FOG(v2f, v2f.vertex);
                return v2f;
            }

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

                // 条件分支语句
                // if(_ShowTex == 1)
                //     col = tex2D(_MainTex, v2f.uv);
                // else
                //     col = fixed4(1,1,1,1);

                // 变体分支语句
                #if defined(_SHOWTEX_ON)
                    col = tex2D(_MainTex, v2f.uv);
                #else
                    col = fixed4(1, 1, 1, 1);
                #endif

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

也可以动态切换是否使用贴图


此方式允许在材质面板中通过 Toggle 切换来动态启用或禁用贴图使用。

也可以使用自定义关键字,效果相同

Shader "Unlit/Lesson04_ToggleDrawer"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}

        // 默认就会有一个关键字 _SHOWTEX_ON
        // 如果想要用 Toggle 来控制关键字的启用与禁用,那么一定需要去声明对应规则的关键字
        [Toggle]_ShowTex ("ShowTex", Float) = 1

        // 自定义关键字
        [Toggle(_MY_TEST)]_ShowTex1 ("ShowTex1", Float) = 1
    }
    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

            // 自定义关键字
            #pragma shader_feature _MY_TEST

            #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;
            fixed _ShowTex1;

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

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

                // 条件分支语句
                // if(_ShowTex == 1)
                //     col = tex2D(_MainTex, v2f.uv);
                // else
                //     col = fixed4(1,1,1,1);

                // 变体分支语句
                // #if defined(_SHOWTEX_ON)
                #if defined(_MY_TEST)
                    col = tex2D(_MainTex, v2f.uv);
                #else
                    col = fixed4(1, 1, 1, 1);
                #endif

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

可以在 Shader 面板中查看定义好的关键字

通过以上方式,在材质面板中就能直观地看到 Toggle 控件与对应的全局关键词或自定义关键词的效果,从而实现对 Shader 变体的动态控制。


4.2 知识点代码

Lesson04_ToggleDrawer.shader

Shader "Unlit/Lesson04_ToggleDrawer"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}

        //默认就会有一个关键字 _SHOWTEX_ON
        //如果想要用toggle来控制关键字的启用与禁用 那么一定需要去声明对应规则的关键字
        [Toggle]_ShowTex ("ShowTex", Float) = 1

        //自定义关键字
        [Toggle(_MY_TEST)]_ShowTex1 ("ShowTex1", Float) = 1
    }
    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

            //自定义关键字
            #pragma shader_feature _MY_TEST

            #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;
            fixed _ShowTex1;

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

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

                //条件分支语句
                // if(_ShowTex == 1)
                //     col = tex2D(_MainTex, v2f.uv);
                // else
                //     col = fixed4(1,1,1,1);

                //变体分支语句
                // #if defined(_SHOWTEX_ON)
                #if defined(_MY_TEST)
                    col = tex2D(_MainTex, v2f.uv);
                #else
                col = fixed4(1, 1, 1, 1);
                #endif

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

Lesson04_自定义材质面板_自带Shader材质属性绘制类_ToggleDrawer.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson04_自定义材质面板_自带Shader材质属性绘制类_ToggleDrawer : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 自带Shader材质属性绘制类是什么?

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

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

        #endregion

        #region 知识点二 ToggleDrawer类

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

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

        //用法:
        //在属性语句块中声明属性时
        //在属性前加上[Toggle]或[Toggle(自定义名称)]
        //[Toggle]_属性名("属性名", Float) = 0或1

        #endregion

        #region 知识点三 ToggleDrawer关联关键字

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

        //使用方式:
        //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的关键词一致,才能正确切换功能

        #endregion
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏