@woosh/meep-engine 3.27.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 (255) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts +15 -0
  4. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
  5. package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
  6. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
  7. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
  8. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
  9. package/src/engine/Engine.d.ts.map +1 -1
  10. package/src/engine/Engine.js +38 -1
  11. package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
  12. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  13. package/src/engine/graphics3/GraphicsEngine.js +834 -830
  14. package/src/shade/RENDERER_CONTRACT.md +19 -10
  15. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
  16. package/src/shade/playground/vgeo_runtime/README.md +27 -13
  17. package/src/shade/playground/vgeo_runtime/main.js +18 -5
  18. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +18 -0
  19. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
  20. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +9 -8
  21. package/src/shade/playground/vgeo_scene/README.md +408 -0
  22. package/src/shade/playground/vgeo_scene/index.html +144 -0
  23. package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
  24. package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
  25. package/src/shade/playground/vgeo_scene/main.js +1716 -0
  26. package/src/shade/renderer/Renderer.d.ts +4 -1
  27. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  28. package/src/shade/renderer/Renderer.js +5 -2
  29. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +1 -2
  30. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  31. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
  32. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
  33. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
  34. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
  35. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +4 -2
  36. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +10 -8
  37. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +12 -11
  38. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +1 -1
  39. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  40. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +1 -1
  41. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
  42. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
  43. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts +32 -0
  44. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
  45. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +59 -0
  46. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
  47. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts +44 -0
  48. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
  49. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +36 -0
  50. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
  51. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_levels.js → level/vgeo_build_levels.js} +61 -95
  52. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts +19 -0
  53. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
  54. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
  55. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +73 -0
  56. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
  57. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +7 -7
  58. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +29 -0
  59. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
  60. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_normals.js → mesh/vgeo_compute_vertex_normals.js} +3 -3
  61. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +31 -0
  62. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
  63. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.js → mesh/vgeo_compute_vertex_tangents.js} +5 -5
  64. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +46 -0
  65. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
  66. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +9 -9
  67. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts +13 -0
  68. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
  69. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +9 -9
  70. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts +13 -0
  71. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
  72. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
  73. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts +22 -0
  74. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
  75. package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
  76. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +52 -0
  77. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
  78. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +1 -1
  79. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts +14 -0
  80. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts +29 -0
  82. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
  83. package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
  84. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
  85. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
  86. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
  87. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts +10 -0
  88. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
  89. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +12 -55
  90. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts +15 -0
  91. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
  92. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.js → partition/vgeo_split_face_set_packed.js} +3 -3
  93. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts +12 -0
  94. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
  95. package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
  96. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts +18 -0
  97. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
  98. package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
  99. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts +9 -0
  100. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
  101. package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
  102. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +24 -0
  103. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
  104. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +20 -0
  105. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
  106. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +14 -0
  107. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
  108. package/src/shade/renderer/geometry/virtual/build/{vgeo_extract_submesh.js → submesh/vgeo_extract_submesh.js} +5 -5
  109. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +12 -0
  110. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
  111. package/src/shade/renderer/geometry/virtual/build/{vgeo_gather_faces.js → submesh/vgeo_gather_faces.js} +2 -2
  112. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts +11 -0
  113. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
  114. package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
  115. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  116. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +9 -11
  117. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts +8 -2
  118. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
  119. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
  120. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts +15 -0
  121. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
  122. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
  123. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +28 -0
  124. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  125. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +7 -3
  126. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  127. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +9 -4
  128. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  129. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +18 -5
  130. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  131. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +9 -1
  132. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +21 -2
  133. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +52 -2
  134. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  135. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +97 -1
  136. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +4 -4
  137. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  138. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +10 -0
  139. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +59 -34
  141. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +8 -8
  142. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  143. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +11 -88
  144. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
  145. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
  146. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +98 -0
  147. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
  148. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
  149. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
  150. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
  151. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
  152. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -0
  153. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -1
  154. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +7 -63
  155. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  156. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +13 -30
  157. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  158. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +6 -52
  159. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  160. package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
  161. package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
  162. package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
  163. package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
  164. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  165. package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -1
  166. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  167. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
  168. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
  169. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  170. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
  171. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
  172. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
  173. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts +22 -0
  174. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
  175. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
  176. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +15 -0
  177. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
  178. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
  179. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
  180. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
  181. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
  182. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
  183. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
  184. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
  185. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  186. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
  187. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  188. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +44 -53
  189. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  190. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
  191. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  192. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
  193. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
  194. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
  195. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
  196. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  197. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
  198. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
  199. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
  200. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  201. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
  202. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
  203. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
  204. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  205. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
  206. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
  207. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
  208. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  209. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
  210. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  211. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +78 -88
  212. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  213. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +21 -31
  214. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  215. package/src/shade/renderer/scene/GPUSceneContext.js +2 -0
  216. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
  217. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
  218. package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
  219. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
  220. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
  221. package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
  222. package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
  223. package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
  224. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  225. package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
  226. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
  227. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
  228. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
  229. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
  230. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
  231. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
  232. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
  233. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
  234. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
  235. package/src/shade/playground/vgeo_viewer/README.md +0 -150
  236. package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
  237. package/src/shade/playground/vgeo_viewer/index.html +0 -77
  238. package/src/shade/playground/vgeo_viewer/main.js +0 -1343
  239. package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
  240. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
  241. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
  242. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
  243. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
  244. package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
  245. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
  246. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
  247. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
  248. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
  249. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
  250. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
  251. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +0 -0
  252. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
  253. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
  254. /package/src/shade/renderer/geometry/virtual/build/{VGeoGatheredFaces.js → submesh/VGeoGatheredFaces.js} +0 -0
  255. /package/src/shade/renderer/geometry/virtual/build/{VGeoSubmesh.js → submesh/VGeoSubmesh.js} +0 -0
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The opaque rasterization buckets a scene has anything in, once each.
3
+ *
4
+ * Every opaque path records one pass per bucket, and the pass is expensive — extract, expand to
5
+ * meshlets, select a virtual-geometry cut, one render pass. So what is iterated has to be the
6
+ * *buckets*, and iterating `ShadeDrawSide` is not that: `Front` and `Back` are one bucket, and a
7
+ * loop over the enum visits it twice and draws the scene's single-sided geometry twice.
8
+ *
9
+ * Which is why this exists rather than the three callers each writing the loop: the enum is the
10
+ * obvious thing to reach for and it is wrong, and it is wrong in a way that costs a whole pass and
11
+ * shows up in nothing but a frame time.
12
+ *
13
+ * @param {Set<number>} active_buckets bucket ids any material in the scene asks for
14
+ * @yields {{draw_mode: ShadeDrawMode, side: ShadeDrawSide, bucket_id: number}} `side` is the
15
+ * bucket's representative, which is what {@link construct_primitive_state} wants
16
+ */
17
+ export function rasterization_opaque_buckets(active_buckets: Set<number>): Generator<{
18
+ draw_mode: number;
19
+ side: number;
20
+ bucket_id: number;
21
+ }, void, unknown>;
22
+ //# sourceMappingURL=rasterization_opaque_buckets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rasterization_opaque_buckets.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH,6DAJW,IAAI,MAAM,CAAC;;;;kBAkBrB"}
@@ -0,0 +1,36 @@
1
+ import { ShadeDrawMode } from "../../material/ShadeDrawMode.js";
2
+ import { TransparencyMode } from "../../material/TransparencyMode.js";
3
+ import { rasterization_material_bucket } from "../expand/bucket/chunk_rasterization_material_bucket.js";
4
+ import { RASTERIZATION_BUCKET_SIDES } from "./construct_primitive_state.js";
5
+
6
+ /**
7
+ * The opaque rasterization buckets a scene has anything in, once each.
8
+ *
9
+ * Every opaque path records one pass per bucket, and the pass is expensive — extract, expand to
10
+ * meshlets, select a virtual-geometry cut, one render pass. So what is iterated has to be the
11
+ * *buckets*, and iterating `ShadeDrawSide` is not that: `Front` and `Back` are one bucket, and a
12
+ * loop over the enum visits it twice and draws the scene's single-sided geometry twice.
13
+ *
14
+ * Which is why this exists rather than the three callers each writing the loop: the enum is the
15
+ * obvious thing to reach for and it is wrong, and it is wrong in a way that costs a whole pass and
16
+ * shows up in nothing but a frame time.
17
+ *
18
+ * @param {Set<number>} active_buckets bucket ids any material in the scene asks for
19
+ * @yields {{draw_mode: ShadeDrawMode, side: ShadeDrawSide, bucket_id: number}} `side` is the
20
+ * bucket's representative, which is what {@link construct_primitive_state} wants
21
+ */
22
+ export function* rasterization_opaque_buckets(active_buckets) {
23
+ for (const draw_mode of Object.values(ShadeDrawMode)) {
24
+ for (const side of RASTERIZATION_BUCKET_SIDES) {
25
+
26
+ const bucket_id = rasterization_material_bucket(TransparencyMode.Opaque, draw_mode, side);
27
+
28
+ if (!active_buckets.has(bucket_id)) {
29
+ // no matching materials, skip
30
+ continue;
31
+ }
32
+
33
+ yield { draw_mode, side, bucket_id };
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The whole of what a vertex shader needs to know to emit a triangle the right way round, in one
3
+ * place — because there is more than one reason to reverse and they are not independent of each
4
+ * other.
5
+ *
6
+ * Feed the answer to `triangle_list_reverse_winding`. Nanite's `ReverseWindingOrder` is the same
7
+ * function for the same reason: a GPU-driven draw mixes instances that disagree about this, so it
8
+ * cannot be pipeline state, and every reason has to be combined before the corner is chosen.
9
+ *
10
+ * @see chunk_triangle_list_reverse_winding
11
+ * @type {CodeChunk}
12
+ */
13
+ export const chunk_triangle_winding_is_reversed: CodeChunk;
14
+ import { CodeChunk } from "../shader/compiler/CodeChunk.js";
15
+ //# sourceMappingURL=chunk_triangle_winding_is_reversed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_triangle_winding_is_reversed.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;GAWG;AACH,iDAFU,SAAS,CAmBb;0BA/BoB,iCAAiC"}
@@ -0,0 +1,35 @@
1
+ import { chunk_material_draw_side } from "../material/chunk_material_draw_side.js";
2
+ import { chunk_node3d_flags } from "../scene/chunk_node3d_flags.js";
3
+ import { NODE3D_STRUCT } from "../scene/NODE3D_STRUCT.js";
4
+ import { CodeChunk } from "../shader/compiler/CodeChunk.js";
5
+
6
+ /**
7
+ * The whole of what a vertex shader needs to know to emit a triangle the right way round, in one
8
+ * place — because there is more than one reason to reverse and they are not independent of each
9
+ * other.
10
+ *
11
+ * Feed the answer to `triangle_list_reverse_winding`. Nanite's `ReverseWindingOrder` is the same
12
+ * function for the same reason: a GPU-driven draw mixes instances that disagree about this, so it
13
+ * cannot be pipeline state, and every reason has to be combined before the corner is chosen.
14
+ *
15
+ * @see chunk_triangle_list_reverse_winding
16
+ * @type {CodeChunk}
17
+ */
18
+ export const chunk_triangle_winding_is_reversed = CodeChunk.from(
19
+ //language=WGSL
20
+ `
21
+ /**
22
+ * Whether this instance's triangles must be emitted back to front.
23
+ *
24
+ * Two reasons, and they cancel: the instance's transform reflects, or the material asks for the
25
+ * back face. A back-sided material on a mirrored instance is wound like a front-sided one on an
26
+ * ordinary instance, and draws with the same pipeline state as both.
27
+ */
28
+ fn triangle_winding_is_reversed( node: ${NODE3D_STRUCT.wgsl_ref}, draw_side: u32 ) -> bool{
29
+ return node3d_global_is_mirrored(node) != material_draws_back_side(draw_side);
30
+ }
31
+ `, [
32
+ NODE3D_STRUCT.declaration_chunk,
33
+ chunk_node3d_flags,
34
+ chunk_material_draw_side,
35
+ ])
@@ -1,6 +1,15 @@
1
1
  export const RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE: number;
2
2
  export const RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE: number;
3
- export const RASTERIZATION_BUCKET_BIT_COUNT_DRAW_SIDE: number;
3
+ /**
4
+ * One bit, not the two {@link ShadeDrawSide} would need. Only double-sided geometry needs a
5
+ * pipeline of its own — `cullMode: 'none'` has no winding equivalent. `Front` and `Back` share
6
+ * one: a back-sided material is a front-sided one drawn with its winding reversed, and the
7
+ * vertex shader does the reversing.
8
+ *
9
+ * @see rasterization_material_bucket
10
+ * @type {number}
11
+ */
12
+ export const RASTERIZATION_BUCKET_BIT_COUNT_DOUBLE_SIDED: number;
4
13
  /**
5
14
  * Maximum number of rasterization buckets. This is a number of permutations of different alpha and draw modes.
6
15
  * See Northlight talk on "Alan Wake 2" meshlet shading.
@@ -1 +1 @@
1
- {"version":3,"file":"RASTERIZATION_BUCKET_LIMIT.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js"],"names":[],"mappings":"AAmBA,+DAA0F;AAC1F,8DAAsF;AACtF,8DAAsF;AAEtF;;;;GAIG;AACH,yCAFU,MAAM,CAEmK"}
1
+ {"version":3,"file":"RASTERIZATION_BUCKET_LIMIT.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js"],"names":[],"mappings":"AAkBA,+DAA0F;AAC1F,8DAAsF;AAEtF;;;;;;;;GAQG;AACH,0DAFU,MAAM,CAE6C;AAE7D;;;;GAIG;AACH,yCAFU,MAAM,CAEsK"}
@@ -1,29 +1,38 @@
1
- import { assert } from "../../../../../core/assert.js";
2
- import { ShadeDrawMode } from "../../../material/ShadeDrawMode.js";
3
- import { ShadeDrawSide } from "../../../material/ShadeDrawSide.js";
4
- import { TransparencyMode } from "../../../material/TransparencyMode.js";
5
-
6
- /**
7
- *
8
- * @param {Object} e enum
9
- * @return {number} number of bits required to represent it
10
- */
11
- function enum_bit_count(e) {
12
- const max = Math.max.apply(null, Object.values(e));
13
-
14
- assert.isNonNegativeInteger(max, 'max');
15
- assert.lessThanOrEqual(max, 5, "the bucket count is going to be absurd");
16
-
17
- return 32 - Math.clz32(max);
18
- }
19
-
20
- export const RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE = enum_bit_count(TransparencyMode);
21
- export const RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE = enum_bit_count(ShadeDrawMode);
22
- export const RASTERIZATION_BUCKET_BIT_COUNT_DRAW_SIDE = enum_bit_count(ShadeDrawSide);
23
-
24
- /**
25
- * Maximum number of rasterization buckets. This is a number of permutations of different alpha and draw modes.
26
- * See Northlight talk on "Alan Wake 2" meshlet shading.
27
- * @type {number}
28
- */
29
- export const RASTERIZATION_BUCKET_LIMIT = (1 << (RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE + RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE + RASTERIZATION_BUCKET_BIT_COUNT_DRAW_SIDE));
1
+ import { assert } from "../../../../../core/assert.js";
2
+ import { ShadeDrawMode } from "../../../material/ShadeDrawMode.js";
3
+ import { TransparencyMode } from "../../../material/TransparencyMode.js";
4
+
5
+ /**
6
+ *
7
+ * @param {Object} e enum
8
+ * @return {number} number of bits required to represent it
9
+ */
10
+ function enum_bit_count(e) {
11
+ const max = Math.max.apply(null, Object.values(e));
12
+
13
+ assert.isNonNegativeInteger(max, 'max');
14
+ assert.lessThanOrEqual(max, 5, "the bucket count is going to be absurd");
15
+
16
+ return 32 - Math.clz32(max);
17
+ }
18
+
19
+ export const RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE = enum_bit_count(TransparencyMode);
20
+ export const RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE = enum_bit_count(ShadeDrawMode);
21
+
22
+ /**
23
+ * One bit, not the two {@link ShadeDrawSide} would need. Only double-sided geometry needs a
24
+ * pipeline of its own — `cullMode: 'none'` has no winding equivalent. `Front` and `Back` share
25
+ * one: a back-sided material is a front-sided one drawn with its winding reversed, and the
26
+ * vertex shader does the reversing.
27
+ *
28
+ * @see rasterization_material_bucket
29
+ * @type {number}
30
+ */
31
+ export const RASTERIZATION_BUCKET_BIT_COUNT_DOUBLE_SIDED = 1;
32
+
33
+ /**
34
+ * Maximum number of rasterization buckets. This is a number of permutations of different alpha and draw modes.
35
+ * See Northlight talk on "Alan Wake 2" meshlet shading.
36
+ * @type {number}
37
+ */
38
+ export const RASTERIZATION_BUCKET_LIMIT = (1 << (RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE + RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE + RASTERIZATION_BUCKET_BIT_COUNT_DOUBLE_SIDED));
@@ -7,6 +7,11 @@
7
7
  */
8
8
  export function rasterization_material_bucket(alpha_mode: number | TransparencyMode, draw_mode: number | ShadeDrawMode, side: number | ShadeDrawSide): number;
9
9
  /**
10
+ * A bucket is a pipeline state, and the third field is the only thing a {@link ShadeDrawSide}
11
+ * still says about one: whether it culls at all. `Front` and `Back` land in the same bucket —
12
+ * a back-sided material is a front-sided one whose winding the vertex shader reverses — so a
13
+ * scene that mixes them draws in one pass, through one expansion chain.
14
+ *
10
15
  * @see TransparencyMode
11
16
  * @see ShadeDrawMode
12
17
  * @see rasterization_material_bucket
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_rasterization_material_bucket.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js"],"names":[],"mappings":"AAuCA;;;;;;GAMG;AACH,0DALW,MAAM,GAAC,gBAAgB,aACvB,MAAM,GAAC,aAAa,QACpB,MAAM,GAAC,aAAa,GACnB,MAAM,CAUjB;AAhCD;;;;;GAKG;AACH,kDAFU,SAAS,CAWjB;iCAlC+B,uCAAuC;8BAF1C,oCAAoC;8BACpC,oCAAoC;0BAExC,uCAAuC"}
1
+ {"version":3,"file":"chunk_rasterization_material_bucket.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js"],"names":[],"mappings":"AA6CA;;;;;;GAMG;AACH,0DALW,MAAM,GAAC,gBAAgB,aACvB,MAAM,GAAC,aAAa,QACpB,MAAM,GAAC,aAAa,GACnB,MAAM,CAYjB;AAzCD;;;;;;;;;;GAUG;AACH,kDAFU,SAAS,CAajB;iCAxC+B,uCAAuC;8BAF1C,oCAAoC;8BACpC,oCAAoC;0BAExC,uCAAuC"}
@@ -1,55 +1,63 @@
1
- import { assert } from "../../../../../core/assert.js";
2
- import { ShadeDrawMode } from "../../../material/ShadeDrawMode.js";
3
- import { ShadeDrawSide } from "../../../material/ShadeDrawSide.js";
4
- import { TransparencyMode } from "../../../material/TransparencyMode.js";
5
- import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
6
- import {
7
- RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE,
8
- RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE,
9
- RASTERIZATION_BUCKET_BIT_COUNT_DRAW_SIDE
10
- } from "./RASTERIZATION_BUCKET_LIMIT.js";
11
-
12
- // A field of N bits is masked with (1 << N) - 1, not N + 1 (the two coincide only at N == 2,
13
- // which is the value all three enums happen to have today).
14
- const mask_alpha = (1 << RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE) - 1;
15
- const shift_alpha = 0;
16
-
17
- const mask_primitive = (1 << RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE) - 1;
18
- const shift_primitive = shift_alpha + RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE;
19
-
20
- const mask_side = (1 << RASTERIZATION_BUCKET_BIT_COUNT_DRAW_SIDE) - 1;
21
- const shift_side = shift_primitive + RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE;
22
-
23
- /**
24
- * @see TransparencyMode
25
- * @see ShadeDrawMode
26
- * @see rasterization_material_bucket
27
- * @type {CodeChunk}
28
- */
29
- export const chunk_rasterization_material_bucket = CodeChunk.from(
30
- //language=WGSL
31
- `
32
- fn rasterization_material_bucket( alpha_mode: u32, draw_mode: u32, side: u32 ) -> u32{
33
- return ( ( alpha_mode & ${mask_alpha} ) << ${shift_alpha} )
34
- | ( ( draw_mode & ${mask_primitive} ) << ${shift_primitive} )
35
- | ( ( side & ${mask_side} ) << ${shift_side} );
36
- }
37
- `
38
- );
39
-
40
- /**
41
- * @see chunk_rasterization_material_bucket
42
- * @param {number|TransparencyMode} alpha_mode
43
- * @param {number|ShadeDrawMode} draw_mode
44
- * @param {number|ShadeDrawSide} side
45
- * @return {number}
46
- */
47
- export function rasterization_material_bucket(alpha_mode, draw_mode, side) {
48
- assert.enum(alpha_mode, TransparencyMode);
49
- assert.enum(draw_mode, ShadeDrawMode);
50
- assert.enum(side, ShadeDrawSide);
51
-
52
- return ((alpha_mode & mask_alpha) << shift_alpha)
53
- | ((draw_mode & mask_primitive) << shift_primitive)
54
- | ((side & mask_side) << shift_side);
55
- }
1
+ import { assert } from "../../../../../core/assert.js";
2
+ import { ShadeDrawMode } from "../../../material/ShadeDrawMode.js";
3
+ import { ShadeDrawSide } from "../../../material/ShadeDrawSide.js";
4
+ import { TransparencyMode } from "../../../material/TransparencyMode.js";
5
+ import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
6
+ import {
7
+ RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE,
8
+ RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE
9
+ } from "./RASTERIZATION_BUCKET_LIMIT.js";
10
+
11
+ // A field of N bits is masked with (1 << N) - 1, not N + 1 (the two coincide only at N == 2,
12
+ // which is the value both of these enums happen to have today).
13
+ const mask_alpha = (1 << RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE) - 1;
14
+ const shift_alpha = 0;
15
+
16
+ const mask_primitive = (1 << RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE) - 1;
17
+ const shift_primitive = shift_alpha + RASTERIZATION_BUCKET_BIT_COUNT_ALPHA_MODE;
18
+
19
+ // the last field carries no mask: it is a boolean by construction, not an enum being narrowed
20
+ const shift_double_sided = shift_primitive + RASTERIZATION_BUCKET_BIT_COUNT_DRAW_MODE;
21
+
22
+ /**
23
+ * A bucket is a pipeline state, and the third field is the only thing a {@link ShadeDrawSide}
24
+ * still says about one: whether it culls at all. `Front` and `Back` land in the same bucket —
25
+ * a back-sided material is a front-sided one whose winding the vertex shader reverses — so a
26
+ * scene that mixes them draws in one pass, through one expansion chain.
27
+ *
28
+ * @see TransparencyMode
29
+ * @see ShadeDrawMode
30
+ * @see rasterization_material_bucket
31
+ * @type {CodeChunk}
32
+ */
33
+ export const chunk_rasterization_material_bucket = CodeChunk.from(
34
+ //language=WGSL
35
+ `
36
+ fn rasterization_material_bucket( alpha_mode: u32, draw_mode: u32, side: u32 ) -> u32{
37
+ let double_sided = u32( side == ${ShadeDrawSide.Double}u );
38
+
39
+ return ( ( alpha_mode & ${mask_alpha} ) << ${shift_alpha} )
40
+ | ( ( draw_mode & ${mask_primitive} ) << ${shift_primitive} )
41
+ | ( double_sided << ${shift_double_sided} );
42
+ }
43
+ `
44
+ );
45
+
46
+ /**
47
+ * @see chunk_rasterization_material_bucket
48
+ * @param {number|TransparencyMode} alpha_mode
49
+ * @param {number|ShadeDrawMode} draw_mode
50
+ * @param {number|ShadeDrawSide} side
51
+ * @return {number}
52
+ */
53
+ export function rasterization_material_bucket(alpha_mode, draw_mode, side) {
54
+ assert.enum(alpha_mode, TransparencyMode);
55
+ assert.enum(draw_mode, ShadeDrawMode);
56
+ assert.enum(side, ShadeDrawSide);
57
+
58
+ const double_sided = side === ShadeDrawSide.Double ? 1 : 0;
59
+
60
+ return ((alpha_mode & mask_alpha) << shift_alpha)
61
+ | ((draw_mode & mask_primitive) << shift_primitive)
62
+ | (double_sided << shift_double_sided);
63
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"graph_meshlets_rasterize.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;GAaG;AACH;IAX+B,KAAK;IACD,IAAI;IACZ,cAAc,EAA9B,MAAM;IACU,KAAK,EAArB,MAAM;IACwB,eAAe;IAC1B,aAAa,GAAhC,MAAM,EAAE;IACW,QAAQ,GAA3B,MAAM,EAAE;IACiB,eAAe;IACtB,aAAa,GAA/B,OAAO;IACN,CAAC,KAAK,EAAC,MAAM,EAAE,KAAK,EAAC,MAAM,EAAE,CAAC,CA0IzC"}
1
+ {"version":3,"file":"graph_meshlets_rasterize.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;GAaG;AACH;IAX+B,KAAK;IACD,IAAI;IACZ,cAAc,EAA9B,MAAM;IACU,KAAK,EAArB,MAAM;IACwB,eAAe;IAC1B,aAAa,GAAhC,MAAM,EAAE;IACW,QAAQ,GAA3B,MAAM,EAAE;IACiB,eAAe;IACtB,aAAa,GAA/B,OAAO;IACN,CAAC,KAAK,EAAC,MAAM,EAAE,KAAK,EAAC,MAAM,EAAE,CAAC,CA2IzC"}
@@ -117,6 +117,7 @@ export function graph_meshlets_rasterize({
117
117
  meshlet_data: scene.geometries.meshlets.buffer_data,
118
118
  meshlet_metadata: scene.geometries.meshlets.buffer_metadata,
119
119
  geometries: geometry_context.buffer_metadata,
120
+ materials: scene.materials.metadata_table.buffer,
120
121
  meshlets: input_meshlets,
121
122
  }
122
123
  });
@@ -1 +1 @@
1
- {"version":3,"file":"graph_rasterize_scene_fast.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js"],"names":[],"mappings":"AAkBA;;;;;;;;;;GAUG;AACH;;;;;;;IAFa;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAC,CAoJ3D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAJ+B,KAAK;IACC,GAAG;IACA,MAAM;SA8C7C"}
1
+ {"version":3,"file":"graph_rasterize_scene_fast.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js"],"names":[],"mappings":"AAmBA;;;;;;;;;;GAUG;AACH;;;;;;;IAFa;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAC,CA0I3D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAJ+B,KAAK;IACC,GAAG;IACA,MAAM;SA8C7C"}
@@ -12,6 +12,7 @@ import { graph_expand_meshes_to_meshlets } from "../expand/mesh/graph_expand_mes
12
12
  import { graph_vgeo_expand_if_enabled } from "../../geometry/virtual/runtime/graph_vgeo_expand_if_enabled.js";
13
13
  import { RasterizationCollectionType } from "../expand/RasterizationCollectionType.js";
14
14
  import { construct_primitive_state } from "../bucket/construct_primitive_state.js";
15
+ import { rasterization_opaque_buckets } from "../bucket/rasterization_opaque_buckets.js";
15
16
  import { graph_mesh_frustum_cull } from "../compute/graph_mesh_frustum_cull.js";
16
17
  import { graph_rasterize_meshes_alpha_tested } from "../native/graph_rasterize_meshes_alpha_tested.js";
17
18
  import { graph_extract_meshes_from_bucket } from "./graph_extract_meshes_from_bucket.js";
@@ -75,59 +76,49 @@ export function graph_rasterize_scene_fast_raw({
75
76
  // rasterize each active opaque bucket in a single pass, with no occlusion filtering
76
77
  let is_first_draw = true;
77
78
 
78
- for (const draw_mode of Object.values(ShadeDrawMode)) {
79
- for (const side of Object.values(ShadeDrawSide)) {
80
-
81
- const bucket_id = rasterization_material_bucket(TransparencyMode.Opaque, draw_mode, side);
82
-
83
- if (!active_buckets.has(bucket_id)) {
84
- // no matching materials, skip
85
- continue;
86
- }
87
-
88
- const gr_bucket_meshes = graph_extract_meshes_from_bucket({
89
- graph,
90
- buckets: gr_render_buckets,
91
- bucket_id,
92
- limits,
93
- });
94
-
95
- let gr_bucket_meshlets = graph_expand_meshes_to_meshlets({
96
- graph,
97
- input_meshes: gr_bucket_meshes,
98
- scene: scene_ctx,
99
- expected_output_size: limits.compute_buffer_size(RasterizationCollectionType.Meshlets),
100
- limits,
101
- });
102
-
103
- // the seam: this bucket's virtual-geometry instances select their cut and append it to
104
- // the same collection, which is the whole of what the rest of this function is told
105
- gr_bucket_meshlets = graph_vgeo_expand_if_enabled({
106
- graph,
107
- input_meshes: gr_bucket_meshes,
108
- output_meshlets: gr_bucket_meshlets,
109
- view: view_ctx,
110
- limits,
111
- });
112
-
113
- graph_record_stat(graph, limits.stats, RasterizationCollectionType.Meshlets, gr_bucket_meshlets);
114
-
115
- const primitive_state = construct_primitive_state(draw_mode, side, job.cull_policy);
116
-
117
- [target_depth, targets_color] = graph_meshlets_rasterize({
118
- graph,
119
- view: view_ctx,
120
- input_meshlets: gr_bucket_meshlets,
121
- depth: target_depth,
122
- color_targets: targets_color,
123
- pass_descriptor: job.opaque_pass,
124
- clear_targets: is_first_draw,
125
- primitive_state,
126
- viewport,
127
- });
128
-
129
- is_first_draw = false;
130
- }
79
+ for (const { draw_mode, side, bucket_id } of rasterization_opaque_buckets(active_buckets)) {
80
+ const gr_bucket_meshes = graph_extract_meshes_from_bucket({
81
+ graph,
82
+ buckets: gr_render_buckets,
83
+ bucket_id,
84
+ limits,
85
+ });
86
+
87
+ let gr_bucket_meshlets = graph_expand_meshes_to_meshlets({
88
+ graph,
89
+ input_meshes: gr_bucket_meshes,
90
+ scene: scene_ctx,
91
+ expected_output_size: limits.compute_buffer_size(RasterizationCollectionType.Meshlets),
92
+ limits,
93
+ });
94
+
95
+ // the seam: this bucket's virtual-geometry instances select their cut and append it to
96
+ // the same collection, which is the whole of what the rest of this function is told
97
+ gr_bucket_meshlets = graph_vgeo_expand_if_enabled({
98
+ graph,
99
+ input_meshes: gr_bucket_meshes,
100
+ output_meshlets: gr_bucket_meshlets,
101
+ view: view_ctx,
102
+ limits,
103
+ });
104
+
105
+ graph_record_stat(graph, limits.stats, RasterizationCollectionType.Meshlets, gr_bucket_meshlets);
106
+
107
+ const primitive_state = construct_primitive_state(draw_mode, side, job.cull_policy);
108
+
109
+ [target_depth, targets_color] = graph_meshlets_rasterize({
110
+ graph,
111
+ view: view_ctx,
112
+ input_meshlets: gr_bucket_meshlets,
113
+ depth: target_depth,
114
+ color_targets: targets_color,
115
+ pass_descriptor: job.opaque_pass,
116
+ clear_targets: is_first_draw,
117
+ primitive_state,
118
+ viewport,
119
+ });
120
+
121
+ is_first_draw = false;
131
122
  }
132
123
 
133
124
  // alpha-tested: reuse the existing native pass but skip HZB filtering by passing hzb=-1
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_forward_shade_standard_fragment_brick4.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js"],"names":[],"mappings":"AA4BA,qEAwJC;0BA3JyB,oCAAoC"}
1
+ {"version":3,"file":"chunk_forward_shade_standard_fragment_brick4.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js"],"names":[],"mappings":"AA6BA,qEA2JC;0BA9JyB,oCAAoC"}
@@ -1,4 +1,5 @@
1
1
  import { chunk_shade_standard_material_direct } from "../../deferred/chunk_shade_standard_material_direct.js";
2
+ import { chunk_material_draw_side } from "../../material/chunk_material_draw_side.js";
2
3
  import { chunk_decode_tangent_normal } from "../../shader/chunk/geometry/normal/chunk_decode_tangent_normal.js";
3
4
  import { INDIRECT_LIGHT_INTENSITY } from "../../deferred/INDIRECT_LIGHT_INTENSITY.js";
4
5
  import {
@@ -38,8 +39,10 @@ fn forward_shade_standard_fragment(
38
39
  let t_normal = decode_tangent_normal(textureSample(texture_normal, texture_normal_sampler, vert.uv));
39
40
  var world_shading_normal:vec3<f32> = normalize( world_tangent_frame * t_normal );
40
41
 
41
- // flip normal if fragment is back-facing,
42
- if(!front_facing) {
42
+ // flip the normal when looking at the surface's back. The raw front_facing cannot say:
43
+ // a back-sided material emits its winding reversed on purpose, so its "front" faces
44
+ // are the surface's back.
45
+ if(!material_fragment_faces_front(front_facing, material_info.draw_side)) {
43
46
  world_shading_normal = -world_shading_normal;
44
47
  }
45
48
 
@@ -177,5 +180,6 @@ fn forward_shade_standard_fragment(
177
180
  chunk_compute_indirect_specular,
178
181
  chunk_brick4_sample_forward_indirect,
179
182
  chunk_compute_specular_occlusion,
183
+ chunk_material_draw_side,
180
184
  ]
181
185
  )
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_forward_shade_standard_fragment_ibl.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js"],"names":[],"mappings":"AA2BA;;;GAGG;AACH,kEA6IC;0BApJyB,oCAAoC"}
1
+ {"version":3,"file":"chunk_forward_shade_standard_fragment_ibl.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js"],"names":[],"mappings":"AA4BA;;;GAGG;AACH,kEAgJC;0BAvJyB,oCAAoC"}
@@ -1,4 +1,5 @@
1
1
  import { chunk_shade_standard_material_direct } from "../../deferred/chunk_shade_standard_material_direct.js";
2
+ import { chunk_material_draw_side } from "../../material/chunk_material_draw_side.js";
2
3
  import { chunk_decode_tangent_normal } from "../../shader/chunk/geometry/normal/chunk_decode_tangent_normal.js";
3
4
  import { chunk_get_ibl_irradiance } from "../../deferred/indirect/chunk_get_ibl_irradiance.js";
4
5
  import { chunk_get_ibl_radiance } from "../../deferred/indirect/chunk_get_ibl_radiance.js";
@@ -41,8 +42,10 @@ fn forward_shade_standard_fragment(
41
42
  let t_normal = decode_tangent_normal(textureSample(texture_normal, texture_normal_sampler, vert.uv));
42
43
  var world_shading_normal:vec3<f32> = normalize( world_tangent_frame * t_normal );
43
44
 
44
- // flip normal if fragment is back-facing,
45
- if(!front_facing) {
45
+ // flip the normal when looking at the surface's back. The raw front_facing cannot say:
46
+ // a back-sided material emits its winding reversed on purpose, so its "front" faces
47
+ // are the surface's back.
48
+ if(!material_fragment_faces_front(front_facing, material_info.draw_side)) {
46
49
  world_shading_normal = -world_shading_normal;
47
50
  }
48
51
 
@@ -169,5 +172,6 @@ fn forward_shade_standard_fragment(
169
172
  chunk_get_ibl_radiance,
170
173
  chunk_get_ibl_irradiance,
171
174
  chunk_compute_specular_occlusion,
175
+ chunk_material_draw_side,
172
176
  ]
173
177
  )
@@ -1 +1 @@
1
- {"version":3,"file":"vertex_shader_chunk.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/forward/vertex_shader_chunk.js"],"names":[],"mappings":"AAUA,4CAoDE;0BAvDwB,oCAAoC"}
1
+ {"version":3,"file":"vertex_shader_chunk.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/forward/vertex_shader_chunk.js"],"names":[],"mappings":"AAeA,4CAgEE;0BAnEwB,oCAAoC"}
@@ -1,7 +1,12 @@
1
+ import { chunk_triangle_winding_is_reversed } from "../chunk_triangle_winding_is_reversed.js";
2
+ import { chunk_node3d_flags } from "../../scene/chunk_node3d_flags.js";
1
3
  import { chunk_scene_database_access } from "../../scene/chunk_scene_database_access.js";
2
4
  import {
3
5
  chunk_compute_normal_matrix_from_m4
4
6
  } from "../../shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js";
7
+ import {
8
+ chunk_triangle_list_reverse_winding
9
+ } from "../../shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js";
5
10
  import {
6
11
  chunk_read_meshlet_vertex_by_draw_index
7
12
  } from "../../shader/chunk/geometry/meshlet/chunk_read_meshlet_vertex_by_draw_index.js";
@@ -26,9 +31,16 @@ fn main(
26
31
  let mesh = scene_read_mesh(&scene_database, meshlet_def.mesh);
27
32
  let node = scene_read_node(&scene_database, mesh.node);
28
33
 
34
+ // the tangent frame's handedness turns on the reflection alone: looking at a surface's back
35
+ // does not change which way its +V runs, and a back-sided material is only a way of looking
36
+ let is_mirrored = node3d_global_is_mirrored(node);
37
+
29
38
  let geo_vertex = read_meshlet_vertex_by_draw_index(
30
39
  meshlet_header,
31
- meshlet_vertex_id,
40
+ triangle_list_reverse_winding(
41
+ meshlet_vertex_id,
42
+ triangle_winding_is_reversed(node, material_info.draw_side)
43
+ ),
32
44
  );
33
45
 
34
46
  let instance_matrix = node.global;
@@ -47,7 +59,9 @@ fn main(
47
59
  output.normal = normalize(normal_model_matrix * geo_vertex.normal);
48
60
 
49
61
  let geometry_tangent = geo_vertex.tangent;
50
- let world_tangent = vec4( normalize( normal_model_matrix * geometry_tangent.xyz ), geometry_tangent.w );
62
+ // a reflection changes the tangent frame's handedness — see NODE3D_GLOBAL_FLAG_MIRRORED
63
+ let tangent_handedness = select(geometry_tangent.w, -geometry_tangent.w, is_mirrored);
64
+ let world_tangent = vec4( normalize( normal_model_matrix * geometry_tangent.xyz ), tangent_handedness );
51
65
  output.tangent = world_tangent;
52
66
 
53
67
  output.color = geo_vertex.color * material_info.albedo_color.rgb;
@@ -59,5 +73,8 @@ fn main(
59
73
  chunk_compute_normal_matrix_from_m4,
60
74
  chunk_read_meshlet_vertex_by_draw_index,
61
75
  chunk_scene_database_access,
76
+ chunk_node3d_flags,
77
+ chunk_triangle_winding_is_reversed,
78
+ chunk_triangle_list_reverse_winding,
62
79
  ]
63
80
  );