-
Notifications
You must be signed in to change notification settings - Fork 0
/
index-gpu.html
113 lines (90 loc) · 2.6 KB
/
index-gpu.html
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
<style>
input[type="range"] {
display: block;
width: 512px;
}
</style>
<canvas id="canvas" width="512" height="512"></canvas>
<script type="module">
import {gen_table_tex, glsl_code} from "./perlin-gpu.js";
let vert_src = `#version 300 es
out vec2 uv;
void main()
{
uv = vec2(gl_VertexID % 2, gl_VertexID / 2);
gl_Position = vec4(uv * 2.0 - 1.0, 0, 1);
}
`;
let frag_src = `#version 300 es
#line 20
precision highp float;
${glsl_code}
uniform sampler2D table;
uniform float time;
uniform int octaves;
uniform float amplitude;
uniform float level;
in vec2 uv;
out vec4 color;
void main()
{
vec3 v = vec3(uv + time, time * 0.125);
float val = fractal(table, v, octaves);
val += level;
val *= amplitude;
val = max(val, 0.0);
val = 1.0 - 1.0 / (val + 1.0);
color = vec4(mix(0.75 * vec3(0.25, 0.5, 1), vec3(1), val), 1);
}
`;
let gl = canvas.getContext("webgl2", {antialias: false});
let vert = gl.createShader(gl.VERTEX_SHADER);
let frag = gl.createShader(gl.FRAGMENT_SHADER);
let prog = gl.createProgram();
let table = gen_table_tex(gl, 1);
let time = 0;
let last = 0;
let now = 0;
gl.shaderSource(vert, vert_src);
gl.shaderSource(frag, frag_src);
gl.compileShader(vert);
gl.compileShader(frag);
if(gl.getShaderParameter(vert, gl.COMPILE_STATUS) === false) {
throw "error: " + gl.getShaderInfoLog(vert);
}
if(gl.getShaderParameter(frag, gl.COMPILE_STATUS) === false) {
throw "error: " + gl.getShaderInfoLog(frag);
}
gl.attachShader(prog, vert);
gl.attachShader(prog, frag);
gl.linkProgram(prog);
if(gl.getProgramParameter(prog, gl.LINK_STATUS) === false) {
throw "error: " + gl.getProgramInfoLog(prog);
}
requestAnimationFrame(function frame() {
now = performance.now() / 1000;
last = last || now;
time += (now - last) * speed.value;
last = now;
gl.useProgram(prog);
gl.uniform1f(gl.getUniformLocation(prog, "time"), time);
gl.uniform1i(gl.getUniformLocation(prog, "octaves"), octaves.value);
gl.uniform1f(gl.getUniformLocation(prog, "amplitude"), amplitude.value);
gl.uniform1f(gl.getUniformLocation(prog, "level"), level.value);
gl.activeTexture(gl.TEXTURE0 + 0);
gl.bindTexture(gl.TEXTURE_2D, table);
gl.uniform1i(gl.getUniformLocation(prog, "table"), 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(frame);
});
</script>
<div>
Speed:
<input type="range" value="0" min="0" max="1" step="any" id="speed">
Octaves:
<input type="range" value="8" min="1" max="8" step="1" id="octaves">
Amplitude:
<input type="range" value="32" min="1" max="256" step="1" id="amplitude">
Level:
<input type="range" value="0" min="-0.25" max="0.25" step="any" id="level">
</div>