UI动效 08

  1. 1. 按钮UI动效——昼夜切换
    1. 1.0.1. 实现思路

按钮UI动效——昼夜切换


实现思路

  • 绘制按钮外形

思路:采样Mask贴图,最后输出颜色时乘上Mask的a通道即可。

代码(若展不开请等待加载完成)
1
2
3
4
5
6
7
8
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(1,1,1,1);
fixed4 shape = tex2D(_MainTex, i.uv);

col.a *= shape.a;
return col;
}

  • 绘制Handle及高光、内阴影

思路:利用Circle()函数画主体的圆,再画两个圆进行计算高光和阴影。同时开放SunPos参数控制Handle的左右移动范围。

代码
1
2
3
4
5
6
7
float Circle(fixed2 uv,fixed2 center,float size,float blur)
{
uv = uv - center;
uv /= size;
float len = length(uv);
return smoothstep(1.,1.-blur,len);
}

  • 背景制作

思路:这时考虑到背景元素,先做三个变色的圆环,写在Handle前面

代码
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
Shader "Unlit/DayNightButton"
{
Properties
{
[hideInInspector]_MainTex ("Texture", 2D) = "white" {}
_UVScale ("UVScale", Float) = 2
_SunPos ("SunPos", Range(-1.6, 1.6)) = -1.6
_SunSize ("SunSize", Float) = 0.75
_SunBlur ("SunBlur", Float) = 0.05
_SunColor ("SunColor", Color) = (1, 0.7568627, 0.1058823, 1)

_SunShadowLightPos1 ("ShadowLightPos1", Vector) = (-0.03, 0.04, 0, 0)
_SunShadowLightSize1 ("ShadowLightSize1", Float) = 0.78
_SunShadowLightPos2 ("ShadowLightPos2", Vector) = (-0.04, -0.05, 0, 0)
_SunShadowLightSize2 ("ShadowLightSize2", Float) = 0.81
_HighLightColor ("HighLightColor", Color) = (1,1,0,1) // #F1DE35
_ShadowColor ("ShadowColor", Color) = (0,1,1,1) // #3B4B4B
_HighLightBlur ("HighLightBlur", Float) = 0.14
_ShadowBlur ("ShadowBlur", Float) = 0.24

_Circle3Range ("Circle3Range", Vector) = (1.5, 2.4, 3.3, 0)
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;
float _UVScale;
fixed _SunPos;
fixed4 _BGColor;
float _ScaleOffset;
float _SunSize;
float _SunBlur;
fixed4 _SunColor;

float4 _SunShadowLightPos1;
float4 _SunShadowLightPos2;
float _SunShadowLightSize1;
float _SunShadowLightSize2;
float _HighLightBlur;
float _ShadowBlur;
fixed4 _HighLightColor;
fixed4 _ShadowColor;

fixed4 _Circle3Range;

float Circle(fixed2 uv,fixed2 center,float size,float blur)
{
uv = uv - center;
uv /= size;
float len = length(uv);
return smoothstep(1.,1.-blur,len);
}

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(1,1,1,1);
fixed4 shape = tex2D(_MainTex, i.uv);

// UV [0, 1] -> [-1, 1]
i.uv -= 0.5;
i.uv *= _UVScale;
// Apply Image(Rect) scale
_ScaleOffset = 535.0 / 210.0;
i.uv = float2(i.uv.x * _ScaleOffset, i.uv.y);

/// BackGround Obj
// 3 Circle
fixed2 sunpos = fixed2(_SunPos, 0);
float dis = abs(distance(i.uv, sunpos));

if (dis < _Circle3Range.x)
{
_BGColor = fixed4(126.0/255.0, 172.0/255.0, 216.0/255.0, 1);
}
else if (dis < _Circle3Range.y)
{
_BGColor = fixed4(94.0/255.0, 150.0/255.0, 205.0/255.0, 1);
}
else if (dis < _Circle3Range.z)
{
_BGColor = fixed4(74.0/255.0, 137.0/255.0, 198.0/255.0, 1);
}
else
{
_BGColor = fixed4(67.0/255.0, 131.0/255.0, 196.0/255.0, 1);
}

// Handle
fixed sun = Circle(i.uv,sunpos,_SunSize,_SunBlur);
col = lerp(_BGColor, _SunColor, sun); // 先处理背景,再加上Handle

// HighLight and Shadow
fixed2 sunpos1 = fixed2(_SunPos + _SunShadowLightPos1.x, _SunShadowLightPos1.y);
fixed2 sunpos2 = fixed2(_SunPos + _SunShadowLightPos2.x, _SunShadowLightPos2.y);
fixed sunShadowLight1 = Circle(i.uv,sunpos1,_SunShadowLightSize1,_HighLightBlur);
fixed sunShadowLight2 = Circle(i.uv,sunpos2,_SunShadowLightSize2,_ShadowBlur);
col = lerp(col, _HighLightColor, saturate(sunShadowLight1 - sunShadowLight2));
col = lerp(col, _ShadowColor, saturate(-1 * (sunShadowLight1 - sunShadowLight2)));


// Shape
col.a *= shape.a;
return col;
}
ENDCG
}
}
}


  • 加入云层背景

思路:通过画圆的叠加制作,注意要使用saturate函数防止画出的云不超过1,否则在叠加的时候会显示错误;先画背景层较淡的云再画上一层云防止遮盖。

