171 lines
5.2 KiB
HTML
171 lines
5.2 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en" >
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<title>GLSL: GPGPU particles</title>
|
||
|
<link rel="stylesheet" href="./style.css">
|
||
|
</head>
|
||
|
<body>
|
||
|
<!-- partial:index.partial.html -->
|
||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>
|
||
|
<script id="vertexShader" type="x-shader/x-vertex">
|
||
|
uniform float u_time;
|
||
|
|
||
|
const float spawnrate = .01;
|
||
|
const float life = 200.;
|
||
|
const float fadetime = 20.;
|
||
|
const int octaves = 5;
|
||
|
const float seed = 43758.5453123;
|
||
|
const float seed2 = 73156.8473192;
|
||
|
|
||
|
float random(float val) {
|
||
|
return fract(sin(val) * seed);
|
||
|
}
|
||
|
|
||
|
vec2 random2(vec2 st, float seed){
|
||
|
st = vec2( dot(st,vec2(127.1,311.7)),
|
||
|
dot(st,vec2(269.5,183.3)) );
|
||
|
return -1.0 + 2.0*fract(sin(st)*seed);
|
||
|
}
|
||
|
|
||
|
float random2d(vec2 uv) {
|
||
|
return fract(
|
||
|
sin(
|
||
|
dot( uv.xy, vec2(12.9898, 78.233) )
|
||
|
) * seed);
|
||
|
}
|
||
|
|
||
|
varying float v_z;
|
||
|
|
||
|
float easeLinear(float time, float begin, float change, float duration)
|
||
|
{
|
||
|
return change * time / duration + begin;
|
||
|
}
|
||
|
vec2 easeLinear(float time, vec2 begin, vec2 change, float duration)
|
||
|
{
|
||
|
return change * time / duration + begin;
|
||
|
}
|
||
|
|
||
|
void main() {
|
||
|
vec4 pos = vec4(position,1.0);
|
||
|
float id = position.z;
|
||
|
bool emitter = mod(id, 2.) == 0.;
|
||
|
float rand = random(id);
|
||
|
float rand1 = random(id + 1.);
|
||
|
float pointsize = 100. * rand * rand1;
|
||
|
|
||
|
// float spawnrate = spawnrate + (sin(u_time / 10.) + 1.) * .01;
|
||
|
float time = mod(u_time - id * spawnrate, life);
|
||
|
float step = time / life;
|
||
|
bool alive = time >= 0.;
|
||
|
|
||
|
vec2 polar = vec2(0., 0.);
|
||
|
|
||
|
if(alive) {
|
||
|
if(emitter) {
|
||
|
// pos.xy = vec2(10. * rand);
|
||
|
vec2 outerPolar = vec2(30. + sin(u_time / 50.) * 10., 200.);
|
||
|
polar = easeLinear(time, vec2(sin(u_time / 50.), 100. + sin(u_time / 10.) * 50.), outerPolar, life);
|
||
|
// polar.x += sin(u_time / 10. * rand) + 1.;
|
||
|
polar.y += (sin((u_time + 100.) / 10. * rand) + 1.) * (polar.x * 2. + 10.);
|
||
|
|
||
|
if(time < fadetime) {
|
||
|
pointsize = easeLinear(time, 0., pointsize, fadetime);
|
||
|
} else if(time > life - fadetime) {
|
||
|
pointsize = easeLinear(time - life + fadetime, pointsize, -pointsize, fadetime);
|
||
|
}
|
||
|
pointsize *= (sin((u_time + 100.) / 10. * rand1) + 1.);
|
||
|
pointsize *= cos(polar.x * 1.5 + u_time * .1) * .5 + 1.;
|
||
|
pos.z = 100.;
|
||
|
} else {
|
||
|
// pos.xy = vec2(10. * rand);
|
||
|
vec2 outerPolar = vec2(30. + sin(u_time / 50.) * 10. + 3.14, 200.);
|
||
|
polar = easeLinear(time, vec2(sin(u_time / 50.) + 3.14, 100. + cos(u_time / 10.) * 50.), outerPolar, life);
|
||
|
// polar.x += sin(u_time / 10. * rand) + 1.;
|
||
|
polar.y += (sin((u_time + 100.) / 10. * rand) + 1.) * (polar.x * 2. + 10.);
|
||
|
|
||
|
if(time < fadetime) {
|
||
|
pointsize = easeLinear(time, 0., pointsize, fadetime);
|
||
|
} else if(time > life - fadetime) {
|
||
|
pointsize = easeLinear(time - life + fadetime, pointsize, -pointsize, fadetime);
|
||
|
}
|
||
|
pointsize *= 1. - (sin((u_time + 100.) / 10. * rand1) + 1.);
|
||
|
// pointsize *= cos(polar.x * 1.5 + u_time * .1) * .5 + 1.;
|
||
|
pos.z = 90.;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pos.x += cos(polar.x) * polar.y;
|
||
|
pos.y += sin(polar.x) * polar.y;
|
||
|
|
||
|
v_z = pos.z / 100. + polar.x / 100.;
|
||
|
gl_PointSize = pointsize;
|
||
|
|
||
|
gl_Position = projectionMatrix *
|
||
|
modelViewMatrix *
|
||
|
pos;
|
||
|
}
|
||
|
</script>
|
||
|
<script id="fragmentShader" type="x-shader/x-fragment">
|
||
|
uniform vec2 u_resolution;
|
||
|
uniform float u_time;
|
||
|
uniform sampler2D tSprite;
|
||
|
|
||
|
varying float v_z;
|
||
|
|
||
|
vec3 hsb2rgb( in vec3 c ){
|
||
|
vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
|
||
|
6.0)-3.0)-1.0,
|
||
|
0.0,
|
||
|
1.0 );
|
||
|
rgb = rgb*rgb*(3.0-2.0*rgb);
|
||
|
return c.z * mix( vec3(1.0), rgb, c.y);
|
||
|
}
|
||
|
|
||
|
#define TAU 6.28318531
|
||
|
float starSDF(vec2 st, int V, float s) {
|
||
|
// st = st*4.-2.;
|
||
|
float a = atan(st.y, st.x)/TAU;
|
||
|
float seg = a * float(V);
|
||
|
a = ((floor(seg) + 0.5)/float(V) +
|
||
|
mix(s,-s,step(.5,fract(seg))))
|
||
|
* TAU;
|
||
|
return abs(dot(vec2(cos(a),sin(a)),
|
||
|
st));
|
||
|
}
|
||
|
|
||
|
void main() {
|
||
|
vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / u_resolution.y;
|
||
|
|
||
|
float dist;
|
||
|
|
||
|
vec2 pointUV = gl_PointCoord.xy - .5 * v_z / v_z;
|
||
|
dist = 1. - length(pointUV) * 3.;
|
||
|
|
||
|
vec2 polar = vec2(atan(uv.y, uv.x), length(uv.xy));
|
||
|
int points = int(dist * 5.);
|
||
|
|
||
|
// gl_FragColor = vec4(hsb2rgb(vec3(polar.y / 3., 1. - v_z * sin(polar.y * u_time / 100.), polar.y * v_z / 10.)), dist);
|
||
|
gl_FragColor = vec4(
|
||
|
mix(
|
||
|
vec3(5.0, 0., 0.),
|
||
|
vec3(.8, 1.5, .5),
|
||
|
clamp(dist * v_z, 0., 1.)
|
||
|
) *
|
||
|
dist,
|
||
|
smoothstep(0.6, .61 + v_z / 1.5, dist)
|
||
|
);
|
||
|
// gl_FragColor *= v_z / 2.;
|
||
|
// gl_FragColor = vec4(vec3(.8, .8, .5), smoothstep(0.8, .81, dist));
|
||
|
// gl_FragColor = vec4(v_z / 2.);
|
||
|
// gl_FragColor = vec4(vec3(dist), dist);
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
|
||
|
<div id="container"></div>
|
||
|
<!-- partial -->
|
||
|
<script src="./script.js"></script>
|
||
|
|
||
|
</body>
|
||
|
</html>
|