unity shader 編輯器擴展類 ShaderGUI


這應該unity5才出的新功能了,今天看文檔時剛巧看到了,就來嘗試了一下。

效果如圖:

這里寫圖片描述


shader 的編輯器擴展分為2種方法:

  1. 是通過UnityEditor下的ShaderGUI類來實現的,形式比較近似於我們一般對unity編輯器的擴展方式。
  2. 是通過直接在shader代碼上通過unity為我們預定義好的一些命令來擴展。

個人比較推薦使用第一種方法,第二種在嘗試時發現

①是第二種控件的種類有限。限制還特別多,變量申請的不對的話,有時也不報錯,不利於維護。

②是文檔里還有錯誤+沒說清楚的地方。

③是第一種方法創建的.cs文件是可以復用到,我們可以只寫一個.cs文件,然后跟好幾個shader文件進行關聯。


先來說說第一種方法:

官方文檔:http://docs.unity3d.com/Manual/SL-CustomShaderGUI.html

CS代碼如下:

 1 using UnityEngine;
 2 using UnityEditor;
 3 using System;
 4 
 5 public class TestShaderGUI : ShaderGUI
 6 {
 7     public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
 8     {
 9         // render the default gui
10         base.OnGUI(materialEditor, properties);
11 
12         Material targetMat = materialEditor.target as Material;
13 
14         // see if redify is set, and show a checkbox
15         bool CS_BOOL = Array.IndexOf(targetMat.shaderKeywords, "CS_BOOL") != -1;
16 
17         EditorGUI.BeginChangeCheck();
18         CS_BOOL = EditorGUILayout.Toggle("CS_BOOL", CS_BOOL);
19 
20         if (EditorGUI.EndChangeCheck())
21         {
22             // enable or disable the keyword based on checkbox
23             if (CS_BOOL)
24                 targetMat.EnableKeyword("CS_BOOL");
25             else
26                 targetMat.DisableKeyword("CS_BOOL");
27         }
28     }
29 }

Shader代碼:

 1 Shader "MyTest/TestShaderGUI"
 2 {
 3     Properties
 4     {
 5         _MainTex("Texture", 2D) = "white" {}
 6     }
 7     SubShader
 8     {
 9         Tags{ "RenderType" = "Opaque" }
10         LOD 200
11 
12         CGPROGRAM
13 
14         #pragma surface surf Lambert addshadow
15 
16         #pragma shader_feature CS_BOOL
17 
18         sampler2D _MainTex;
19 
20         struct Input
21         {
22             float2 uv_MainTex;
23         };
24 
25         void surf(Input IN, inout SurfaceOutput o)
26         {
27             half4 c = tex2D(_MainTex, IN.uv_MainTex);
28             o.Albedo = c.rgb;
29             o.Alpha = c.a;
30 
31             #if CS_BOOL
32             o.Albedo.gb *= 0.5;
33             #endif
34         }
35 
36         ENDCG
37     }
38     CustomEditor "TestShaderGUI"
39 }

重點就是 
#pragma shader_feature CS_BOOL 
CustomEditor "TestShaderGUI"

shader_feature 是unity用來在shader中創建編譯指令變量的關鍵字,它的作用與multi_compile幾乎是一樣的。 
我們通過創建的變量與TestShaderGUI類中創建的控件來相關聯,達到傳值的目的。 
CustomEditor的作用則是將shader文件與cs文件關聯起來。

#pragma shader_feature#pragma multi_compile的問題可以看這里來進行了解,官方文檔: 
http://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html

這里說一下我的理解: 
首先#pragma shader_feature#pragma multi_compile的作用其實都是為了給unity所謂的"mega shaders""uber shaders"創建變量的。 
唯一的區別就是沒有被使用過的shader_feature變量將不會被編譯。 
所以在使用上區別就是在materials的作用范圍內用shader_feature,而multi_compile的范圍一般則是全局的。 
例如有一種全局變量是multi_compile_fog,則是跟開啟霧效相關的。


第二種方法:

官方文檔: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

        // 創建變量,用來接收控件的值
        #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
    }
}

 原鏈接:http://lib.csdn.net/article/unity3d/41995


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM