@woosh/meep-engine 3.28.0 → 3.30.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 (685) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/package.json +1 -1
  4. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  5. package/src/core/binary/BinaryBuffer.js +14 -2
  6. package/src/core/binary/BitSet.d.ts +16 -0
  7. package/src/core/binary/BitSet.d.ts.map +1 -1
  8. package/src/core/binary/BitSet.js +159 -49
  9. package/src/core/binary/allocator/OffsetAllocator.d.ts +48 -0
  10. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  11. package/src/core/binary/allocator/OffsetAllocator.js +208 -9
  12. package/src/core/binary/compression/compress_bytes.d.ts +20 -0
  13. package/src/core/binary/compression/compress_bytes.d.ts.map +1 -0
  14. package/src/core/binary/compression/compress_bytes.js +35 -0
  15. package/src/core/binary/compression/decompress_bytes_into.d.ts +30 -0
  16. package/src/core/binary/compression/decompress_bytes_into.d.ts.map +1 -0
  17. package/src/core/binary/compression/decompress_bytes_into.js +87 -0
  18. package/src/core/binary/compression/deflate_decompress_bound.d.ts +27 -0
  19. package/src/core/binary/compression/deflate_decompress_bound.d.ts.map +1 -0
  20. package/src/core/binary/compression/deflate_decompress_bound.js +32 -0
  21. package/src/core/bvh2/bvh3/BVH.d.ts.map +1 -1
  22. package/src/core/bvh2/bvh3/BVH.js +14 -1
  23. package/src/core/cache/FrequencySketch.d.ts +3 -1
  24. package/src/core/cache/FrequencySketch.d.ts.map +1 -1
  25. package/src/core/cache/FrequencySketch.js +10 -4
  26. package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts.map +1 -1
  27. package/src/core/cache/wtinylfu/CacheWTinylfu.js +24 -2
  28. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
  29. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
  30. package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
  31. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
  32. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
  33. package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
  34. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
  35. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
  36. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
  37. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
  38. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
  39. package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
  40. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
  41. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
  42. package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
  43. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
  44. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
  45. package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
  46. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
  47. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
  48. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
  49. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
  50. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
  51. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
  52. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts +20 -0
  53. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts.map +1 -1
  54. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +69 -4
  55. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
  56. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
  57. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
  58. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +93 -17
  59. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  60. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +930 -69
  61. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
  62. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
  63. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
  64. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
  65. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
  66. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
  67. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts +25 -0
  68. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts.map +1 -0
  69. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.js +228 -0
  70. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts +13 -0
  71. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts.map +1 -1
  72. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.js +10 -128
  73. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.d.ts.map +1 -1
  74. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.js +11 -1
  75. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
  76. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
  77. package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
  78. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
  79. package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
  80. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
  81. package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
  82. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
  83. package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
  84. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
  85. package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
  86. package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
  87. package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
  88. package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
  89. package/src/core/graph/mn_graph_collapse_weighted_edge.js +6 -6
  90. package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -1
  91. package/src/core/math/lookup/ParameterLookupTable.js +10 -5
  92. package/src/core/math/noise/sdnoise.d.ts.map +1 -1
  93. package/src/core/math/noise/sdnoise.js +16 -10
  94. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
  95. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  96. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
  97. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
  98. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
  99. package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
  100. package/src/core/model/object/ImmutableObjectPool.d.ts.map +1 -1
  101. package/src/core/model/object/ImmutableObjectPool.js +17 -7
  102. package/src/core/process/executor/ConcurrentExecutor.d.ts +1 -5
  103. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  104. package/src/core/process/executor/ConcurrentExecutor.js +95 -1
  105. package/src/core/process/task/task_find_dependency_cycle.d.ts +17 -0
  106. package/src/core/process/task/task_find_dependency_cycle.d.ts.map +1 -0
  107. package/src/core/process/task/task_find_dependency_cycle.js +81 -0
  108. package/src/core/wfc/WFCCellChoice.d.ts +17 -0
  109. package/src/core/wfc/WFCCellChoice.d.ts.map +1 -0
  110. package/src/core/wfc/WFCCellChoice.js +36 -0
  111. package/src/core/wfc/WFCLattice.d.ts +105 -0
  112. package/src/core/wfc/WFCLattice.d.ts.map +1 -0
  113. package/src/core/wfc/WFCLattice.js +235 -0
  114. package/src/core/wfc/WFCRuleTable.d.ts +172 -0
  115. package/src/core/wfc/WFCRuleTable.d.ts.map +1 -0
  116. package/src/core/wfc/WFCRuleTable.js +334 -0
  117. package/src/core/wfc/WFCState.d.ts +273 -0
  118. package/src/core/wfc/WFCState.d.ts.map +1 -0
  119. package/src/core/wfc/WFCState.js +552 -0
  120. package/src/core/wfc/WFCStatus.d.ts +11 -0
  121. package/src/core/wfc/WFCStatus.d.ts.map +1 -0
  122. package/src/core/wfc/WFCStatus.js +28 -0
  123. package/src/core/wfc/WFCTileWeights.d.ts +48 -0
  124. package/src/core/wfc/WFCTileWeights.d.ts.map +1 -0
  125. package/src/core/wfc/WFCTileWeights.js +86 -0
  126. package/src/core/wfc/WFC_UNRESOLVED.d.ts +12 -0
  127. package/src/core/wfc/WFC_UNRESOLVED.d.ts.map +1 -0
  128. package/src/core/wfc/WFC_UNRESOLVED.js +11 -0
  129. package/src/core/wfc/wfc_estimate_bytes.d.ts +24 -0
  130. package/src/core/wfc/wfc_estimate_bytes.d.ts.map +1 -0
  131. package/src/core/wfc/wfc_estimate_bytes.js +47 -0
  132. package/src/core/wfc/wfc_rule_table_tile_components.d.ts +27 -0
  133. package/src/core/wfc/wfc_rule_table_tile_components.d.ts.map +1 -0
  134. package/src/core/wfc/wfc_rule_table_tile_components.js +80 -0
  135. package/src/core/wfc/wfc_solve.d.ts +21 -0
  136. package/src/core/wfc/wfc_solve.d.ts.map +1 -0
  137. package/src/core/wfc/wfc_solve.js +154 -0
  138. package/src/core/wfc/wfc_state_apply_boundary.d.ts +18 -0
  139. package/src/core/wfc/wfc_state_apply_boundary.d.ts.map +1 -0
  140. package/src/core/wfc/wfc_state_apply_boundary.js +61 -0
  141. package/src/core/wfc/wfc_state_assign.d.ts +11 -0
  142. package/src/core/wfc/wfc_state_assign.d.ts.map +1 -0
  143. package/src/core/wfc/wfc_state_assign.js +36 -0
  144. package/src/core/wfc/wfc_state_ban_bits.d.ts +17 -0
  145. package/src/core/wfc/wfc_state_ban_bits.d.ts.map +1 -0
  146. package/src/core/wfc/wfc_state_ban_bits.js +81 -0
  147. package/src/core/wfc/wfc_state_collapse.d.ts +12 -0
  148. package/src/core/wfc/wfc_state_collapse.d.ts.map +1 -0
  149. package/src/core/wfc/wfc_state_collapse.js +73 -0
  150. package/src/core/wfc/wfc_state_flush_dirty.d.ts +12 -0
  151. package/src/core/wfc/wfc_state_flush_dirty.d.ts.map +1 -0
  152. package/src/core/wfc/wfc_state_flush_dirty.js +39 -0
  153. package/src/core/wfc/wfc_state_propagate.d.ts +14 -0
  154. package/src/core/wfc/wfc_state_propagate.d.ts.map +1 -0
  155. package/src/core/wfc/wfc_state_propagate.js +155 -0
  156. package/src/core/wfc/wfc_state_read.d.ts +11 -0
  157. package/src/core/wfc/wfc_state_read.d.ts.map +1 -0
  158. package/src/core/wfc/wfc_state_read.js +38 -0
  159. package/src/core/wfc/wfc_state_restrict.d.ts +18 -0
  160. package/src/core/wfc/wfc_state_restrict.d.ts.map +1 -0
  161. package/src/core/wfc/wfc_state_restrict.js +39 -0
  162. package/src/core/wfc/wfc_state_set_eligible.d.ts +24 -0
  163. package/src/core/wfc/wfc_state_set_eligible.d.ts.map +1 -0
  164. package/src/core/wfc/wfc_state_set_eligible.js +49 -0
  165. package/src/core/wfc/wfc_state_undo_to.d.ts +13 -0
  166. package/src/core/wfc/wfc_state_undo_to.d.ts.map +1 -0
  167. package/src/core/wfc/wfc_state_undo_to.js +84 -0
  168. package/src/core/wfc/wfc_words_per_cell.d.ts +11 -0
  169. package/src/core/wfc/wfc_words_per_cell.d.ts.map +1 -0
  170. package/src/core/wfc/wfc_words_per_cell.js +16 -0
  171. package/src/engine/ecs/EntityComponentDataset.d.ts +8 -0
  172. package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
  173. package/src/engine/ecs/EntityComponentDataset.js +37 -14
  174. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts +8 -1
  175. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
  176. package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +37 -2
  177. package/src/engine/ecs/guid/UUID.d.ts.map +1 -1
  178. package/src/engine/ecs/guid/UUID.js +45 -17
  179. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +1 -1
  180. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +3 -1
  181. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  182. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +366 -360
  183. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.d.ts.map +1 -1
  184. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.js +24 -10
  185. package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
  186. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  187. package/src/engine/graphics3/DebugDrawSystem.js +206 -203
  188. package/src/engine/graphics3/DecalSystem.d.ts +4 -5
  189. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  190. package/src/engine/graphics3/DecalSystem.js +5 -5
  191. package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
  192. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
  193. package/src/engine/graphics3/FogOfWarSystem.js +8 -12
  194. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
  195. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
  196. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +24 -5
  197. package/src/engine/interpolation/Interpoland.d.ts +7 -1
  198. package/src/engine/interpolation/Interpoland.d.ts.map +1 -1
  199. package/src/engine/interpolation/Interpoland.js +8 -1
  200. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
  201. package/src/engine/interpolation/InterpolationSystem.js +3 -0
  202. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +5 -3
  203. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -1
  204. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +14 -3
  205. package/src/engine/interpolation/pose_interpoland.d.ts.map +1 -1
  206. package/src/engine/interpolation/pose_interpoland.js +2 -0
  207. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  208. package/src/engine/network/orchestrator/NetworkPeer.js +15 -10
  209. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  210. package/src/engine/physics/cloth/ecs/ClothWorld.js +17 -0
  211. package/src/engine/physics/mls-mpm/MLS_MPM.d.ts.map +1 -1
  212. package/src/engine/physics/mls-mpm/MLS_MPM.js +14 -0
  213. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +2 -1
  214. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -1
  215. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +1 -1
  216. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +1 -0
  217. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -1
  218. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +1 -0
  219. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
  220. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +2 -1
  221. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -1
  222. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +12 -3
  223. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +1 -0
  224. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts.map +1 -1
  225. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +1 -0
  226. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
  227. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
  228. package/src/engine/sound/sopra/runtime/EventInstance.js +4 -1
  229. package/src/format/image/avif/av1/decode/decode_coefficients.d.ts.map +1 -1
  230. package/src/format/image/avif/av1/decode/decode_coefficients.js +248 -259
  231. package/src/format/image/avif/av1/decode/read_golomb.d.ts +21 -0
  232. package/src/format/image/avif/av1/decode/read_golomb.d.ts.map +1 -0
  233. package/src/format/image/avif/av1/decode/read_golomb.js +49 -0
  234. package/src/format/image/avif/av1/filter/loop_restoration.js +461 -451
  235. package/src/format/image/avif/av1/util/round2.d.ts +19 -2
  236. package/src/format/image/avif/av1/util/round2.d.ts.map +1 -1
  237. package/src/format/image/avif/av1/util/round2.js +51 -27
  238. package/src/format/image/avif/heif/parse_avif_file.js +24 -0
  239. package/src/shade/RENDERER_CONTRACT.md +12 -7
  240. package/src/shade/playground/caldera/README.md +529 -0
  241. package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
  242. package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
  243. package/src/shade/playground/caldera/caldera_format.js +241 -0
  244. package/src/shade/playground/caldera/index.html +126 -0
  245. package/src/shade/playground/caldera/main.d.ts.map +1 -0
  246. package/src/shade/playground/caldera/main.js +1565 -0
  247. package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
  248. package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
  249. package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
  250. package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
  251. package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
  252. package/src/shade/playground/vgeo_runtime/README.md +5 -3
  253. package/src/shade/playground/vgeo_runtime/main.js +3 -2
  254. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +3 -3
  255. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -1
  256. package/src/shade/playground/vgeo_runtime/sample_asset.js +3 -3
  257. package/src/shade/playground/vgeo_scene/README.md +103 -24
  258. package/src/shade/playground/vgeo_scene/main.js +525 -24
  259. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  260. package/src/shade/renderer/GraphicsContext.js +6 -0
  261. package/src/shade/renderer/Renderer.d.ts +2 -0
  262. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  263. package/src/shade/renderer/Renderer.js +23 -0
  264. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  265. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
  266. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  267. package/src/shade/renderer/buffer/table/GPUTypedTable.js +14 -0
  268. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +69 -33
  269. package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
  270. package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
  271. package/src/shade/renderer/extension/RenderExtension.js +15 -19
  272. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
  273. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
  274. package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
  275. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  276. package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
  277. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  278. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
  279. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
  280. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
  281. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  282. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
  283. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
  284. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +155 -64
  285. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +76 -16
  286. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +3 -3
  287. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +448 -0
  288. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +44 -7
  289. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  290. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +48 -9
  291. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
  292. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
  293. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
  294. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
  295. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
  296. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
  297. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
  298. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
  299. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
  300. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
  301. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
  302. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
  303. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +19 -6
  304. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -1
  305. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.js +20 -7
  306. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
  307. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
  308. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
  309. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
  310. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
  311. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
  312. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
  313. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
  314. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
  315. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
  316. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
  317. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
  318. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +2 -27
  319. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -1
  320. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +120 -1564
  321. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
  322. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
  323. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
  324. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
  325. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
  326. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
  327. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
  328. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
  329. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
  330. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
  331. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
  332. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
  333. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
  334. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
  335. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
  336. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
  337. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
  338. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
  339. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
  340. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
  341. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +74 -0
  342. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
  343. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +78 -0
  344. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +12 -7
  345. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -1
  346. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js +33 -11
  347. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
  348. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
  349. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
  350. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
  351. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
  352. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
  353. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
  354. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
  355. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
  356. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +32 -7
  357. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -1
  358. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +243 -24
  359. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +12 -8
  360. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -1
  361. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +58 -50
  362. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +5 -0
  363. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -1
  364. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js +13 -1
  365. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
  366. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
  367. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
  368. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +23 -5
  369. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -1
  370. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.js +28 -21
  371. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.js +1 -1
  372. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
  373. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +224 -60
  374. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +15 -0
  375. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -1
  376. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +17 -0
  377. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +17 -0
  378. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -1
  379. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +19 -0
  380. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +10 -1
  381. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -1
  382. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +103 -9
  383. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +14 -2
  384. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -1
  385. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +38 -14
  386. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
  387. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  388. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +27 -4
  389. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
  390. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
  391. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
  392. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
  393. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  394. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
  395. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
  396. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
  397. package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
  398. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
  399. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
  400. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
  401. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
  402. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
  403. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
  404. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
  405. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
  406. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
  407. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
  408. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
  409. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
  410. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
  411. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
  412. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
  413. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  414. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
  415. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
  416. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
  417. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
  418. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
  419. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
  420. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
  421. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
  422. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
  423. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
  424. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
  425. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
  426. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
  427. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  428. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +37 -13
  429. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
  430. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
  431. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
  432. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -0
  433. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  434. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +19 -1
  435. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
  436. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
  437. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
  438. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
  439. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
  440. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
  441. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
  442. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
  443. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
  444. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
  445. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
  446. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
  447. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +4 -2
  448. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  449. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +8 -4
  450. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  451. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
  452. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
  453. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
  454. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
  455. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
  456. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  457. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
  458. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
  459. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
  460. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
  461. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
  462. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
  463. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
  464. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
  465. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
  466. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  467. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
  468. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
  469. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  470. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +111 -33
  471. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
  472. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  473. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +112 -42
  474. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
  475. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  476. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +51 -21
  477. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
  478. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  479. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
  480. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
  481. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +14 -1
  482. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  483. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +34 -0
  484. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -1
  485. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +18 -0
  486. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  487. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +47 -19
  488. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
  489. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
  490. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
  491. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
  492. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
  493. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  494. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +10 -0
  495. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  496. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
  497. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
  498. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
  499. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  500. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +4 -0
  501. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
  502. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +12 -3
  503. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  504. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -4
  505. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
  506. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  507. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
  508. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
  509. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
  510. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
  511. package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.d.ts.map +1 -1
  512. package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.js +7 -1
  513. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  514. package/src/shade/renderer/lightmap/GPULightMap.js +349 -336
  515. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  516. package/src/shade/renderer/loader/gltf/load_gltf.js +1137 -1128
  517. package/src/shade/renderer/particles/DESIGN.md +14 -5
  518. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +25 -10
  519. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  520. package/src/shade/renderer/particles/GPUParticleSystem.js +182 -38
  521. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  522. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +16 -10
  523. package/src/shade/renderer/particles/graph_particles.d.ts +4 -2
  524. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  525. package/src/shade/renderer/particles/graph_particles.js +8 -2
  526. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  527. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +8 -2
  528. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  529. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +10 -4
  530. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  531. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
  532. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts +31 -0
  533. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts.map +1 -0
  534. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.js +62 -0
  535. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  536. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
  537. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +13 -0
  538. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  539. package/src/shade/renderer/particles/vm/ParticleVMReference.js +95 -17
  540. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  541. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +4 -12
  542. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts +21 -0
  543. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts.map +1 -0
  544. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.js +28 -0
  545. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  546. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  547. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +4 -5
  548. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  549. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +5 -3
  550. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
  551. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
  552. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  553. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +4 -3
  554. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  555. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
  556. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  557. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
  558. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  559. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +13 -5
  560. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  561. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
  562. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  563. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
  564. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
  565. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
  566. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  567. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
  568. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
  569. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
  570. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  571. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +1 -7
  572. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  573. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
  574. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  575. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +2 -7
  576. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  577. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +19 -2
  578. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  579. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +4 -8
  580. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  581. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +5 -8
  582. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  583. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +19 -2
  584. package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
  585. package/src/shade/renderer/shader/type/WebGPUStruct.js +12 -0
  586. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
  587. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
  588. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
  589. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
  590. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  591. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
  592. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts +8 -2
  593. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts.map +1 -1
  594. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.js +41 -6
  595. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +2383 -2356
  596. package/src/view/tooltip/DomTooltipManager.d.ts +7 -0
  597. package/src/view/tooltip/DomTooltipManager.d.ts.map +1 -1
  598. package/src/view/tooltip/DomTooltipManager.js +22 -0
  599. package/src/view/tooltip/DomTooltipObserver.d.ts.map +1 -1
  600. package/src/view/tooltip/DomTooltipObserver.js +13 -3
  601. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
  602. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
  603. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
  604. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
  605. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
  606. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
  607. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
  608. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
  609. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
  610. package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
  611. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts +0 -18
  612. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
  613. package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
  614. package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
  615. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts +0 -52
  616. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
  617. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
  618. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
  619. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts +0 -32
  620. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
  621. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts +0 -59
  622. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
  623. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts +0 -44
  624. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
  625. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
  626. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
  627. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts +0 -73
  628. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
  629. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +0 -13
  630. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
  631. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts +0 -12
  632. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
  633. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
  634. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
  635. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts +0 -13
  636. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
  637. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts +0 -19
  638. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
  639. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
  640. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
  641. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts +0 -31
  642. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
  643. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts +0 -18
  644. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
  645. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
  646. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
  647. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
  648. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
  649. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts +0 -14
  650. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
  651. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts +0 -11
  652. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
  653. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts +0 -46
  654. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
  655. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +0 -22
  656. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
  657. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts +0 -29
  658. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
  659. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts +0 -9
  660. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
  661. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts +0 -10
  662. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
  663. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts +0 -15
  664. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
  665. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
  666. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
  667. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
  668. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
  669. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
  670. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
  671. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
  672. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
  673. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
  674. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
  675. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
  676. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
  677. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
  678. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
  679. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
  680. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
  681. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
  682. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
  683. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
  684. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
  685. /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
