Unity Shader之自定义GUI
shader可以自己写一个shader gui,即写一个类继承自ShaderGUI,参考文档:https://docs.unity3d.com/Manual/SL-CustomEditor.html
这是完全没有问题的,但有时想简单点,不想这么麻烦。
那么可以使用unity给我们提供好的一些GUI,即MaterialPropertyDrawer,
参考文档:https://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html
总体来说,MaterialPropertyDrawers内置了4种最常见的面板:ToggleDrawer,EnumDrawer,KeywordEnumDrawer,PowerSliderDrawer。
类别 | 描述 |
ToggleDrawer | 把一个类型为float的属性显示为一个开关,它的值要么是0要么是1。当选中它时,Unity还会设置一个名为大写属性名_ON(可以自定义名字)的shader feature(需要在shader里使用”#pragma shader_feature”来定义它),我们可以在shader里用过#if、#ifdef或者#if defined关键词来判断它当前是否被开启。 |
EnumDrawer | 把一个类型为float的属性显示为一个下拉列表。可以使用UnityEngine.Rendering命名空间下的各种状态来设置对应的渲染状态,例如ZWrite、ZTest、Blend等。据实验推测,这个值不可以随便定义,老老实实用UnityEngine.Rendering。 |
KeywordEnum | 和EnumDrawer类似,也会把一个类型为float的属性显示为一个下拉列表,但不同的是它会定义一组shader keyword(需要在shader里使用”#pragma multi_compile”来定义它们)。这些keyword的名字是大写属性名_枚举名。同样,我们可以在shader里用过#if、#ifdef或者#if defined配合#elif来判断当前选择是哪个keyword。最多同时支持9个keywords。 |
PowerSliderDrawer | 显示一个非线性响应的滑动条,其中PowerSliderDrawer中的参数指定了底数,然后我们再根据Range()来指定范围。其实简单说来就是滑动条上的数值不再是均匀变化了,而是xslider进行变化,但我们在shader里还是可以直接访问到一个float数值。 |
下面的代码没有任何实际意义,只是为了演示四种面板:
1 Shader "Custom/Material Property Drawer Example" 2 { 3 Properties 4 { 5 // Header creates a header text before the shader property. 6 [Header(Material Property Drawer Example)] 7 // Space creates vertical space before the shader property. 8 [Space] 9 10 _MainTex ("Main Tex", 2D) = "white" {} 11 _SecondTex ("Second Tex", 2D) = "white" {} 12 13 // Large amount of space 14 [Space(50)] 15 16 // Toggle displays a **float** as a toggle. 17 // The property value will be 0 or 1, depending on the toggle state. 18 // When it is on, a shader keyword with the uppercase property name +"_ON" will be set, 19 // or an explicitly specified shader keyword. 20 [Toggle] _Invert ("Invert color?", Float) = 0 21 22 // Will set "ENABLE_FANCY" shader keyword when set 23 [Toggle(ENABLE_FANCY)] _Fancy ("Fancy?", Float) = 0 24 25 // Enum displays a popup menu for a **float** property. 26 // You can supply either an enum type name 27 // (preferably fully qualified with namespaces, in case there are multiple types), 28 // or explicit name/value pairs to display. 29 // Up to **7** name/value pairs can be specified 30 [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend Mode", Float) = 1 31 [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend Mode", Float) = 1 32 [Enum(Off, 0, On, 1)] _ZWrite ("ZWrite", Float) = 0 33 [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest ("ZTest", Float) = 0 34 [Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull Mode", Float) = 1 35 36 // KeywordEnum displays a popup menu for a **float** property, and enables corresponding shader keyword. 37 // This is used with "#pragma multi_compile" in shaders, to enable or disable parts of shader code. 38 // Each name will enable "property name" + underscore + "enum name", uppercased, shader keyword. 39 // Up to **9** names can be provided. 40 [KeywordEnum(None, Add, Multiply)] _Overlay ("Overlay mode", Float) = 0 41 42 // PowerSlider displays a slider with a non-linear response for a Range shader property. 43 // A slider with 3.0 response curve 44 [PowerSlider(3.0)] _Shininess ("Shininess", Range (0.01, 1)) = 0.08 45 } 46 SubShader 47 { 48 Tags { "Queue"="Transparent" "RenderType"="Transparent" } 49 Blend [_SrcBlend] [_DstBlend] 50 ZWrite [_ZWrite] 51 ZTest [_ZTest] 52 Cull [_Cull] 53 54 Pass 55 { 56 CGPROGRAM 57 // Need to define _INVERT_ON shader keyword 58 #pragma shader_feature _INVERT_ON 59 // Need to define _INVERT_ON shader keyword 60 #pragma shader_feature ENABLE_FANCY 61 // No comma between features 62 #pragma multi_compile _OVERLAY_NONE _OVERLAY_ADD _OVERLAY_MULTIPLY 63 64 #pragma vertex vert 65 #pragma fragment frag 66 67 #include "UnityCG.cginc" 68 69 sampler2D _MainTex; 70 float4 _MainTex_ST; 71 sampler2D _SecondTex; 72 float4 _SecondTex_ST; 73 float _Shininess; 74 75 struct appdata 76 { 77 float4 vertex : POSITION; 78 float2 uv : TEXCOORD0; 79 }; 80 81 struct v2f 82 { 83 float4 uv : TEXCOORD0; 84 float4 vertex : SV_POSITION; 85 }; 86 87 v2f vert (appdata v) 88 { 89 v2f o; 90 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 91 o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex); 92 o.uv.zw = TRANSFORM_TEX(v.uv, _SecondTex); 93 return o; 94 } 95 96 fixed4 frag (v2f i) : SV_Target 97 { 98 // sample the texture 99 fixed4 col = tex2D(_MainTex, i.uv.xy); 100 101 // Use #if, #ifdef or #if defined 102 #if _INVERT_ON 103 col = 1 - col; 104 #endif 105 106 // Use #if, #ifdef or #if defined 107 #if ENABLE_FANCY 108 col.r = 0.5; 109 #endif 110 111 fixed4 secCol = tex2D(_SecondTex, i.uv.zw); 112 113 #if _OVERLAY_ADD 114 col += secCol; 115 #elif _OVERLAY_MULTIPLY 116 col *= secCol; 117 #endif 118 119 col *= _Shininess; 120 121 return col; 122 } 123 ENDCG 124 } 125 } 126 }
效果如下:
可参考: