Task 5 of 6
Task 3 painted pixels. But an image doesn't have to stay an image: in this
course an image is a nested array — photo[y][x] is an [r, g, b, a]
pixel with channels 0–1 — and a kernel can read it like any other array argument.
Drop graphical: true, and the same per-pixel indexing produces
numbers instead of colors: a measurement per pixel, ready for JavaScript.
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].
photo — each cell
the average of that pixel's red, green and blue channels.graphical: true, output [64, 64]photo[this.thread.y][this.thread.x](r + g + b) / 3The pixel lookup is identical to the grayscale task — only the ending changes:
return a number instead of calling this.color().
const pixel = photo[this.thread.y][this.thread.x];
return (pixel[0] + pixel[1] + pixel[2]) / 3;This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.