@@ -1,6 +1,7 @@
1
1
  import { Color } from "../../../core/color/Color.js";
2
2
  import { m4_linear_determinant } from "../../../core/geom/3d/mat4/m4_linear_determinant.js";
3
3
  import Vector3 from "../../../core/geom/Vector3.js";
4
+ import { GIGABYTE } from "../../../core/science/units/memory/GIGABYTE.js";
4
5
  import { EntityComponentDataset } from "../../../engine/ecs/EntityComponentDataset.js";
5
6
  import { Transform64 } from "../../../engine/ecs/transform/Transform64.js";
6
7
  import { OrbitalCameraController } from "../../renderer/camera/OrbitalCameraController.js";
@@ -25,6 +26,12 @@ import { make_sunlight } from "../../renderer/light/make_sunlight.js";
25
26
  import { place_light } from "../../renderer/light/place_light.js";
26
27
  import { ShadeDrawSide } from "../../renderer/material/ShadeDrawSide.js";
27
28
  import { StandardShadeMaterial } from "../../renderer/material/StandardShadeMaterial.js";
29
+ import { TransparencyMode } from "../../renderer/material/TransparencyMode.js";
30
+ import { ColorSpace } from "../../renderer/texture/ColorSpace.js";
31
+ import { ShadeTexture } from "../../renderer/texture/ShadeTexture.js";
32
+ import { TextureWrapType } from "../../renderer/texture/TextureWrapType.js";
33
+ import { ShadeImage } from "../../renderer/texture/source/ShadeImage.js";
34
+ import { Sampler2D } from "../../../engine/graphics/texture/sampler/Sampler2D.js";
28
35
  import {
29
36
  RasterizationCollectionType
30
37
  } from "../../renderer/rasterize/expand/RasterizationCollectionType.js";
