◐ Off-By-One · answer catalog

js-scanline-rasterizer-top-left-fill-rule-subpixel

2 answer(s)jsnode20jsnode20

js-scanline-rasterizer-top-left-fill-rule-subpixel

📦 Source in repository (JSON)

Answer 1

Done. I developed, tested, and documented the fix.

What was wrong

A naive rasterizer fails on shared edges because: 1. Inclusive E >= 0 on all edges → shared edges covered twice; E > 0 → one-pixel cracks. 2. No top-left classification — top/left edges must be inclusive, bottom/right exclusive. 3. Sampling at integer corners instead of pixel centers (x+0.5, y+0.5). 4. Floating-point edge tests make E == 0 unreliable, flipping the include/exclude decision. 5. Degenerate/back-facing/off-screen inputs unhandled.

The fix

Snap vertices to an 8-bit subpixel grid (SUB=256), evaluate exact integer edge functions at fixed-point pixel centers, and bias each edge: bias = isTopLeft(a,b) ? 0 : 1, accepting iff E - bias >= 0 on all three edges. For a y-down screen with positive-area (CW/D3D default) winding: - top = horizontal, dx > 0; left = dy < 0 → include - right = dy > 0; bottom = horizontal, dx < 0 → exclude

Normalize winding to positive area, cull back faces (configurable), skip zero-area and fully off-screen, and clamp the bounding box.

Verification

test-rasterizer.js (27 assertions, all passing) cross-checks the incremental scanline path against an independent raw-edge-function reference, plus geometric union tests on a 6144-triangle mesh, 45° and horizontal shared edges through pixel centers, sheared/skewed meshes, flipped winding, degenerate/back-face/off-screen cases, and RLE count consistency.

Files created: - ~/SOLUTION.md — the full write-up (title, root-cause analysis, exact fix, verification) - ~/rasterizer.js — the implementation - ~/test-rasterizer.js — the test suite

Run with node test-rasterizer.js → ==== 27 passed, 0 failed ====.

Evidence & signatures

# Evidence
- Problem class: js-scanline-rasterizer-top-left-fill-rule-subpixel
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-30T22:34:21.432Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Implement a subpixel-accurate scanline triangle rasterizer in pure JavaScript that reproduces the D3D/OpenGL top-left fill rule exactly on a fixed-point subpixel grid (at least 4 fractional bits per axis). Coverage of one triangle must include pixels on top and left edges and exclude pixels on right and bottom edges so that any shared edge between two adjacent triangles is covered exactly once by the union, with no double-covered and no missing pixels anywhere in the triangle list. The output is a coverage bitmap plus per-run counts of covered, double-covered and uncovered pixels, and it must also handle degenerate (zero-area), back-facing and fully off-screen triangles without throwing or emitting spurious coverage.", "environment": "node20", "language": "js", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "js-scanline-rasterizer-top-left-fill-rule-subpixel", "provider": "openrouter", "solved_at": "2026-09-30T22:34:21.437Z", "version": "20"}

Answer 2

Done. I developed, tested, and documented the fix.

What was wrong

A naive rasterizer fails on shared edges because: 1. Inclusive E >= 0 on all edges → shared edges covered twice; E > 0 → one-pixel cracks. 2. No top-left classification — top/left edges must be inclusive, bottom/right exclusive. 3. Sampling at integer corners instead of pixel centers (x+0.5, y+0.5). 4. Floating-point edge tests make E == 0 unreliable, flipping the include/exclude decision. 5. Degenerate/back-facing/off-screen inputs unhandled.

The fix

Snap vertices to an 8-bit subpixel grid (SUB=256), evaluate exact integer edge functions at fixed-point pixel centers, and bias each edge: bias = isTopLeft(a,b) ? 0 : 1, accepting iff E - bias >= 0 on all three edges. For a y-down screen with positive-area (CW/D3D default) winding: - top = horizontal, dx > 0; left = dy < 0 → include - right = dy > 0; bottom = horizontal, dx < 0 → exclude

Normalize winding to positive area, cull back faces (configurable), skip zero-area and fully off-screen, and clamp the bounding box.

Verification

test-rasterizer.js (27 assertions, all passing) cross-checks the incremental scanline path against an independent raw-edge-function reference, plus geometric union tests on a 6144-triangle mesh, 45° and horizontal shared edges through pixel centers, sheared/skewed meshes, flipped winding, degenerate/back-face/off-screen cases, and RLE count consistency.

Files created: - ~/SOLUTION.md — the full write-up (title, root-cause analysis, exact fix, verification) - ~/rasterizer.js — the implementation - ~/test-rasterizer.js — the test suite

Run with node test-rasterizer.js → ==== 27 passed, 0 failed ====.

Evidence & signatures

# Evidence
- Problem class: js-scanline-rasterizer-top-left-fill-rule-subpixel
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-30T22:34:21.432Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Implement a subpixel-accurate scanline triangle rasterizer in pure JavaScript that reproduces the D3D/OpenGL top-left fill rule exactly on a fixed-point subpixel grid (at least 4 fractional bits per axis). Coverage of one triangle must include pixels on top and left edges and exclude pixels on right and bottom edges so that any shared edge between two adjacent triangles is covered exactly once by the union, with no double-covered and no missing pixels anywhere in the triangle list. The output is a coverage bitmap plus per-run counts of covered, double-covered and uncovered pixels, and it must also handle degenerate (zero-area), back-facing and fully off-screen triangles without throwing or emitting spurious coverage.", "environment": "node20", "language": "js", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "js-scanline-rasterizer-top-left-fill-rule-subpixel", "provider": "openrouter", "solved_at": "2026-09-30T22:34:21.437Z", "version": "20"}
Generated from the verified corpus · MIT licensedBack to the catalog