nishi code wiki / research / voxel rendering on WebGL2
Real-time rendering on a constrained stack: voxels, WebGL2, no compute
SOTA census · compiled 2026-08-01 · 5 axes · ~30 sourced claims · 8 declared gaps
lineage: forked from research_rtrender parent domain: real-time rendering + GPU architecture corpus slug: reference-voxelrender-webgl2-sota-2026-08-01
Claims are labelled SHIPPING / RESEARCH / ANNOUNCED / DEPRECATED. Gaps are declared UNVERIFIED rather than guessed.
1. The constraint filter — what shipping-AAA SOTA cannot survive
Constraints, stated once: WebGL2 / GLSL ES 3.00, fragment + vertex shaders only, no compute shaders, integer/fixed-point core, no third-party engines, everything reimplementable from papers. Current renderer: per-pixel integer DDA voxel raycast in a fragment shader, skinned-mesh NPC pass, sun shadow march, bump mapping, procedural clouds, 60 fps at 480×300 upscaled, scoring 983/1000 on an internal groundtruth critic that saturates at 1000.
| Parent-brief axis | Status there | Why it dies at this boundary |
|---|---|---|
| Nanite-class virtualized geometry | SHIPPING (UE5) | Needs software raster in compute with 64-bit atomics; WebGL2 has neither compute nor atomics |
| Lumen GI (~8 ms at 1080p internal, next-gen consoles, Epic quality) | SHIPPING | HWRT/SWRT tracing in compute + surface cache; no ray query, no compute |
| ReSTIR DI/GI (6x–60x unbiased; Zero Day 15 ms, Amusement Park 50 ms at 1920×1080; ≤8 rays/px — SIGGRAPH 2020) | RESEARCH→prod | 1-spp stochastic output requires an A-trous or ML denoiser + TAA downstream; noiseless it is not |
| DLSS 4 / FSR 4 (FSR 4: ~1.3 ms at 4K on RX 9070 XT) | SHIPPING | Vendor ML hardware + driver stacks; not a web API |
| Neural texture compression / neural materials (RTXNTC, PSNR 40–50 dB, ~5 bits/texel) | SHIPPING SDK | Needs SM 6.9 long vectors or LinAlg; no DirectX on the web platform |
| DirectX Cooperative Vectors | DEPRECATED | Never shipped retail — see lineage correction below |
All parent figures above are quoted verbatim from research_rtrender (compiled 2026-07-31) and carry their sources there; the Cooperative Vectors verdict is sourced to devblogs.microsoft.com/directx/shader-model-6-9-retail-and-more/ (2026-02-26). What survives the filter is narrow: anything expressible as render-to-texture fragment passes, vertex-stage skinning, and CPU-side wasm. That narrowness is the subject of this brief.
2. The browser platform, honestly, in 2026
| Thing | Status | Source (date) |
|---|---|---|
| WebGL2 | SHIPPING, pervasive | khronos.org/blog/webgl-2-achieves-pervasive-support-from-all-major-web-browsers (2022-02); caniuse.com/webgl2 — every major browser; IE never shipped it |
| WebGL 2.0 Compute | DEPRECATED | Prototyped behind a flag, abandoned in favor of WebGPU; never shipped cross-browser (see UNVERIFIED #6 for exact date) |
| WebGPU | SHIPPING, ~82–85% global | caniuse.com/webgpu + github.com/gpuweb/gpuweb/wiki/Implementation-Status (early–mid 2026; secondary sources disagree inside the 82–85% band) |
| WebGPU per engine | SHIPPING | Chrome 113 default (2023-05); Safari 26 (2025-09); Firefox 141 default on Windows (2025-07), 145 on macOS Apple Silicon (2025-11) — Firefox Linux/Android still not default-on |
| wasm fixed-width 128-bit SIMD | SHIPPING, universal | chromestatus.com/feature/6533147810332672 — Chrome 91 (2021-05); all engines since Safari 16.4 (2023-03) |
| wasm Relaxed SIMD (FMA, dot products; 1.5–3x on vector workloads per Chrome's own numbers) | SHIPPING | chromestatus.com/feature/5082417973952512 — Chrome 114 (2023-06); Firefox 120+; Safari 18.4+; developer.chrome.com/blog/io24-webassembly-webgpu-1 (2024-05) |
| Wasm 3.0 (64-bit address space, GC, exceptions) | SHIPPING spec | webassembly.org/news/2025-09-17-wasm-3.0/ (2025-09-17) |
What WebGL2 / GLSL ES 3.00 actually gives this stack: real integer and bitwise ops (the integer DDA core is legal and exact), texelFetch, 3D textures, integer textures, multiple render targets, instancing, transform feedback, uniform buffers, float render targets via EXT_color_buffer_float. What it withholds: compute shaders, storage buffers, atomics, shared memory, bitCount() (that is GLSL ES 3.1+ — popcount must be emulated with SWAR arithmetic or an 8-bit lookup texture), and any 64-bit integer type (64-bit voxel masks split into two uints). GPGPU on this stack means the classic form: ping-pong render-to-texture fragment passes. That is not a toy — it is exactly the shape Radiance Cascades wants (axis 4).
The WebGPU verdict for 2026: at ~82–85% global support with Firefox default-on only for Windows and Apple-Silicon macOS, WebGPU is a legitimate second backend but not a floor. A renderer that requires it silently drops one user in six. WebGL2 remains the correctness baseline; WebGPU is an acceleration tier — revisit when caniuse crosses ~90% and Firefox ships default-on across desktop Linux.
3. Voxel-specific SOTA — the one axis where the constraint is not a handicap
| Thing | Status | Source (date) |
|---|---|---|
| Teardown — shipped voxel raymarch renderer, fully destructible, dynamic GI/soft shadows/AO, non-axis-aligned voxel bodies | SHIPPING | en.wikipedia.org/wiki/Teardown_(video_game) (EA 2020-10, 1.0 2022-04); softwareengineeringdaily.com/podcasts/teardown-and-voxel-based-rendering-with-dennis-gustafsson/ (2025-01); gamedeveloper.com “How beautiful voxels laid the way…”; blog.voxagon.se |
| Sparse Voxel DAGs — merge identical subtrees of an SVO; orders-of-magnitude compression; ray trace directly on the DAG | RESEARCH (production-adopted) | Kämpe, Sintorn, Assarsson, ACM TOG / SIGGRAPH — dl.acm.org/doi/10.1145/2461912.2462024 (2013-07) |
| 64-trees / contrees — 4³ branching, one 64-bit occupancy mask per node, ~half the tree depth of an octree | RESEARCH + open practice | Micro 64-tree, Graphics Interface — dl.acm.org/doi/10.5555/2532129.2532158 (2013); dubiousconst282.github.io/2024/10/03/voxel-ray-tracing/ (2024-10-03); github.com/dubiousconst282/VoxelRT |
| Transform-Aware Sparse Voxel DAGs — dedup across rotations/reflections | RESEARCH | dl.acm.org/doi/10.1145/3728301 (2025) |
| NAADF — nested axis-aligned distance fields; 3–5x faster ray traversal than DAG-class structures; 3-layer structure edits fast (no restructuring) | RESEARCH, code public | Ulschmid, Ott, Macho, Wimmer, Ohrhallinger, Computer Graphics Forum (Eurographics 2026) — onlinelibrary.wiley.com/doi/10.1111/cgf.70413 (2026); github.com/cg-tuwien/NAADF; listed at kesen.realtimerendering.com/eg2026Papers.htm |
Teardown is the existence proof for this whole stack's thesis: a shipped, beloved game whose every surface is voxel ray-marched with true dynamic lighting, built by a tiny team with no triangle-GI machinery at all (Software Engineering Daily interview with Dennis Gustafsson, 2025-01). It is the closest shipped analogue to the Nishi renderer's architecture — the difference is scale of acceleration structure, not kind.
The structure ladder is well mapped. SVO → SVDAG (2013) bought memory: identical subtrees merged, billions of voxels in GPU memory. 64-trees buy traversal: a 4³ branching factor packs 64 children's occupancy into one 64-bit mask, halving tree depth versus an octree (each level divides an axis by 4, not 2) and letting one fetch answer “which of my 64 cells are solid”. The 2024 guide by dubiousconst282 is the best practical treatment and comes with a working repo. NAADF (Eurographics 2026) is the new frontier: instead of a deep hierarchy it uses three layers augmented with in-cell axis-aligned distance fields acting as empty-space-skip caches, and the authors measure 3–5x faster ray tracing than state-of-the-art DAG variants — while remaining much cheaper to edit than SVOs/DAGs because the three layers live in separate buffers and edits need no restructuring. For a destructible world that is the pairing that matters: DAGs bought compression by making edits hard; NAADF buys speed and keeps edits cheap.
WebGL2 porting notes (analysis, not sourced claims): 64-bit masks become uvec2; child indexing needs popcount, emulated in ES 3.00 by SWAR (v = v - ((v>>1u)&0x55555555u)…) or an 8-bit LUT texture; node pools live in integer textures addressed with texelFetch. Nothing in 64-tree or NAADF-style traversal requires compute — both are per-ray algorithms, and this renderer already runs one ray per pixel in a fragment shader. The integer core is an asset here: traversal against integer coordinates can be gated bit-exactly against the flat DDA.
4. Noiseless GI — Radiance Cascades, and why noiseless is load-bearing here
| Thing | Status | Source (date) |
|---|---|---|
| Radiance Cascades — noiseless GI via multi-level radiance probes; developed at Grinding Gear Games for Path of Exile 2 | RESEARCH (public since ExileCon 2023) | 80.lv/articles/radiance-cascades-new-approach-to-calculating-global-illumination (2023); pathofexile.com forum thread 3448733 |
| Reported cost: 0.3 ms/frame on a GTX 970, 2D cascade demo, no denoising, no temporal accumulation | RESEARCH (secondhand figure) | 80.lv (2023) — see UNVERIFIED #3 |
| Fragment-shader-only implementations exist and run in-browser / in GameMaker's GLSL-ES-class shaders | SHIPPING (open demos) | tmpvar.com/poc/radiance-cascades (living PoC); mini.gmshaders.com/p/radiance-cascades — Xor with Sannikov (2024); radiance.wiki (community hub) |
| Holographic Radiance Cascades — single-shot variant building rays from short intervals | RESEARCH | arxiv.org/abs/2505.02041 (2025-05) |
The idea in one paragraph. Sannikov's penumbra hypothesis: resolving illumination needs high spatial resolution only near surfaces and high angular resolution only far from them — never both at once. Radiance Cascades exploits the inverse relationship directly: cascade level i+1 doubles ray count (angular resolution) while halving probe density (spatial resolution), each level tracing only a bounded ring of ray intervals; merging the cascades reconstructs a full radiance field. Total cost is constant and scene-independent; there is no stochastic sampling, hence no noise, no denoiser, no temporal accumulation, zero temporal latency.
Why this is the decision-changer for a no-compute stack. The parent brief's GI ladder — BVH → ReSTIR DI → A-trous → radiance cache — is a pipeline for laundering 1-spp noise into an image, and every stage past the first assumes machinery (compute traversal, denoiser, TAA) this stack cannot host. Radiance Cascades inverts the premise: spend the budget on a deterministic structure instead of stochastic samples. The cascades are just textures; building and merging them are just fragment passes over quads; the probe traces are the same ray-march this renderer already does per-pixel for its sun shadow. The 2D screen-space form is proven in GLSL-ES-class shaders today (tmpvar, GM Shaders); the 3D world-space form is where the open research frontier sits — and where a voxel grid is the friendliest possible host, since interval traces become the engine's native integer DDA.
5. What this means for the Nishi stack — the ranked adoptable ladder
| # | Technique | Payoff / cost | Exit criterion |
|---|---|---|---|
| 0 | Extend the groundtruth critic | Makes rungs 1–5 measurable / ~1 wk | Current renderer scores ≤900/1000 on the extended critic with ≥3 new axes; old and new critic disagree on at least one known-bad scene |
| 1 | 64-tree (contree) traversal replacing the flat integer DDA | 2–10x fewer traversal steps/px, draw-distance headroom / 2–3 wks incl. popcount emulation | Mean steps/pixel ↓≥2x on the standard scene at 480×300; frame ≤16.6 ms; bit-exact hit positions vs flat DDA on the gate scene (integer core makes this a hard equality gate, not a tolerance) |
| 2 | Brick-level axis-aligned distance fields (NAADF-lite: 3 layers + in-cell AADF skip caches) | Paper-claimed 3–5x over DAG-class traversal, edits stay O(brick) / 3–4 wks on top of rung 1 | Steps/pixel ↓≥3x on open scenes vs rung 1; world-edit latency ≤ current renderer's; rung-1 bit-exact gate stays green |
| 3 | Radiance Cascades — 2D screen-space first, then 3D world-space over the voxel grid | Noiseless GI + soft shadows at constant cost; retires the per-pixel sun shadow march / 4–8 wks staged | Total lighting ≤4 ms/frame at 480×300 on the baseline GPU; zero history buffers (noiseless by construction, not by accumulation); extended-critic lighting axis ≥ parity with the shadow march |
| 4 | TAAU-lite: temporal upscale 480×300 → 960×600 (parent's rung 1 survives the filter — history blend is a fragment pass) | Output resolution 4x at ~zero shading cost / 2–3 wks | Beats the current upscale on the extended critic at equal frame time; camera-only reprojection for the static voxel world, MRT motion vectors for the skinned NPC pass; disocclusion-reset proven on a gate scene |
| 5 | wasm SIMD128 + Relaxed SIMD for CPU-side voxel ops (remeshing, light injection, edit batching) | 1.5–3x on vector loops per Chrome's published range / 1–2 wks | Hot-loop microbench ≥2x in-browser on Chrome and Firefox; outputs bit-exact vs scalar path |
| 6 | WebGPU compute as a second backend, never the floor | Unlocks the parent brief's whole compute tier for the ≥82% cohort / large | Trigger, not schedule: caniuse ≥90% AND Firefox default-on across desktop incl. Linux; feature-parity gate green on both backends before any WebGPU-only feature |
Explicit non-adoptions, so nobody relitigates them: ReSTIR (1-spp noise with no denoiser to launder it), 3D Gaussian Splatting (the tile radix sort is the correctness bottleneck per the parent, and it wants compute; also wrong representation — this is a voxel engine), Nanite-class mesh virtualization (compute raster + 64-bit atomics), frame generation (the parent already rules it out on latency grounds even with compute). None of these are “later” — they are wrong for this boundary, and the ladder above is not a consolation prize: rungs 1–3 are the current voxel research frontier, and the frontier happens to fit in a fragment shader.
Declared UNVERIFIED — do not treat as measured
- The upstream report's text. The July 2026 source report's transcript was a 0-byte file (one of the killed research subagents the parent's method note documents). Its Cooperative Vectors claims could not be re-read; the conflict was resolved in the published parent's favor by rule and by the Microsoft 2026-02-26 source.
- Whether the retail Path of Exile 2 build ships Radiance Cascades as its production GI. Origin at GGG for PoE2 is sourced; retail use is not.
- The 0.3 ms / GTX 970 Radiance Cascades figure is secondhand (80.lv reporting Sannikov), applies to the 2D cascade demo, and the article's exact publication date was not pinned beyond 2023.
- NAADF's 3–5x is the authors' own comparison against their DAG-variant baselines; test hardware and scene set were not extracted (abstract and repository read, full paper not).
- Exact caniuse percentages: WebGPU secondary sources disagree (82% vs 84.7%) inside the band quoted; the WebGL2 exact percentage was not fetched, only its “every major browser” status.
- The exact date the WebGL 2.0 Compute effort was formally abandoned.
- Teardown's internal render resolution and per-pass frame budgets — never published with measurement context.
- The real cost of popcount emulation in GLSL ES 3.00 on the Nishi renderer — a porting risk for rungs 1–2, unmeasured until rung 1's gate runs.
Method. Compiled 2026-08-01. The assigned primary source (a prior agent's report transcript) was 0 bytes on disk, so this brief was rebuilt from the published parent research_rtrender (fetched live 2026-08-01, 16,299 bytes, byte-identical to the local source copy) plus a fresh 8-query web sweep verifying every voxel-, browser- and GI-specific claim above; parent-brief figures are quoted verbatim and sourced there. Read in full: NAADF abstract + repo, the 64-tree guide, RC community sources. Skimmed: caniuse aggregators, podcast summaries. What would change the conclusions: WebGPU crossing ~90% with Firefox default-on across desktop (promotes rung 6 to a schedule), or a published 3D world-space Radiance Cascades production ship with measured budgets (would harden rung 3's estimate).