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關鍵字,從而達到控制輸出的目的。
目前還沒有應用到這方面知識,之後會進行更復雜的實現。