代码
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
Shader "Unlit/DayNightButton"
{
Properties
{
[hideInInspector]_MainTex ("Texture", 2D) = "white" {}
_UVScale ("UVScale", Float) = 2
_SunPos ("SunPos", Range(-1.6, 1.6)) = -1.6
_SunSize ("SunSize", Float) = 0.75
_SunBlur ("SunBlur", Float) = 0.05
_SunColor ("SunColor", Color) = (1, 0.7568627, 0.1058823, 1) // #FAAB0F

_SunShadowLightPos1 ("ShadowLightPos1", Vector) = (-0.03, 0.04, 0, 0)
_SunShadowLightSize1 ("ShadowLightSize1", Float) = 0.78
_SunShadowLightPos2 ("ShadowLightPos2", Vector) = (-0.04, -0.05, 0, 0)
_SunShadowLightSize2 ("ShadowLightSize2", Float) = 0.81
_HighLightColor ("HighLightColor", Color) = (1,1,0,1) // #F1DE35
_ShadowColor ("ShadowColor", Color) = (0,1,1,1) // #3B4B4B
_HighLightBlur ("HighLightBlur", Float) = 0.14
_ShadowBlur ("ShadowBlur", Float) = 0.24

_Circle3Range ("Circle3Range", Vector) = (1.5, 2.4, 3.3, 0)
_Circle1ColorDay ("Circle1ColorDay", Color) = (0.4941176, 0.6745098, 0.8470588, 1)
_Circle2ColorDay ("Circle2ColorDay", Color) = (0.36862745, 0.58823529, 0.80392157, 1)
_Circle3ColorDay ("Circle3ColorDay", Color) = (0.29019608, 0.5372549, 0.77647059, 1)
_Circle4ColorDay ("Circle4ColorDay", Color) = (0.2627451, 0.51372549, 0.76862745, 1)

_CloudPos ("CloudPos", Vector) = (0,0,0,0)
_CloudSize ("CloudSize", Float) = 5
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;
float _UVScale;
fixed _SunPos;
fixed4 _BGColor;
float _ScaleOffset;
float _SunSize;
float _SunBlur;
fixed4 _SunColor;

float4 _SunShadowLightPos1;
float4 _SunShadowLightPos2;
float _SunShadowLightSize1;
float _SunShadowLightSize2;
float _HighLightBlur;
float _ShadowBlur;
fixed4 _HighLightColor;
fixed4 _ShadowColor;

fixed4 _Circle3Range;
fixed4 _Circle1ColorDay;
fixed4 _Circle2ColorDay;
fixed4 _Circle3ColorDay;
fixed4 _Circle4ColorDay;

fixed4 _CloudPos;
fixed _CloudSize;

float Circle(fixed2 uv,fixed2 center,float size,float blur)
{
uv = uv - center;
uv /= size;
float len = length(uv);
return smoothstep(1.,1.-blur,len);
}
float DrawCloud(fixed2 uv,fixed2 center,float size)
{
uv = uv - center;
uv /= size;
float col = Circle(uv,fixed2(-.04,0.02),0.18,0.05);
col += Circle(uv,fixed2(-0.22,-0.05),0.2,0.05); // L1
col += Circle(uv,fixed2(-0.42,-0.07),0.18,0.05); // L2
col += Circle(uv,fixed2(0.12,0),0.18,0.05); // R1
col += Circle(uv,fixed2(0.27,0.1),0.16,0.05); // R2
col += Circle(uv,fixed2(0.37,0.23),0.16,0.05); // R3
return saturate(col);
//col = col * smoothstep(-0.1,-0.1+0.01,uv.y); // cut off
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(1,1,1,1);
fixed4 shape = tex2D(_MainTex, i.uv);

// UV [0, 1] -> [-1, 1]
i.uv -= 0.5;
i.uv *= _UVScale;
// Apply Image(Rect) scale
_ScaleOffset = 535.0 / 210.0;
i.uv = float2(i.uv.x * _ScaleOffset, i.uv.y);

/// BackGround Obj
// 3 Circle
fixed2 sunpos = fixed2(_SunPos, 0);
float dis = abs(distance(i.uv, sunpos));

if (dis < _Circle3Range.x)
{
_BGColor = _Circle1ColorDay;
}
else if (dis < _Circle3Range.y)
{
_BGColor = _Circle2ColorDay;
}
else if (dis < _Circle3Range.z)
{
_BGColor = _Circle3ColorDay;
}
else
{
_BGColor = _Circle4ColorDay;
}
// Clouds
col = lerp(_BGColor, fixed4(0.635294,0.7568627,0.87843137,1), DrawCloud(i.uv, fixed2(_CloudPos.x - 0.04 , _CloudPos.y + 0.42), _CloudSize));
col = lerp(col, fixed4(1,1,1,1), DrawCloud(i.uv, _CloudPos.xy, _CloudSize));
//

/// Handle
fixed sun = Circle(i.uv,sunpos,_SunSize,_SunBlur);
col = lerp(col, _SunColor, sun);
// HighLight and Shadow
fixed2 sunpos1 = fixed2(_SunPos + _SunShadowLightPos1.x, _SunShadowLightPos1.y);
fixed2 sunpos2 = fixed2(_SunPos + _SunShadowLightPos2.x, _SunShadowLightPos2.y);
fixed sunShadowLight1 = Circle(i.uv,sunpos1,_SunShadowLightSize1,_HighLightBlur);
fixed sunShadowLight2 = Circle(i.uv,sunpos2,_SunShadowLightSize2,_ShadowBlur);
col = lerp(col, _HighLightColor, saturate(sunShadowLight1 - sunShadowLight2));
col = lerp(col, _ShadowColor, saturate(-1 * (sunShadowLight1 - sunShadowLight2)));


// Shape
col.a *= shape.a;
return col;
}
ENDCG
}
}
}


  • 制作背景昼夜颜色插值效果

思路:定义昼夜背景色,使用Handle的x轴位置Remap到[0, 1]做插值。

代码
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
// ...

