Make One GPU Thread Return 32 Bits
The minimum path runs one GPU hardware thread and returns four RGBA bytes. That 32-bit result makes every stage easy to inspect.
The sequence starts with two browser operations:
- Create an invisible
<canvas>HTML element. - Call its
getContext()method to acquire WebGL.
Build the WebGL Context
A browser canvas owns the WebGL context:
The canvas starts at its default size of 300 by 150 pixels:
A 2x2 canvas keeps this first run compact:
Depth testing and antialiasing add graphics work that this GPGPU path does not need. The context options remove both and request high-performance, desynchronized execution:
A readable gl.getError() wrapper turns numeric failures into precise diagnostic names:
The Shader class compiles the GLSL pair, links the program, binds a four-vertex strip, and renders two triangles:
The complete run path now writes the RGBA value [0, 255, 127, 0] across a 16x16 viewport:
A later pass can consume the color attachment directly as a texture after a state swap. For inspection, readPixels() copies the 16x16 RGBA result into a byte array:
Keep GLSL 1.00 Precision Under Direct Control
The GLSL 1.00 preprocessor cuts floating-point literals below 1.0000001e-37 = pow(2, -123) * (1 + 0.0633825). Its decimal-literal path shrinks values below 1e-37 to zero and ignores the sign. The preprocessor causes that behavior before the GPU runs the shader; ANGLE's constant-union implementation shows the relevant translation path.
The next function runs dynamic shader source and returns floating-point values, raw bytes, and the corresponding bit string:
The dynamic runner can now execute the packing shader against a 1x1 target:
Desktop and laptop GPUs can write floating-point values to 8 color buffers at once. Smartphones generally retain the RGBA8888 path and its 32 output bits per shader thread. The final block creates a floating-point texture, attaches it to an offscreen framebuffer, runs GLSL, and reads four 32-bit channels at full desktop width: