自定义材质GUI,注释都有
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
public class MyLightShaderGUI : ShaderGUI
{
/// <summary>
/// 平滑源
/// </summary>
enum SmoothnessSource
{
Uniform, Albedo, Metallic
}
private Material _target;
private MaterialEditor _materialEditor;
private MaterialProperty[] _properties;
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
//base.OnGUI(materialEditor, properties);
_target = materialEditor.target as Material;
_materialEditor = materialEditor;
_properties = properties;
DrawMain();
DrawSecondary();
}
void DrawMain()
{
GUILayout.Label("主要贴图", EditorStyles.boldLabel);
//画出主贴图挂件
MaterialProperty mainTex = SelfFindProperty("_MainTex"); //主贴图属性
_materialEditor.TexturePropertySingleLine(
MakeLabel(mainTex,"主贴图(RGB)"),
mainTex,
SelfFindProperty("_Tint")); //生成挂件, 并在同一行生成颜色选择器
DrawMetallic();
DrawSmoothness();
DrawNorml();
DrawEmission();
_materialEditor.TextureScaleOffsetProperty(mainTex); //创建纹理缩放偏移ST
}
/// <summary>
/// 次要项
/// </summary>
void DrawSecondary()
{
GUILayout.Label("次要贴图", EditorStyles.boldLabel);
MaterialProperty detailTex = SelfFindProperty("_DetailTex");
_materialEditor.TexturePropertySingleLine(
MakeLabel(detailTex, "Albedo (RGB) multiplied by 2"), detailTex
);
DrawSecondaryNormal();
_materialEditor.TextureScaleOffsetProperty(detailTex);
}
void DrawSecondaryNormal()
{
MaterialProperty detailNormalTex = SelfFindProperty("_DetailNormalMap");
_materialEditor.TexturePropertySingleLine(
MakeLabel(detailNormalTex),
detailNormalTex,
detailNormalTex.textureValue ? SelfFindProperty("_DetailBumpScale") : null);
}
void DrawSmoothness()
{
//根据是否启用关键字设置金属源
SmoothnessSource source = SmoothnessSource.Uniform;
if (IsKeywordEnabled("_SMOOTHNESS_ALBEDO")) {
source = SmoothnessSource.Albedo;
}
else if (IsKeywordEnabled("_SMOOTHNESS_METALLIC")) {
source = SmoothnessSource.Metallic;
}
MaterialProperty smoothness = SelfFindProperty("_Smoothness");
EditorGUI.indentLevel += 2; //缩进级别+2
_materialEditor.ShaderProperty(smoothness, MakeLabel(smoothness));
EditorGUI.indentLevel += 1;
EditorGUI.BeginChangeCheck();
RecordAction("Smothness Source"); //支持回撤功能,必须在修改之前
source = (SmoothnessSource)EditorGUILayout.EnumPopup(MakeLabel("金属Source"), source); //枚举
if (EditorGUI.EndChangeCheck())
{
//如果修改了, 那么设置关键字
SetKeyword("_SMOOTHNESS_ALBEDO", source == SmoothnessSource.Albedo);
SetKeyword("_SMOOTHNESS_METALLIC", source == SmoothnessSource.Metallic);
}
EditorGUI.indentLevel -= 3;
}
void DrawMetallic()
{
MaterialProperty metallicMap = SelfFindProperty("_MetallicMap");
EditorGUI.BeginChangeCheck(); //当发生改变才执行此操作
_materialEditor.TexturePropertySingleLine(
MakeLabel(metallicMap),
metallicMap,
//使用金属贴图时隐藏滑块
metallicMap.textureValue?null:SelfFindProperty("_Metallic")
);
if (EditorGUI.EndChangeCheck())
{
SetKeyword("_METALLIC_MAP", metallicMap.textureValue);
}
}
void DrawNorml()
{
MaterialProperty normalTex = SelfFindProperty("_NormalMap");
_materialEditor.TexturePropertySingleLine(
MakeLabel(normalTex),
normalTex,
//当没有法线贴图将不会显示 缩放比例
normalTex.textureValue ? SelfFindProperty("_BumpScale") : null); //生成挂件, 并在同一行生成颜色选择器
}
//0~99用于亮度 0~3用于曝光
static ColorPickerHDRConfig emissionConfig =
new ColorPickerHDRConfig(0f, 99f, 1f / 99f, 3f);
void DrawEmission()
{
MaterialProperty map = SelfFindProperty("_EmissionMap");
EditorGUI.BeginChangeCheck();
_materialEditor.TexturePropertyWithHDRColor(
MakeLabel(map, "Emission (RGB)"),
map,
SelfFindProperty("_Emission"),
emissionConfig,
false
);
if (EditorGUI.EndChangeCheck())
{
SetKeyword("_EMISSION_MAP", map.textureValue);
}
}
MaterialProperty SelfFindProperty(string property)
{
return FindProperty(property, _properties);
}
static GUIContent staticLabel = new GUIContent();
static GUIContent MakeLabel (
MaterialProperty property, string tooltip = null
) {
staticLabel.text = property.displayName;
staticLabel.tooltip = tooltip;
return staticLabel;
}
static GUIContent MakeLabel (string tooltip = null
) {
staticLabel.tooltip = tooltip;
return staticLabel;
}
/// <summary>
/// 设置关键字,所设置的关键字,可以在shader文件中定义多编译的指令
/// </summary>
void SetKeyword(string keyword, bool state)
{
if(state)
_target.EnableKeyword(keyword);
else
_target.DisableKeyword(keyword);
}
/// <summary>
/// 是否开启了关键字
/// </summary>
bool IsKeywordEnabled (string keyword) {
return _target.IsKeywordEnabled(keyword);
}
/// <summary>
/// 使得支持撤销操作,使用时必须在改变前使用
/// </summary>
/// <param name="label"></param>
void RecordAction (string label) {
_materialEditor.RegisterPropertyChangeUndo(label);
}
}
#endif
My First Lighting Shader文件
#pragma shader_feature 这个指令如果没有使用到这个关键字比如没有创建金属贴图就不会编译这个变体
#pragma shader_feature _ _METALLIC_MAP //自定义金属贴图关键字
#pragma shader_feature _ _SMOOTHNESS_ALBEDO _SMOOTHNESS_METALLIC //自定义金属源关键字
#pragma shader_feature _EMISSION_MAP //这里发射自发光只在basePass中有
相应的shader文件 My_Lighting.cginc
float GetMetallic(Interpolators i)
{
#if defined(_METALLIC_MAP)
return tex2D(_MetallicMap, i.uv.xy).r;
#else
return _Metallic;
#endif
}
float GetSmoothness(Interpolators i)
{
float smoothness = 1;
#if defined(_SMOOTHNESS_ALBEDO) //定义从反照率设置平滑度
smoothness = tex2D(_MainTex, i.uv.xy).a;//DXT5中x存储在alpha通道中
#elif defined(_SMOOTHNESS_METALLIC) && defined(_MetallicMap)
//设置了金属贴图 并且 开启了以金属贴图为金属源
smoothness = tex2D(_MetallicMap, i.uv.xy).a;
#endif
return smoothness * _Smoothness;
}
float3 GetEmission(Interpolators i)
{
#if defined(FORWARD_BASE_PASS)
#if defined(_EMISSION_MAP)
return tex2D(_EmissionMap, i.uv.xy) * _Emission;
#else
return _Emission;
#endif
#else
return 0;
#endif
}
片元程序中