在这一篇文章中,我们要介绍关键字的枚举类型。
在平时我们书写Shader的过程中都会定义很多的关键字来区分shader的不同用途和功能,当然Unity内置的关键字宏也很多,比如如下代码摘自Lighting.cginc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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 无参
1
2
|
//当勾选上时,定义_FANCY_ON这个宏
[
Toggle
]
_Fancy
(
"Fancy?"
,
Int
)
=
0
|
也就是当勾选这个参数时,就表示定义了_FANCY_ON这个宏,在代码中使用时#if _FANCY_ON 或 #if defined(_FANCY_ON) 或 #ifdef _FANCY_ON 结果为真,完整源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
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里面定义宏的名字,可以跟外面的不一样
1
2
|
// Will set "ENABLE_FANCY" shader keyword when set
[
Toggle
(
ENABLE_FANCY
)
]
_Fancy
(
"Fancy?"
,
Float
)
=
0
|
还是上面类似的例子,源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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
1
2
3
|
// 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哈哈~