-
Notifications
You must be signed in to change notification settings - Fork 8
/
shaders.go
268 lines (230 loc) · 6.97 KB
/
shaders.go
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
package main
const vertexShader = `#version 300 es
layout (location = 0) in vec2 vert;
layout (location = 1) in vec2 uvs;
layout (location = 2) in vec2 effect;
uniform highp float uTime;
uniform highp float uPulse;
uniform highp float uTouchX;
uniform highp float uTouchY;
out highp vec2 uv;
out highp vec2 pos;
out highp vec2 pos2;
out mediump vec2 eff;
void main() {
uv = uvs;
pos2 = vec2(vert.x, vert.y);
gl_Position = vec4(2.0*vert.x-1.0, 2.0*vert.y-1.0, 0.0, 1.0);
pos = gl_Position.xy;
eff = effect;
if (eff.x == 100.0) { // Unused
gl_Position.x = pos.x - sin(uTime)/30.0;
gl_Position.y = pos.y - cos(uTime)/20.0;
} else if(eff.x == 6.0) {
gl_Position.x = pos.x - sin(uTime)/30.0;
} else if(eff.x == 7.0) {
gl_Position.x = pos.x + sin(uTime)/30.0;
} else {
gl_Position = vec4(2.0*vert.x-1.0, 2.0*vert.y-1.0, 0.0, 1.0);
}
}
`
const fragmentShader = `#version 300 es
in highp vec2 uv;
in highp vec2 pos;
in highp vec2 pos2;
in mediump vec2 eff;
uniform sampler2D image;
uniform highp float uTime;
uniform highp float uPulse;
uniform highp float uTouchX;
uniform highp float uTouchY;
layout (location = 0) out highp vec4 color;
precision highp float;
precision lowp int;
vec2 random2( vec2 p ) {
return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453);
}
float random (in vec2 _st) {
return fract(sin(dot(_st.xy,
vec2(12.9898,78.233)))*
43758.5453123);
}
// Based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in vec2 _st) {
vec2 i = floor(_st);
vec2 f = fract(_st);
// Four corners in 2D of a tile
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
#define NUM_OCTAVES 5
float fbm ( in vec2 _st) {
float v = 0.0;
float a = 0.5;
vec2 shift = vec2(100.0);
// Rotate to reduce axial bias
mat2 rot = mat2(cos(0.5), sin(0.5),
-sin(0.5), cos(0.50));
for (int i = 0; i < NUM_OCTAVES; ++i) {
v += a * noise(_st);
_st = rot * _st * 2.0 + shift;
a *= 0.5;
}
return v;
}
void main() {
// skip all outside of the screen
if (pos.x > 1.0) {
discard;
return; // Not sure if needed?
}
color = texture(image, uv);
if (eff.x == 0.0) {
if (color.r > 0.5 && color.g < 0.2) {
color.r = 0.0;
}
} else if(eff.x == 12.0) { // Bitrot
vec2 u_resolution = vec2(1000.0, 1000.0);
vec2 st = gl_FragCoord.xy/u_resolution.xy*2.0;
color.r = 0.0;
st *= 70.0;
vec2 ipos = floor(st);
vec2 fpos = fract(st);
color.a = max(0.2, fract(random(ipos)*tan(uTime)*10.0));
} else if(eff.x == 10.0 || eff.x == 11.0) { // Menu bg
vec2 u_resolution = vec2(1000.0, 1000.0);
vec2 st = gl_FragCoord.xy/u_resolution.xy*3.;
vec3 c = vec3(0.0);
vec2 q = vec2(0.);
q.x = fbm( st + 0.00*uTime);
q.y = fbm( st + vec2(1.0));
vec2 r = vec2(0.);
r.x = fbm( st + 1.0*q + vec2(1.7,9.2)+ 0.15*uTime );
r.y = fbm( st + 1.0*q + vec2(8.3,2.8)+ 0.126*uTime );
float f = fbm(st+r);
c = mix(vec3(0.101961,0.619608,0.666667),
vec3(0.666667,0.666667,0.198039),
clamp((f*f)*4.0,0.0,1.0));
c = mix(c,
vec3(0,0,sin(uTime*0.164706)),
clamp(length(q),0.0,1.0));
c = mix(c,
vec3(sin(uTime*0.666667),1,1),
clamp(length(r.x),0.0,1.0));
//float dx = distance(pos2.x, 0.5+sin(uTime)/10.0);
float dx = distance(pos2.x, 0.5);
float dy = distance(pos2.y, -0.05);
if (eff.x == 10.0) {
color = vec4((f*f*f+.6*f*f+.5*f)*c,1.2-(dx/dy)-dy/2.0);
color.r += (1.2-(dx/dy)-dy) + uTouchX/3.0;
color.b += (1.4-(dx/dy)-dy) + uTouchY/3.0;
} else {
color = vec4((f*f*f+.6*f*f+.5*f)*c,1.0);
}
} else if (eff.x == 1.0 || eff.x == 9.0) { // MetaBalls + EffectBg
vec4 c = color;
if (uTime < 4.0) {
c.a += sin(c.a*uTime/3.0)-1.0;
}
vec2 u_resolution = vec2(1000.0, 1000.0);
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec3 color2 = vec3(.0);
// Scale
if (eff.x == 9.0) {
st *= 60.0;
} else {
st *= 20.0;
}
// Tile the space
vec2 i_st = floor(st);
vec2 f_st = fract(st);
float m_dist = 1.0; // minimum distance
for (int j= -1; j <= 1; j++ ) {
for (int i= -1; i <= 1; i++ ) {
// Neighbor place in the grid
vec2 neighbor = vec2(float(i),float(j));
// Random position from current + neighbor place in the grid
vec2 offset = random2(i_st + neighbor);
// Animate the offset
offset = 0.5 + 0.5*sin(uTime + 6.2831*offset);
// Position of the cell
vec2 pos2 = neighbor + offset - f_st;
// Cell distance
float dist = length(pos2);
// Metaball it!
if (eff.x == 9.0) {
//m_dist = min(m_dist, m_dist*dist)*(1.0+(pos.y-uPulse));
m_dist = min(m_dist, m_dist*dist)*(pos.y-uPulse+1.5);
} else {
m_dist = min(m_dist, m_dist*dist)*(pos.y+0.2);
}
}
}
if (eff.x == 9.0) {
color2 += step(0.01, m_dist);
color = c * vec4(color2,1.0);
if (color.r == 0.0 && color.b == 0.0 && color.g == 0.0 && color.a > 0.0) {
c.r += sin(uPulse*pos.y);
c.b += uPulse;
c.a = max(0.4, pos.y);
color = c;
} else {
c.g += sin(uTime/10.0)/10.0;
c.r += cos(uTime/5.0)/10.0;
c.b += sin(uTime/20.0)/10.0;
color = c;
}
} else {
color2 += step(0.05*pos.y, m_dist);
color = c * vec4(color2,1.0);
if (color.r == 0.0 && color.b == 0.0 && color.g == 0.0 && color.a > 0.0) {
color = c;
color.a = clamp(sin(pos.x*uTime), 1.0, 0.5);
color.b = 0.8;
}
if (color.r > 0.5 && color.g < 0.2) {
color.b = clamp(sin(uTime), 0.0, 0.8);
color.r = clamp(sin(uTime), 0.0, 0.3);
}
}
} else if(eff.x == 2.0 || eff.x == 4.0) { // TileTop
if (pos.y > 0.75) {
color.a = 1.0-pos.y;
}
if (eff.x == 4.0) {
if (color.r > 0.5 && color.g < 0.2) {
color.r = 0.0;
}
}
} else if(eff.x == 3.0) { // Stats
if (color.r > 0.5 && color.g < 0.2) {
color.r = 0.0;
}
color.b += 0.8;
} else if (eff.x == 8.0) { // stats blinking
color.b = sin(uTime*7.0);
} else if(eff.x == 5.0) { // GameOver (Red)
if (color.a > 0.4) {
color.r = 1.0;
color.a = 0.2;
}
} else if(eff.x == 6.0 || eff.x == 7.0) { // Game Over "Logo"
if (color.r > 0.5 && color.g < 0.2) {
color.a = 0.0;
}
} else {
if (color.r > 0.5 && color.g < 0.2) {
color.r = 0.0;
}
}
}
`