Skip to content

Commit 80cceb4

Browse files
committed
Add UIGradient shader
1 parent 71e0ec8 commit 80cceb4

8 files changed

+375
-0
lines changed

Diff for: Editor.meta

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Editor/UIGradientShaderGUI.cs

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using System;
2+
using System.Linq;
3+
using UnityEditor;
4+
using UnityEngine;
5+
6+
namespace Zigurous.UI.Editor
7+
{
8+
public sealed class UIGradientShaderGUI : ShaderGUI
9+
{
10+
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
11+
{
12+
EditorGUILayout.Space();
13+
14+
Material material = materialEditor.target as Material;
15+
16+
if (material == null) {
17+
throw new ArgumentNullException(nameof(material));
18+
}
19+
20+
GradientColorKey[] colorKeys = Enumerable
21+
.Range(0, material.GetInt("_Colors"))
22+
.Select((s, t) => new GradientColorKey(material.GetColor($"_Color{t}"), material.GetFloat($"_ColorTime{t}")))
23+
.ToArray();
24+
25+
GradientAlphaKey[] alphaKeys = Enumerable
26+
.Range(0, material.GetInt("_Alphas"))
27+
.Select((s, t) => new GradientAlphaKey(material.GetFloat($"_Alpha{t}"), material.GetFloat($"_AlphaTime{t}")))
28+
.ToArray();
29+
30+
Gradient gradient = new Gradient();
31+
gradient.SetKeys(colorKeys, alphaKeys);
32+
33+
EditorGUI.BeginChangeCheck();
34+
35+
Gradient field = EditorGUILayout.GradientField("Gradient", gradient);
36+
37+
if (!EditorGUI.EndChangeCheck())
38+
{
39+
base.OnGUI(materialEditor, properties);
40+
return;
41+
}
42+
43+
for (int i = 0; i < 8; i++)
44+
{
45+
material.SetColor($"_Color{i}", Color.magenta);
46+
material.SetFloat($"_ColorTime{i}", -1f);
47+
material.SetFloat($"_Alpha{i}", -1f);
48+
material.SetFloat($"_AlphaTime{i}", -1f);
49+
}
50+
51+
for (int i = 0; i < field.colorKeys.Length; i++)
52+
{
53+
material.SetColor($"_Color{i}", field.colorKeys[i].color);
54+
material.SetFloat($"_ColorTime{i}", field.colorKeys[i].time);
55+
}
56+
57+
for (int i = 0; i < field.alphaKeys.Length; i++)
58+
{
59+
material.SetFloat($"_Alpha{i}", field.alphaKeys[i].alpha);
60+
material.SetFloat($"_AlphaTime{i}", field.alphaKeys[i].time);
61+
}
62+
63+
material.SetInt("_Colors", field.colorKeys.Length);
64+
material.SetInt("_Alphas", field.alphaKeys.Length);
65+
66+
EditorUtility.SetDirty(material);
67+
68+
base.OnGUI(materialEditor, properties);
69+
}
70+
71+
}
72+
73+
}

Diff for: Editor/UIGradientShaderGUI.cs.meta

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Editor/Zigurous.UI.Editor.asmdef

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "Zigurous.UI.Editor",
3+
"references": [
4+
"Zigurous.UI"
5+
],
6+
"includePlatforms": [
7+
"Editor"
8+
],
9+
"excludePlatforms": [],
10+
"allowUnsafeCode": false,
11+
"overrideReferences": false,
12+
"precompiledReferences": [],
13+
"autoReferenced": true,
14+
"defineConstraints": [],
15+
"versionDefines": [],
16+
"noEngineReferences": false
17+
}

Diff for: Editor/Zigurous.UI.Editor.asmdef.meta

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Shaders.meta

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Shaders/UIGradient.shader

+242
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
Shader "Zigurous/UI/Gradient"
2+
{
3+
Properties
4+
{
5+
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
6+
[HideInInspector] _Color ("Tint", Color) = (1,1,1,1)
7+
8+
[HideInInspector] _StencilComp ("Stencil Comparison", Float) = 8
9+
[HideInInspector] _Stencil ("Stencil ID", Float) = 0
10+
[HideInInspector] _StencilOp ("Stencil Operation", Float) = 0
11+
[HideInInspector] _StencilWriteMask ("Stencil Write Mask", Float) = 255
12+
[HideInInspector] _StencilReadMask ("Stencil Read Mask", Float) = 255
13+
14+
[HideInInspector] _ColorMask ("Color Mask", Float) = 15
15+
16+
_Rotation ("Rotation", Range(0, 180)) = 0
17+
18+
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
19+
20+
[HideInInspector] _Color0 ("Color 0", Color) = (1, 1, 1, 1)
21+
[HideInInspector] _Color1 ("Color 1", Color) = (1, 1, 1, 1)
22+
[HideInInspector] _Color2 ("Color 2", Color) = (1, 1, 1, 1)
23+
[HideInInspector] _Color3 ("Color 3", Color) = (1, 1, 1, 1)
24+
[HideInInspector] _Color4 ("Color 4", Color) = (1, 1, 1, 1)
25+
[HideInInspector] _Color5 ("Color 5", Color) = (1, 1, 1, 1)
26+
[HideInInspector] _Color6 ("Color 6", Color) = (1, 1, 1, 1)
27+
[HideInInspector] _Color7 ("Color 7", Color) = (1, 1, 1, 1)
28+
29+
[HideInInspector] _ColorTime0 ("Color Time 0", Float) = 0
30+
[HideInInspector] _ColorTime1 ("Color Time 1", Float) = 0
31+
[HideInInspector] _ColorTime2 ("Color Time 2", Float) = 0
32+
[HideInInspector] _ColorTime3 ("Color Time 3", Float) = 0
33+
[HideInInspector] _ColorTime4 ("Color Time 4", Float) = 0
34+
[HideInInspector] _ColorTime5 ("Color Time 5", Float) = 0
35+
[HideInInspector] _ColorTime6 ("Color Time 6", Float) = 0
36+
[HideInInspector] _ColorTime7 ("Color Time 7", Float) = 0
37+
38+
[HideInInspector] _Colors ("Colors", Int) = 0
39+
40+
[HideInInspector] _Alpha0 ("Alpha 0", Float) = 0
41+
[HideInInspector] _Alpha1 ("Alpha 1", Float) = 0
42+
[HideInInspector] _Alpha2 ("Alpha 2", Float) = 0
43+
[HideInInspector] _Alpha3 ("Alpha 3", Float) = 0
44+
[HideInInspector] _Alpha4 ("Alpha 4", Float) = 0
45+
[HideInInspector] _Alpha5 ("Alpha 5", Float) = 0
46+
[HideInInspector] _Alpha6 ("Alpha 6", Float) = 0
47+
[HideInInspector] _Alpha7 ("Alpha 7", Float) = 0
48+
49+
[HideInInspector] _AlphaTime0 ("Alpha Time 0", Float) = 0
50+
[HideInInspector] _AlphaTime1 ("Alpha Time 1", Float) = 0
51+
[HideInInspector] _AlphaTime2 ("Alpha Time 2", Float) = 0
52+
[HideInInspector] _AlphaTime3 ("Alpha Time 3", Float) = 0
53+
[HideInInspector] _AlphaTime4 ("Alpha Time 4", Float) = 0
54+
[HideInInspector] _AlphaTime5 ("Alpha Time 5", Float) = 0
55+
[HideInInspector] _AlphaTime6 ("Alpha Time 6", Float) = 0
56+
[HideInInspector] _AlphaTime7 ("Alpha Time 7", Float) = 0
57+
58+
[HideInInspector] _Alphas ("Alphas", Int) = 0
59+
}
60+
61+
SubShader
62+
{
63+
Tags
64+
{
65+
"Queue"="Transparent"
66+
"IgnoreProjector"="True"
67+
"RenderType"="Transparent"
68+
"PreviewType"="Plane"
69+
"CanUseSpriteAtlas"="True"
70+
}
71+
72+
Stencil
73+
{
74+
Ref [_Stencil]
75+
Comp [_StencilComp]
76+
Pass [_StencilOp]
77+
ReadMask [_StencilReadMask]
78+
WriteMask [_StencilWriteMask]
79+
}
80+
81+
Cull Off
82+
Lighting Off
83+
ZWrite Off
84+
ZTest [unity_GUIZTestMode]
85+
Blend SrcAlpha OneMinusSrcAlpha
86+
ColorMask [_ColorMask]
87+
88+
Pass
89+
{
90+
Name "Default"
91+
92+
CGPROGRAM
93+
94+
#pragma vertex vert
95+
#pragma fragment frag
96+
#pragma target 2.0
97+
98+
#include "UnityCG.cginc"
99+
#include "UnityUI.cginc"
100+
101+
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
102+
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
103+
104+
struct appdata_t
105+
{
106+
float4 vertex : POSITION;
107+
float4 color : COLOR;
108+
float2 texcoord : TEXCOORD0;
109+
110+
UNITY_VERTEX_INPUT_INSTANCE_ID
111+
};
112+
113+
struct v2f
114+
{
115+
float4 vertex : SV_POSITION;
116+
fixed4 color : COLOR;
117+
float2 texcoord : TEXCOORD0;
118+
float4 worldPosition : TEXCOORD1;
119+
120+
UNITY_VERTEX_OUTPUT_STEREO
121+
};
122+
123+
sampler2D _MainTex;
124+
fixed4 _Color;
125+
fixed4 _TextureSampleAdd;
126+
float4 _ClipRect;
127+
float4 _MainTex_ST;
128+
float _Rotation;
129+
130+
float4 _Color0, _Color1, _Color2, _Color3, _Color4, _Color5, _Color6, _Color7;
131+
float _Alpha0, _Alpha1, _Alpha2, _Alpha3, _Alpha4, _Alpha5, _Alpha6, _Alpha7;
132+
float _ColorTime0, _ColorTime1, _ColorTime2, _ColorTime3, _ColorTime4, _ColorTime5, _ColorTime6, _ColorTime7;
133+
float _AlphaTime0, _AlphaTime1, _AlphaTime2, _AlphaTime3, _AlphaTime4, _AlphaTime5, _AlphaTime6, _AlphaTime7;
134+
int _Colors, _Alphas;
135+
136+
float4 get_gradient (float2 texcoord)
137+
{
138+
float4 cc[8] = { _Color0, _Color1, _Color2, _Color3, _Color4, _Color5, _Color6, _Color7 };
139+
float aa[8] = { _Alpha0, _Alpha1, _Alpha2, _Alpha3, _Alpha4, _Alpha5, _Alpha6, _Alpha7 };
140+
float ct[8] = { _ColorTime0, _ColorTime1, _ColorTime2, _ColorTime3, _ColorTime4, _ColorTime5, _ColorTime6, _ColorTime7 };
141+
float at[8] = { _AlphaTime0, _AlphaTime1, _AlphaTime2, _AlphaTime3, _AlphaTime4, _AlphaTime5, _AlphaTime6, _AlphaTime7 };
142+
143+
float4 cv1 = cc[0], cv2 = cc[_Colors - 1];
144+
float ct1 = ct[0], ct2 = ct[_Colors - 1];
145+
float av1 = aa[0], av2 = aa[_Alphas - 1];
146+
float at1 = at[0], at2 = at[_Alphas - 1];
147+
148+
float t = texcoord.x;
149+
150+
for (int i = 0; i < _Colors; i++)
151+
{
152+
if (ct[i] > t)
153+
break;
154+
155+
cv1 = cc[i];
156+
ct1 = ct[i];
157+
}
158+
159+
for (int j = 0; j < _Colors; j++)
160+
{
161+
if (ct[j] < t)
162+
continue;
163+
164+
cv2 = cc[j];
165+
ct2 = ct[j];
166+
break;
167+
}
168+
169+
for (int k = 0; k < _Alphas; k++)
170+
{
171+
if (at[k] > t)
172+
break;
173+
174+
av1 = aa[k];
175+
at1 = at[k];
176+
}
177+
178+
for (int l = 0; l < _Alphas; l++)
179+
{
180+
if (at[l] < t)
181+
continue;
182+
183+
av2 = aa[l];
184+
at2 = at[l];
185+
break;
186+
}
187+
188+
float lerpA = (t - at1) / (at2 - at1);
189+
float lerpC = (t - ct1) / (ct2 - ct1);
190+
float4 finalC = lerp(cv1, cv2, lerpC);
191+
float4 finalA = lerp(av1, av2, lerpA);
192+
finalC.a = finalA;
193+
194+
return finalC;
195+
}
196+
197+
v2f vert (appdata_t v)
198+
{
199+
v2f OUT;
200+
UNITY_SETUP_INSTANCE_ID(v);
201+
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
202+
OUT.worldPosition = v.vertex;
203+
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
204+
205+
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
206+
OUT.color = v.color * _Color;
207+
208+
const float Deg2Rad = (UNITY_PI * 2.0) / 360.0;
209+
float rotationRadians = _Rotation * Deg2Rad;
210+
float s = sin(rotationRadians);
211+
float c = cos(rotationRadians);
212+
float2x2 rotationMatrix = float2x2(c, -s, s, c);
213+
OUT.texcoord.xy = mul(v.texcoord.xy, rotationMatrix);
214+
215+
return OUT;
216+
}
217+
218+
fixed4 frag (v2f IN) : SV_Target
219+
{
220+
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
221+
222+
#ifdef UNITY_UI_CLIP_RECT
223+
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
224+
#endif
225+
226+
#ifdef UNITY_UI_ALPHACLIP
227+
clip (color.a - 0.001);
228+
#endif
229+
230+
float2 texcoord = (IN.texcoord - _MainTex_ST.zw) / _MainTex_ST.xy;
231+
float4 gradient = get_gradient(texcoord);
232+
return color * gradient;
233+
}
234+
235+
ENDCG
236+
237+
}
238+
239+
}
240+
241+
CustomEditor "Zigurous.UI.Editor.UIGradientShaderGUI"
242+
}

Diff for: Shaders/UIGradient.shader.meta

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)