Set a Custom Canvas Target in GPU.js
This article explains how to direct graphical output from GPU.js to a
custom HTML5 <canvas> element. Because WebGL contexts
cannot be rebound to new elements once created, routing output requires
either attaching your canvas during the GPU instance setup for maximum
performance or blitting the rendered frames from a compiled graphical
kernel onto a secondary canvas dynamically.
Direct Method: Passing a Custom Canvas to the GPU Instance
The most performant way to render to a custom canvas is to attach the
DOM element directly when instantiating the GPU object. A
graphical kernel created under this instance will render straight to
your custom canvas without requiring data copies.
<canvas id="render-surface" width="512" height="512"></canvas>const targetCanvas = document.getElementById('render-surface');
// Bind the custom canvas during GPU initialization
const gpu = new GPU({
canvas: targetCanvas,
mode: 'webgl2' // Falls back to 'webgl' if unsupported
});
// Create a graphical kernel
const renderKernel = gpu.createKernel(function() {
const x = this.thread.x / this.output.x;
const y = this.thread.y / this.output.y;
this.color(x, y, 0.5, 1.0);
})
.setOutput([targetCanvas.width, targetCanvas.height])
.setGraphical(true);
// Execute the kernel to render directly onto targetCanvas
renderKernel();When .setGraphical(true) is enabled, the kernel draws
its pixel values using this.color() into the WebGL context
bound to targetCanvas.
Dynamic Method: Routing a Compiled Kernel to Multiple Canvases
Because a WebGL context cannot change its host canvas after creation,
you cannot swap the underlying canvas of an already compiled kernel. If
you must output an existing compiled kernel to an arbitrary or dynamic
canvas, use the 2D Canvas API's drawImage() method to
transfer pixels from the kernel's internal canvas to your target
canvas.
// Function to blit output to any arbitrary canvas
function renderToCustomCanvas(kernel, destinationCanvas) {
// Execute the kernel so its internal canvas is updated
kernel();
const destContext = destinationCanvas.getContext('2d');
// Ensure the target canvas matches dimensions
destinationCanvas.width = kernel.canvas.width;
destinationCanvas.height = kernel.canvas.height;
// Draw the compiled kernel's WebGL canvas onto the destination canvas
destContext.drawImage(kernel.canvas, 0, 0);
}
// Example usage with a dynamically selected canvas
const secondaryCanvas = document.getElementById('secondary-canvas');
renderToCustomCanvas(renderKernel, secondaryCanvas);Summary of Options
- Use instance-level assignment
(
new GPU({ canvas })) if the canvas target is known before kernel execution. This avoids memory overhead and renders with pure WebGL speed. - Use pixel transfer (
drawImage) if you need to project the results of a single compiled kernel onto multiple or dynamically generated canvases across your application interface.