-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfrag.glsl
267 lines (215 loc) · 5.98 KB
/
frag.glsl
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
/*
frag.glsl
Copyright 2017 Antoine Morin-Paulhus
You may use this file under the terms of the
Creative Commons "Attribution-NonCommercial 3.0 Unported" License.
You may find details of this license at the following URL:
https://creativecommons.org/licenses/by-nc/3.0/legalcode
*/
precision highp float;
varying vec2 UV;
uniform vec3 iResolution;
uniform vec2 renderBufferRatio;
uniform vec3 rocket_pos;
uniform vec3 rocket_speed;
uniform vec2 star;
uniform vec2 asteroid;
uniform float accelerating;
varying vec2 lastUV;
uniform float time;
uniform float destruction;
uniform float gotstar;
uniform int pass;
uniform sampler2D pass0;
uniform sampler2D pass1;
uniform sampler2D pass2;
uniform sampler2D lastPass;
uniform float ratio;
#define PI 3.14159265359
#define PI2 6.28318
//PASSES=3
vec4 rocket_side(vec2 pos){
vec4 col = vec4(0.0);
// Clip (because otherwise a sine is repeated)
if(pos.x < -0.5 || pos.x > 0.5){
return col;
}
if(
// Base parabolic shape
(pos.y > -0.14 && 3.0 * (pos.y - 0.3) < cos(pos.x * 8.0) * (2.0 - pos.y))
&&
(pos.y > 0.0 || distance(pos, vec2(0.0, 0.1)) < 0.27))
{
// Window
if (
distance(pos, vec2(0.0,0.2)) < 0.05
)
{
col.rgb += 0.4;
col.a = 1.0;
}
// Rest
else
{
col.rgb += 0.98;
col.a = 1.0;
}
}
else if (
pos.y < -0.4 + 0.5 * cos(4.5 * pos.x)
&&
pos.y > -0.5 + 0.3 * cos(3.0 * pos.x)
)
{
col.rgb += vec3(1.0,0.1,0.2);
col.a = 1.0;
}
// Propeller
else if (pos.x < 0.1 && pos.y < 0.0 && pos.y > -0.3)
{
col.rgb += vec3(0.3,0.3,0.3) + 0.3 * cos(pos.x * 10.0 + 1.0);
col.a = 1.0;
}
return col;
}
vec4 rocket(vec2 pos){
if(pos.x > 0.0){
return rocket_side(pos);
} else {
return rocket_side(pos * vec2(-1.0, 1.0));
}
}
mat2 rotation(vec2 pos, float angle){
mat2 r = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
return r;
}
float tri(float a){
float aa = mod(a, 1.0);
if(aa < 0.5){
return aa * 2.0;
} else {
return 1.0 - (aa - 0.5) * 2.0;
}
}
void main(void){
float x = UV.x * ratio;
float y = UV.y;
vec4 col = vec4(0.0);
vec2 pos = vec2(x, y) - vec2(0.5 * ratio, 0.5);
float angle = rocket_pos.z;
angle += 0.01 * cos(time * PI2) + 0.02 * cos(2.0 * time * PI2);
vec2 rp = (pos - rocket_pos.xy) * rotation(pos, angle);
rp *= 4.0;
// Asteroid distance
float ad = distance(pos.xy, asteroid);
vec2 pixel = 1.0 / iResolution.xy;
if(pass == 1){
// Draw smoke
float spreadfac = 1.0 - abs(rocket_speed.y) * 10.0;
float speedfac = 1.0 * length(abs(rocket_speed.xy));
col += 0.1 * texture2D(pass1, lastUV + vec2(0.0, 0.002));
col += 0.2 * texture2D(pass1, lastUV + vec2(0.0, 0.008));
col += 0.5* texture2D(pass1, lastUV + vec2(0.0, 0.03));
col += 0.5 * texture2D(pass1, lastUV + vec2(0.002, 0.0));
col += 0.5 * texture2D(pass1, lastUV + vec2(-0.002, 0.0));
col += 0.5 * texture2D(pass1, lastUV + vec2(0.008, 0.0));
col += 0.5 * texture2D(pass1, lastUV + vec2(-0.008, 0.0));
col *= 0.44;
vec2 smoke_pos = (pos - rocket_pos.xy) * rotation(pos, angle);
smoke_pos += vec2(0.0, 0.1);
smoke_pos += vec2(0.0, 0.06 * accelerating);
smoke_pos *= vec2(1.0, 1.0 - 0.5 * accelerating);
float sd = distance(smoke_pos, vec2(0.0)) / 0.06;
if(sd < 1.0){
float smokeblend = (1.0 - sd);
smokeblend = pow(smokeblend, 2.0);
col.rgb += smokeblend * vec3(1.0, 0.4, 0.1);
col.g += 0.6 * accelerating * smokeblend * (1.0 + 0.5 * cos(time * 20.0 + pos.y * 10.0));
}
col *= 0.8;
// Make whiter smoke with time
col = 0.85 * col + 0.15 * length(col.rgb)/3.0;
// Asteroid smoke
if(ad < 0.1){
col.rgb += 0.01 * (1.0 - ad)/0.1 * vec3(1.0, 0.3, 0.4);
}
// Explosion
if(destruction > 0.5){
float d = distance(rocket_pos.xy, pos);
if(d < 0.1 + 0.1 * cos(time * 10.0 - d * 10.0)){
vec2 p = pos - rocket_pos.xy;
float a = atan(p.y, p.x);
float fac = 0.1;
if(tri(a / PI2 * 8.0) > cos(d * 30.0)){
fac += 0.2;
}
col.rgb += fac *
vec3(0.8 * abs(cos(d * 40.0 + time * 100.0)), 0.2, 0.2);
}
}
} else if (pass == 2) {
// Smoke
col += texture2D(lastPass, lastUV);
} else if (pass == 3){
// Sky
col.r += pos.y * 0.4 + 0.05 * cos(pos.y * 0.3 + time * 0.4) + 0.4;
col.b += 0.3 * pos.y + 0.1 * cos(pos.y * 0.3 + time * 1.0) + 0.4;
// Add star
if(distance(pos, star) < 0.1){
float closefac = 0.0;
float rd = distance(rocket_pos.xy, star) / 0.4;
if(rd < 1.0){
closefac += 1.0 - rd;
}
vec2 sp = (pos - star);
float angle = atan(sp.y, sp.x);
float d = length(sp) / (0.04 + 0.08 * closefac);
float f = 1.0 - tri(angle * 5.0 / PI2) * 0.27;
if(d < f){
col.rg += 0.98;
}
}
// Success
if(gotstar > 0.5){
float d = distance(rocket_pos.xy, pos) / 0.2;
if(d < 1.0){
vec2 p = pos - rocket_pos.xy;
float a = atan(p.y, p.x);
float fac = 0.0;
fac += 0.3 * abs(cos(d * 20.0 - time * 10.0));
col.rgb +=
(1.0 - d) *
fac *
vec3(1.0, 1.0, 0.0);
}
}
// Rocket
vec4 r = rocket(rp);
col = col * (1.0 - r.a) + r * r.a;
float rd = distance(pos, rocket_pos.xy) / 0.2;
// Subtle Rocket glow
if(rd < 1.0){
col.r += 0.1 * abs(cos(time)) * (1.0 - rd);
col.g += 0.1 * abs(cos(1.2 * time + 1.0)) * (1.0 - rd);
col.b += 0.1 * abs(cos(1.3 * time + 2.0)) * (1.0 - rd);
}
// Smoke:
col += texture2D(lastPass, lastUV);
// Add asteroid
if(ad < 0.2){
ad = ad/0.12;
vec2 ap = (pos - asteroid);
float angle = atan(ap.y, ap.x);
angle += time * 2.0;
float f = 1.0 - cos(angle * 6.0) * 0.07 - cos(angle * 20.0 + 1.0) * 0.02 - cos(angle * 3.0 + 2.0) * 0.04;
if(ad < f){
col.rgb *= 0.0;
col.rgb += vec3(0.6, 0.2, 0.2);
col.rgb += 0.1 * cos(ad * 4.0 + f);
}
}
col *= 1.0 - 0.3 * pow(length(pos),2.0);
}
col.a = 1.0;
gl_FragColor = col;
}