Alpha to coverage, hands-on
One tuft of strands, drawn the way games draw hair and grass, and three ways to turn their alpha into pixels. A small WebGL2 playground that goes with my RYU6Recomp research. September 2026.
This playground needs WebGL2, which this browser does not provide.
What to look for
- Alpha blend. Pale, see-through gaps where the clear edges of near strands wrote depth and cut away the strands behind them. Blending only works if every strand is sorted back to front, and hair makes that expensive.
- Alpha test. Crisp but stair-stepped edges. Turn on pixel zoom: every pixel is either strand or background, and more MSAA samples do not change that.
- Alpha to coverage. Soft edges from 2× upwards, with no sorting and depth writes left on. Set MSAA to 1× and it has nothing to work with.
Why it matters for RYU6Recomp
In stock emulation, the hair in the PS4 demo I study came out blocked, without its alpha. Restoring alpha to coverage in the emulator's shader backend fixed it, in the shadPS4 build I use as the reference for my own runtime. The before and after are on the RYU6Recomp case study.
How the playground works
Each strand is a curved card with a few fine hairs in its alpha channel, which is how games draw both hair and grass. The scene renders into its own multisampled framebuffer, with as many samples as your GPU allows up to eight, which is resolved into a texture and drawn to the page. Pixel zoom renders the same scene at a quarter of the resolution and scales it up without filtering, so single pixels and their coverage become visible. It is plain WebGL2 with no libraries; the source is this page's script.