REPRODUCING VGA, NOT EMULATING IT
Second Reality barely uses a normal video mode. It uses “tweaked” modes built by writing undocumented CRTC registers, and it animates by changing where the hardware starts reading memory rather than by moving pixels.
Unchained planar modes 320x400 and 640x400, plus a 16-colour 640x350 EGA mode for the end scroller. CRTC start address + pixel panning The panorama scroll, the endcard’s wipe-in and its ripple are all a moving read pointer, not a blit. Line-compare split screens The plasma’s falling screen is the hardware split point sweeping down a table. Palette animation Most fades, flashes and colour cycles never touch a pixel.
So the port keeps an 8-bit indexed framebuffer and does the palette lookup in a shader, exactly as the DAC did. Changing 768 bytes changes the whole screen — which is the entire reason the original could afford these effects on a 486.
WHAT IS ACTUALLY ON THE GPU
One triangle. Two textures. A four-line fragment shader. That is the whole of it:
the framebuffer a 320x400 Uint8Array, uploaded as an 8-bit single-channel texture, nearest-filtered the palette a 256x1 RGBA texture, nearest-filtered the shader index -> palette lookup -> pixel
That shader is the DAC. The palette is kept the way the hardware kept it — 6-bit, 0..63 per channel — and only widened to 8-bit at the moment of upload, so a fade is still 768 bytes changing and nothing redrawing.
It is written directly against WebGL2, about forty lines, no graphics library. The triangle is generated from gl_VertexID in the vertex shader, so there is not even a vertex buffer — three vertices, and the palette lookup.
Everything else is arithmetic on that one array, in plain JavaScript. The scroll is a moving read offset, the plasma's falling screen is a line-compare row, the endcard's ripple is a per-row start address — reproduced as the register writes they were, not as effects that resemble them.
Which also means none of the 3D is done by the GPU. The ship, the glenz solid and the dot tunnel are the original's own software rasterisers ported line for line — gouraud spans, XOR span transitions, erase-and-plot dots — all writing 8-bit indices into that same array. The GPU never sees a polygon.