Skip to content

Instantly share code, notes, and snippets.

@janispritzkau
Last active June 15, 2023 08:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janispritzkau/d9370d56d65eda9993391fda56fd29c6 to your computer and use it in GitHub Desktop.
Save janispritzkau/d9370d56d65eda9993391fda56fd29c6 to your computer and use it in GitHub Desktop.
Simple WebGL example with basic error handling
const canvas = document.querySelector("canvas")
canvas.width = 800, canvas.height = 600
canvas.style.width = `${canvas.width / devicePixelRatio}px`
const gl = canvas.getContext("webgl")
const vertexShader = gl.createShader(gl.VERTEX_SHADER)
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(vertexShader, `
attribute vec4 position;
void main() {
gl_Position = position;
}
`)
gl.shaderSource(fragmentShader, `
precision highp float;
uniform float time;
uniform vec2 resolution;
void main() {
vec2 uv = gl_FragCoord.xy / resolution.xy;
gl_FragColor = vec4(0.5 + 0.5 * cos(time + uv.xyx + vec3(0, 2, 4)), 1);
}
`)
const program = gl.createProgram()
for (const shader of [vertexShader, fragmentShader]) {
gl.compileShader(shader)
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(shader))
}
gl.attachShader(program, shader)
}
gl.linkProgram(program)
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error(gl.getProgramInfoLog(program))
}
gl.useProgram(program)
const buffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
const posAttr = gl.getAttribLocation(program, "position");
gl.enableVertexAttribArray(posAttr)
gl.vertexAttribPointer(posAttr, 2, gl.FLOAT, false, 0, 0)
// pass resolution to shader as global variable
gl.uniform2f(gl.getUniformLocation(program, "resolution"), canvas.width, canvas.height)
// add time uniform for animation
const timeU = gl.getUniformLocation(program, "time")
const array = new Float32Array([
-1, -1, -1, 1, 1, -1,
1, -1, 1, 1, 0, 0
])
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW)
function frame() {
gl.clearColor(0, 0, 0, 0)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.uniform1f(timeU, performance.now() / 1000)
gl.drawArrays(gl.TRIANGLES, 0, array.length / 2)
const error = gl.getError()
if (error) throw new Error(`WebGL error code: ${error}`)
requestAnimationFrame(frame)
}
requestAnimationFrame(frame)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment