Unity ShaderLab 框架全解析3
该系列主要是根据Unity官方文档和个人搜集的知识对Unity ShaderLab框架进行总结,比较基础,用于提高知识学习、复习的效率。对于文中给到的文章链接的作者表示感谢
Custom Shader GUI
有时shader的一些属性数据无法在编辑器面板上很好的展示出来,所有Unity允许用户自定义shader的显示面板,比如增加其他的控制方式。
在ShaderLab的Subshader外写下如下语句:
CustomEditor "name"
Unity会自动寻找名为“name”的类,该类需要继承自ShaderGUI 类,每一个定义上述语句的shader都会实例化一个“name”类的实例并执行里面的代码。
下面根据个人理解解释一下官方案例:
自定义的表面着色器:
Shader "Custom/Redify" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
__SubShader__ {
Tags { "RenderType"="Opaque" }
__LOD__ 200
CGPROGRAM
#pragma surface surf Lambert addshadow
#pragma shader_feature REDIFY_ON //通过shader_feature 编译指令定义关键字
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
#if REDIFY_ON //如果定义关键字,那么就改变输出的Albedo颜色
o.Albedo.gb *= 0.5;
#endif
}
ENDCG
}
CustomEditor "CustomShaderGUI"
}
自定义的CustomShaderGUI 类,继承自ShaderGUI:
using UnityEngine;
using UnityEditor;
using System;
public class CustomShaderGUI : ShaderGUI
{
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
// render the default gui
base.OnGUI(materialEditor, properties);
Material targetMat = materialEditor.target as Material;
// see if redify is set, and show a checkbox
bool redify = Array.IndexOf(targetMat.shaderKeywords, "REDIFY_ON") != -1;
EditorGUI.BeginChangeCheck();
redify = EditorGUILayout.Toggle("Redify material", redify);
if (EditorGUI.EndChangeCheck())
{
// enable or disable the keyword based on checkbox
if (redify)
targetMat.EnableKeyword("REDIFY_ON");
else
targetMat.DisableKeyword("REDIFY_ON");
}
}
}
和之前说的一样,在shader文件中写下如下语句:
CustomEditor "CustomShaderGUI"
Unity查找到对应的类并执行代码,另外关键的是,shader中使用编译指令定义了关键字——REDIFY_ON (这部分和编译指令以及shader辩变体有关,具体参考这篇文章:Shader入门(二十一)多重变体(Multiple Variants))。
总之,通过控制该关键字的定义,可以产生不通效果的shader。在CustomShaderGUI 类的OnGUI函数中进行检测,如果GUI发生变动(即checkbox被手动更改),那么根据redify 的值来控制是否定义shader当中的REDIFY_ON关键字,从而达到控制输出的目的。
目前还没有应用到这方面知识,之后会进行更复杂的实现。