Readme

Testing WebGL

A minimal template for writing shaders.

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
export async function WebGLTest(request: Request): Promise<Response> {
const vs = `#version 300 es
precision highp float;
layout(location=0) in vec2 position;
layout(location=1) in vec2 texcoord;
out vec2 v_texcoord;
void main() {
v_texcoord = texcoord;
gl_Position = vec4(position, 0.0, 1.0);
}`;
const fs = `#version 300 es
precision highp float;
in vec2 v_texcoord;
layout(location=0) out vec4 fragColor;
void main() {
fragColor = vec4(v_texcoord, 1.,1.);
}`;
return new Response(
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>WebGL</title>
<style>
*,*::before,*::after {
box-sizing: border-box;
}
* {
margin: 0;
}
html,body {
overflow: hidden;
}
#canvas {
width: 100vw;
height: 100dvh;
touch-action: none;
}
</style>
</head>
<body>
<canvas id="canvas" />
<script>
"use strict";
const compileShader = (gl, type, source) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const msg = gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
throw new Error(msg);
}
return shader;
};
const createProgram = (gl, vs, fs) => {
const vert = compileShader(gl, gl.VERTEX_SHADER, vs);
const frag = compileShader(gl, gl.FRAGMENT_SHADER, fs);
const program = gl.createProgram();
gl.attachShader(program, vert);
gl.attachShader(program, frag);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const msg = gl.getProgramInfoLog(program);
gl.deleteProgram(program);
throw new Error(msg);
}
gl.detachShader(program, vert);
gl.deleteShader(vert);
gl.detachShader(program, frag);
gl.deleteShader(frag);
return program;
};
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl2", { antialias: true, alpha: true, powerPreference: "high-performance" });
const program = createProgram(gl, \`${vs}\`,\`${fs}\`);
gl.useProgram(program);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.of(-1, 1, -1, -1, 1, 1, 1, -1), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.of(0, 1, 0, 0, 1, 1, 1, 0), gl.STATIC_DRAW);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.