Task 6 of 6
Everything from this module in one pipeline. Kernel one reads the
photo and produces a 64×64 luminance map — pure numbers.
That result comes back to JavaScript, and you pass it straight into kernel two, a
graphical kernel that paints the map as a grayscale picture.
Array in → numbers out → array in again → pixels out. Data flowing through kernels is the whole game (and Pipelines & Textures shows how to keep that flow on the GPU).
Image data comes in row-major: image[y][x] is the pixel in row y,
column x, and each pixel is an [r, g, b, a] array with channels from
0 to 1. Mind the inversion that catches everyone — sizes are given width-first
(output: [width, height]), but indexing runs row-first, so this thread's own
pixel is image[this.thread.y][this.thread.x]. Swap those two and you read the
transpose of your image. Three-dimensional data follows the same rule:
output: [w, h, d] is indexed [z][y][x].
luminance returns
0.299r + 0.587g + 0.114b per pixel, and paint renders the map
as gray pixels with this.color().photo[this.thread.y][this.thread.x], return the weighted luminancemapthis.color(l, l, l, 1)Same lookup as before, but return a number:
return 0.299 * pixel[0] + 0.587 * pixel[1] + 0.114 * pixel[2];map is a plain 2D array of numbers, so
const l = map[this.thread.y][this.thread.x];
this.color(l, l, l, 1);This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.