@woosh/meep-engine 3.14.6 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/package.json +1 -1
  2. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +48 -0
  3. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  4. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +246 -3
  5. package/src/shade/RENDERER_CONTRACT.md +584 -580
  6. package/src/shade/playground/avboit/README.md +117 -0
  7. package/src/shade/playground/avboit/index.html +215 -0
  8. package/src/shade/playground/avboit/main.d.ts +2 -0
  9. package/src/shade/playground/avboit/main.d.ts.map +1 -0
  10. package/src/shade/playground/avboit/main.js +875 -0
  11. package/src/shade/renderer/Renderer.d.ts +16 -0
  12. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  13. package/src/shade/renderer/Renderer.js +29 -28
  14. package/src/shade/renderer/ShadeTransparencyMode.d.ts +13 -0
  15. package/src/shade/renderer/ShadeTransparencyMode.d.ts.map +1 -0
  16. package/src/shade/renderer/ShadeTransparencyMode.js +30 -0
  17. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts +9 -0
  18. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  19. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +26 -0
  20. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts +7 -2
  21. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  22. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +12 -1
  23. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +1 -1
  24. package/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.d.ts +3 -0
  25. package/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.d.ts.map +1 -0
  26. package/src/shade/renderer/rasterize/{native/oit → forward}/FORWARD_VERTEX_SHADER_STRUCT.js +4 -4
  27. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.d.ts +3 -0
  28. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.d.ts.map +1 -0
  29. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.js +17 -0
  30. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_brick4.d.ts +1 -1
  31. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -0
  32. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_brick4.js +16 -16
  33. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_ibl.d.ts +1 -1
  34. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -0
  35. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_ibl.js +17 -17
  36. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_material_side_should_draw.d.ts +1 -1
  37. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +1 -0
  38. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_material_side_should_draw.js +2 -2
  39. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts +3 -0
  40. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -0
  41. package/src/shade/renderer/rasterize/{native/oit → forward}/vertex_shader_chunk.js +4 -4
  42. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts +27 -0
  43. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts.map +1 -0
  44. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.js +27 -0
  45. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts +107 -0
  46. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts.map +1 -0
  47. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.js +120 -0
  48. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +463 -0
  49. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +509 -0
  50. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.d.ts +15 -0
  51. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.d.ts.map +1 -0
  52. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.js +33 -0
  53. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.d.ts +20 -0
  54. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.d.ts.map +1 -0
  55. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.js +38 -0
  56. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts +38 -0
  57. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts.map +1 -0
  58. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +130 -0
  59. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.d.ts +37 -0
  60. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.d.ts.map +1 -0
  61. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.js +73 -0
  62. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts +9 -0
  63. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts.map +1 -0
  64. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.js +17 -0
  65. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.d.ts +11 -0
  66. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.d.ts.map +1 -0
  67. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.js +18 -0
  68. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.d.ts +9 -0
  69. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.d.ts.map +1 -0
  70. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.js +17 -0
  71. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.d.ts +9 -0
  72. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.d.ts.map +1 -0
  73. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.js +17 -0
  74. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.d.ts +15 -0
  75. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.d.ts.map +1 -0
  76. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.js +25 -0
  77. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts +17 -0
  78. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts.map +1 -0
  79. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.js +35 -0
  80. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.d.ts +11 -0
  81. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.d.ts.map +1 -0
  82. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.js +21 -0
  83. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.d.ts +9 -0
  84. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.d.ts.map +1 -0
  85. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.js +26 -0
  86. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.d.ts +11 -0
  87. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.d.ts.map +1 -0
  88. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.js +22 -0
  89. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.d.ts +10 -0
  90. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.d.ts.map +1 -0
  91. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.js +21 -0
  92. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts +10 -0
  93. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts.map +1 -0
  94. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.js +32 -0
  95. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.d.ts +20 -0
  96. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.d.ts.map +1 -0
  97. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.js +27 -0
  98. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.d.ts +10 -0
  99. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.d.ts.map +1 -0
  100. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.js +18 -0
  101. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.d.ts +9 -0
  102. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.d.ts.map +1 -0
  103. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.js +21 -0
  104. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.d.ts +9 -0
  105. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.d.ts.map +1 -0
  106. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.js +23 -0
  107. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.d.ts +13 -0
  108. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.d.ts.map +1 -0
  109. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.js +27 -0
  110. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.d.ts +22 -0
  111. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.d.ts.map +1 -0
  112. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.js +38 -0
  113. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +117 -0
  114. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -0
  115. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +935 -0
  116. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts +8 -0
  117. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts.map +1 -0
  118. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.js +135 -0
  119. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts +3 -0
  120. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts.map +1 -0
  121. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.js +101 -0
  122. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts +3 -0
  123. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts.map +1 -0
  124. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js +96 -0
  125. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts +3 -0
  126. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts.map +1 -0
  127. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js +83 -0
  128. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.d.ts +9 -0
  129. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.d.ts.map +1 -0
  130. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.js +119 -0
  131. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts +3 -0
  132. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts.map +1 -0
  133. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js +81 -0
  134. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts +15 -0
  135. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts.map +1 -0
  136. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +237 -0
  137. package/src/shade/renderer/rasterize/native/material_draw_indirect.d.ts +22 -0
  138. package/src/shade/renderer/rasterize/native/material_draw_indirect.d.ts.map +1 -0
  139. package/src/shade/renderer/rasterize/native/material_draw_indirect.js +69 -0
  140. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  141. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +665 -722
  142. package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +3 -3
  143. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +4 -4
  144. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +4 -4
  145. package/src/shade/renderer/rasterize/native/oit/FORWARD_VERTEX_SHADER_STRUCT.d.ts +0 -3
  146. package/src/shade/renderer/rasterize/native/oit/FORWARD_VERTEX_SHADER_STRUCT.d.ts.map +0 -1
  147. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.d.ts +0 -3
  148. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.d.ts.map +0 -1
  149. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.js +0 -17
  150. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +0 -1
  151. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +0 -1
  152. package/src/shade/renderer/rasterize/native/oit/chunk_material_side_should_draw.d.ts.map +0 -1
  153. package/src/shade/renderer/rasterize/native/oit/vertex_shader_chunk.d.ts +0 -3
  154. package/src/shade/renderer/rasterize/native/oit/vertex_shader_chunk.d.ts.map +0 -1
