forked from hilmizr/dinochrome-flight
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Explosion.js
127 lines (97 loc) · 3.52 KB
/
Explosion.js
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
import { IcosahedronGeometry, TextureLoader, ShaderMaterial, Mesh, ShaderChunk } from './libs/three137/three.module.js';
import { noise } from './libs/Noise.js';
import { Tween } from './libs/Toon3D.js';
class Explosion {
static vshader = `
#include <noise>
uniform float u_time;
varying float noise;
void main() {
float time = u_time;
float displacement;
float b;
// add time to the noise parameters so it's animated
noise = 10.0 * -.10 * turbulence( .5 * normal + time );
b = 5.0 * pnoise( 0.05 * position + vec3( 2.0 * time ), vec3( 100.0 ) );
displacement = - 10. * noise + b;
// move the position along the normal and transform it
vec3 newPosition = position + normal * displacement;
gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
}
`
static fshader = `
#define PI 3.141592653589
#define PI2 6.28318530718
uniform vec2 u_mouse;
uniform vec2 u_resolution;
uniform float u_time;
uniform float u_opacity;
uniform sampler2D u_tex;
varying float noise;
// <https://www.shadertoy.com/view/4dS3Wd>
// By Morgan McGuire @morgan3d, http://graphicscodex.com
//https://www.clicktorelease.com/blog/vertex-displacement-noise-3d-webgl-glsl-three-js/
float random( vec3 scale, float seed ){
return fract( sin( dot( gl_FragCoord.xyz + seed, scale ) ) * 43758.5453 + seed ) ;
}
void main() {
// get a random offset
float r = .01 * random( vec3( 12.9898, 78.233, 151.7182 ), 0.0 );
// lookup vertically in the texture, using noise and offset
// to get the right RGB colour
vec2 t_pos = vec2( 0, 1.3 * noise + r );
vec4 color = texture2D( u_tex, t_pos );
gl_FragColor = vec4( color.rgb, u_opacity );
}
`
constructor(parent, obstacles) {
const geometry = new IcosahedronGeometry(20, 4);
this.obstacles = obstacles;
this.uniforms = {
u_time: { value: 0.0 },
u_mouse: { value: { x: 0.0, y: 0.0 } },
u_opacity: { value: 0.6 },
u_resolution: { value: { x: 0, y: 0 } },
u_tex: { value: new TextureLoader().load(`${game.assetsPath}ptera/explosion.png`) }
}
ShaderChunk.noise = noise;
const material = new ShaderMaterial({
uniforms: this.uniforms,
vertexShader: Explosion.vshader,
fragmentShader: Explosion.fshader,
transparent: true,
opacity: 0.6
});
this.ball = new Mesh(geometry, material);
const scale = 0.05;
this.ball.scale.set(scale, scale, scale);
parent.add(this.ball);
this.tweens = [];
this.tweens.push(new Tween(this.ball.scale, 'x', 0.2, 1.5, this.onComplete.bind(this), 'outQuad'));
this.active = true;
}
onComplete() {
this.ball.parent.remove(this.ball);
this.tweens = [];
this.active = false;
this.ball.geometry.dispose();
this.ball.material.dispose();
if (this.obstacles) this.obstacles.removeExplosion(this);
}
update(time) {
if (!this.active) return;
this.uniforms.u_time.value += time;
this.uniforms.u_opacity.value = this.ball.material.opacity;
if (this.tweens.length < 2) {
const elapsedTime = this.uniforms.u_time.value - 1;
if (elapsedTime > 0) {
this.tweens.push(new Tween(this.ball.material, 'opacity', 0, 0.5));
}
}
this.tweens.forEach(tween => {
tween.update(time);
});
this.ball.scale.y = this.ball.scale.z = this.ball.scale.x;
}
}
export { Explosion };