<轉(zhuǎn)>我也忘了轉(zhuǎn)自哪里,抱歉,感謝原作者
效果如圖:
shader 的編輯器擴(kuò)展分為2種方法:
是通過
UnityEditor
下的
ShaderGUI
類來實(shí)現(xiàn)的沟堡,形式比較近似于我們一般對(duì)unity編輯器的擴(kuò)展方式。
是通過直接在
shader
代碼上通過unity為我們預(yù)定義好的一些命令來擴(kuò)展护糖。
個(gè)人比較推薦使用第一種方法,第二種在嘗試時(shí)發(fā)現(xiàn)
①是第二種控件的種類有限朦促。限制還特別多,變量申請(qǐng)的不對(duì)的話,有時(shí)也不報(bào)錯(cuò),不利于維護(hù)雌贱。
②是文檔里還有錯(cuò)誤+沒說清楚的地方。
③是第一種方法創(chuàng)建的.cs文件是可以復(fù)用到偿短,我們可以只寫一個(gè).cs文件欣孤,然后跟好幾個(gè)shader文件進(jìn)行關(guān)聯(lián)。
先來說說第一種方法:
官方文檔:http://docs.unity3d.com/Manual/SL-CustomShaderGUI.html
CS代碼:
using UnityEngine;using UnityEditor;using System;public class TestShaderGUI : 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 CS_BOOL = Array.IndexOf(targetMat.shaderKeywords, "CS_BOOL") != -1; EditorGUI.BeginChangeCheck(); CS_BOOL = EditorGUILayout.Toggle("CS_BOOL", CS_BOOL); if (EditorGUI.EndChangeCheck()) { // enable or disable the keyword based on checkbox if (CS_BOOL) targetMat.EnableKeyword("CS_BOOL"); else targetMat.DisableKeyword("CS_BOOL"); } }}
shader
Shader "MyTest/TestShaderGUI"{ Properties { _MainTex("Texture", 2D) = "white" {} } SubShader { Tags{ "RenderType" = "Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert addshadow #pragma shader_feature CS_BOOL 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 CS_BOOL o.Albedo.gb *= 0.5; #endif } ENDCG } CustomEditor "TestShaderGUI"}
重點(diǎn)就是?#pragma shader_feature CS_BOOL
?CustomEditor "TestShaderGUI"
shader_feature
?是unity用來在shader中創(chuàng)建編譯指令變量的關(guān)鍵字昔逗,它的作用與multi_compile
幾乎是一樣的降传。?
我們通過創(chuàng)建的變量與TestShaderGUI
類中創(chuàng)建的控件來相關(guān)聯(lián),達(dá)到傳值的目的勾怒。?CustomEditor
的作用則是將shader
文件與cs文件關(guān)聯(lián)起來婆排。
#pragma shader_feature
和#pragma multi_compile
的問題可以看這里來進(jìn)行了解,官方文檔:?
http://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html
這里說一下我的理解:?
首先#pragma shader_feature
和#pragma multi_compile
的作用其實(shí)都是為了給unity所謂的"mega shaders"
和"uber shaders"
創(chuàng)建變量的笔链。?
唯一的區(qū)別就是沒有被使用過的shader_feature
變量將不會(huì)被編譯段只。?
所以在使用上區(qū)別就是在materials
的作用范圍內(nèi)用shader_feature
,而multi_compile
的范圍一般則是全局的鉴扫。?
例如有一種全局變量是multi_compile_fog
赞枕,則是跟開啟霧效相關(guān)的。
第二種方法:
官方文檔:http://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html
Shader代碼:
Shader "MyTest/TestShaderGUI"{ Properties { _MainTex("Texture", 2D) = "white" {} // 聲明需要的控件 [Toggle(S_BOOL)] _S_BOOL("S_BOOL", Int) = 0 [Toggle] _MyToggle1("MyToggle1", Float) = 0 [Toggle(MyToggle2)] _MyToggle2("MyToggle2", Float) = 0 [KeywordEnum(One, Two, Three)] _MyEnum("MyEnum", Float) = 0 } SubShader { Tags{ "RenderType" = "Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert addshadow // 創(chuàng)建變量坪创,用來接收控件的值 #pragma shader_feature S_BOOL #pragma shader_feature _MYTOGGLE1_ON #pragma shader_feature MyToggle2 #pragma multi_compile _MYENUM_ONE _MYENUM_TWO _MYENUM_THREE 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 S_BOOL o.Albedo.gb *= 0.5; #endif //#if _MYTOGGLE1_ON //o.Albedo.gb *= 0.5; //#endif //#if MyToggle2 //o.Albedo.gb *= 0.5; //#endif //#if _MYENUM_ONE //o.Albedo.gb *= 0.2; //#elif _MYENUM_TWO //o.Albedo.gb *= 0.5; //#elif _MYENUM_THREE //o.Albedo.gb *= 0.7; //#endif } ENDCG }}
這個(gè)就不細(xì)說了炕婶,上面的注釋已經(jīng)把重點(diǎn)標(biāo)出來了,嚴(yán)重不推薦用這種做法