@@ -0,0 +1,117 @@
1
+ # avboit
2
+
3
+ AVBOIT against MBOIT on the deck's own test case: a stack of near-opaque cards at a chosen depth
4
+ separation, a tinted glass pane, an opaque surface pushed through the transparency pipeline, an
5
+ opaque backdrop. `npm run dev`, then `/src/shade/playground/avboit/`.
6
+
7
+ The pipeline itself is documented in
8
+ [`AVBOIT_PLAN_2026_09_03.md`](../../renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md); this
9
+ page is its device tier — the real compile, the look, and the timings.
10
+
11
+ ## What to look for
12
+
13
+ - **Depth-complexity invariance.** Four cards at alpha 0.85 and spacing 1.5. Under MBOIT the cards
14
+ behind the front one show through more than their alpha allows and the black bar behind the stack
15
+ is visible through all four (deck slides 35–38). Under AVBOIT the front card hides what is behind
16
+ it by its alpha and no more. Seen on 2026-09-03 (ledger entry 12).
17
+ - **The slice floor.** Drop the spacing under AVBOIT. When the cards land in one slice the stack
18
+ degrades to weighted blending — the deck's fail case (slides 86–92). With 4096 virtual slices the
19
+ floor at this camera is about 1.6 cm, and the two-slice bias means cards need more than 3.2 cm to
20
+ occlude each other cleanly; 0.05 should still resolve, 0.02 should not.
21
+ - **RGB transmittance.** With **tint transmitted light by base colour** on
22
+ (`renderer.avboit.transmission_tint_from_base_color`, off by default), the glass pane filters the
23
+ backdrop by its base colour under AVBOIT — glTF's transmission semantics — and never under MBOIT
24
+ or the tracer, which have no per-channel transmission. Off, all three modes render the pane as
25
+ the same clear glass. Switch the tint to `none` for a control.
26
+ - **An opaque surface through the transparency pipeline.** The small pale quad one unit behind the
27
+ last card is alpha 1 on a `Transparent` material — the deck's "0 % transmittance card" (slides
28
+ 35–38). Both pipelines clamp its coverage at 0.997, so it should read as solid with a hard edge
29
+ against the backdrop and the dark bar. Under MBOIT the moment reconstruction cannot hold a step
30
+ that steep: the quad leaks what is behind it, and where its depth jumps against the background the
31
+ reconstruction tears along the edge. Under AVBOIT the quad occupies a slice of its own and the
32
+ edge is only as soft as the 1/8-resolution volume's trilinear filter.
33
+ - **Slopes.** Orbit until a card or the pane is at a grazing angle. A splat fragment carries the
34
+ depth of its 1/8-resolution pixel centre, which on a slope can differ from the full-resolution
35
+ fragment's depth by more than the two-slice bias; self-occlusion along the slope would show as the
36
+ surface darkening or striping toward the grazing edge. Copy the camera when you find one.
37
+ - **Brick4.** The indirect-lighting select runs the Brick4 draw variant. The scene has no probes, so
38
+ the indirect term is black either way; what it proves is that the variant compiles and draws.
39
+ - **Nothing else changes.** TAA, shadows and exposure are pinned across the switch; auto exposure
40
+ is off by default because it keeps drifting for seconds after any change.
41
+
42
+ ## The reference
43
+
44
+ The third mode, **path traced (reference)**, hands the frame to `renderer.path_tracer`, the
45
+ accumulating path tracer. It rolls every transparent hit against the surface's alpha
46
+ (`chunk_render_trace_path.js`, the opacity roll) and continues the ray, so over many samples it
47
+ converges to the exact order-independent composite of the card stack — what both OIT modes are
48
+ approximating. The report shows the sample count of the slowest tile; judge nothing under a few
49
+ hundred. TAA is forced off while tracing (two temporal filters over one image), the running-mean
50
+ floor is lowered from the tracer's default so the image keeps settling, and any camera move or
51
+ **Reset accumulation** starts over.
52
+
53
+ Two things the reference does *not* settle:
54
+
55
+ - **The glass tint.** The tracer's thin-walled transmission carries the `(1 - F)` Fresnel split and
56
+ no per-channel colour (`chunk_render_trace_path.js`, the substrate slot), so for the pane it is a
57
+ reference for the Fresnel coverage only. Compare the pane with the tint switch off.
58
+ - **Shadow rays through transparency.** The tracer's occlusion query treats geometry as opaque
59
+ (its own `TODO`), so cards cast full shadows in the reference where the rasterized modes cast
60
+ none. Look at the stack, not at its shadow on the floor.
61
+
62
+ ## Camera
63
+
64
+ Drag to orbit, wheel to zoom, right-drag to pan, W/A/S/D to move (the `OrbitalCameraController`, on
65
+ `document.body`, so dragging across the panel moves the camera too and the keys need the page
66
+ focused — click it once). The camera and its controls are wired before the device is requested, so
67
+ they work even where the renderer cannot start; a control whose handler fails says so in the report
68
+ panel rather than only in the console. **Copy camera** puts
69
+ `{"position":[…],"target":[…],"fov_degrees":…}` on the clipboard and in the box; **Apply camera**
70
+ reads the box back. From the console: `camera_state()`, `apply_camera(state)`, or
71
+ `configure({ camera: state })` alongside the other controls.
72
+
73
+ ## Timings
74
+
75
+ **Profile** starts a `GPUProfileSession` at `WORKLOAD` level (pass spans, the frame graph, dispatch
76
+ and draw counts); pressing it again drains the in-flight frames, stops, and downloads
77
+ `avboit-<mode>-<timestamp>.sgpt`. Record a few seconds in one mode, switch, record again with the
78
+ same settings, and open both in the inspector:
79
+
80
+ ```bash
81
+ npm run dev --workspace @woosh/gpu-inspector-tool
82
+ ```
83
+
84
+ The passes to compare are under the `transparencies` scope: `AVBOIT/occupancy`, `AVBOIT/build warp`,
85
+ `AVBOIT/splat`, `AVBOIT / integrate`, `AVBOIT/draw`, `AVBOIT / resolve` against `MBOIT/generate
86
+ moments`, `MBOIT/resolve moments`, `OIT Blend`. Without `timestamp-query` the capture has the
87
+ structure and no durations; the report says so when it starts. `start_profile()` / `stop_profile()`
88
+ from the console do the same.
89
+
90
+ ## One scripted session
91
+
92
+ The in-app browser pane has no WebGPU adapter in this environment, so the device-tier checks are
93
+ run by hand. One session, in order, results pasted back into the ledger:
94
+
95
+ 1. Open the page. The report should say `mode AVBOIT, IBL indirect, 4 cards, …` and the scene should render.
96
+ 2. Press **Compile check**. Expect `10/10 AVBOIT modules compiled`. Anything else: paste the block.
97
+ 3. Switch **indirect lighting** to Brick4. The frame should still render (black indirect is expected).
98
+ 4. Compare the stack: AVBOIT vs MBOIT at the defaults. Does the black bar show through under AVBOIT?
99
+ 5. `configure({ spacing: 0.05 })` then `configure({ spacing: 0.02 })` under AVBOIT: the first should
100
+ still occlude, the second should blend.
101
+ 6. `configure({ spacing: 1.5, tint_from_base_color: true, tint: 'none' })` then `tint: 'red'`: the
102
+ backdrop behind the pane should go red under AVBOIT only. With the switch off the pane is the
103
+ same clear glass in every mode.
104
+ 7. `configure({ mode: 'REFERENCE', tint: 'none' })`, wait for the report to pass ~300 samples, and
105
+ compare the stack against AVBOIT at the same settings: which of the two OIT modes is closer to
106
+ it, and where do they differ (the bar behind the stack is the sharpest test).
107
+ 8. With the opaque quad on, zoom on its edges against the backdrop and against the dark bar under
108
+ MBOIT, AVBOIT and the reference: is the edge a clean step, and does anything behind the quad show
109
+ through its interior?
110
+ 9. Orbit to a grazing view of a card or the pane; if the surface darkens or stripes toward the
111
+ grazing edge under AVBOIT and not under MBOIT, **Copy camera** and paste the state with the note.
112
+ 10. **Profile** a few seconds in AVBOIT, then in MBOIT at the same settings; open both captures in
113
+ the inspector and read the `transparencies` scope.
114
+
115
+ Everything the page does is reachable from the console: `renderer`, `scene`, `camera`, `controller`,
116
+ `configure({...})`, `camera_state()`, `apply_camera(state)`, `compile_check()` (its last result is
117
+ on `globalThis.__last_compile`), `start_profile()`, `stop_profile()`.
@@ -0,0 +1,215 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>meep — AVBOIT / MBOIT transparency A/B</title>
6
+ <style>
7
+ :root {
8
+ color-scheme: dark;
9
+ --bg: #14161a;
10
+ --panel: #1c1f25;
11
+ --line: #2b3038;
12
+ --text: #d6dae0;
13
+ --muted: #8b939f;
14
+ --pass: #55c46a;
15
+ --fail: #ff6b6b;
16
+ --warn: #e5b54a;
17
+ }
18
+
19
+ * { box-sizing: border-box; }
20
+
21
+ body {
22
+ margin: 0;
23
+ padding: 16px;
24
+ background: var(--bg);
25
+ color: var(--text);
26
+ font: 13px/1.5 system-ui, -apple-system, Segoe UI, sans-serif;
27
+ }
28
+
29
+ body:focus { outline: none; }
30
+
31
+ h1 { font-size: 16px; font-weight: 600; margin: 0 0 4px; }
32
+
33
+ p.lede { margin: 0 0 14px; color: var(--muted); max-width: 90ch; }
34
+
35
+ .stage { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
36
+
37
+ canvas {
38
+ display: block;
39
+ border: 1px solid var(--line);
40
+ border-radius: 4px;
41
+ background: #000;
42
+ }
43
+
44
+ aside {
45
+ width: 340px;
46
+ background: var(--panel);
47
+ border: 1px solid var(--line);
48
+ border-radius: 8px;
49
+ padding: 12px 14px;
50
+ }
51
+
52
+ aside h2 {
53
+ font-size: 11px;
54
+ text-transform: uppercase;
55
+ letter-spacing: 0.06em;
56
+ color: var(--muted);
57
+ margin: 0 0 8px;
58
+ }
59
+
60
+ label { display: flex; gap: 8px; align-items: center; padding: 3px 0; }
61
+
62
+ label span { flex: 1; }
63
+
64
+ select, input[type="number"], textarea {
65
+ font: inherit;
66
+ background: #14161a;
67
+ color: var(--text);
68
+ border: 1px solid var(--line);
69
+ border-radius: 4px;
70
+ padding: 3px 6px;
71
+ width: 120px;
72
+ }
73
+
74
+ textarea {
75
+ width: 100%;
76
+ height: 3.4em;
77
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
78
+ font-size: 11px;
79
+ resize: vertical;
80
+ }
81
+
82
+ button {
83
+ font: inherit;
84
+ padding: 6px 12px;
85
+ border-radius: 6px;
86
+ border: 1px solid var(--line);
87
+ background: #22303f;
88
+ color: var(--text);
89
+ cursor: pointer;
90
+ margin-top: 10px;
91
+ width: 100%;
92
+ }
93
+
94
+ button:disabled { opacity: 0.45; cursor: default; }
95
+
96
+ button.recording { border-color: var(--fail); color: var(--fail); }
97
+
98
+ .hint { color: var(--muted); font-size: 12px; margin: 6px 0 0; }
99
+
100
+ .pair { display: flex; gap: 8px; }
101
+
102
+ pre {
103
+ background: #14161a;
104
+ border: 1px solid var(--line);
105
+ border-radius: 6px;
106
+ padding: 8px 10px;
107
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
108
+ font-size: 11.5px;
109
+ white-space: pre-wrap;
110
+ margin: 10px 0 0;
111
+ max-height: 40vh;
112
+ overflow: auto;
113
+ }
114
+
115
+ pre.pass { border-color: var(--pass); }
116
+ pre.fail { border-color: var(--fail); }
117
+
118
+ hr { border: 0; border-top: 1px solid var(--line); margin: 12px 0; }
119
+ </style>
120
+ </head>
121
+ <body tabindex="0">
122
+
123
+ <h1>AVBOIT / MBOIT transparency A/B</h1>
124
+ <p class="lede">
125
+ The deck’s test harness in miniature: a stack of camera-facing transparent cards at a chosen depth
126
+ separation, a tinted glass pane, an opaque surface pushed through the transparency pipeline, and an
127
+ opaque backdrop. “Mode” flips <code>renderer.transparency_mode</code> between the voxel-based and the
128
+ moment-based pipelines with everything else held still, or to the path tracer for a reference that
129
+ accumulates while the camera is still. Drag to orbit, wheel to zoom, right-drag to pan; the camera state
130
+ copies as JSON so a view can be handed over exactly. “Profile” records GPU timings into an
131
+ <code>.sgpt</code> capture for the gpu-inspector-tool.
132
+ </p>
133
+
134
+ <div class="stage">
135
+ <div>
136
+ <canvas id="view"></canvas>
137
+ <p class="hint">drag to orbit · wheel to zoom · right-drag to pan · W/A/S/D to move (click the page first, the keys listen on the body)</p>
138
+ </div>
139
+
140
+ <aside>
141
+ <h2>transparency</h2>
142
+
143
+ <label><span>mode</span>
144
+ <select id="mode">
145
+ <option value="AVBOIT" selected>AVBOIT (voxels)</option>
146
+ <option value="MBOIT">MBOIT (moments)</option>
147
+ <option value="REFERENCE">path traced (reference)</option>
148
+ </select>
149
+ </label>
150
+
151
+ <label><span>indirect lighting</span>
152
+ <select id="indirect">
153
+ <option value="IBL" selected>IBL</option>
154
+ <option value="Brick4">Brick4</option>
155
+ </select>
156
+ </label>
157
+
158
+ <label><span>card alpha</span><input type="number" id="alpha" value="0.85" min="0.05" max="0.997" step="0.05"></label>
159
+ <label><span>card spacing</span><input type="number" id="spacing" value="1.5" min="0.001" max="10" step="0.1"></label>
160
+ <label><span>card count</span><input type="number" id="count" value="4" min="1" max="12" step="1"></label>
161
+ <label><span>glass pane</span><input type="checkbox" id="glass" checked></label>
162
+ <label><span>tint transmitted light by base colour (AVBOIT)</span><input type="checkbox" id="tint_from_base_color"></label>
163
+ <label><span>glass tint</span>
164
+ <select id="tint">
165
+ <option value="red" selected>red</option>
166
+ <option value="green">green</option>
167
+ <option value="blue">blue</option>
168
+ <option value="none">none (clear)</option>
169
+ </select>
170
+ </label>
171
+ <label><span>opaque quad, transparent material</span><input type="checkbox" id="opaque_quad" checked></label>
172
+
173
+ <hr>
174
+
175
+ <h2>renderer</h2>
176
+
177
+ <label><span>TAA</span><input type="checkbox" id="taa" checked></label>
178
+ <label><span>shadows</span><input type="checkbox" id="shadows" checked></label>
179
+ <label><span>auto exposure</span><input type="checkbox" id="exposure"></label>
180
+ <label><span>exposure (stops)</span><input type="number" id="exposure_compensation" value="1.5" step="0.5"></label>
181
+ <label><span>width</span><input type="number" id="width" value="1280" step="2"></label>
182
+ <label><span>height</span><input type="number" id="height" value="720" step="2"></label>
183
+
184
+ <button id="apply">Apply</button>
185
+ <button id="reset">Reset accumulation (reference)</button>
186
+
187
+ <hr>
188
+
189
+ <h2>camera</h2>
190
+
191
+ <textarea id="camera_state" placeholder='{"position":[x,y,z],"target":[x,y,z],"fov_degrees":45}'></textarea>
192
+ <div class="pair">
193
+ <button id="copy_camera">Copy camera</button>
194
+ <button id="apply_camera">Apply camera</button>
195
+ </div>
196
+
197
+ <hr>
198
+
199
+ <h2>measure</h2>
200
+
201
+ <button id="profile">Profile (record GPU timings)</button>
202
+ <button id="compile">Compile check (AVBOIT modules)</button>
203
+
204
+ <pre id="report">ready</pre>
205
+ </aside>
206
+ </div>
207
+
208
+ <script type="module">
209
+ import { start } from './main.js';
210
+
211
+ start();
212
+ </script>
213
+
214
+ </body>
215
+ </html>
@@ -0,0 +1,2 @@
1
+ export function start(): Promise<void>;
2
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/avboit/main.js"],"names":[],"mappings":"AAoRA,uCAslBC"}