@@ -76,14 +83,35 @@ const element = id => document.getElementById(id);
76
83
  /**
77
84
  * Where the containers are served from when the page is opened without a `?scene=`.
78
85
  *
79
- * `tools/geometry/virtual/vgeo_serve.js` binds this by default and answers `/scenes.json` with what
80
- * it holds, so a page with no parameters finds the scene that is there rather than asking for a URL
81
- * to be pasted. It is a *separate* origin on purpose: vite refuses `/@fs/` outside the workspace,
82
- * and a forty-gigabyte directory has no business inside one.
86
+ * Same origin as the page, and that is the point: `tools/dev/vite_test_assets.js` serves this prefix
87
+ * out of the package's own `test_assets/` **and** out of an asset root outside the checkout, by
88
+ * range, so a fifty-gigabyte converted scene is reached from the dev server that is already running.
89
+ * It used to be `http://localhost:5200` — a second server, started by hand, that this page was
90
+ * useless without.
83
91
  *
84
92
  * @type {string}
85
93
  */
86
- const DEFAULT_ORIGIN = 'http://localhost:5200';
94
+ const ASSET_PREFIX = '/test_assets';
95
+
96
+ /**
97
+ * What a scene manifest is named, and therefore what {@link resolve_scene_url} asks the asset root
98
+ * for when the page is opened with no parameters at all.
99
+ *
100
+ * @type {string}
101
+ */
102
+ const SCENE_SUFFIX = '.vgeoscene.json';
103
+
104
+ /**
105
+ * What the material sidecar beside a scene manifest is named.
106
+ *
107
+ * `vgeo_scene_materials.js` writes it: the material each container is, and the constants to shade
108
+ * that material with. It is a separate file from the scene because it answers to a separate source
109
+ * — the original project, extracted — and a scene nobody has done that to is still a scene, so the
110
+ * page opens with or without it.
111
+ *
112
+ * @type {string}
113
+ */
114
+ const MATERIALS_SUFFIX = '.vgeomaterials.json';
87
115
 
