美文网首页
自定义Unity材质Inspector之关键字枚举(Keywor

自定义Unity材质Inspector之关键字枚举(Keywor

作者: 星易乾川 | 来源:发表于2017-07-02 13:19 被阅读0次

<转>我也忘了转自哪里,抱歉,感谢原作者

在这一篇文章中,我们要介绍关键字的枚举类型。

在平时我们书写Shader的过程中都会定义很多的关键字来区分shader的不同用途和功能,当然Unity内置的关键字宏也很多,比如如下代码摘自Lighting.cginc

inline fixed4 LightingLambert (SurfaceOutput s, UnityGI gi) { fixed4 c; c = UnityLambertLight (s, gi.light);   #if defined(DIRLIGHTMAP_SEPARATE) #ifdef LIGHTMAP_ON c += UnityLambertLight (s, gi.light2); #endif #ifdef DYNAMICLIGHTMAP_ON c += UnityLambertLight (s, gi.light3); #endif #endif   #ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT c.rgb += s.Albedo * gi.indirect.diffuse; #endif   return c; }

但这简单的几句代码里就定义了 DIRLIGHTMAP_SEPARATE,LIGHTMAP_ON,DYNAMICLIGHTMAP_ON,UNITY_LIGHT_FUNCTION_APPLY_INDIRECT 这4个关键字宏。

通常定义这些编译宏的好处就是在最少的代码完成最多的功能,而这些宏是给编译器看的。

对于这些宏的开启与关闭,我们最常见的就是直接在代码里面对齐进行关闭,但这样的操作往往是依赖图形工程师或技术美术的支持,普通的美工和其他人是不敢随便动的。那有没有一种方式,提供一个简单的选择界面,让普通美工或策划来控制这些宏的开启和关闭呢?

答案当然是有,这就是今天的介绍内容。内容依然来自Unity的官方文档(MaterialPropertyDrawer),pass:官方文档中有不少错误的地方,希望博友注意哦!

1、最简单的一种:Toggle 无参

//当勾选上时,定义_FANCY_ON这个宏
[Toggle]_Fancy("Fancy?",Int)=0

也就是当勾选这个参数时,就表示定义了_FANCY_ON这个宏,在代码中使用时#if _FANCY_ON 或 #if defined(_FANCY_ON)  或 #ifdef _FANCY_ON 结果为真,完整源码如下:

Shader "MaterialPropertyDrawer/MaterialPropertyDrawerKeywordEnumToggleNull" {     Properties     {         //当勾选上时,定义_FANCY_ON这个宏         [Toggle] _Fancy ("Fancy?", Int) = 0     }     SubShader     {         pass         {             Tags{ "LightMode"="ForwardBase"}             CGPROGRAM             #pragma shader_feature _FANCY_ON             #pragma vertex vert             #pragma fragment frag             #include "UnityCG.cginc"               struct vertOut{                 float4 pos:SV_POSITION;                 float4 color:COLOR;             };             vertOut vert(appdata_base v)             {                 vertOut o = (vertOut)0;                 o.pos=mul(UNITY_MATRIX_MVP,v.vertex);                                  o.color=float4(1,0,0,1);//红                                  #if _FANCY_ON                     o.color=float4(0,1,0,1);//绿                 #endif                                  return o;             }             float4 frag(vertOut i):COLOR             {                 return i.color;             }             ENDCG }//end pass } }

2、看上去更易理解的Toggle:有参

其实这种跟上面的那种是一样的,只是Toggle里面带有宏参数,在Toggle里面定义宏的名字,可以跟外面的不一样

// Will set "ENABLE_FANCY" shader keyword when set
[Toggle(ENABLE_FANCY)]_Fancy("Fancy?",Float)=0

还是上面类似的例子,源码如下:

Shader "MaterialPropertyDrawer/MaterialPropertyDrawerKeywordEnumToggleNull" { Properties {         [Toggle(FANCY_ON)] _Fancy ("Fancy?", Int) = 0 } SubShader { pass{             Tags{ "LightMode"="ForwardBase"}             CGPROGRAM             #pragma shader_feature FANCY_ON             #pragma vertex vert             #pragma fragment frag             #include "UnityCG.cginc"             #include "Lighting.cginc"               struct vertOut{                 float4 color:COLOR;             };             vertOut vert(appdata_base v)             {                 vertOut o = (vertOut)0;                                  o.color=float4(1,0,0,1);//红                                  #if FANCY_ON                     o.color=float4(0,1,0,1);//绿                 #endif                                  return o;             }             float4 frag(vertOut i):COLOR             {                 return i.color;             }             ENDCG }//end pass } }

3、更多状态的关键字定义

在上面的示例中都只定义了一个关键字的开和关,那要定义更多状态的关键字要怎么处理呢?使用KeywordEnum

// Display a popup with None,Add,Multiply choices.
// Each option will set _OVERLAY_NONE, _OVERLAY_ADD, _OVERLAY_MULTIPLY shader keywords.
[KeywordEnum(None,Add,Multiply)]_Overlay("Overlay mode",Float)=0

使用_Overlay一个变量来定义_OVERLAY_NONE,_OVERLAY_ADD, _OVERLAY_MULTIPLY三个关键字的互斥使用。

我们的示例如下:


Shader"MaterialPropertyDrawer/MaterialPropertyDrawerKeywordEnum"{    Properties{        [KeywordEnum(Red,Green,Blue)]_ColorMode("Color Mode",Float)=0    }    SubShader{        pass{            Tags{"LightMode"="ForwardBase"}            CGPROGRAM            #pragma shader_feature _COLORMODE_RED _COLORMODE_GREEN _COLORMODE_BLUE            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"             structvertOut{                float4pos:SV_POSITION;                float4color:COLOR;            };            vertOutvert(appdata_basev)            {                vertOuto=(vertOut)0;                o.pos=mul(UNITY_MATRIX_MVP,v.vertex);                o.color=float4(0,0,0,1);                                #if _COLORMODE_RED                    o.color=float4(1,0,0,1);                                #elif _COLORMODE_GREEN                    o.color=float4(0,1,0,1);                                #elif _COLORMODE_BLUE                    o.color=float4(0,0,1,1);                #endif                                returno;            }            float4frag(vertOuti):COLOR            {                returni.color;            }            ENDCG}//end pass}}

这样的使用,就给用户提供了一个下拉框来选择要激活哪一个关键字,如下所示:

这就可以任意切换了,O(∩_∩)O哈哈~

相关文章

  • 自定义Unity材质Inspector之关键字枚举(Keywor

    <转>我也忘了转自哪里,抱歉,感谢原作者 在这一篇文章中,我们要介绍关键字的枚举类型。 在平时我们书写Shader...

  • 自定义Unity材质Inspector之枚举类型(Enum)

    <转>我也忘了转自哪里,抱歉,感谢原作者 最近发现Unity的一个黑科技(其实很久以前就发现了,只是方便开头而已,...

  • 8.枚举和注解

    一、枚举 枚举的二种实现方式: 自定义类实现枚举 使用 enum 关键字实现枚举 自定义类实现枚举: 不需要提供s...

  • 枚举类与注解

    1.自定义枚举类: 2.使用enum关键字定义枚举类:image.png 其余步骤与自定义枚举类一致

  • Unity插件之Odin 2.Inspector使用-Group

    Unity插件之Odin 2.Inspector使用-GroupAndLayout 简介 Odin定义了很多的属性...

  • CPP class

    class definition example: Keyword this 关键字:thisThe keywor...

  • Java篇-枚举的使用

    一 : 自定义枚举类 枚举类调用 二 : 使用enum关键字定义枚举类 让枚举类实现接口: 可以让不同的枚举类的对...

  • Shader笔记——自定义Material面板

    Unity为用户提供了专门快速实现自定义材质面板的基础类:MaterialPropertyDrawer。 1.0不...

  • 枚举2--java25(02/18/2016)

    一、枚举类1.如何自定义枚举类2.如何使用enum关键字定义枚举类:将枚举类对象相同部分删掉,同时中间用逗号分隔。...

  • id & instancetype

    一、 instancetype关键字 官方文档 先进的OC Use the instancetype keywor...

网友评论

      本文标题:自定义Unity材质Inspector之关键字枚举(Keywor

      本文链接:https://www.haomeiwen.com/subject/brbncxtx.html