• 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

  • 相关阅读:
    jsp 认知(2)
    jsp 认知
    Java 匿名类
    Usage of readonly and const
    Javascript 原型继承(续)—从函数到构造器的角色转换
    JavaScript 原型继承开端
    JS 函数调用
    Javascript Basic Operation Extraction
    JS单词形式的运算符
    git问题收集
  • 原文地址:https://www.cnblogs.com/luxishi/p/7419025.html
Copyright © 2020-2023  润新知