@woosh/meep-engine 3.26.0 → 3.28.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 (449) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +542 -0
  4. package/src/core/binary/lz4/LZ4_LEVEL.d.ts +33 -0
  5. package/src/core/binary/lz4/LZ4_LEVEL.d.ts.map +1 -0
  6. package/src/core/binary/lz4/LZ4_LEVEL.js +32 -0
  7. package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts +33 -0
  8. package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts.map +1 -0
  9. package/src/core/binary/lz4/lz4_compress_block_at_level.js +47 -0
  10. package/src/core/binary/lz4/lz4_compress_block_hc.d.ts +40 -0
  11. package/src/core/binary/lz4/lz4_compress_block_hc.d.ts.map +1 -0
  12. package/src/core/binary/lz4/lz4_compress_block_hc.js +1382 -0
  13. package/src/core/binary/lz4/lz4_decompress_block.d.ts +2 -1
  14. package/src/core/binary/lz4/lz4_decompress_block.d.ts.map +1 -1
  15. package/src/core/binary/lz4/lz4_decompress_block.js +31 -6
  16. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts +15 -0
  17. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
  18. package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
  19. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
  20. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
  21. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
  22. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +14 -7
  23. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  24. package/src/core/geom/3d/shape/HeightMapShape3D.js +87 -78
  25. package/src/engine/Engine.d.ts.map +1 -1
  26. package/src/engine/Engine.js +38 -1
  27. package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
  28. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  29. package/src/engine/graphics3/GraphicsEngine.js +834 -830
  30. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  31. package/src/shade/RENDERER_CONTRACT.md +19 -10
  32. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
  33. package/src/shade/playground/vgeo_runtime/README.md +186 -27
  34. package/src/shade/playground/vgeo_runtime/index.html +112 -62
  35. package/src/shade/playground/vgeo_runtime/main.js +678 -88
  36. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +18 -0
  37. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
  38. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +23 -5
  39. package/src/shade/playground/vgeo_scene/README.md +408 -0
  40. package/src/shade/playground/vgeo_scene/index.html +144 -0
  41. package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
  42. package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
  43. package/src/shade/playground/vgeo_scene/main.js +1716 -0
  44. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +1 -1
  45. package/src/shade/renderer/Renderer.d.ts +4 -1
  46. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  47. package/src/shade/renderer/Renderer.js +5 -2
  48. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +1 -2
  49. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +11 -0
  50. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  51. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +16 -8
  52. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  53. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +16 -11
  54. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  55. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
  56. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
  57. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
  58. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
  59. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +77 -7
  60. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +36 -23
  61. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +17 -14
  62. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +19 -1
  63. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  64. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +21 -1
  65. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
  66. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
  67. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts +32 -0
  68. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
  69. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +59 -0
  70. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
  71. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts +44 -0
  72. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
  73. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +36 -0
  74. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
  75. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_levels.js → level/vgeo_build_levels.js} +61 -95
  76. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts +19 -0
  77. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
  78. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
  79. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +73 -0
  80. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +7 -7
  82. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +29 -0
  83. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
  84. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_normals.js → mesh/vgeo_compute_vertex_normals.js} +3 -3
  85. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +31 -0
  86. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
  87. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.js → mesh/vgeo_compute_vertex_tangents.js} +5 -5
  88. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +46 -0
  89. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
  90. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +9 -9
  91. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts +13 -0
  92. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
  93. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +63 -16
  94. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts +13 -0
  95. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
  96. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
  97. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts +22 -0
  98. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
  99. package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
  100. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +52 -0
  101. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
  102. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +1 -1
  103. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts +14 -0
  104. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
  105. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts +29 -0
  106. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
  107. package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
  108. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
  109. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
  110. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
  111. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts +10 -0
  112. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
  113. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +12 -55
  114. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts +15 -0
  115. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
  116. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.js → partition/vgeo_split_face_set_packed.js} +3 -3
  117. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts +12 -0
  118. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
  119. package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
  120. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts +18 -0
  121. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
  122. package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
  123. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts +9 -0
  124. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
  125. package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
  126. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +24 -0
  127. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
  128. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +20 -0
  129. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
  130. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +14 -0
  131. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
  132. package/src/shade/renderer/geometry/virtual/build/{vgeo_extract_submesh.js → submesh/vgeo_extract_submesh.js} +5 -5
  133. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +12 -0
  134. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
  135. package/src/shade/renderer/geometry/virtual/build/{vgeo_gather_faces.js → submesh/vgeo_gather_faces.js} +2 -2
  136. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts +11 -0
  137. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
  138. package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
  139. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  141. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +10 -11
  142. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +22 -0
  143. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  144. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +24 -0
  145. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts +8 -2
  146. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
  147. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
  148. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +12 -0
  149. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  150. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +13 -0
  151. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +8 -1
  152. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  153. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +11 -3
  154. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +9 -0
  155. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  156. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +10 -1
  157. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts +15 -0
  158. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
  159. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
  160. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts +18 -0
  161. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts.map +1 -0
  162. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.js +17 -0
  163. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts +8 -0
  164. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts.map +1 -0
  165. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.js +7 -0
  166. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +3 -0
  167. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -0
  168. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts +14 -0
  169. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts.map +1 -0
  170. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.js +13 -0
  171. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts +11 -0
  172. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts.map +1 -0
  173. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.js +10 -0
  174. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +28 -0
  175. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  176. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +7 -3
  177. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +20 -0
  178. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
  179. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +20 -2
  180. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +4 -0
  181. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
  182. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +4 -0
  183. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +29 -3
  184. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  185. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +81 -122
  186. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +40 -0
  187. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  188. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +44 -0
  189. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +69 -0
  190. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -0
  191. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +236 -0
  192. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +14 -0
  193. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
  194. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +15 -0
  195. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts +31 -0
  196. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts.map +1 -0
  197. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.js +32 -0
  198. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +10 -0
  199. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
  200. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +21 -1
  201. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts +15 -0
  202. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts.map +1 -0
  203. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.js +84 -0
  204. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts +22 -0
  205. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -0
  206. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +96 -0
  207. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  208. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +63 -3
  209. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  210. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +219 -17
  211. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  212. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +156 -11
  213. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +656 -0
  214. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +33 -36
  215. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -1
  216. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +109 -193
  217. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +109 -29
  218. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  219. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +173 -105
  220. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +37 -0
  221. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +109 -26
  222. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +548 -0
  223. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +29 -50
  224. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  225. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +55 -487
  226. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts +84 -0
  227. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -0
  228. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +393 -0
  229. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts +234 -0
  230. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -0
  231. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +1388 -0
  232. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts +81 -0
  233. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts.map +1 -0
  234. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.js +89 -0
  235. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +53 -34
  236. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
  237. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +407 -124
  238. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts +100 -0
  239. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts.map +1 -0
  240. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.js +219 -0
  241. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts +17 -0
  242. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts.map +1 -0
  243. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.js +47 -0
  244. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts +20 -0
  245. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts.map +1 -0
  246. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.js +19 -0
  247. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -1
  248. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +30 -12
  249. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +8 -8
  250. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  251. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +11 -73
  252. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
  253. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
  254. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +98 -0
  255. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
  256. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
  257. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
  258. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
  259. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
  260. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -0
  261. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -1
  262. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +18 -1
  263. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -1
  264. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +5 -15
  265. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts +3 -0
  266. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts.map +1 -0
  267. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.js +77 -0
  268. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts +3 -0
  269. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -0
  270. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +130 -0
  271. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  272. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +32 -37
  273. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  274. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +576 -230
  275. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +15 -18
  276. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -1
  277. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +19 -28
  278. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  279. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +45 -25
  280. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  281. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +11 -0
  282. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  283. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +0 -1
  284. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +12 -10
  285. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +1 -0
  286. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +8 -0
  287. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +7 -2
  288. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -1
  289. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +8 -3
  290. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +2 -0
  291. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +19 -0
  292. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -1
  293. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +1 -1
  294. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts +5 -0
  295. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts.map +1 -0
  296. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.js +22 -0
  297. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts +14 -0
  298. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts.map +1 -0
  299. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.js +13 -0
  300. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts +17 -0
  301. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts.map +1 -0
  302. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.js +16 -0
  303. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts +15 -0
  304. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts.map +1 -0
  305. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.js +16 -0
  306. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts +23 -0
  307. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts.map +1 -0
  308. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.js +28 -0
  309. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts +2 -0
  310. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts.map +1 -0
  311. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.js +13 -0
  312. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +10 -5
  313. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -1
  314. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +15 -6
  315. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +6 -1
  316. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  317. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +38 -1
  318. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  319. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +4 -3
  320. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  321. package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
  322. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  323. package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
  324. package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
  325. package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
  326. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  327. package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -1
  328. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  329. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +6 -3
  330. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  331. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +6 -3
  332. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  333. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
  334. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  335. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
  336. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  337. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
  338. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
  339. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
  340. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  341. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +12 -4
  342. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts +22 -0
  343. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
  344. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
  345. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +2 -0
  346. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  347. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +58 -57
  348. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +15 -0
  349. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
  350. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
  351. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  352. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +3 -5
  353. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  354. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +3 -4
  355. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
  356. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
  357. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
  358. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
  359. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
  360. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
  361. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  362. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +3 -4
  363. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  364. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
  365. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  366. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +7 -7
  367. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  368. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +83 -78
  369. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  370. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +44 -53
  371. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  372. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
  373. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  374. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
  375. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
  376. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
  377. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
  378. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  379. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
  380. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
  381. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
  382. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  383. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
  384. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
  385. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
  386. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  387. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
  388. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
  389. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
  390. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  391. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
  392. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  393. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +85 -89
  394. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  395. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +28 -32
  396. package/src/shade/renderer/scene/GPUSceneContext.d.ts +22 -2
  397. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  398. package/src/shade/renderer/scene/GPUSceneContext.js +61 -4
  399. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
  400. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
  401. package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
  402. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
  403. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
  404. package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
  405. package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
  406. package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
  407. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  408. package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
  409. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
  410. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
  411. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
  412. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
  413. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
  414. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
  415. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
  416. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
  417. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
  418. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  419. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +92 -16
  420. package/src/shade/renderer/view/GPUViewContext.d.ts +5 -0
  421. package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
  422. package/src/shade/renderer/view/GPUViewContext.js +21 -0
  423. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  424. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +74 -3
  425. package/src/shade/playground/vgeo_viewer/README.md +0 -150
  426. package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
  427. package/src/shade/playground/vgeo_viewer/index.html +0 -77
  428. package/src/shade/playground/vgeo_viewer/main.js +0 -1343
  429. package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
  430. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
  431. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
  432. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +0 -723
  433. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
  434. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
  435. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +0 -50
  436. package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
  437. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
  438. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
  439. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
  440. package/src/shade/renderer/shader/chunk/jobs/NOTES.md +0 -47
  441. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
  442. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
  443. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.js +0 -102
  444. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
  445. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +0 -0
  446. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
  447. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
  448. /package/src/shade/renderer/geometry/virtual/build/{VGeoGatheredFaces.js → submesh/VGeoGatheredFaces.js} +0 -0
  449. /package/src/shade/renderer/geometry/virtual/build/{VGeoSubmesh.js → submesh/VGeoSubmesh.js} +0 -0
@@ -64,11 +64,11 @@ export class FluidObstacleSystem extends System<any> {
64
64
  /**
65
65
  * @param {FluidComponent} fluid
66
66
  */
67
- static "__#396@#refresh_masks"(fluid: FluidComponent): void;
67
+ static "__#403@#refresh_masks"(fluid: FluidComponent): void;
68
68
  /**
69
69
  * @param {FluidComponent} fluid
70
70
  */
71
- static "__#396@#clear_field"(fluid: FluidComponent): void;
71
+ static "__#403@#clear_field"(fluid: FluidComponent): void;
72
72
  /**
73
73
  * Mark every cell of `fluid` whose centre lies within `inflation` of the
74
74
  * posed shape as solid. Iteration is clipped to the shape's world AABB
@@ -80,7 +80,7 @@ export class FluidObstacleSystem extends System<any> {
80
80
  * @param {number} inflation world-units SDF threshold
81
81
  * @param {Float64Array} point length-3 scratch
82
82
  */
83
- static "__#396@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
83
+ static "__#403@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
84
84
  /**
85
85
  * Write the obstacle's translation velocity onto every face of every cell
86
86
  * it voxelized — the moving-wall boundary condition. Runs AFTER the mask
@@ -100,7 +100,7 @@ export class FluidObstacleSystem extends System<any> {
100
100
  * @param {number} wvy
101
101
  * @param {number} wvz
102
102
  */
103
- static "__#396@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
103
+ static "__#403@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
104
104
  constructor();
105
105
  dependencies: (typeof FluidObstacle)[];
106
106
  components_used: (ResourceAccessSpecification<typeof Transform64> | ResourceAccessSpecification<typeof RigidBody> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof FluidComponent> | ResourceAccessSpecification<typeof FluidObstacle>)[];
@@ -277,16 +277,25 @@ change every frame, you are on the wrong path — see §8.
277
277
 
278
278
  `ShadeMaterial` is the base: `transparency_mode`, `draw_mode` and `draw_side`.
279
279
 
280
- **`draw_side` is part of the rasterization bucket key, and it changes what is drawn.** `Front` (the
281
- default) culls back faces, `Back` culls front faces, and `Double` culls neither — the three map
282
- straight onto the pipeline's cull mode, so a bucket exists per side that any material in the scene
283
- asks for. A face seen from behind is shaded with its normal flipped, so `Double` is a working
284
- double-sided material and not a hint. glTF `doubleSided: true` arrives as `Double` and stays that
285
- way; the loader's fix-up pass only rewrites `Back` to `Front`, by flipping the geometry.
286
-
287
- Shadow passes invert the mapping — `Front` culls *front* faces there — so a one-sided surface casts
288
- from its back face and does not shadow-acne against its own lit side. `Double` has no opposite and
289
- stays unculled in both.
280
+ **`draw_side` changes what is drawn.** `Front` (the default) draws the front face, `Back` the back
281
+ face, `Double` both. A face seen from behind is shaded with its normal flipped, so `Double` is a
282
+ working double-sided material and not a hint. glTF `doubleSided: true` arrives as `Double` and
283
+ stays that way; glTF cannot ask for `Back`, which comes from authoring.
284
+
285
+ **Only `Double` costs a pipeline of its own.** It culls nothing, and no amount of winding expresses
286
+ that. `Front` and `Back` differ by winding alone, and the vertex shader reverses winding per
287
+ instance, so the two share a rasterization bucket and draw in one pass — which matters because a
288
+ bucket is not a pipeline here but a whole chain: extract, expand to meshlets, select a
289
+ virtual-geometry cut, one render pass.
290
+
291
+ **That is also why a mirrored instance works.** Place a mesh under a negative scale, or under a
292
+ parent that reflects, and it draws right way out, with the handedness of its tangent frame flipped
293
+ to match — the reflection and the material's side are the same one bit, combined before a corner is
294
+ chosen. glTF makes this the rule rather than an extra: the determinant of a node's world transform
295
+ decides its winding, and a conformant renderer has to read it.
296
+
297
+ Shadow passes cull the other face — so a one-sided surface casts from its back face and does not
298
+ shadow-acne against its own lit side. `Double` has no opposite and stays unculled in both.
290
299
 
291
300
  `StandardShadeMaterial` is the PBR one everything uses:
292
301
 
@@ -693,7 +693,7 @@ what they are looking at is the observer.
693
693
  ## 7. The inspector
694
694
 
695
695
  `packages/gpu-inspector-tool/`. A static site: drop a `.sgpt` on it, or pass `?file=` for a
696
- bookmarkable view — the affordance the `vgeo_viewer` playground already establishes in this codebase.
696
+ bookmarkable view — the affordance the `.vgeo` playgrounds already establish in this codebase.
697
697
 
698
698
  ### 7.1 Technology
699
699
 
@@ -6,42 +6,108 @@ This page draws nothing itself: every triangle on screen is there because the co
6
6
  the HZB meshlet filter, the material bucket, the indirect draw and the G-buffer took it from there
7
7
  without knowing that virtual geometry exists.
8
8
 
9
- That is the whole difference from [`../vgeo_viewer/`](../vgeo_viewer/README.md), and the two are
10
- worth keeping apart. The viewer draws a **CPU** cut through Shade's direct geometry path — it
11
- proves the DAG, the format and the residency clamp, and by construction it proves nothing about the
12
- engine. This page proves the engine seam and nothing about the DAG, because the DAG has its own
13
- tests and its own oracle.
9
+ This page proves the engine seam and nothing about the DAG, because the DAG has its own tests and
10
+ its own oracle: `renderer/geometry/virtual/runtime/cut/__fixtures__/vgeo_select_cut.js`, a **CPU**
11
+ traversal of the same rule that every cut spec is held to. A `vgeo_viewer` page used to draw that
12
+ traversal on screen through Shade's direct geometry path, carrying its own renderer, its own camera
13
+ and its own streaming loop; it was retired rather than kept as a second runtime, and everything it
14
+ showed is shown here or on the scene page below.
15
+
16
+ It is also not [`../vgeo_scene/`](../vgeo_scene/README.md), which opens a whole converted set —
17
+ thousands of containers, tens of thousands of instances, one cut — and is where the claim about a
18
+ *scene* is measured. This page is one container framed on its own bounding sphere, which is what
19
+ makes it a viewer and what makes its readings about the seam rather than about breadth.
20
+
21
+ And it proves one thing no spec can, which is what the surface **looks like**. The retired viewer
22
+ drew with `cullMode: 'none'` and coloured its cut per cluster; this page draws through a
23
+ `Front`-sided standard material with a light on it. That is the difference that caught the sample
24
+ torus being wound inside-out — the near surface culled away, the far inner wall showing through the
25
+ hole where it should have been, and normals pointing into the tube so what survived was lit from
26
+ inside. Eighteen thousand specs and a second playground had drawn that container without a single
27
+ one of them being able to notice, which is the argument for this page and part of the argument
28
+ against the other one.
29
+
30
+ ## How it is lit, and why that is not decoration
31
+
32
+ A sun and an **environment map** (`load_default_environment`, the same octahedral sky eight other
33
+ playgrounds light themselves with), and **TAA on**.
34
+
35
+ Both are here for the geometry rather than for the picture. A directional light alone puts every
36
+ surface facing away from it at ambient zero, which is precisely the silhouette and the creases —
37
+ the places a cut is worth looking at — and a converted asset arrives with normals and no material
38
+ authoring, so the environment is most of what there is to shade it with. TAA is the other half: a
39
+ cut is re-selected every frame against a threshold in *pixels*, so the seams between two levels of
40
+ detail land on different pixels from one frame to the next, and without a temporal filter every one
41
+ of them is an aliased edge that crawls. The crawl reads as the cut being unstable when it is the
42
+ rasterizer being point-sampled.
43
+
44
+ Neither costs a reading. TAA runs downstream of the G-buffer, long after the cut has been selected
45
+ and drawn, and its sub-pixel jitter does not move the cut: the τ table below is identical with it on
46
+ and off. The environment is not awaited — `test_assets/` is gitignored, so a checkout without it
47
+ gets the sun alone and still draws every triangle the cut selected.
48
+
49
+ **Not the GPU sky, and that is worth writing down.** `renderer/atmosphere/GPUSky.js` and
50
+ `view/GPUViewSkyContext.js` would be the natural source for this and are **not reachable**: nothing
51
+ in the engine constructs either, `GPUSceneContext` has no `sky` for `GPUViewSkyContext.update` to
52
+ ask for, and `Renderer` does not mention the atmosphere at all. Reviving it is not a playground's
53
+ change — the sky produces an already-convolved GPU texture with `SPHERE_PROBE_MIPMAP_LEVELS` mips,
54
+ while `GPULightCollection` builds its environment privately from a CPU `ShadeTexture` and convolves
55
+ a full mip chain itself, so the two do not meet without a new way to hand that class a GPU-side
56
+ environment. That is a lighting change every scene in the engine would take, and it wants its own
57
+ piece of work.
14
58
 
15
59
  ## What it shows
16
60
 
17
- The container is built in the page and opened holding **only its root page**. Everything else
18
- arrives because the cut asked for it: a clamped cluster emits a want, the want names the page it
19
- was discovered through, the feedback readback resolves it to a byte range out of that page's own
20
- child table, and the page installs. Nothing is prefetched and no directory is read.
61
+ A container is opened holding **only its root page**. Everything else arrives because the cut asked
62
+ for it: a clamped cluster emits a want, the want names the page it was discovered through, the
63
+ feedback readback resolves it to a byte range out of that page's own child table, and the page
64
+ installs. Nothing is prefetched and no directory is read.
21
65
 
22
- Measured on an nvidia/lovelace adapter, a 128×48 torus at 64 KB pages — 13 pages, built in ~0.5 s
23
- in-page — and **re-measured on the same adapter after the review campaign**, which rewrote the VRAM
24
- tier onto fixed-stride page slots, moved selectability off the RAM tier, corrected the near plane's
25
- sign and replaced the scale correction. Every row is identical:
66
+ The one the page loads itself is built in the page, so there is something to look at without a file.
67
+ It is not what the page is *for*: **drop a `.vgeo` on the window**, or open the page at
68
+ `?file=<url>`, and that container is swapped for a real one. A sample torus is thirteen pages and a
69
+ converted asset is thousands, and the claim being made here is about the second.
70
+
71
+ Measured on an nvidia/lovelace adapter, a 128×48 torus at 64 KB pages — 13 pages, built in ~0.4 s
72
+ in-page — at a render target of 978×546. **The viewport is part of the measurement now**: τ is a
73
+ count of render-target pixels, the canvas follows the window, so a row of this table without the
74
+ resolution beside it is half a reading.
26
75
 
27
76
  | τ (px) | drawn clusters | pages visited | clamped | wavefronts | queue remaining |
28
77
  |---:|---:|---:|---:|---:|---:|
29
- | 0.5 | 50 | 9 | 0 | 14 | 0 |
30
- | 1 | 31 | 8 | 0 | 14 | 0 |
31
- | 2 | 18 | 6 | 0 | 11 | 0 |
32
- | 4 | 17 | 6 | 0 | 11 | 0 |
33
- | 8 | 9 | 5 | 0 | 8 | 0 |
34
- | 16 | 8 | 5 | 0 | 8 | 0 |
78
+ | 0.5 | 38 | 9 | 0 | 14 | 0 |
79
+ | 1 | 18 | 6 | 0 | 11 | 0 |
80
+ | 2 | 15 | 6 | 0 | 11 | 0 |
81
+ | 4 | 9 | 5 | 0 | 8 | 0 |
82
+ | 8 | 6 | 5 | 0 | 8 | 0 |
83
+ | 16 | 4 | 3 | 0 | 6 | 0 |
35
84
 
36
- The last two columns are new and are what the review's M8 was about: the descent ran fourteen
37
- wavefronts at its deepest against a budget of 64, and stopped with nothing still queued. A non-zero
38
- `queue remaining` is the one reading here that means a **hole** rather than a coarser surface.
85
+ The last two columns are what the review's M8 was about: the descent ran fourteen wavefronts at its
86
+ deepest against a budget of 64, and stopped with nothing still queued. A non-zero `queue remaining`
87
+ is the one reading here that means a **hole** rather than a coarser surface.
39
88
 
40
89
  The cut is monotone in τ and it is a *fraction* of the asset at every setting, which is design §1's
41
90
  whole claim: rendering cost is a function of the threshold and the resolution, not of the source
42
- triangle count. Residency settles at 9 of 13 pages and 230 KB — the four it never fetches are the
91
+ triangle count. Residency settles at 9 of 13 pages and 231 KB — the four it never fetches are the
43
92
  ones the cut never wanted.
44
93
 
94
+ The same claim, on the largest container of a converted 2,975-asset set — 920 MB, 17,172 pages,
95
+ 27,960,383 source triangles, served over HTTP by range requests at `?file=`:
96
+
97
+ | | |
98
+ |---|---:|
99
+ | drawn clusters | 10,766 |
100
+ | pages resident | 1,691 of 17,172 |
101
+ | bytes read | 87.6 MB of 920.7 MB |
102
+ | clamped | 0 |
103
+ | refused installs | 0 |
104
+ | opened in | 5 ms |
105
+
106
+ Nine and a half per cent of the file, and the container was on screen five milliseconds after its
107
+ first range came back. `clamped` reaching zero is the streaming having finished rather than the
108
+ budget having given up — which is a distinction the panel can now make, because `refused` is beside
109
+ it.
110
+
45
111
  Two readings are worth watching for what they say about the loop rather than the picture:
46
112
 
47
113
  - **`clamped` goes to zero.** The first frames draw a coarse, watertight surface because the pages
@@ -52,11 +118,94 @@ Two readings are worth watching for what they say about the loop rather than the
52
118
  costs streaming latency and nothing on screen, and a loop that insisted on a reading every frame
53
119
  would stall the frame it was reading.
54
120
 
121
+ ## What residency costs, and what it used to
122
+
123
+ The numbers above were taken with the tier nowhere near full. The reading that matters for a
124
+ runtime is the one with the tier full and the camera moving, and until 2026-09-14 it was
125
+ disqualifying: on this same container at 4,096 slots, zoomed in on a rosette, a DevTools trace had
126
+ twenty-four main-thread tasks over 50 ms in five and a half seconds, the longest 637 ms, `refused`
127
+ at 4.1 million and `pages visited` at 4,044 of 4,096 — every resident page touched every frame, so
128
+ nothing could be evicted, while selectability was recomputed over the whole geometry on every
129
+ install and every evict. `RUNTIME_PLAN_2026_09_14.md` in `runtime/` is the diagnosis and the
130
+ rebuild.
131
+
132
+ Measured after it, on an nvidia/lovelace adapter at 1258×646, a tour of eight rosettes held five
133
+ seconds each, twice round, then the rosette at rest:
134
+
135
+ | | before | after |
136
+ |---|---:|---:|
137
+ | main-thread tasks over 50 ms | 24 in 5.5 s, longest 637 ms | 4 in 150 s, longest 115 ms |
138
+ | `refused`, whole run | 4,166,982 | 999, over 3,009 evictions |
139
+ | `clamped` at rest, zoomed in | 1,334 | 0 |
140
+ | `pages visited` zoomed in | 4,044 of 4,096 | 2,000–3,200 of 4,096 |
141
+ | frame time zoomed in | — | p50 8.3 ms, p95 12.6 ms |
142
+ | page fetches on workers | 0 | all of them |
143
+
144
+ The panel's `RAM evicted`, `fetching` and `worker fetches` rows are new with it, and `refused` is
145
+ the reading to keep watching: it climbs only while the tier is full of pages the cut still draws
146
+ from, which is a budget saying no and not a tier scanning.
147
+
148
+ **`quarantined`** came here from the retired viewer, and it is the row that tells two coarse
149
+ surfaces apart. A page that fails its retries is quarantined with its reason and is never asked for
150
+ again; the clamped cut then keeps that region correct with a coarser ancestor, indefinitely. On
151
+ screen that is indistinguishable from a container that is merely still arriving, and `clamped`
152
+ alone cannot separate them — a count that will not fall while this is non-zero is a page that is
153
+ never coming.
154
+
155
+ Two things the tour still shows. The four long tasks left are `GPUMeshletManager` compactions —
156
+ a refused allocation with free space behind it rebuilds every batch, which is the one O(resident)
157
+ event the rebuild deferred. And under a vite dev server the first seconds after a container opens
158
+ stall while the four page-fetch workers' module graphs are served; a bundled build does not pay
159
+ that.
160
+
161
+ ## Putting an asset in it
162
+
163
+ Drop a `.vgeo` anywhere on the window, or open the page at `?file=/some/asset.vgeo` — a URL source
164
+ reads by `Range` request, so a container is opened out of its header and root page rather than
165
+ downloaded. Either way the asset on screen is retired first: its mesh row, its entity, its VRAM
166
+ pages and its place in the RAM tier's budget all go back, and the camera reframes on the new
167
+ container's own bounding sphere, which is the difference between a torus a unit across and a
168
+ building thirty metres up.
169
+
170
+ Two refusals are worth recognising, because both leave what is on screen exactly as it was and say
171
+ so in the panel rather than clearing the page:
172
+
173
+ - **"this container makes no promise about its own [page size]"** — built before `FORMAT` §11.14, so
174
+ its pages may be over the size its header names, and this tier lays out fixed-stride slots.
175
+ Rebuild it.
176
+ - **"this container's pages are bounded at N and this pool holds pages of 65536"** — right format,
177
+ wrong size. The pool's page size is fixed for the life of the page, because there is no slot-size
178
+ class table; build the asset at 64 KB.
179
+
180
+ The VRAM tier here is built with **4,096 page slots** rather than the engine default of 1,024,
181
+ which is a decision this page takes on its own and worth knowing when reading its numbers against
182
+ another host's. At the default, an asset over a thousand pages fills the tier and `refused` starts
183
+ climbing — and the cut then clamps against a budget instead of against τ, which is the one thing
184
+ this page is not supposed to be showing you. `refused` is in the panel so that when it *is* the
185
+ budget, you can see it is.
186
+
187
+ ## Profiling it
188
+
189
+ **`T` records a GPU capture, `T` again stops it and downloads an `.sgpt`** — the same key and the
190
+ same module (`playground/profile_hotkey.js`) the other playgrounds bind, so there is one
191
+ implementation of the drain and the naming rather than one per page. The level is `WORKLOAD`: pass
192
+ spans, the frame graph, and dispatch/draw counts, which measures around 14 KB a frame here.
193
+
194
+ It answers the question the panel cannot. Every reading above is a **count** — clusters drawn, pages
195
+ visited, wavefronts run — and not one of them is a cost. What is worth knowing is how the seed, the
196
+ traverse loop, the collect and the expansion compare against the rasterization they feed, and
197
+ whether the descent's wavefront count shows up as time or disappears into occupancy.
198
+
199
+ The capture's note carries **τ, the asset and the cut it selected**, next to the adapter and the
200
+ resolution, because the same 0.4 ms is a triumph at ten thousand clusters and a scandal at nine. A
201
+ capture without those is a number with nothing to divide it by.
202
+
55
203
  ## Driving it
56
204
 
57
- `__state()` is the whole surface a headless session needs — frames, the cut's counters, and both
58
- residency tiers. `__page.runtime.tau` is the threshold. The panel shows nothing `__state()` does
59
- not.
205
+ `__state()` is the whole surface a headless session needs — frames, the cut's counters, the asset,
206
+ the render target's size, and both residency tiers. `__page.runtime.tau` is the threshold,
207
+ `__load_url(url)` opens a container without a pointer to drop with. The panel shows nothing
208
+ `__state()` does not.
60
209
 
61
210
  ```
62
211
  npm run dev --workspace @woosh/meep-engine
@@ -68,7 +217,7 @@ rhetorical claim: 18,569 passing specs did not notice it failing to boot at all,
68
217
  `scene.add(make_sunlight())` had outlived `Scene.add` and the page threw before defining
69
218
  `__state`. Treat a green suite without a drive as unverified.
70
219
 
71
- ### The headless recipe, and the two things that cost an hour
220
+ ### The headless recipe, and the four things that cost an hour
72
221
 
73
222
  Start the dev server, then launch Chrome with a debugging port and connect over CDP:
74
223
 
@@ -88,6 +237,16 @@ chrome --headless=new --enable-unsafe-webgpu --remote-debugging-port=9333 \
88
237
  `chrome://omnibox-popup` targets as well, and the first entry is routinely not the page. Attaching
89
238
  to one of those and asking it for `navigator.gpu` answers `undefined`, which reads exactly like a
90
239
  browser without WebGPU.
240
+ - **Resize the window, not the viewport.** `Emulation.setDeviceMetricsOverride` moves `innerWidth`
241
+ and leaves `document.documentElement.clientWidth` where it was, so the page never resizes and the
242
+ override reads as the fix not working. `Browser.getWindowForTarget` then `Browser.setWindowBounds`
243
+ is a real resize and the canvas follows it.
244
+ - **A drop is dispatchable.** `new DataTransfer()`, `items.add(new File([bytes], name))`, then
245
+ `window.dispatchEvent(new DragEvent('drop', { dataTransfer }))` goes through the page's own
246
+ handler — no pointer, and no separate code path to keep honest. `?file=` needs a server that
247
+ answers `Range` with a `206`; vite refuses `/@fs/` outside the workspace, so an asset off the
248
+ tree wants twenty lines of `http.createServer` with `Access-Control-Expose-Headers:
249
+ Content-Range`.
91
250
 
92
251
  Open the page as Chrome's startup URL rather than with `Page.navigate` — the `load` event is not a
93
252
  reliable signal here, so poll for `__state` itself. Then set `__page.runtime.tau` and read
@@ -1,62 +1,112 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>meep — virtual geometry runtime</title>
6
-
7
- <link rel="icon" href="data:,">
8
-
9
- <style>
10
- :root { color-scheme: dark; }
11
-
12
- html, body { height: 100%; margin: 0; overflow: hidden; background: #070b10; }
13
-
14
- #panel {
15
- position: absolute; top: 0; right: 0; width: 320px; max-height: 100vh; overflow-y: auto;
16
- z-index: 10; padding: 12px 14px; box-sizing: border-box;
17
- font: 12px/1.45 ui-monospace, "Cascadia Mono", Consolas, monospace;
18
- color: #dfe6ee; background: rgba(12, 16, 22, 0.88);
19
- border-left: 1px solid #2b3947;
20
- }
21
-
22
- #panel h1 { margin: 0 0 8px; font-size: 13px; letter-spacing: 0.06em; color: #7fd2ff; }
23
-
24
- #panel h2 {
25
- margin: 14px 0 6px; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
26
- color: #6b7c8d; border-bottom: 1px solid #24313d; padding-bottom: 3px;
27
- }
28
-
29
- #panel .row { display: flex; justify-content: space-between; gap: 8px; }
30
- #panel .row span:last-child { color: #f2f6fa; text-align: right; }
31
- #panel .muted { color: #6b7c8d; }
32
- #panel .bad { color: #ff8a7a; }
33
- #panel .good { color: #8fe388; }
34
- #panel input[type=range] { width: 100%; }
35
- #panel label { display: block; margin: 6px 0 2px; }
36
-
37
- #status { white-space: pre-wrap; }
38
- #status.error { color: #ff8a7a; }
39
- </style>
40
- </head>
41
- <body tabindex="0">
42
-
43
- <div id="panel">
44
- <h1>virtual geometry runtime</h1>
45
- <div id="status" class="muted">starting…</div>
46
-
47
- <label>threshold τ <span id="tau-value">1.0</span> px</label>
48
- <input id="tau" type="range" min="0.25" max="16" step="0.25" value="1">
49
-
50
- <h2>cut</h2>
51
- <div id="cut"></div>
52
-
53
- <h2>residency</h2>
54
- <div id="residency"></div>
55
- </div>
56
-
57
- <canvas id="view" width="960" height="600"></canvas>
58
-
59
- <script type="module" src="./main.js"></script>
60
-
61
- </body>
62
- </html>
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>meep — virtual geometry runtime</title>
6
+
7
+ <link rel="icon" href="data:,">
8
+
9
+ <style>
10
+ :root { color-scheme: dark; }
11
+
12
+ html, body { height: 100%; margin: 0; overflow: hidden; background: #070b10; }
13
+
14
+ /* Placed, not sized. `Renderer` owns both of the canvas's sizes — it writes `width`/`height`
15
+ in device pixels and an **inline** `style.width`/`style.height` in CSS pixels every time
16
+ it configures the context — and an inline style beats a rule in here. So a `width: 100%`
17
+ on this selector would look like it was doing the work while the renderer quietly pinned
18
+ the canvas to whatever it was first told, and `main.js` measures the window rather than
19
+ the canvas for exactly that reason. */
20
+ #view { position: absolute; top: 0; left: 0; display: block; }
21
+
22
+ #panel {
23
+ position: absolute; top: 0; right: 0; width: 320px; max-height: 100vh; overflow-y: auto;
24
+ z-index: 10; padding: 12px 14px; box-sizing: border-box;
25
+ font: 12px/1.45 ui-monospace, "Cascadia Mono", Consolas, monospace;
26
+ color: #dfe6ee; background: rgba(12, 16, 22, 0.88);
27
+ border-left: 1px solid #2b3947;
28
+ }
29
+
30
+ #panel h1 { margin: 0 0 8px; font-size: 13px; letter-spacing: 0.06em; color: #7fd2ff; }
31
+
32
+ #panel h2 {
33
+ margin: 14px 0 6px; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
34
+ color: #6b7c8d; border-bottom: 1px solid #24313d; padding-bottom: 3px;
35
+ }
36
+
37
+ #panel .row { display: flex; justify-content: space-between; gap: 8px; }
38
+
39
+ /* A dropped file's name is as long as the file's name, and a converter's names are hashes.
40
+ Clipped rather than wrapped so the rows stay one line each, and `min-width: 0` because a
41
+ flex item refuses to shrink below its content without it — which is what put a horizontal
42
+ scrollbar across the whole panel. The full name is in the tooltip. */
43
+ #panel .row span:last-child {
44
+ color: #f2f6fa; text-align: right;
45
+ min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
46
+ }
47
+
48
+ #panel .row span:first-child { flex: none; }
49
+ #panel .muted { color: #6b7c8d; }
50
+ #panel .bad { color: #ff8a7a; }
51
+ #panel .good { color: #8fe388; }
52
+ #panel input[type=range] { width: 100%; }
53
+ #panel label { display: block; margin: 6px 0 2px; }
54
+
55
+ /* `overflow-wrap` as well as the wrap, because the status carries a URL and a URL has no
56
+ spaces to break at — one `?file=` was enough to push a scrollbar across the panel. */
57
+ #status { white-space: pre-wrap; overflow-wrap: anywhere; }
58
+ #status.error { color: #ff8a7a; }
59
+
60
+ #hint, #profile-note { margin-top: 10px; color: #6b7c8d; }
61
+
62
+ #profile-status { margin-top: 4px; color: #dfe6ee; word-break: break-word; }
63
+ #profile-status.recording { color: #ff8a7a; }
64
+
65
+ /* Shown only while something is being dragged over the window. `inset: 0` rather than the
66
+ canvas's box because a file dropped on the panel is a file dropped on the page. */
67
+ #drop {
68
+ position: absolute; inset: 0; z-index: 20;
69
+ display: none; align-items: center; justify-content: center;
70
+ font: 20px ui-monospace, monospace; color: #7fd2ff;
71
+ background: rgba(6, 12, 20, 0.82); border: 3px dashed #7fd2ff; box-sizing: border-box;
72
+ }
73
+
74
+ #drop.active { display: flex; }
75
+ </style>
76
+ </head>
77
+ <body tabindex="0">
78
+
79
+ <canvas id="view"></canvas>
80
+
81
+ <div id="drop">drop a .vgeo file</div>
82
+
83
+ <div id="panel">
84
+ <h1>virtual geometry runtime</h1>
85
+ <div id="status" class="muted">starting…</div>
86
+
87
+ <label>threshold τ <span id="tau-value">1.0</span> px</label>
88
+ <input id="tau" type="range" min="0.25" max="16" step="0.25" value="1">
89
+
90
+ <h2>asset</h2>
91
+ <div id="asset"></div>
92
+
93
+ <h2>cut</h2>
94
+ <div id="cut"></div>
95
+
96
+ <h2>residency</h2>
97
+ <div id="residency"></div>
98
+
99
+ <h2>profiling</h2>
100
+ <div id="profile-status">idle · T to record</div>
101
+ <div id="profile-note"><strong>T</strong> starts a GPU capture and <strong>T</strong> again
102
+ stops it and downloads an <code>.sgpt</code>. The capture's note carries τ and the cut it
103
+ selected, because a pass timing here means nothing without them.</div>
104
+
105
+ <div id="hint">drop a <code>.vgeo</code> file anywhere on the page, or open
106
+ <code>?file=/some/asset.vgeo</code></div>
107
+ </div>
108
+
109
+ <script type="module" src="./main.js"></script>
110
+
111
+ </body>
112
+ </html>