88
116
  /**
89
117
  * Head bytes read on the first request of every container.
@@ -233,6 +261,50 @@ class VGeoScenePlayground {
233
261
  */
234
262
  mirror_material;
235
263
 
264
+ /**
265
+ * One material per distinct material the source scene used, when a sidecar was found.
266
+ *
267
+ * Empty when it was not, and {@link material} then draws everything as before.
268
+ *
269
+ * @type {StandardShadeMaterial[]}
270
+ */
271
+ materials = [];
272
+
273
+ /**
274
+ * Which of {@link materials} each container is, indexed the same as the scene manifest's
275
+ * geometries. `-1` for a container the sidecar had no material for.
276
+ *
277
+ * @type {number[]}
278
+ */
279
+ geometry_material = [];
280
+
281
+ /**
282
+ * Containers drawn with their own material rather than with {@link material}.
283
+ * @type {number}
284
+ */
285
+ materialised = 0;
286
+
287
+ /**
288
+ * Texture slots bound from the sidecar — zero when the scene has no texture coordinates to
289
+ * sample them with, which is the ordinary case for a converted set.
290
+ *
291
+ * @type {number}
292
+ */
293
+ textures_bound = 0;
294
+
295
+ /**
296
+ * What a container the sidecar had no material for is drawn with.
297
+ *
298
+ * Not {@link material}: that one is a pale grey chosen to read well when it is the *only*
299
+ * material in the frame, and at 0.72 it is brighter than almost anything the extraction
300
+ * produces. Six hundred of those among two thousand real surfaces do not look like missing
301
+ * data, they look like the scene — and they drag the exposure down over everything else. A
302
+ * neutral dielectric grey sits in the range the real materials occupy.
303
+ *
304
+ * @type {StandardShadeMaterial}
305
+ */
306
+ unmaterialised;
307
+
236
308
  /**
237
309
  * Instances placed with a negative-determinant transform.
238
310
  * @type {number}
@@ -428,9 +500,9 @@ class VGeoScenePlayground {
428
500
 
429
501
  const worker = async () => {
430
502
  while (next < geometries.length) {
431
- const record = geometries[next++];
503
+ const index = next++;
432
504
 
433
- await this.open_one(record, options);
505
+ await this.open_one(geometries[index], options, index);
434
506
  }
435
507
  };
436
508
 
@@ -457,7 +529,7 @@ class VGeoScenePlayground {
457
529
  * @param {VGeoReadOptions} options
458
530
  * @returns {Promise<void>}
459
531
  */
