Task 2 of 5

Chain Kernels, Skip the Round Trip

Here's the payoff of textures: a texture returned by one kernel can be passed straight into the next kernel as an argument. gpu.js binds the texture as the input — no download, no re-upload, no JavaScript in the middle. The data makes the whole trip without ever leaving the card.

In Data In, Data Out you chained two kernels through JavaScript: the luminance map came back as arrays, then went up again for the second pass. Same chain below — except this time luminance is a pipeline kernel, and the second pass eats its texture directly.

Array layout in gpu.js

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].

kernel to kernel by texture — javascript never sees the middle
Goal: finish the contrast kernel — stretch each luminance value around the midpoint with (l − 0.5) × 2 + 0.5, clamped to 0–1 — and keep the texture handoff intact.

Requirements

Hint 1 — textures index like arrays

Inside contrast, the texture argument reads exactly like the 2D arrays you already know: map[this.thread.y][this.thread.x]. The kernel doesn't care where the data lives.

Hint 2 — the clamp
return Math.min(Math.max((l - 0.5) * 2 + 0.5, 0), 1);

Same idea elsewhere

Handing a texture from kernel to kernel is what CUDA does when consecutive launches read and write the same device pointers, and what a WebGPU compute pass does when one dispatch's storage buffer becomes the next dispatch's binding. On Metal it's two encoders sharing an MTLBuffer. Nobody copies to the CPU in between.

All tasks in Pipelines & Textures

  1. Flip On the Pipeline
  2. Chain Kernels, Skip the Round Trip
  3. toArray() Is a Tollbooth
  4. Feedback Loops: immutable Textures
  5. The Payoff: Photo to Screen, Zero Readbacks

This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.