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