下拉列表
shader中定义了很多参数,如果全部显示在Inspector上会显得比较杂乱,我们可以定义几种模式,在每种模式下只显示对应的参数,这时就可以对shader的编辑面板进行拓展。
举个例子,这里定义了模式1和模式2,在模式1下显示参数1和参数2,在模式2下显示参数3
宏定义
在开发过程中,我们希望shader中的部分逻辑功能只对某些图片或模型生效,这时就可以使用宏定义,将部分逻辑包起来,在面板上添加勾选框,勾选就表示打开这部分逻辑
比如,Material1和Material2都使用同一个shader,Material1勾选开启这部分逻辑,Material2未勾选忽略这部分逻辑,这就增加了shader的复用性
例如,这里勾选后会执行改变颜色的逻辑
具体实现
新建一个普通的unlit shader,定义一些参数
Shader "MyCustom/ShaderEditor"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
//表示shader中的一些参数
_parameter1 ("_parameter1", Float) = 1
_parameter2 ("_parameter2", Float) = 2
_parameter3 ("_parameter3", Float) = 3
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//定义宏
#pragma shader_feature CUSTOM_GREEN
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _parameter1;
float _parameter2;
float _parameter3;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = 1;
#ifdef CUSTOM_GREEN
//这里改颜色来表示某些逻辑操作
col = fixed4(0, 1, 0, 1);
#endif
return col;
}
ENDCG
}
}
//指定使用的Editor
CustomEditor "GUIExtension.ShaderCustomEditor"
}
在Editor目录下,新建如下脚本,对Inspector面板修改,注意这里继承基类ShaderGUI,命名空间也要加上GUIExtension
using UnityEditor;
using UnityEngine;
namespace GUIExtension
{
/// <summary>
/// 编辑shader的Inspector面板
/// </summary>
public class ShaderCustomEditor : ShaderGUI
{
//下拉列表中的选项
private string[] options = new string[]
{
"模式1",
"模式2",
};
//shader中定义的宏
private string KeyWord = "CUSTOM_GREEN";
//下拉列表的第几个选项
private int index = 0;
/// <summary>
/// 重绘Inspector面板
/// </summary>
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
Material targetMat = materialEditor.target as Material;
if (targetMat == null)
return;
EditorGUILayout.BeginHorizontal();
//下拉列表
index = EditorGUILayout.Popup(index, options);
EditorGUILayout.EndHorizontal();
switch (index)
{
case 0:
//选择pattern1时,显示_parameter1和_parameter2这两个参数
materialEditor.FloatProperty(FindProperty("_parameter1", properties), "参数1");
materialEditor.FloatProperty(FindProperty("_parameter2", properties), "参数2");
break;
case 1:
materialEditor.FloatProperty(FindProperty("_parameter3", properties), "参数3");
break;
}
//检查keyword是否开启
bool currentValue = targetMat.IsKeywordEnabled(KeyWord);
EditorGUI.BeginChangeCheck();
bool newValue = EditorGUILayout.Toggle("Green", currentValue);
if (EditorGUI.EndChangeCheck())
{
if (newValue)
{
targetMat.EnableKeyword(KeyWord);
}
else
{
targetMat.DisableKeyword(KeyWord);
}
}
}
}
}