460
- async open_one(record, options) {
532
+ async open_one(record, options, index = -1) {
461
533
  const url = new URL(record.file, this.base).href;
462
534
 
463
535
  try {
@@ -484,6 +556,19 @@ class VGeoScenePlayground {
484
556
 
485
557
  const matrices = record.instances;
486
558
 
559
+ /*
560
+ The container's own material when the sidecar named one. There is no per-instance
561
+ material here and there is nothing to choose between: a `.vgeo` is one primitive of the
562
+ source document and a glTF primitive has exactly one material, so the container *is*
563
+ the material bucket.
564
+ */
565
+ const own_material = index < 0 ? undefined : this.materials[this.geometry_material[index]];
566
+ const material = own_material ?? this.unmaterialised ?? this.material;
567
+
568
+ if (own_material !== undefined) {
569
+ this.materialised++;
570
+ }
571
+
487
572
  const transform = new Transform64();
488
573
 
489
574
  for (let i = 0; i < matrices.length; i += 16) {
@@ -512,9 +597,16 @@ class VGeoScenePlayground {
512
597
  this.mirrored++;
513
598
  }
514
599
 
600
+ /*
601
+ `?mirrored=` splits reflected instances into a bucket of their own, which is a
602
+ diagnostic about winding rather than about materials — so it takes precedence when
603
+ it is on, and the container's own material is what draws otherwise.
604
+ */
515
605
  place_primitive(
516
606
  this.scene_context, geometry,
517
- reflected ? this.mirror_material : this.material,
607
+ reflected && this.mirror_material !== this.material
608
+ ? this.mirror_material
609
+ : material,
518
610
  transform
519
611
  );
520
612
 
@@ -612,6 +704,8 @@ class VGeoScenePlayground {
612
704
  refused: this.refused,
613
705
  instances: this.placed,
614
706
  mirrored: this.mirrored,
707
+ materials: this.materials.length,
708
+ materialised: this.materialised,
615
709
  faces: this.manifest === undefined ? 0 : scene_faces(this.manifest),
616
710
  bytes: this.manifest?.total_bytes ?? 0,
617
711
  bytes_read,
@@ -952,12 +1046,328 @@ function human_bytes(bytes) {
952
1046
  }
953
1047
 
954
1048
  /**
955
- * Where the scene manifest is, out of `?scene=` or out of the asset server's own listing.
1049
+ * Build the engine material a sidecar entry describes.
956
1050
  *
957
- * The listing is what makes the page turn-key: `vgeo_serve.js` answers `/scenes.json` with the
958
- * manifests in the directory it is serving, so a page opened with no parameters at all finds the
959
- * one scene that is there. More than one and it takes the first and says which, because a page
960
- * that refuses to choose between two is a page that shows nothing.
1051
+ * **What is bound here is the `constant` block, not the textures**, and that is a property of this
1052
+ * asset rather than of the extraction. Zorah's containers carry position, normal and tangent and no
1053
+ * texture coordinates at all — the source document the conversion read is `POSITION` only — so
1054
+ * there is nothing to sample an albedo map *with* until a UV-carrying source is built and the
1055
+ * containers are made again from it. The material's `textures` are in the sidecar and the images
1056
+ * are on disk, waiting for that.
1057
+ *
1058
+ * The constants are not a stand-in for the textures. `albedo` is the extracted base colour map's
1059
+ * own alpha-weighted mean multiplied by the material's authored tint, `roughness` and `metallic`
1060
+ * come from the real ORM, and the draw side and alpha mode are what the material instance actually
1061
+ * overrode. What the surface loses is its detail, not its identity.
1062
+ *
1063
+ * @param {object} definition one entry of the sidecar's `materials`
1064
+ * @param {number} side what `?side=` asked for, which still wins
1065
+ * @returns {StandardShadeMaterial}
1066
+ */
1067
+ function make_scene_material(definition, side) {
1068
+ const material = new StandardShadeMaterial();
1069
+
1070
+ material.name = definition.name;
1071
+
1072
+ const constant = definition.constant ?? {};
1073
+ const albedo = constant.albedo ?? [0.72, 0.74, 0.78];
1074
+
1075
+ material.diffuse_color.set(albedo[0], albedo[1], albedo[2], 1);
1076
+
1077
+ /*
1078
+ With no ORM bound the material samples the engine's default white pixel, so every one of these
1079
+ factors is the value itself rather than a multiplier on a map.
1080
+ */
1081
+ material.roughness_factor = constant.roughness ?? 0.55;
1082
+ material.metallic_factor = constant.metallic ?? 0;
1083
+
1084
+ /*
1085
+ `ambient = fma(orm.r, ambient_factors.a, ambient_factors.b)`. `StandardShadeMaterial`
1086
+ constructs with `LinearModifier(1, 1)`, which against the default white ORM pixel is 2 and
1087
+ saturates to 1 in the G-buffer's unorm alpha — a material that has said nothing about occlusion
1088
+ is therefore unoccluded, which is the right answer and the reason the default is that pair.
1089
+
1090
+ This states it rather than reaching it by saturation, because the value here has to survive
1091
+ `bind_scene_textures` switching to (1, 0) when a real ORM arrives: Unreal's red channel *is*
1092
+ ambient occlusion and the conversion wants it applied, which is a decision about the source
1093
+ rather than a correction to the engine.
1094
+ */
1095
+ material.ambient_factors.a = 0;
1096
+ material.ambient_factors.b = 1;
1097
+
1098
+ const emissive = definition.emissive_factor ?? [0, 0, 0];
1099
+
1100
+ material.emissive_factor.set(emissive[0], emissive[1], emissive[2], 1);
1101
+
1102
+ /*
1103
+ A two-sided material is two-sided because the artist said so — foliage cards, cloth, thin
1104
+ stone tracery — and drawing it `Front` loses half of it. `?side=` overrides the lot, because
1105
+ its whole purpose is to ask whether something is missing or merely culled.
1106
+ */
1107
+ material.draw_side = side ?? (definition.draw_side === 'Double'
1108
+ ? ShadeDrawSide.Double
1109
+ : definition.draw_side === 'Back' ? ShadeDrawSide.Back : ShadeDrawSide.Front);
1110
+
1111
+ /*
1112
+ Alpha testing needs an alpha to test and the albedo texture is what carries it, so a masked
1113
+ material with no texture bound would discard by a constant and disappear entirely. Opaque is
1114
+ the honest fallback until the textures can be sampled.
1115
+ */
1116
+ material.transparency_mode = TransparencyMode.Opaque;
1117
+
1118
+ return material;
1119
+ }
1120
+
1121
+ /**
1122
+ * An environment of one constant radiance, for asking how much of a surface's brightness is its own
1123
+ * colour and how much is the sky.
1124
+ *
1125
+ * The real environment is an HDR sky with a sun in it, and a rough reflection integrates a wide
1126
+ * enough lobe to gather that sun — so comparing a surface against one pixel of the background
1127
+ * proves nothing about whether the image-based lighting is over-contributing. Against a **uniform**
1128
+ * environment the comparison is exact: no reflected direction can return more than the constant, so
1129
+ * a surface brighter than it is being lit by more than it reflects, and by how much.
1130
+ *
1131
+ * Big enough to carry a mip chain rather than 1×1 — `sample_environment_map` reads `lod` and
1132
+ * `lod + 1`, and a texture with one level has nowhere to read the second from. Every level is the
1133
+ * same value, so the roughness the sampler picks its lod from cannot change the answer.
1134
+ *
1135
+ * @param {number} value linear radiance, the same in all three channels
1136
+ * @returns {ShadeTexture}
1137
+ */
1138
+ function make_uniform_environment(value) {
1139
+ const size = 64;
1140
+
1141
+ // An environment is half-float; a float32 sampler uploads at twice the pitch the texture was
1142
+ // created with and the whole thing is refused. `Float16Array` converts on assignment, so these
1143
+ // are plain radiances rather than bit patterns — writing the bits instead stores the *number*
1144
+ // 14336 and lights the scene with it.
1145
+ const sampler = Sampler2D.float16(4, size, size);
1146
+
1147
+ for (let i = 0; i < size * size; i++) {
1148
+ sampler.data[i * 4] = value;
1149
+ sampler.data[i * 4 + 1] = value;
1150
+ sampler.data[i * 4 + 2] = value;
1151
+ sampler.data[i * 4 + 3] = 1;
1152
+ }
1153
+
1154
+ const image = ShadeImage.fromSampler2D(sampler);
1155
+
1156
+ image.color_space = ColorSpace.LinearSRGB;
1157
+
1158
+ const texture = ShadeTexture.from(image);
1159
+
1160
+ texture.wrapS = TextureWrapType.ClampToEdge;
1161
+ texture.wrapT = TextureWrapType.ClampToEdge;
1162
+
1163
+ return texture;
1164
+ }
1165
+
1166
+ /**
1167
+ * Fetch one extracted texture and make a {@link ShadeTexture} of it.
1168
+ *
1169
+ * `createImageBitmap` rather than `ShadeImage.fromArrayBuffer`: these are ordinary PNGs written by
1170
+ * the extraction and the browser's own decoder is what should read them.
1171
+ * `colorSpaceConversion: 'none'` matters — the extraction already wrote the exact bytes Unreal had,
1172
+ * and letting the browser convert them to the display profile on the way in shifts every albedo.
1173
+ *
1174
+ * A UDIM set has no place to go in a fixed material, so its first tile is taken and the caller is
1175
+ * told; composing the grid and rescaling the UVs belongs in the converter, not here.
1176
+ *
1177
+ * @param {object} slot one of a sidecar material's `textures`
1178
+ * @param {string} base where the textures are served from
1179
+ * @returns {Promise<ShadeTexture|null>}
1180
+ */
1181
+ async function load_scene_texture(slot, base) {
1182
+ const file = slot.files?.[0]?.file;
1183
+
1184
+ if (file === undefined || base === null) {
1185
+ return null;
1186
+ }
1187
+
1188
+ const url = `${base.replace(/\/$/, '')}/${file}`;
1189
+ const response = await fetch(url);
1190
+
1191
+ if (!response.ok) {
1192
+ throw new Error(`${url} answered HTTP ${response.status}`);
1193
+ }
1194
+
1195
+ const bitmap = await createImageBitmap(await response.blob(), {
1196
+ premultiplyAlpha: 'none',
1197
+ colorSpaceConversion: 'none',
1198
+ });
1199
+
1200
+ const image = ShadeImage.fromImageBitmap(bitmap);
1201
+
1202
+ /*
1203
+ A base colour map is sRGB encoded and everything else — normals, and an ORM's occlusion,
1204
+ roughness and metalness — is linear data that must not be decoded on the way in. The extraction
1205
+ read the flag off the Unreal asset and wrote it into the sidecar rather than guessing it from
1206
+ the slot, because the two disagree often enough to matter.
1207
+ */
1208
+ image.color_space = slot.srgb === true ? ColorSpace.SRGB : ColorSpace.None;
1209
+
1210
+ return ShadeTexture.from(image);
1211
+ }
1212
+
1213
+ /**
1214
+ * Bind the real maps onto the materials, where the scene can sample them.
1215
+ *
1216
+ * Returns what happened rather than throwing: one texture that will not load is one material drawn
1217
+ * from its constants, and the rest of the scene is unaffected.
1218
+ *
1219
+ * @param {object[]} definitions the sidecar's materials
1220
+ * @param {StandardShadeMaterial[]} materials what {@link make_scene_material} built from them
1221
+ * @param {string} base
1222
+ * @returns {Promise<{bound: number, failed: string[], udim: number}>}
1223
+ */
1224
+ async function bind_scene_textures(definitions, materials, base) {
1225
+ const cache = new Map();
1226
+ const failed = [];
1227
+
1228
+ let bound = 0;
1229
+ let udim = 0;
1230
+
1231
+ const obtain = async (slot) => {
1232
+ const key = slot.files?.[0]?.file;
1233
+
1234
+ if (key === undefined) {
1235
+ return null;
1236
+ }
1237
+
1238
+ if (!cache.has(key)) {
1239
+ cache.set(key, load_scene_texture(slot, base));
1240
+ }
1241
+
1242
+ return cache.get(key);
1243
+ };
1244
+
1245
+ const SLOTS = [
1246
+ ['albedo', 'texture_albedo'],
1247
+ ['normal', 'texture_normal'],
1248
+ ['orm', 'texture_orm'],
1249
+ ];
1250
+
1251
+ await Promise.all(definitions.map(async (definition, i) => {
1252
+ for (const [name, field] of SLOTS) {
1253
+ const slot = definition.textures?.[name];
1254
+
1255
+ if (slot === undefined || slot.missing === true) {
1256
+ continue;
1257
+ }
1258
+
1259
+ if (slot.udim === true) {
1260
+ udim++;
1261
+ }
1262
+
1263
+ try {
1264
+ const texture = await obtain(slot);
1265
+
1266
+ if (texture !== null) {
1267
+ materials[i][field] = texture;
1268
+ bound++;
1269
+ }
1270
+ } catch (error) {
1271
+ failed.push(`${definition.name}.${name}: ${error.message ?? error}`);
1272
+ }
1273
+ }
1274
+
1275
+ /*
1276
+ The tint already multiplied the texture's mean to make the constant. With the texture
1277
+ itself bound, the mean has to come back out or the surface is darkened by its own colour
1278
+ twice.
1279
+ */
1280
+ if (materials[i].texture_albedo !== undefined) {
1281
+ const tint = definition.diffuse_color ?? [1, 1, 1, 1];
1282
+
1283
+ materials[i].diffuse_color.set(tint[0], tint[1], tint[2], 1);
1284
+ }
1285
+
1286
+ /*
1287
+ Every one of these is a **multiplier on the map**, as glTF specifies — `roughness = orm.g *
1288
+ roughness_factor`, `metalness = orm.b * metallic_factor`. The constants that stood in for
1289
+ the map have to give way, or the map is scaled by the mean of itself.
1290
+
1291
+ glTF's default for both factors is 1 and `StandardShadeMaterial`'s own is 0 for metalness,
1292
+ which is right for a bare material with no map to multiply. The extraction wrote that 0
1293
+ through even where it was binding an ORM, and a factor of zero suppressing the map is the
1294
+ specified behaviour rather than a fault in it — so this is the extraction saying which of
1295
+ the two cases it is in.
1296
+ */
1297
+ if (materials[i].texture_orm !== undefined) {
1298
+ materials[i].roughness_factor = definition.roughness_factor ?? 1;
1299
+ materials[i].metallic_factor = definition.metallic_factor ?? 1;
1300
+
1301
+ materials[i].ambient_factors.a = 1;
1302
+ materials[i].ambient_factors.b = 0;
1303
+ }
1304
+ }));
1305
+
1306
+ return { bound, failed, udim };
1307
+ }
1308
+
1309
+ /**
1310
+ * Read the material sidecar beside a scene, if there is one.
1311
+ *
1312
+ * `?materials=<url>` names one explicitly and `?materials=off` refuses it, which is how the page
1313
+ * still shows what a converted scene looks like with nothing but geometry — the picture this page
1314
+ * had before there was anything to say about its surfaces.
1315
+ *
1316
+ * A sidecar that is absent is not an error. It is the ordinary case for any scene that has not had
1317
+ * its source project extracted.
1318
+ *
1319
+ * @param {string} scene_url
1320
+ * @param {URLSearchParams} parameters
1321
+ * @returns {Promise<object|null>}
1322
+ */
1323
+ async function load_scene_materials(scene_url, parameters) {
1324
+ const requested = parameters.get('materials');
1325
+
1326
+ if (requested === 'off') {
1327
+ return null;
1328
+ }
1329
+
1330
+ const url = requested !== null && requested !== ''
1331
+ ? new URL(requested, globalThis.location.href).href
1332
+ : scene_url.replace(new RegExp(`${SCENE_SUFFIX.replace(/\./g, '\\.')}$`), MATERIALS_SUFFIX);
1333
+
1334
+ if (url === scene_url) {
1335
+ return null;
1336
+ }
1337
+
1338
+ let response;
1339
+
1340
+ try {
1341
+ response = await fetch(url);
1342
+ } catch (error) {
1343
+ console.warn(`material sidecar ${url} — ${error.message ?? error}`);
1344
+
1345
+ return null;
1346
+ }
1347
+
1348
+ if (!response.ok) {
1349
+ // the ordinary case: this scene has no sidecar
1350
+ return null;
1351
+ }
1352
+
1353
+ const sidecar = await response.json();
1354
+
1355
+ if (sidecar.format !== 1) {
1356
+ console.warn(`${url} is a format-${sidecar.format} sidecar and this page reads format 1`);
1357
+
1358
+ return null;
1359
+ }
1360
+
1361
+ return sidecar;
1362
+ }
1363
+
1364
+ /**
1365
+ * Where the scene manifest is, out of `?scene=` or out of the asset root's own listing.
1366
+ *
1367
+ * The listing is what makes the page turn-key: the dev server answers `?find=` with the paths of
1368
+ * every manifest under every root it serves, so a page opened with no parameters at all finds the
1369
+ * one scene that is there. More than one and it takes the first and says which, because a page that
1370
+ * refuses to choose between two is a page that shows nothing.
961
1371
  *
962
1372
  * @returns {Promise<string>}
963
1373
  */
@@ -968,13 +1378,13 @@ async function resolve_scene_url() {
968
1378
  return new URL(requested, globalThis.location.href).href;
969
1379
  }
970
1380
 
971
- const listing = await fetch(`${DEFAULT_ORIGIN}/scenes.json`);
1381
+ const listing = await fetch(`${ASSET_PREFIX}/?find=${encodeURIComponent(SCENE_SUFFIX)}`);
972
1382
 
973
1383
  if (!listing.ok) {
974
1384
  throw new Error(
975
- `no ?scene= was given and ${DEFAULT_ORIGIN} answered HTTP ${listing.status};`
976
- + ` start the asset server with`
977
- + ` "node tools/geometry/virtual/vgeo_serve.js <container directory>"`
1385
+ `no ?scene= was given and ${ASSET_PREFIX}/?find= answered HTTP ${listing.status};`
1386
+ + ` that listing is "tools/dev/vite_test_assets.js" under the dev server, so this is a`
1387
+ + ` page being served by something else — pass the manifest as ?scene=<url>`
978
1388
  );
979
1389
  }
980
1390
 
@@ -982,12 +1392,17 @@ async function resolve_scene_url() {
982
1392
 
983
1393
  if (scenes.length === 0) {
984
1394
  throw new Error(
985
- `${DEFAULT_ORIGIN} is serving no .vgeoscene.json;`
1395
+ `nothing under ${ASSET_PREFIX}/ is a ${SCENE_SUFFIX};`
986
1396
  + ` build one with "node tools/geometry/virtual/vgeo_scene.js <manifest.vgeo.json>"`
1397
+ + ` under the asset root the dev server named at startup`
987
1398
  );
988
1399
  }
989
1400
 
990
- return `${DEFAULT_ORIGIN}/${scenes[0]}`;
1401
+ // the listing answers with a path, and a path is not a URL: a directory with a space in it is
1402
+ // ordinary on a Windows asset drive and is a 404 if it goes out unencoded
1403
+ const encoded = scenes[0].split('/').map(encodeURIComponent).join('/');
1404
+
1405
+ return new URL(`${ASSET_PREFIX}/${encoded}`, globalThis.location.href).href;
991
1406
  }
992
1407
 
993
1408
  /**
@@ -1079,7 +1494,7 @@ async function start() {
1079
1494
  more, because the cut is a function of the resolution, so it is a URL parameter and `refused`
1080
1495
  is in the panel to say when it was the wrong one.
1081
1496
  */
1082
- const page_capacity = Number(parameters.get('pages') ?? 12288);
1497
+ const page_capacity = Number(parameters.get('pages') ?? 16384);
1083
1498
 
1084
1499
  const capacities = scene_capacities(manifest, page_capacity);
1085
1500
 
@@ -1125,7 +1540,15 @@ async function start() {
1125
1540
  direction: new Vector3(-manifest.sun[0], -manifest.sun[1], -manifest.sun[2]),
1126
1541
  });
1127
1542
 
1128
- place_light(scene, sun);
1543
+ /*
1544
+ `?sun=off` leaves the scene to its environment alone. Paired with `?env=uniform:<v>` it is a
1545
+ closed question rather than an argument: the only light is then a constant radiance from every
1546
+ direction, so a surface cannot return more of it than it reflects, and any surface brighter
1547
+ than the environment it is standing in is being lit by something that is not there.
1548
+ */
1549
+ if (parameters.get('sun') !== 'off') {
1550
+ place_light(scene, sun);
1551
+ }
1129
1552
 
1130
1553
  /*
1131
1554
  Image-based lighting, and for the geometry rather than for the picture: a sun alone puts every
@@ -1133,7 +1556,23 @@ async function start() {
1133
1556
  cut is worth looking at. Not awaited — `test_assets/` is gitignored, so a checkout without it
1134
1557
  gets the sun alone and still draws every triangle the cut selected.
1135
1558
  */
1136
- load_default_environment(scene);
1559
+ /*
1560
+ `?env=off` leaves it out, and it is a **diagnostic about the shading rather than about the
1561
+ geometry**: the environment is the only wide, neutral light in the scene, so it is the term to
1562
+ remove when a surface reads paler than its own albedo and the question is whether that colour
1563
+ is coming from the material at all. The renderer already treats a missing environment as an
1564
+ ordinary state — a checkout without `test_assets/` renders by the sun alone — so this needs
1565
+ nothing but skipping the load.
1566
+ */
1567
+ const environment = parameters.get('env');
1568
+
1569
+ if (environment === 'off') {
1570
+ // nothing: the sun alone
1571
+ } else if (environment !== null && environment.startsWith('uniform')) {
1572
+ scene.lights.environment = make_uniform_environment(Number(environment.split(':')[1] ?? 0.5));
1573
+ } else {
1574
+ load_default_environment(scene);
1575
+ }
1137
1576
 
1138
1577
  const camera = new PerspectiveCamera();
1139
1578
 
@@ -1162,7 +1601,7 @@ async function start() {
1162
1601
  */
1163
1602
  const residency = new VGeoResidencyOptions();
1164
1603
 
1165
- residency.ram_budget_bytes = 1024 * 1024 * 1024;
1604
+ residency.ram_budget_bytes = 2 * GIGABYTE;
1166
1605
 
1167
1606
  /*
1168
1607
  VRAM is a strict subset of RAM, so the RAM tier has to be able to hold the whole VRAM tier and
@@ -1279,6 +1718,61 @@ async function start() {
1279
1718
 
1280
1719
  page.mirror_material = mirrored_mode === null ? material : mirror_material;
1281
1720
 
1721
+ /*
1722
+ The scene's own materials, when the source project has been extracted beside it. 3,163
1723
+ containers resolve to a few hundred distinct materials — a `.vgeo` is one glTF primitive and a
1724
+ primitive has one material — so this is a few hundred buckets in the draw path rather than one,
1725
+ which is the scene's real shape rather than a cost this page is choosing to pay.
1726
+ */
1727
+ const sidecar = await load_scene_materials(scene_url, parameters);
1728
+
1729
+ if (sidecar !== null) {
1730
+ const side = DRAW_SIDES[parameters.get('side')];
1731
+
1732
+ page.materials = sidecar.materials.map(definition => make_scene_material(definition, side));
1733
+ page.geometry_material = sidecar.geometry_material;
1734
+
1735
+ page.unmaterialised = make_scene_material({
1736
+ name: 'unmaterialised',
1737
+ constant: { albedo: [0.18, 0.18, 0.18], roughness: 0.7, metallic: 0 },
1738
+ }, side);
1739
+
1740
+ const noted = sidecar.materials.filter(m => (m.unsupported ?? []).length > 0).length;
1741
+
1742
+ page.status(
1743
+ `${sidecar.material_count} materials, `
1744
+ + `${noted} with something the standard material cannot carry`
1745
+ );
1746
+
1747
+ /*
1748
+ The maps themselves, but only when the containers can sample them. `uv0` is the sidecar
1749
+ saying the source document carried `TEXCOORD_0`; for a scene converted from a
1750
+ `POSITION`-only document there is nothing to sample *with*, and binding an albedo map would
1751
+ put one texel across every surface in the frame.
1752
+
1753
+ `?textures=off` refuses them, which is how the two halves are compared on the same scene.
1754
+ */
1755
+ if (sidecar.uv0 === true && parameters.get('textures') !== 'off') {
1756
+ page.status(`${sidecar.material_count} materials — loading textures…`);
1757
+
1758
+ const bound = await bind_scene_textures(
1759
+ sidecar.materials, page.materials, sidecar.texture_base,
1760
+ );
1761
+
1762
+ page.textures_bound = bound.bound;
1763
+
1764
+ for (const failure of bound.failed) {
1765
+ console.warn(`texture — ${failure}`);
1766
+ }
1767
+
1768
+ page.status(
1769
+ `${sidecar.material_count} materials, ${bound.bound} textures`
1770
+ + (bound.udim > 0 ? ` (${bound.udim} UDIM sets took their first tile)` : '')
1771
+ + (bound.failed.length > 0 ? `, ${bound.failed.length} failed` : '')
1772
+ );
1773
+ }
1774
+ }
1775
+
1282
1776
  globalThis.addEventListener('pagehide', () => page.feedback.destroy());
1283
1777
 
1284
1778
  renderer.add_extension(new VGeoFrameStart(page));
@@ -1605,6 +2099,13 @@ function paint(page, capacities, state) {
1605
2099
  ['containers', `${scene.containers.toLocaleString()} / ${scene.declared.toLocaleString()}`],
1606
2100
  ['instances', scene.instances.toLocaleString()],
1607
2101
  ['reflected', scene.mirrored.toLocaleString()],
2102
+ [
2103
+ 'materials',
2104
+ scene.materials === 0
2105
+ ? 'one — no sidecar'
2106
+ : `${scene.materials.toLocaleString()} over `
2107
+ + `${scene.materialised.toLocaleString()} containers`,
2108
+ ],
1608
2109
  ['source triangles', scene.faces.toLocaleString()],
1609
2110
  ['on the server', human_bytes(scene.bytes)],
1610
2111
  ['read', human_bytes(scene.bytes_read)],