GPU.js Graphical Mode Thread to Pixel Mapping
In GPU.js, enabling graphical mode transforms a kernel into a
hardware-accelerated pixel shader that renders directly to an HTML5
canvas. Thread indices determine exactly which pixel on the screen is
being processed by mapping the kernel's execution grid directly to the
canvas's width and height. Because GPU.js relies on WebGL under the
hood, this mapping follows a Cartesian coordinate system where thread
index (0, 0) corresponds to the bottom-left corner of the
canvas rather than the top-left standard seen in conventional 2D web
graphics.
The Coordinate Grid Setup
When you configure a kernel with { graphical: true },
you define its output dimensions using
setOutput([width, height]). GPU.js allocates a grid of
threads matching these exact dimensions:
this.thread.x: Represents the horizontal column index, ranging from0towidth - 1.this.thread.y: Represents the vertical row index, ranging from0toheight - 1.
Each individual thread runs concurrently for a single pixel location
defined by (this.thread.x, this.thread.y).
The WebGL Origin (Bottom-Left Orientation)
The most critical distinction when mapping thread indices to canvas pixels is the coordinate origin:
this.thread.x = 0, this.thread.y = 0targets the bottom-left pixel.this.thread.x = width - 1, this.thread.y = 0targets the bottom-right pixel.this.thread.x = 0, this.thread.y = height - 1targets the top-left pixel.this.thread.x = width - 1, this.thread.y = height - 1targets the top-right pixel.
Standard HTML5 Canvas 2D contexts and DOM mouse events place
(0, 0) at the top-left corner. If you are translating input
data (such as image buffers or mouse click coordinates) into the
graphical kernel, the Y-axis must be inverted:
// Converting standard top-left DOM coordinates to GPU.js graphical space:
const gpuY = canvasHeight - 1 - domY;Emitting Pixel Colors
Instead of returning numerical values as standard kernels do, a
graphical kernel writes to its mapped pixel using the built-in
this.color(r, g, b, a) method. The arguments require
normalized floating-point values between 0.0 and
1.0:
const renderKernel = gpu.createKernel(function() {
// Normalize coordinates from 0.0 to 1.0
const u = this.thread.x / this.output.x;
const v = this.thread.y / this.output.y;
// Outputs red along X-axis, green along Y-axis, fully opaque
this.color(u, v, 0.0, 1.0);
})
.setOutput([800, 600])
.setGraphical(true);
renderKernel();In this execution, this.output.x and
this.output.y reflect the canvas dimensions (800 and 600).
As this.thread.x traverses from left to right, the red
channel increases. As this.thread.y traverses from bottom
to top, the green channel increases, accurately reflecting the
underlying WebGL coordinate space.