_Circle1ColorDay ("Circle1ColorDay", Color) = (0.4941176, 0.6745098, 0.8470588, 1)
_Circle2ColorDay ("Circle2ColorDay", Color) = (0.36862745, 0.58823529, 0.80392157, 1)
_Circle3ColorDay ("Circle3ColorDay", Color) = (0.29019608, 0.5372549, 0.77647059, 1)
_Circle4ColorDay ("Circle4ColorDay", Color) = (0.2627451, 0.51372549, 0.76862745, 1)

_Circle1ColorNight ("Circle1ColorNight", Color) = (0.4, 0.4196078, 0.4862745, 1)
_Circle2ColorNight ("Circle2ColorNight", Color) = (0.2352941, 0.27058824, 0.3529412, 1)
_Circle3ColorNight ("Circle3ColorNight", Color) = (0.1529412, 0.1882353, 0.2705882, 1)
_Circle4ColorNight ("Circle4ColorNight", Color) = (0.1098039, 0.14509804, 0.2470588, 1)

// ...

float Remap(float value, fixed2 InMinMax, fixed2 OutMinMax)
{
return OutMinMax.x + (value - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
}
// ...

// fragment:

if (dis < _Circle3Range.x)
{
_BGColor = lerp(_Circle1ColorDay, _Circle1ColorNight, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1)));
}
else if (dis < _Circle3Range.y)
{
_BGColor = lerp(_Circle2ColorDay, _Circle2ColorNight, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1)));
}
else if (dis < _Circle3Range.z)
{
_BGColor = lerp(_Circle3ColorDay, _Circle3ColorNight, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1)));
}
else
{
_BGColor = lerp(_Circle4ColorDay, _Circle4ColorNight, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1)));
}

Handle主体颜色同理。


  • 制作云随Handle移动的下移插值效果

思路:使用Handle的X轴位置Remap到[0, 1]做云Y轴位置的[0, -2]插值。

代码
1
2
3
// Clouds
col = lerp(_BGColor, fixed4(0.635294,0.7568627,0.87843137,1), DrawCloud(i.uv, fixed2(_CloudPos.x - 0.04 , _CloudPos.y + 0.42 + Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, -2))), _CloudSize));
col = lerp(col, fixed4(1,1,1,1), DrawCloud(i.uv, fixed2(_CloudPos.x, _CloudPos.y + Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, -2))), _CloudSize));

  • 绘制”月球坑”与显隐控制

思路:继续使用Circle函数在Handle后面继续绘制,有黑色描边则需要绘制两次,显隐则使用Handle的X轴位置Remap到[0, 1]做颜色插值,为了不在移动Handle的一开始就出现月球坑,使用clamp函数进行一些偏移。

代码
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
//...
_HoleCenterX ("HoleCenterX", Vector) = (0.31, -0.11, -0.31, 0)
_HoleCenterY ("HoleCenterY", Vector) = (0.06, -0.35, 0.24, 0)
_HoleSize ("HoleSize", Vector) = (0.24, 0.16, 0.15, 0)
_HoleShadowSize ("HoleShadowSize", Float) = 0.02
_HoleShadowBlur ("HoleShadowBlur", Float) = 0.1
_HoleShadowColor ("HoleShadowColor", Color) = (0.4 ,0.4, 0.4,1)

//...
fixed4 _HoleCenterX;
fixed4 _HoleCenterY;
fixed4 _HoleSize;
fixed _HoleShadowBlur;
float _HoleShadowSize;
fixed4 _HoleShadowColor;
//...

/// Handle
fixed sun = Circle(i.uv,sunpos,_SunSize,_SunBlur);
col = lerp(col, lerp(_SunColor, _MoonColor, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1))), sun);
// 3 Hole in Handle
fixed hole1 = Circle(i.uv,sunpos - fixed2(_HoleCenterX.x, _HoleCenterY.x),_HoleSize.x,0.05);
fixed hole1S = Circle(i.uv,sunpos - fixed2(_HoleCenterX.x, _HoleCenterY.x),_HoleSize.x + _HoleShadowSize, _HoleShadowBlur);
fixed hole2 = Circle(i.uv,sunpos - fixed2(_HoleCenterX.y, _HoleCenterY.y),_HoleSize.y,0.05);
fixed hole2S = Circle(i.uv,sunpos - fixed2(_HoleCenterX.y, _HoleCenterY.y),_HoleSize.y + _HoleShadowSize, _HoleShadowBlur);
fixed hole3 = Circle(i.uv,sunpos - fixed2(_HoleCenterX.z, _HoleCenterY.z),_HoleSize.z,0.05);
fixed hole3S = Circle(i.uv,sunpos - fixed2(_HoleCenterX.z, _HoleCenterY.z),_HoleSize.z + _HoleShadowSize, _HoleShadowBlur);
col = lerp(col, _HoleShadowColor, clamp(Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(-0.5, saturate(hole1S + hole2S + hole3S))), 0, 1)); // clamp与-0.5 为调整开始出现月球坑的时间
col = lerp(col, fixed4(0.5882353,0.6352941,0.7137255,1), clamp(Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(-0.5, saturate(hole1 + hole2 + hole3))), 0, 1));


  • 绘制”星星”与显隐控制

思路:使用SDF绘制单个星星,再加入位置、缩放、闪烁进度、边缘凹陷度等变量,并分别存入四维变量中,即一个四维变量控制4个星星。

绘制星星使用的SDF
SDF参数测试过程

