WebGL Motion Blur Compositing
by balefrost
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="1920" height="1080" style="width: 100%; height: auto"></canvas>
<br />
<button id="renderBtn">Render</button>
</body>
</html>
JavaScript
const SAMPLES = 32;
const OPTION = 'webgl';
let pos = 130;
//Setup testing page
window.onload = ()=>{
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d', {willReadFrequently: true});
draw(ctx);
document.getElementById('renderBtn').addEventListener('click', ()=>{
pos = 130;
draw(ctx);
webGLComposite(canvas, ctx);
});
}
//Generates a simple image purely for testing. Treat this function as a black box
function draw(ctx){
ctx.fillStyle = '#22ffff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#FFFF66';
ctx.beginPath();
ctx.arc(pos, 1080/4, 100, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.arc(pos, 1080/4*3, 100, 0, Math.PI * 2);
ctx.fill();
}
function webGLComposite(canvas, ctx){
const sampleCanvas = new OffscreenCanvas(canvas.width, canvas.height);
const sampleCtx = sampleCanvas.getContext('2d');
//Setup webgl shit
const createShader = (gl, type, source)=>{
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return undefined;
};
const createProgram = (gl, vs, fs)=>{
const prg = gl.createProgram();
gl.attachShader(prg, vs);
gl.attachShader(prg, fs);
gl.linkProgram(prg);
if (gl.getProgramParameter(prg, gl.LINK_STATUS)){
return prg;
}
console.log(gl.getProgramInfoLog(prg));
return undefined;
};
const blurCanvas = new OffscreenCanvas(canvas.width, canvas.height);
const gl = blurCanvas.getContext('webgl2', {preserveDrawingBuffer: true});
const vs = createShader(gl, gl.VERTEX_SHADER, `#version 300 es
in vec4...