代码
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//...
fixed4 _StarColor;
float4 _StarsSize;
float4 _StarsBlink;
float4 _StarsStrenth;
fixed4 _StarsPosX;
fixed4 _StarsPosY;
fixed4 _StarsLen;
fixed4 _StarsRound;
float4 _StarsSizeG2;
float4 _StarsBlinkG2;
float4 _StarsStrenthG2;
fixed4 _StarsPosXG2;
fixed4 _StarsPosYG2;
fixed4 _StarsLenG2;
fixed4 _StarsRoundG2;

//...
float dot2(fixed2 v)
{
return dot(v.x, v.y);
}
float dot2Offset(fixed2 v, fixed2 offset)
{
return dot(v.x - offset.x, v.y - offset.y);
}
float sdRoundedCross(fixed2 p, fixed h, fixed2 center,float size)
{
p = p - center;
p /= size;
float k = 0.5 * (h + 1.0 / h);
p = abs(p);
return (p.x < 1.0 && p.y < p.x * (k - h) + h) ? k - sqrt(dot2(p - fixed2(1, k))) : 1; // sqrt(min(dot2(p - fixed2(0, h)), dot2(p - fixed2(1, 0))))
}
float Remap(float value, fixed2 InMinMax, fixed2 OutMinMax)
{
return OutMinMax.x + (value - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
}

//...
// Stars
float clampSunPos = clamp(_SunPos.x, -0.4, 1.6); // _SunPos.x对星星的显隐影响从这里开始生效,-0.4时全部星星未出现,作为初始状态
// 1-4
float star1 = sdRoundedCross(i.uv, _StarsLen.x, fixed2(_StarsPosX.x, _StarsPosY.x), _StarsSize.x) - _StarsRound.x;
star1 = pow(star1, _StarsBlink.x * abs(sin(1.2 * clampSunPos)));
//col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star1)) - (_StarsStrenth.x * sign(i.uv.x) * sign(i.uv.y) * dot2(i.uv)), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));//uv偏移前
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star1)) - (_StarsStrenth.x * sign(i.uv.x - _StarsPosX.x) * sign(i.uv.y - _StarsPosY.x) * dot2Offset(i.uv, fixed2(_StarsPosX.x, _StarsPosY.x))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star2 = sdRoundedCross(i.uv, _StarsLen.y, fixed2(_StarsPosX.y, _StarsPosY.y), _StarsSize.y) - _StarsRound.y;
star2 = pow(star2, _StarsBlink.y * abs(cos(clampSunPos + 140)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star2)) - (_StarsStrenth.y * sign(i.uv.x - _StarsPosX.y) * sign(i.uv.y - _StarsPosY.y) * dot2Offset(i.uv, fixed2(_StarsPosX.y, _StarsPosY.y))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star3 = sdRoundedCross(i.uv, _StarsLen.z, fixed2(_StarsPosX.z, _StarsPosY.z), _StarsSize.z) - _StarsRound.z;
star3 = pow(star3, _StarsBlink.z * abs(sin(1.1 * clampSunPos+ 60)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star3)) - (_StarsStrenth.z * sign(i.uv.x - _StarsPosX.z) * sign(i.uv.y - _StarsPosY.z) * dot2Offset(i.uv, fixed2(_StarsPosX.z, _StarsPosY.z))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star4 = sdRoundedCross(i.uv, _StarsLen.w, fixed2(_StarsPosX.w, _StarsPosY.w), _StarsSize.w) - _StarsRound.w;
star4 = pow(star4, _StarsBlink.w * abs(cos(clampSunPos + 140)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star4)) - (_StarsStrenth.w * sign(i.uv.x - _StarsPosX.w) * sign(i.uv.y - _StarsPosY.w) * dot2Offset(i.uv, fixed2(_StarsPosX.w, _StarsPosY.w))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));
// 5-8
float star5 = sdRoundedCross(i.uv, _StarsLenG2.x, fixed2(_StarsPosXG2.x, _StarsPosYG2.x), _StarsSizeG2.x) - _StarsRoundG2.x;
star5 = pow(star5, _StarsBlinkG2.x * abs(sin(clampSunPos + 60)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star5)) - (_StarsStrenthG2.x * sign(i.uv.x - _StarsPosXG2.x) * sign(i.uv.y - _StarsPosYG2.x) * dot2Offset(i.uv, fixed2(_StarsPosXG2.x, _StarsPosYG2.x))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star6 = sdRoundedCross(i.uv, _StarsLenG2.y, fixed2(_StarsPosXG2.y, _StarsPosYG2.y), _StarsSizeG2.y) - _StarsRoundG2.y;
star6 = pow(star6, _StarsBlinkG2.y * abs(sin(clampSunPos + 13)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star6)) - (_StarsStrenthG2.y * sign(i.uv.x - _StarsPosXG2.y) * sign(i.uv.y - _StarsPosYG2.y) * dot2Offset(i.uv, fixed2(_StarsPosXG2.y, _StarsPosYG2.y))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star7 = sdRoundedCross(i.uv, _StarsLenG2.z, fixed2(_StarsPosXG2.z, _StarsPosYG2.z), _StarsSizeG2.z) - _StarsRoundG2.z;
star7 = pow(star7, _StarsBlinkG2.z * abs(sin(1.2 * clampSunPos)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star7)) - (_StarsStrenthG2.z * sign(i.uv.x - _StarsPosXG2.z) * sign(i.uv.y - _StarsPosYG2.z) * dot2Offset(i.uv, fixed2(_StarsPosXG2.z, _StarsPosYG2.z))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star8 = sdRoundedCross(i.uv, _StarsLenG2.w, fixed2(_StarsPosXG2.w, _StarsPosYG2.w), _StarsSizeG2.w) - _StarsRoundG2.w;
star8 = pow(star8, _StarsBlinkG2.w * abs(sin(clampSunPos + 110)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star8)) - (_StarsStrenthG2.w * sign(i.uv.x - _StarsPosXG2.w) * sign(i.uv.y - _StarsPosYG2.w) * dot2Offset(i.uv, fixed2(_StarsPosXG2.w, _StarsPosYG2.w))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

  • 绘制内阴影

思路:使用圆角矩形SDF直接做效果,通过位置、大小微调来实现偏左上角的阴影。

无内阴影
有内阴影

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//...
_ShadowSize ("ShadowSize", Vector) = (3.5, 1.4, 0.64, 0.9)
_ShadowRadius ("ShadowRadius", Float) = 1.32
_ShadowPos ("ShadowPos", Vector) = (-0.62, 0.04, 0, 0)
_ShadowColorOut ("ShadowColorOut", Color) = (0 , 0, 0, 1)

//...
fixed4 _ShadowSize;
fixed4 _ShadowPos;
fixed _ShadowRadius;
fixed4 _ShadowColorOut;

//...
/// Shadow
float ra = min(_ShadowRadius,min(_ShadowSize.x,_ShadowSize.y));
float sdrb = sdRoundBox(i.uv + _ShadowPos.xy, _ShadowSize.xy, ra);
col = lerp(col, _ShadowColorOut, 1.0 - smoothstep(0.0, _ShadowSize.z, abs(sdrb)));

其他:

  • 目前效果差不多了,星星的上下移动插值就不做了,原理和云层的位移一样。
  • 另外遮罩图形也可以用SDF做,可以做到完全不用材质,因为项目里已经有贴图了所以直接用了。

完整代码与Inspector参数:

代码
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
Shader "Unlit/DayNightButton"
{
Properties
{
[hideInInspector]_MainTex ("Texture", 2D) = "white" {}
_UVScale ("UVScale", Float) = 2
_SunPos ("SunPos", Range(-1.6, 1.6)) = -1.6
_SunSize ("SunSize", Float) = 0.75
_SunBlur ("SunBlur", Float) = 0.05
_SunColor ("SunColor", Color) = (1, 0.7568627, 0.1058823, 1) // #FAAB0F
_MoonColor ("MoonColor", Color) = (0.76862745, 0.79215686, 0.8431373, 1) // #C4CAD7

_SunShadowLightPos1 ("ShadowLightPos1", Vector) = (-0.03, 0.04, 0, 0)
_SunShadowLightSize1 ("ShadowLightSize1", Float) = 0.78
_SunShadowLightPos2 ("ShadowLightPos2", Vector) = (-0.04, -0.05, 0, 0)
_SunShadowLightSize2 ("ShadowLightSize2", Float) = 0.81
_HighLightColor ("HighLightColor", Color) = (0.945098, 0.8705882,0.2078431,1) // #F1DE35
_HighLightNightColor ("HighLightNightColor", Color) = (0.945098, 0.8705882,0.2078431,1) // #F1DE35
_ShadowColor ("ShadowColor", Color) = (0,1,1,1) // #3B4B4B
_HighLightBlur ("HighLightBlur", Float) = 0.14
_ShadowBlur ("ShadowBlur", Float) = 0.24

_Circle3Range ("Circle3Range", Vector) = (1.5, 2.4, 3.3, 0)
_Circle1ColorDay ("Circle1ColorDay", Color) = (0.4941176, 0.6745098, 0.8470588, 1)
_Circle2ColorDay ("Circle2ColorDay", Color) = (0.36862745, 0.58823529, 0.80392157, 1)
_Circle3ColorDay ("Circle3ColorDay", Color) = (0.29019608, 0.5372549, 0.77647059, 1)
_Circle4ColorDay ("Circle4ColorDay", Color) = (0.2627451, 0.51372549, 0.76862745, 1)

_Circle1ColorNight ("Circle1ColorNight", Color) = (0.4, 0.4196078, 0.4862745, 1)
_Circle2ColorNight ("Circle2ColorNight", Color) = (0.2352941, 0.27058824, 0.3529412, 1)
_Circle3ColorNight ("Circle3ColorNight", Color) = (0.1529412, 0.1882353, 0.2705882, 1)
_Circle4ColorNight ("Circle4ColorNight", Color) = (0.1098039, 0.14509804, 0.2470588, 1)

_CloudPos ("CloudPos", Vector) = (0,0,0,0)
_CloudSize ("CloudSize", Float) = 5

_HoleCenterX ("HoleCenterX", Vector) = (0.31, -0.11, -0.31, 0)
_HoleCenterY ("HoleCenterY", Vector) = (0.06, -0.35, 0.24, 0)
_HoleSize ("HoleSize", Vector) = (0.24, 0.16, 0.15, 0)
_HoleShadowSize ("HoleShadowSize", Float) = 0.02
_HoleShadowBlur ("HoleShadowBlur", Float) = 0.1
_HoleShadowColor ("HoleShadowColor", Color) = (0.4 ,0.4, 0.4,1)

_StarColor ("StarColor", Color) = (1, 1, 1, 1)
_StarsSize ("StarsSize_4", Vector) = (2.4, 2, 3.4, 1.5)
_StarsBlink ("StarsBlink_4", Vector) = (1, 1, 1, 1)
_StarsStrenth ("StasrStrenth_4", Vector) = (50, 50, 50, 160)
_StarsPosX ("StarsPosX_4", Vector) = (-1.8, -1.6, -1.1, -1)
_StarsPosY ("StarsPosY_4", Vector) = (0.3, -0.4, -1.1, -1)
[hideInInspector] _StarsLen ("StarsLen_4", Vector) = (1, 1, 1, 1)
[hideInInspector] _StarsRound ("StarsRound_8", Vector) = (0, 0, 0, 0)
_StarsSizeG2 ("StarsSize_8", Vector) = (2.2, 1.6, 2.4, 3)
_StarsBlinkG2 ("StarsBlink_8", Vector) = (1, 1, 1, 1)
_StarsStrenthG2 ("StasrStrenth_8", Vector) = (100, 100, 80, 45)
_StarsPosXG2 ("StarsPosX_8", Vector) = (-0.65, -0.1, 0.06, 0.4)
_StarsPosYG2 ("StarsPosY_8", Vector) = (-0.09, -0.36, -0.48, 0.12)
[hideInInspector] _StarsLenG2 ("StarsLen_8", Vector) = (1, 1, 1, 1)
[hideInInspector] _StarsRoundG2 ("StarsRound_8", Vector) = (0, 0, 0, 0)

_ShadowSize ("ShadowSize", Vector) = (3.5, 1.4, 0.64, 0.9)
_ShadowRadius ("ShadowRadius", Float) = 1.32
_ShadowPos ("ShadowPos", Vector) = (-0.62, 0.04, 0, 0)
_ShadowColorOut ("ShadowColorOut", Color) = (0 , 0, 0, 1)
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;
float _UVScale;
fixed _SunPos;
fixed4 _BGColor;
float _ScaleOffset;
float _SunSize;
float _SunBlur;
fixed4 _SunColor;
fixed4 _MoonColor;

float4 _SunShadowLightPos1;
float4 _SunShadowLightPos2;
float _SunShadowLightSize1;
float _SunShadowLightSize2;
float _HighLightBlur;
float _ShadowBlur;
fixed4 _HighLightColor;
fixed4 _HighLightNightColor;
fixed4 _ShadowColor;

fixed4 _Circle3Range;
fixed4 _Circle1ColorDay;
fixed4 _Circle2ColorDay;
fixed4 _Circle3ColorDay;
fixed4 _Circle4ColorDay;
fixed4 _Circle1ColorNight;
fixed4 _Circle2ColorNight;
fixed4 _Circle3ColorNight;
fixed4 _Circle4ColorNight;

fixed4 _CloudPos;
fixed _CloudSize;

fixed4 _HoleCenterX;
fixed4 _HoleCenterY;
fixed4 _HoleSize;
fixed _HoleShadowBlur;
float _HoleShadowSize;
fixed4 _HoleShadowColor;

fixed4 _StarColor;
float4 _StarsSize;
float4 _StarsBlink;
float4 _StarsStrenth;
fixed4 _StarsPosX;
fixed4 _StarsPosY;
fixed4 _StarsLen;
fixed4 _StarsRound;
float4 _StarsSizeG2;
float4 _StarsBlinkG2;
float4 _StarsStrenthG2;
fixed4 _StarsPosXG2;
fixed4 _StarsPosYG2;
fixed4 _StarsLenG2;
fixed4 _StarsRoundG2;

fixed4 _ShadowSize;
fixed4 _ShadowPos;
fixed _ShadowRadius;
fixed4 _ShadowColorOut;

float Circle(fixed2 uv,fixed2 center,float size,float blur)
{
uv = uv - center;
uv /= size;
float len = length(uv);
return smoothstep(1.,1.-blur,len);
}
float DrawCloud(fixed2 uv,fixed2 center,float size)
{
uv = uv - center;
uv /= size;
float col = Circle(uv,fixed2(-.04,0.02),0.18,0.05);
col += Circle(uv,fixed2(-0.22,-0.05),0.2,0.05); // L1
col += Circle(uv,fixed2(-0.42,-0.07),0.18,0.05); // L2
col += Circle(uv,fixed2(0.12,0),0.18,0.05); // R1
col += Circle(uv,fixed2(0.27,0.1),0.16,0.05); // R2
col += Circle(uv,fixed2(0.37,0.23),0.16,0.05); // R3
return saturate(col);
//col = col * smoothstep(-0.1,-0.1+0.01,uv.y); // cut off
}
float dot2(fixed2 v)
{
return dot(v.x, v.y);
}
float dot2Offset(fixed2 v, fixed2 offset)
{
return dot(v.x - offset.x, v.y - offset.y);
}
float sdRoundedCross(fixed2 p, fixed h, fixed2 center,float size)
{
p = p - center;
p /= size;
float k = 0.5 * (h + 1.0 / h);
p = abs(p);
return (p.x < 1.0 && p.y < p.x * (k - h) + h) ? k - sqrt(dot2(p - fixed2(1, k))) : 1; // sqrt(min(dot2(p - fixed2(0, h)), dot2(p - fixed2(1, 0))))
}
float sdRoundBox(fixed2 p, fixed2 b, fixed4 r)
{
r.xy = (p.x > 0.0) ? r.xy : r.zw;
r.x = (p.y > 0.0) ? r.x : r.y;
fixed2 q = abs(p) - b + r.x;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x;
}
float Remap(float value, fixed2 InMinMax, fixed2 OutMinMax)
{
return OutMinMax.x + (value - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
}

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(1,1,1,1);
fixed4 shape = tex2D(_MainTex, i.uv);

// UV [0, 1] -> [-1, 1]
i.uv -= 0.5;
i.uv *= _UVScale;
// Apply Image(Rect) scale
_ScaleOffset = 535.0 / 210.0;
i.uv = float2(i.uv.x * _ScaleOffset, i.uv.y);

/// BackGround Obj
// 3 Circle
fixed2 sunpos = fixed2(_SunPos, 0);
float dis = abs(distance(i.uv, sunpos));

if (dis < _Circle3Range.x)
{
_BGColor = lerp(_Circle1ColorDay, _Circle1ColorNight, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1)));
}
else if (dis < _Circle3Range.y)
{
_BGColor = lerp(_Circle2ColorDay, _Circle2ColorNight, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1)));
}
else if (dis < _Circle3Range.z)
{
_BGColor = lerp(_Circle3ColorDay, _Circle3ColorNight, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1)));
}
else
{
_BGColor = lerp(_Circle4ColorDay, _Circle4ColorNight, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1)));
}
// Clouds
col = lerp(_BGColor, fixed4(0.635294,0.7568627,0.87843137,1), DrawCloud(i.uv, fixed2(_CloudPos.x - 0.04 , _CloudPos.y + 0.42 + Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, -2))), _CloudSize));
col = lerp(col, fixed4(1,1,1,1), DrawCloud(i.uv, fixed2(_CloudPos.x, _CloudPos.y + Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, -2))), _CloudSize));
// Stars
float clampSunPos = clamp(_SunPos.x, -0.4, 1.6); // _SunPos.x对星星的显隐影响从这里开始生效,-0.4时全部星星未出现,作为初始状态
// 1-4
float star1 = sdRoundedCross(i.uv, _StarsLen.x, fixed2(_StarsPosX.x, _StarsPosY.x), _StarsSize.x) - _StarsRound.x;
star1 = pow(star1, _StarsBlink.x * abs(sin(1.2 * clampSunPos)));
//col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star1)) - (_StarsStrenth.x * sign(i.uv.x) * sign(i.uv.y) * dot2(i.uv)), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));//uv偏移前
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star1)) - (_StarsStrenth.x * sign(i.uv.x - _StarsPosX.x) * sign(i.uv.y - _StarsPosY.x) * dot2Offset(i.uv, fixed2(_StarsPosX.x, _StarsPosY.x))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star2 = sdRoundedCross(i.uv, _StarsLen.y, fixed2(_StarsPosX.y, _StarsPosY.y), _StarsSize.y) - _StarsRound.y;
star2 = pow(star2, _StarsBlink.y * abs(cos(clampSunPos + 140)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star2)) - (_StarsStrenth.y * sign(i.uv.x - _StarsPosX.y) * sign(i.uv.y - _StarsPosY.y) * dot2Offset(i.uv, fixed2(_StarsPosX.y, _StarsPosY.y))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star3 = sdRoundedCross(i.uv, _StarsLen.z, fixed2(_StarsPosX.z, _StarsPosY.z), _StarsSize.z) - _StarsRound.z;
star3 = pow(star3, _StarsBlink.z * abs(sin(1.1 * clampSunPos+ 60)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star3)) - (_StarsStrenth.z * sign(i.uv.x - _StarsPosX.z) * sign(i.uv.y - _StarsPosY.z) * dot2Offset(i.uv, fixed2(_StarsPosX.z, _StarsPosY.z))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star4 = sdRoundedCross(i.uv, _StarsLen.w, fixed2(_StarsPosX.w, _StarsPosY.w), _StarsSize.w) - _StarsRound.w;
star4 = pow(star4, _StarsBlink.w * abs(cos(clampSunPos + 140)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star4)) - (_StarsStrenth.w * sign(i.uv.x - _StarsPosX.w) * sign(i.uv.y - _StarsPosY.w) * dot2Offset(i.uv, fixed2(_StarsPosX.w, _StarsPosY.w))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));
// 5-8
float star5 = sdRoundedCross(i.uv, _StarsLenG2.x, fixed2(_StarsPosXG2.x, _StarsPosYG2.x), _StarsSizeG2.x) - _StarsRoundG2.x;
star5 = pow(star5, _StarsBlinkG2.x * abs(sin(clampSunPos + 60)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star5)) - (_StarsStrenthG2.x * sign(i.uv.x - _StarsPosXG2.x) * sign(i.uv.y - _StarsPosYG2.x) * dot2Offset(i.uv, fixed2(_StarsPosXG2.x, _StarsPosYG2.x))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star6 = sdRoundedCross(i.uv, _StarsLenG2.y, fixed2(_StarsPosXG2.y, _StarsPosYG2.y), _StarsSizeG2.y) - _StarsRoundG2.y;
star6 = pow(star6, _StarsBlinkG2.y * abs(sin(clampSunPos + 13)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star6)) - (_StarsStrenthG2.y * sign(i.uv.x - _StarsPosXG2.y) * sign(i.uv.y - _StarsPosYG2.y) * dot2Offset(i.uv, fixed2(_StarsPosXG2.y, _StarsPosYG2.y))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star7 = sdRoundedCross(i.uv, _StarsLenG2.z, fixed2(_StarsPosXG2.z, _StarsPosYG2.z), _StarsSizeG2.z) - _StarsRoundG2.z;
star7 = pow(star7, _StarsBlinkG2.z * abs(sin(1.2 * clampSunPos)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star7)) - (_StarsStrenthG2.z * sign(i.uv.x - _StarsPosXG2.z) * sign(i.uv.y - _StarsPosYG2.z) * dot2Offset(i.uv, fixed2(_StarsPosXG2.z, _StarsPosYG2.z))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));

float star8 = sdRoundedCross(i.uv, _StarsLenG2.w, fixed2(_StarsPosXG2.w, _StarsPosYG2.w), _StarsSizeG2.w) - _StarsRoundG2.w;
star8 = pow(star8, _StarsBlinkG2.w * abs(sin(clampSunPos + 110)));
col = lerp(col, _StarColor, Remap(clamp(1.0 - smoothstep(0.0,0.1,abs(star8)) - (_StarsStrenthG2.w * sign(i.uv.x - _StarsPosXG2.w) * sign(i.uv.y - _StarsPosYG2.w) * dot2Offset(i.uv, fixed2(_StarsPosXG2.w, _StarsPosYG2.w))), 0.6, 1), fixed2(0.6, 1), fixed2(0, 1)));



/// Handle
fixed sun = Circle(i.uv,sunpos,_SunSize,_SunBlur);
col = lerp(col, lerp(_SunColor, _MoonColor, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1))), sun);
// 3 Hole in Handle
fixed hole1 = Circle(i.uv,sunpos - fixed2(_HoleCenterX.x, _HoleCenterY.x),_HoleSize.x,0.05);
fixed hole1S = Circle(i.uv,sunpos - fixed2(_HoleCenterX.x, _HoleCenterY.x),_HoleSize.x + _HoleShadowSize, _HoleShadowBlur);
fixed hole2 = Circle(i.uv,sunpos - fixed2(_HoleCenterX.y, _HoleCenterY.y),_HoleSize.y,0.05);
fixed hole2S = Circle(i.uv,sunpos - fixed2(_HoleCenterX.y, _HoleCenterY.y),_HoleSize.y + _HoleShadowSize, _HoleShadowBlur);
fixed hole3 = Circle(i.uv,sunpos - fixed2(_HoleCenterX.z, _HoleCenterY.z),_HoleSize.z,0.05);
fixed hole3S = Circle(i.uv,sunpos - fixed2(_HoleCenterX.z, _HoleCenterY.z),_HoleSize.z + _HoleShadowSize, _HoleShadowBlur);
col = lerp(col, _HoleShadowColor, clamp(Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(-0.5, saturate(hole1S + hole2S + hole3S))), 0, 1)); // clamp与-0.5 为调整开始出现月球坑的时间
col = lerp(col, fixed4(0.5882353,0.6352941,0.7137255,1), clamp(Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(-0.5, saturate(hole1 + hole2 + hole3))), 0, 1));

// HighLight and Shadow
fixed2 sunpos1 = fixed2(_SunPos + _SunShadowLightPos1.x, _SunShadowLightPos1.y);
fixed2 sunpos2 = fixed2(_SunPos + _SunShadowLightPos2.x, _SunShadowLightPos2.y);
fixed sunShadowLight1 = Circle(i.uv,sunpos1,_SunShadowLightSize1,_HighLightBlur);
fixed sunShadowLight2 = Circle(i.uv,sunpos2,_SunShadowLightSize2,_ShadowBlur);
col = lerp(col, lerp(_HighLightColor, _HighLightNightColor, Remap(_SunPos, fixed2(-1.6, 1.6), fixed2(0, 1))), saturate(sunShadowLight1 - sunShadowLight2));
col = lerp(col, _ShadowColor, saturate(-1 * (sunShadowLight1 - sunShadowLight2)));

/// Shadow
float ra = min(_ShadowRadius,min(_ShadowSize.x,_ShadowSize.y));
float sdrb = sdRoundBox(i.uv + _ShadowPos.xy, _ShadowSize.xy, ra);
col = lerp(col, _ShadowColorOut, 1.0 - smoothstep(0.0, _ShadowSize.z, abs(sdrb)));

// Shape
col.a *= shape.a;
return col;
}
ENDCG
}
}
}

C#代码
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

/// <summary>
/// 使用DoTween插件制作的缓动效果,搭配EventTrigger组件使用
/// </summary>
public class NewMat : MonoBehaviour
{
private const float BEGIN_POS = -1.6f;
private const float END_POS = 1.6f;
private const float L_POS = -1.3f;
private const float R_POS = 1.3f;
private Material _mat;
private Tween tween_enter;
private Tween tween_exit;
private Tween tween_down;
private bool inBtn;
private bool inAnim;
void Start()
{
_mat = Instantiate(GetComponent<Image>().material);
GetComponent<Image>().material = _mat;
_mat = GetComponent<Image>().material;
_mat.SetFloat("_SunPos", BEGIN_POS);
inBtn = false;
inAnim = false;
}

public void OnMouseEnter()
{
if (!inBtn)
{
if (inAnim) return;

inBtn = true;

tween_enter?.Kill();

if (_mat.GetFloat("_SunPos") < 0)
{
tween_enter = DOTween.To((value) =>
{
_mat.SetFloat("_SunPos", value);
}, _mat.GetFloat("_SunPos"), L_POS, 0.3f);
}
else
{
tween_enter = DOTween.To((value) =>
{
_mat.SetFloat("_SunPos", value);
}, _mat.GetFloat("_SunPos"), R_POS, 0.3f);
}
}


}
public void OnMouseExit()
{
if (inBtn)
{
if (inAnim) return;

inBtn = false;

tween_exit?.Kill();

if (_mat.GetFloat("_SunPos") < 0)
{
tween_exit = DOTween.To((value) =>
{
_mat.SetFloat("_SunPos", value);
}, _mat.GetFloat("_SunPos"), BEGIN_POS, 0.3f);
}
else
{
tween_exit = DOTween.To((value) =>
{
_mat.SetFloat("_SunPos", value);
}, _mat.GetFloat("_SunPos"), END_POS, 0.3f);
}
}
}
public void OnMouseDown()
{
if (inAnim) return;
inAnim = true;
tween_down?.Kill();

if (_mat.GetFloat("_SunPos") < 0)
{
tween_down = DOTween.To((value) =>
{
_mat.SetFloat("_SunPos", value);
}, _mat.GetFloat("_SunPos"), END_POS, 1f).OnComplete(()=> { inAnim = false; inBtn = false; });
}
else
{
tween_down = DOTween.To((value) =>
{
_mat.SetFloat("_SunPos", value);
}, _mat.GetFloat("_SunPos"), BEGIN_POS, 1f).OnComplete(() => { inAnim = false; inBtn = false; });
}
}
}

参数