@woosh/meep-engine 3.11.2 → 3.12.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 (551) hide show
  1. package/README.md +14 -18
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/editor/SelectionVisualizer.js +127 -127
  4. package/editor/entity_world_bounds.js +27 -27
  5. package/editor/particles/rebuildParticleEmitter.js +31 -31
  6. package/editor/process/SymbolicDisplayProcess.js +1 -1
  7. package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
  8. package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
  9. package/editor/prototypeEditorShell.js +156 -156
  10. package/editor/selection/editor_pick.js +130 -130
  11. package/editor/selection/screen_rect_frustum.js +119 -119
  12. package/editor/tools/v2/TransformControls.js +971 -971
  13. package/package.json +1 -1
  14. package/src/engine/Engine.d.ts +3 -3
  15. package/src/engine/Engine.d.ts.map +1 -1
  16. package/src/engine/Engine.js +726 -726
  17. package/src/engine/EngineHarness.d.ts +1 -1
  18. package/src/engine/EngineHarness.js +590 -590
  19. package/src/engine/ecs/HIERARCHY_REVIEW.md +717 -717
  20. package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts +1 -1
  21. package/src/engine/ecs/terrain/ecs/BuildLightTexture.js +27 -27
  22. package/src/engine/ecs/terrain/ecs/Terrain.d.ts +1 -5
  23. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  24. package/src/engine/ecs/terrain/ecs/Terrain.js +790 -790
  25. package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +129 -129
  26. package/src/engine/graphics/ecs/camera/camera_find_active.d.ts +1 -1
  27. package/src/engine/graphics/ecs/camera/camera_find_active.js +28 -28
  28. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +1 -1
  29. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +428 -428
  30. package/src/engine/graphics/ecs/water/Water.d.ts +1 -1
  31. package/src/engine/graphics/ecs/water/Water.js +104 -104
  32. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +1 -1
  33. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1 -1
  34. package/src/engine/graphics3/AnimationGraphSystem.d.ts +65 -0
  35. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -0
  36. package/src/engine/graphics3/AnimationGraphSystem.js +329 -0
  37. package/src/engine/graphics3/AnimationGraphSystem3.d.ts +6 -61
  38. package/src/engine/graphics3/AnimationGraphSystem3.d.ts.map +1 -1
  39. package/src/engine/graphics3/AnimationGraphSystem3.js +6 -325
  40. package/src/engine/graphics3/AnimationSystem.d.ts +76 -0
  41. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -0
  42. package/src/engine/graphics3/AnimationSystem.js +352 -0
  43. package/src/engine/graphics3/AnimationSystem3.d.ts +6 -72
  44. package/src/engine/graphics3/AnimationSystem3.d.ts.map +1 -1
  45. package/src/engine/graphics3/AnimationSystem3.js +6 -348
  46. package/src/engine/graphics3/CameraSystem.d.ts +49 -0
  47. package/src/engine/graphics3/CameraSystem.d.ts.map +1 -0
  48. package/src/engine/graphics3/CameraSystem.js +170 -0
  49. package/src/engine/graphics3/CameraSystem3.d.ts +6 -45
  50. package/src/engine/graphics3/CameraSystem3.d.ts.map +1 -1
  51. package/src/engine/graphics3/CameraSystem3.js +6 -166
  52. package/src/engine/graphics3/DebugDrawSystem.d.ts +72 -0
  53. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -0
  54. package/src/engine/graphics3/DebugDrawSystem.js +205 -0
  55. package/src/engine/graphics3/DebugDrawSystem3.d.ts +6 -68
  56. package/src/engine/graphics3/DebugDrawSystem3.d.ts.map +1 -1
  57. package/src/engine/graphics3/DebugDrawSystem3.js +6 -201
  58. package/src/engine/graphics3/DecalSystem.d.ts +81 -0
  59. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -0
  60. package/src/engine/graphics3/DecalSystem.js +441 -0
  61. package/src/engine/graphics3/DecalSystem3.d.ts +6 -77
  62. package/src/engine/graphics3/DecalSystem3.d.ts.map +1 -1
  63. package/src/engine/graphics3/DecalSystem3.js +6 -437
  64. package/src/engine/graphics3/FogOfWarSystem.d.ts +74 -0
  65. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -0
  66. package/src/engine/graphics3/FogOfWarSystem.js +265 -0
  67. package/src/engine/graphics3/FogOfWarSystem3.d.ts +6 -70
  68. package/src/engine/graphics3/FogOfWarSystem3.d.ts.map +1 -1
  69. package/src/engine/graphics3/FogOfWarSystem3.js +6 -261
  70. package/src/engine/graphics3/GraphicsEngine.d.ts +340 -0
  71. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -0
  72. package/src/engine/graphics3/GraphicsEngine.js +790 -0
  73. package/src/engine/graphics3/GraphicsEngine3.d.ts +6 -336
  74. package/src/engine/graphics3/GraphicsEngine3.d.ts.map +1 -1
  75. package/src/engine/graphics3/GraphicsEngine3.js +6 -786
  76. package/src/engine/graphics3/HighlightSystem.d.ts +82 -0
  77. package/src/engine/graphics3/HighlightSystem.d.ts.map +1 -0
  78. package/src/engine/graphics3/HighlightSystem.js +241 -0
  79. package/src/engine/graphics3/HighlightSystem3.d.ts +6 -78
  80. package/src/engine/graphics3/HighlightSystem3.d.ts.map +1 -1
  81. package/src/engine/graphics3/HighlightSystem3.js +6 -237
  82. package/src/engine/graphics3/LightSystem.d.ts +40 -0
  83. package/src/engine/graphics3/LightSystem.d.ts.map +1 -0
  84. package/src/engine/graphics3/LightSystem.js +211 -0
  85. package/src/engine/graphics3/LightSystem3.d.ts +6 -36
  86. package/src/engine/graphics3/LightSystem3.d.ts.map +1 -1
  87. package/src/engine/graphics3/LightSystem3.js +6 -207
  88. package/src/engine/graphics3/MeshSystem.d.ts +106 -0
  89. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -0
  90. package/src/engine/graphics3/MeshSystem.js +647 -0
  91. package/src/engine/graphics3/MeshSystem3.d.ts +6 -102
  92. package/src/engine/graphics3/MeshSystem3.d.ts.map +1 -1
  93. package/src/engine/graphics3/MeshSystem3.js +6 -642
  94. package/src/engine/graphics3/ParticipatingMedia.d.ts +2 -2
  95. package/src/engine/graphics3/ParticipatingMedia.js +203 -203
  96. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts +87 -0
  97. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -0
  98. package/src/engine/graphics3/ParticipatingMediaSystem.js +184 -0
  99. package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts +6 -83
  100. package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts.map +1 -1
  101. package/src/engine/graphics3/ParticipatingMediaSystem3.js +6 -180
  102. package/src/engine/graphics3/ParticleEmitterSystem.d.ts +76 -0
  103. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -0
  104. package/src/engine/graphics3/ParticleEmitterSystem.js +289 -0
  105. package/src/engine/graphics3/ParticleEmitterSystem3.d.ts +6 -72
  106. package/src/engine/graphics3/ParticleEmitterSystem3.d.ts.map +1 -1
  107. package/src/engine/graphics3/ParticleEmitterSystem3.js +6 -285
  108. package/src/engine/graphics3/PathDisplaySystem.d.ts +70 -0
  109. package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -0
  110. package/src/engine/graphics3/PathDisplaySystem.js +309 -0
  111. package/src/engine/graphics3/PathDisplaySystem3.d.ts +6 -66
  112. package/src/engine/graphics3/PathDisplaySystem3.d.ts.map +1 -1
  113. package/src/engine/graphics3/PathDisplaySystem3.js +6 -305
  114. package/src/engine/graphics3/Pickable.d.ts +1 -1
  115. package/src/engine/graphics3/Pickable.js +65 -65
  116. package/src/engine/graphics3/PickingQuery.d.ts +1 -1
  117. package/src/engine/graphics3/PickingQuery.js +48 -48
  118. package/src/engine/graphics3/PickingSystem.d.ts +67 -0
  119. package/src/engine/graphics3/PickingSystem.d.ts.map +1 -0
  120. package/src/engine/graphics3/PickingSystem.js +273 -0
  121. package/src/engine/graphics3/PickingSystem3.d.ts +6 -63
  122. package/src/engine/graphics3/PickingSystem3.d.ts.map +1 -1
  123. package/src/engine/graphics3/PickingSystem3.js +6 -269
  124. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +47 -0
  125. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -0
  126. package/src/engine/graphics3/ShadedGeometrySystem.js +169 -0
  127. package/src/engine/graphics3/ShadedGeometrySystem3.d.ts +6 -43
  128. package/src/engine/graphics3/ShadedGeometrySystem3.d.ts.map +1 -1
  129. package/src/engine/graphics3/ShadedGeometrySystem3.js +6 -165
  130. package/src/engine/graphics3/TerrainSystem.d.ts +80 -0
  131. package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -0
  132. package/src/engine/graphics3/TerrainSystem.js +566 -0
  133. package/src/engine/graphics3/TerrainSystem3.d.ts +6 -76
  134. package/src/engine/graphics3/TerrainSystem3.d.ts.map +1 -1
  135. package/src/engine/graphics3/TerrainSystem3.js +6 -562
  136. package/src/engine/graphics3/TooltipComponentSystem.d.ts +65 -0
  137. package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -0
  138. package/src/engine/graphics3/TooltipComponentSystem.js +328 -0
  139. package/src/engine/graphics3/TooltipComponentSystem3.d.ts +6 -61
  140. package/src/engine/graphics3/TooltipComponentSystem3.d.ts.map +1 -1
  141. package/src/engine/graphics3/TooltipComponentSystem3.js +6 -324
  142. package/src/engine/graphics3/Trail3DSystem.d.ts +73 -0
  143. package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -0
  144. package/src/engine/graphics3/Trail3DSystem.js +221 -0
  145. package/src/engine/graphics3/Trail3DSystem3.d.ts +6 -69
  146. package/src/engine/graphics3/Trail3DSystem3.d.ts.map +1 -1
  147. package/src/engine/graphics3/Trail3DSystem3.js +6 -217
  148. package/src/engine/graphics3/VolumetricLightMap.d.ts +2 -2
  149. package/src/engine/graphics3/VolumetricLightMap.js +2 -2
  150. package/src/engine/graphics3/VolumetricLightMapSystem.d.ts +98 -0
  151. package/src/engine/graphics3/VolumetricLightMapSystem.d.ts.map +1 -0
  152. package/src/engine/graphics3/VolumetricLightMapSystem.js +261 -0
  153. package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts +6 -94
  154. package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts.map +1 -1
  155. package/src/engine/graphics3/VolumetricLightMapSystem3.js +10 -261
  156. package/src/engine/graphics3/WaterSystem.d.ts +59 -0
  157. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -0
  158. package/src/engine/graphics3/WaterSystem.js +293 -0
  159. package/src/engine/graphics3/WaterSystem3.d.ts +6 -55
  160. package/src/engine/graphics3/WaterSystem3.d.ts.map +1 -1
  161. package/src/engine/graphics3/WaterSystem3.js +6 -289
  162. package/src/engine/graphics3/animation/AnimationGraphController.d.ts +1 -1
  163. package/src/engine/graphics3/animation/AnimationGraphController.js +518 -518
  164. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +1 -1
  165. package/src/engine/graphics3/animation/ClipListPlayer.js +263 -263
  166. package/src/engine/graphics3/animation/ClipPlayback.d.ts +2 -2
  167. package/src/engine/graphics3/animation/ClipPlayback.js +84 -84
  168. package/src/engine/graphics3/decal/graph_build_decal_clusters.d.ts.map +1 -1
  169. package/src/engine/graphics3/decal/graph_build_decal_clusters.js +6 -8
  170. package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts +0 -7
  171. package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts.map +1 -1
  172. package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
  173. package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts +0 -4
  174. package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts.map +1 -1
  175. package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
  176. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +2 -2
  177. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
  178. package/src/engine/graphics3/highlight/pack_highlight_table.js +74 -74
  179. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +1 -1
  180. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +101 -101
  181. package/src/engine/graphics3/preview/make_model_thumbnail.d.ts +3 -3
  182. package/src/engine/graphics3/preview/make_model_thumbnail.d.ts.map +1 -1
  183. package/src/engine/graphics3/preview/make_model_thumbnail.js +48 -48
  184. package/src/engine/graphics3/shade_camera_projection_ray.d.ts +1 -1
  185. package/src/engine/graphics3/shade_camera_projection_ray.js +77 -77
  186. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +1 -1
  187. package/src/engine/graphics3/shade_node_to_entity_composition.js +84 -84
  188. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts +16 -2
  189. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts.map +1 -1
  190. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +28 -4
  191. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +1 -1
  192. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
  193. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +5 -2
  194. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +564 -451
  195. package/src/shade/device/ShadeGPUCommandContext.d.ts +18 -2
  196. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  197. package/src/shade/device/ShadeGPUCommandContext.js +994 -940
  198. package/src/shade/device/immediate_data_supported.d.ts +33 -0
  199. package/src/shade/device/immediate_data_supported.d.ts.map +1 -0
  200. package/src/shade/device/immediate_data_supported.js +53 -0
  201. package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts +18 -0
  202. package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts.map +1 -1
  203. package/src/shade/device/mock/SoftwareGPUCommandEncoder.js +24 -0
  204. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts +7 -0
  205. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts.map +1 -1
  206. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.js +49 -1
  207. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  208. package/src/shade/device/mock/SoftwareGPUDevice.js +20 -2
  209. package/src/shade/device/mock/SoftwareGPUImmediateData.d.ts +65 -0
  210. package/src/shade/device/mock/SoftwareGPUImmediateData.d.ts.map +1 -0
  211. package/src/shade/device/mock/SoftwareGPUImmediateData.js +160 -0
  212. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts +7 -0
  213. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts.map +1 -1
  214. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.js +50 -0
  215. package/src/shade/device/mock/pipeline_immediate_size.d.ts +11 -0
  216. package/src/shade/device/mock/pipeline_immediate_size.d.ts.map +1 -0
  217. package/src/shade/device/mock/pipeline_immediate_size.js +18 -0
  218. package/src/shade/device/pipeline/PipelineLayoutManager.d.ts.map +1 -1
  219. package/src/shade/device/pipeline/PipelineLayoutManager.js +1 -0
  220. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
  221. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +0 -1
  222. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.d.ts.map +1 -1
  223. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +0 -1
  224. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
  225. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +133 -134
  226. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +202 -202
  227. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +249 -249
  228. package/src/shade/renderer/GraphicsContext.d.ts +9 -2
  229. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  230. package/src/shade/renderer/GraphicsContext.js +13 -1
  231. package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSETS.js +1 -1
  232. package/src/shade/renderer/animation/pose/PosePlayback.d.ts +2 -1
  233. package/src/shade/renderer/animation/pose/PosePlayback.d.ts.map +1 -1
  234. package/src/shade/renderer/animation/pose/PosePlayback.js +2 -1
  235. package/src/shade/renderer/animation/shader_animation_apply.d.ts.map +1 -1
  236. package/src/shade/renderer/animation/shader_animation_apply.js +128 -129
  237. package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts.map +1 -1
  238. package/src/shade/renderer/animation/shader_animation_pose_resolve.js +176 -177
  239. package/src/shade/renderer/animation/shader_animation_tick.d.ts.map +1 -1
  240. package/src/shade/renderer/animation/shader_animation_tick.js +125 -126
  241. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.d.ts.map +1 -1
  242. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.js +98 -99
  243. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
  244. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +212 -213
  245. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts.map +1 -1
  246. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.js +120 -121
  247. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.d.ts.map +1 -1
  248. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.js +75 -76
  249. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
  250. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +371 -372
  251. package/src/shade/renderer/animation/skinning/shader_skin_matrix_prep.d.ts.map +1 -1
  252. package/src/shade/renderer/animation/skinning/shader_skin_matrix_prep.js +104 -105
  253. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  254. package/src/shade/renderer/atmosphere/GPUSky.js +145 -142
  255. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts +34 -0
  256. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts.map +1 -0
  257. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.js +36 -0
  258. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.d.ts +20 -0
  259. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.d.ts.map +1 -0
  260. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.js +25 -0
  261. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts +14 -1
  262. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts.map +1 -1
  263. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.js +163 -177
  264. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.d.ts +20 -0
  265. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.d.ts.map +1 -0
  266. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.js +46 -0
  267. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.d.ts +11 -1
  268. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.d.ts.map +1 -1
  269. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.js +57 -27
  270. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.d.ts +19 -1
  271. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.d.ts.map +1 -1
  272. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.js +69 -33
  273. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.d.ts +13 -0
  274. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.d.ts.map +1 -1
  275. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.js +35 -35
  276. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.d.ts +13 -0
  277. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.d.ts.map +1 -0
  278. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.js +38 -0
  279. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.d.ts +17 -0
  280. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.d.ts.map +1 -0
  281. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.js +29 -0
  282. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.d.ts +21 -0
  283. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.d.ts.map +1 -0
  284. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.js +42 -0
  285. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts +2 -2
  286. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts.map +1 -1
  287. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +164 -84
  288. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.d.ts.map +1 -1
  289. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +215 -204
  290. package/src/shade/renderer/atmosphere/shader_transmittance_lut.d.ts.map +1 -1
  291. package/src/shade/renderer/atmosphere/shader_transmittance_lut.js +79 -67
  292. package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +136 -136
  293. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  294. package/src/shade/renderer/buffer/table/GPUDatabase.js +2 -3
  295. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +319 -319
  296. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
  297. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +41 -42
  298. package/src/shade/renderer/buffer/util/shader_buffer_intra_copy_regions.d.ts.map +1 -1
  299. package/src/shade/renderer/buffer/util/shader_buffer_intra_copy_regions.js +83 -84
  300. package/src/shade/renderer/dynamic/shader_dynamic_mesh.d.ts.map +1 -1
  301. package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +177 -170
  302. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +918 -918
  303. package/src/shade/renderer/geometry/bvh/record_blas_refit.js +4 -4
  304. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.d.ts.map +1 -1
  305. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.js +121 -122
  306. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +774 -774
  307. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts +1 -1
  308. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
  309. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +69 -70
  310. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +367 -367
  311. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +184 -184
  312. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +1115 -1115
  313. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +217 -217
  314. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  315. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +142 -143
  316. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
  317. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +0 -1
  318. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
  319. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +140 -141
  320. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
  321. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +0 -1
  322. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
  323. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +0 -1
  324. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
  325. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +191 -198
  326. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.d.ts +0 -6
  327. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.d.ts.map +1 -1
  328. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.js +120 -120
  329. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.d.ts +0 -4
  330. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.d.ts.map +1 -1
  331. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.js +112 -112
  332. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  333. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +10 -9
  334. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts +0 -6
  335. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts.map +1 -1
  336. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.js +1 -1
  337. package/src/shade/renderer/lightmap/bake/raster/shader_lightmap_to_viz_buffer.js +222 -222
  338. package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_tile_composit.js +81 -81
  339. package/src/shade/renderer/material/GPUMaterialContext.js +380 -380
  340. package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
  341. package/src/shade/renderer/object_property/shader_object_property_process.d.ts.map +1 -1
  342. package/src/shade/renderer/object_property/shader_object_property_process.js +83 -84
  343. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts.map +1 -1
  344. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.js +57 -58
  345. package/src/shade/renderer/particles/prototypeParticleSystem.js +2 -3
  346. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  347. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +117 -118
  348. package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
  349. package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +77 -79
  350. package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
  351. package/src/shade/renderer/particles/shaders/shader_particle_render.js +190 -183
  352. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  353. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +99 -100
  354. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
  355. package/src/shade/renderer/particles/sort/shader_particle_sort.js +158 -161
  356. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +184 -184
  357. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +119 -119
  358. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +3 -4
  359. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
  360. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +266 -267
  361. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
  362. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +270 -271
  363. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  364. package/src/shade/renderer/postprocess/gtao/GTAO.js +4 -0
  365. package/src/shade/renderer/postprocess/nss/shader_nss_concat.d.ts.map +1 -1
  366. package/src/shade/renderer/postprocess/nss/shader_nss_concat.js +68 -69
  367. package/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.d.ts.map +1 -1
  368. package/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.js +225 -226
  369. package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.d.ts.map +1 -1
  370. package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js +49 -50
  371. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
  372. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +291 -292
  373. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.d.ts.map +1 -1
  374. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +230 -231
  375. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +16 -2
  376. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +1 -1
  377. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.js +12 -12
  378. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  379. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +341 -345
  380. package/src/shade/renderer/rasterize/bucket/shader_count_meshlets_by_material.d.ts.map +1 -1
  381. package/src/shade/renderer/rasterize/bucket/shader_count_meshlets_by_material.js +68 -69
  382. package/src/shade/renderer/rasterize/bucket/shader_make_meshlet_indirect_draw_commands_by_material.d.ts.map +1 -1
  383. package/src/shade/renderer/rasterize/bucket/shader_make_meshlet_indirect_draw_commands_by_material.js +59 -60
  384. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  385. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  386. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +57 -57
  387. package/src/shade/renderer/rasterize/bucket/shader_sort_meshlets_by_material.d.ts.map +1 -1
  388. package/src/shade/renderer/rasterize/bucket/shader_sort_meshlets_by_material.js +64 -65
  389. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
  390. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +168 -169
  391. package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.d.ts.map +1 -1
  392. package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.js +160 -161
  393. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  394. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +109 -110
  395. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  396. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +115 -116
  397. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_classify_bucket.d.ts.map +1 -1
  398. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_classify_bucket.js +139 -140
  399. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_count_by_rasterization_bucket.d.ts.map +1 -1
  400. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_count_by_rasterization_bucket.js +91 -92
  401. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.d.ts.map +1 -1
  402. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.js +88 -89
  403. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  404. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +90 -91
  405. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  406. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +65 -66
  407. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  408. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +89 -90
  409. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
  410. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +169 -170
  411. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  412. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +7 -3
  413. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  414. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +89 -90
  415. package/src/shade/renderer/rasterize/expand/mesh/shader_meshes_to_meshlet_counts.d.ts.map +1 -1
  416. package/src/shade/renderer/rasterize/expand/mesh/shader_meshes_to_meshlet_counts.js +61 -62
  417. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  418. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +153 -154
  419. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  420. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +77 -81
  421. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +144 -144
  422. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +88 -88
  423. package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +217 -217
  424. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +179 -179
  425. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +178 -178
  426. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +194 -194
  427. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_opaque_pass_descriptor.js +76 -76
  428. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  429. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +5 -1
  430. package/src/shade/renderer/restir/di/shader_restir_di_denoise.d.ts.map +1 -1
  431. package/src/shade/renderer/restir/di/shader_restir_di_denoise.js +136 -137
  432. package/src/shade/renderer/restir/di/shader_restir_di_resample.d.ts.map +1 -1
  433. package/src/shade/renderer/restir/di/shader_restir_di_resample.js +129 -130
  434. package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
  435. package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +99 -100
  436. package/src/shade/renderer/restir/di/shader_restir_di_spatial.d.ts.map +1 -1
  437. package/src/shade/renderer/restir/di/shader_restir_di_spatial.js +116 -117
  438. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +383 -383
  439. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy_naive.js +123 -123
  440. package/src/shade/renderer/scene/hierarchy/shader_nodes_record_input_positions.d.ts.map +1 -1
  441. package/src/shade/renderer/scene/hierarchy/shader_nodes_record_input_positions.js +64 -65
  442. package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy.d.ts.map +1 -1
  443. package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy.js +372 -373
  444. package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy_naive.d.ts.map +1 -1
  445. package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy_naive.js +111 -112
  446. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
  447. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +0 -1
  448. package/src/shade/renderer/shader/ComputeShader.d.ts +24 -3
  449. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  450. package/src/shade/renderer/shader/ComputeShader.js +350 -292
  451. package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
  452. package/src/shade/renderer/shader/ImageShader.js +217 -214
  453. package/src/shade/renderer/shader/ShaderDescriptor.d.ts +5 -0
  454. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  455. package/src/shade/renderer/shader/ShaderDescriptor.js +46 -0
  456. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.d.ts +18 -0
  457. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.d.ts.map +1 -0
  458. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.js +32 -0
  459. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.d.ts +7 -0
  460. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.d.ts.map +1 -1
  461. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.js +17 -6
  462. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.d.ts +21 -0
  463. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.d.ts.map +1 -0
  464. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.js +69 -0
  465. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.d.ts +9 -0
  466. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.d.ts.map +1 -0
  467. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.js +22 -0
  468. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.d.ts +16 -0
  469. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.d.ts.map +1 -0
  470. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.js +41 -0
  471. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.d.ts +11 -0
  472. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.d.ts.map +1 -1
  473. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.js +15 -19
  474. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.d.ts +23 -0
  475. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.d.ts.map +1 -0
  476. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.js +44 -0
  477. package/src/shade/renderer/shader/chunk/geometry/octahedron/chunk_uv_octahedral_unit_decode.d.ts.map +1 -1
  478. package/src/shade/renderer/shader/chunk/geometry/octahedron/chunk_uv_octahedral_unit_decode.js +1 -4
  479. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts +7 -1
  480. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts.map +1 -1
  481. package/src/shade/renderer/shader/compiler/CodeChunk.js +37 -2
  482. package/src/shade/renderer/shader/graph/compute/compute_binding_read_names.d.ts.map +1 -1
  483. package/src/shade/renderer/shader/graph/compute/compute_binding_read_names.js +6 -0
  484. package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.js +1 -1
  485. package/src/shade/renderer/shader/graph/compute/graph_compute_pass.js +1 -1
  486. package/src/shade/renderer/shader/graph/graph_image_pass.js +1 -1
  487. package/src/shade/renderer/shader/graph/graph_prepare_bindings.d.ts.map +1 -1
  488. package/src/shade/renderer/shader/graph/graph_prepare_bindings.js +7 -0
  489. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.d.ts +3 -1
  490. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.d.ts.map +1 -1
  491. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.js +12 -1
  492. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
  493. package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +1 -0
  494. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.d.ts +21 -0
  495. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.d.ts.map +1 -0
  496. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.js +21 -0
  497. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts +59 -1
  498. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  499. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +195 -2
  500. package/src/shade/renderer/shader/type/type_has_arrays.d.ts +14 -0
  501. package/src/shade/renderer/shader/type/type_has_arrays.d.ts.map +1 -0
  502. package/src/shade/renderer/shader/type/type_has_arrays.js +33 -0
  503. package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.d.ts +47 -0
  504. package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.d.ts.map +1 -0
  505. package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.js +448 -0
  506. package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.js +3 -3
  507. package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +3 -3
  508. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +2 -2
  509. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +4 -4
  510. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.d.ts.map +1 -1
  511. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +231 -232
  512. package/src/shade/renderer/view/GPUViewSkyContext.d.ts.map +1 -1
  513. package/src/shade/renderer/view/GPUViewSkyContext.js +169 -173
  514. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +1 -1
  515. package/src/shade/renderer/volumetrics/NOTES.md +238 -0
  516. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.js +145 -145
  517. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts.map +1 -1
  518. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.js +38 -15
  519. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +14 -2
  520. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  521. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +591 -577
  522. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +17 -0
  523. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  524. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +20 -2
  525. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  526. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +29 -18
  527. package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.js +260 -260
  528. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts +53 -3
  529. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts.map +1 -1
  530. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.js +175 -59
  531. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts +0 -2
  532. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts.map +1 -1
  533. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +17 -6
  534. package/src/shade/renderer/water/shader_water.js +246 -246
  535. package/src/shade/vitest.setup.mjs +1 -1
  536. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +291 -291
  537. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -1
  538. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  539. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +1325 -1297
  540. package/src/view/minimap/Minimap.d.ts +2 -2
  541. package/src/view/minimap/Minimap.d.ts.map +1 -1
  542. package/src/view/minimap/Minimap.js +225 -225
  543. package/src/view/minimap/dom/MinimapCameraView.d.ts +3 -3
  544. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  545. package/src/view/minimap/dom/MinimapCameraView.js +206 -206
  546. package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.d.ts +0 -3
  547. package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.d.ts.map +0 -1
  548. package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.js +0 -20
  549. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts +0 -2
  550. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts.map +0 -1
  551. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.js +0 -1
@@ -1,372 +1,371 @@
1
- import { mat4x4f, u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
- import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
3
- import {
4
- MESHLET_METADATA_FLAGS
5
- } from "../../geometry/meshlet/encoding/MESHLET_METADATA_FLAGS.js";
6
- import {
7
- MESHLET_METADATA_STRUCT
8
- } from "../../geometry/meshlet/encoding/MESHLET_METADATA_STRUCT.js";
9
- import { chunk_scene_database_access } from "../../scene/chunk_scene_database_access.js";
10
- import { chunk_mat4_inverse } from "../../shader/chunk/geometry/mat4/chunk_mat4_inverse.js";
11
- import {
12
- chunk_meshlet_compute_attribute_section_offset
13
- } from "../../shader/chunk/geometry/meshlet/chunk_meshlet_compute_attribute_section_offset.js";
14
- import {
15
- chunk_decode_vertex_normal
16
- } from "../../shader/chunk/geometry/normal/chunk_decode_vertex_normal.js";
17
- import {
18
- chunk_encode_vertex_normal
19
- } from "../../shader/chunk/geometry/normal/chunk_encode_vertex_normal.js";
20
- import {
21
- chunk_decode_vertex_tangent
22
- } from "../../shader/chunk/geometry/normal/tangent/chunk_decode_vertex_tangent.js";
23
- import {
24
- chunk_encode_vertex_tangent
25
- } from "../../shader/chunk/geometry/normal/tangent/chunk_encode_vertex_tangent.js";
26
- import {
27
- chunk_dual_quat_transform_direction
28
- } from "../../shader/chunk/geometry/quaternion/dual/chunk_dual_quat_transform_direction.js";
29
- import {
30
- chunk_dual_quat_transform_point
31
- } from "../../shader/chunk/geometry/quaternion/dual/chunk_dual_quat_transform_point.js";
32
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
33
- import { ComputeShader } from "../../shader/ComputeShader.js";
34
- import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
35
- import { chunk_skin_blend_mesh_local } from "./chunk_skin_blend_mesh_local.js";
36
- import { SKINNING_BINDING_STRUCT } from "./SKINNING_BINDING_STRUCT.js";
37
-
38
- /**
39
- * Workgroup size — also the per-meshlet vertex stride. Each thread
40
- * handles vertex `local_id`, then loops by `WORKGROUP_SIZE` for
41
- * meshlets larger than the workgroup.
42
- */
43
- export const SKINNING_WORKGROUP_SIZE = 64;
44
-
45
- const resources = new ShaderResourceSetDescriptor();
46
- resources.createGroup()
47
- // First workgroup of the current sub-dispatch. WebGPU caps
48
- // `dispatchWorkgroups` along each dimension at the device's
49
- // `maxComputeWorkgroupsPerDimension` (65535 minimum per the
50
- // spec, often higher in practice), so the host paginates large
51
- // totals into multiple dispatches and increments this offset
52
- // between them. The shader adds it to `wg_id.x` before indexing
53
- // `dispatch_lookup`, so the per-pair mapping stays a flat array
54
- // regardless of how many sub-dispatches it gets split into.
55
- .addUniform('dispatch_offset', u32)
56
- .addStorageBuffer('meshlet_data', WebGPUArray.from(u32), true)
57
- .addStorageBuffer('meshlet_metadata', WebGPUArray.from(MESHLET_METADATA_STRUCT), false)
58
- .addStorageBuffer('skin_matrices', WebGPUArray.from(mat4x4f), false)
59
- .addStorageBuffer('prev_skin_matrices', WebGPUArray.from(mat4x4f), false)
60
- .addStorageBuffer('skinning_bindings', WebGPUArray.from(SKINNING_BINDING_STRUCT), false)
61
- .addStorageBuffer('dispatch_lookup', WebGPUArray.from(u32), false)
62
- // Per-meshlet base u32-word offset into the side-buffer that
63
- // holds previous-frame mesh-local positions. Sentinel
64
- // `0xFFFFFFFF` for non-clone meshlets — those skip the
65
- // prev-position write entirely, since the velocity post-pass
66
- // will fall back to per-object math for them.
67
- .addStorageBuffer('prev_position_offsets', WebGPUArray.from(u32), false)
68
- .addStorageBuffer('prev_positions', WebGPUArray.from(u32), true)
69
- // Scene-graph state — read-only. We need the SkinnedMesh's
70
- // `transforms` row to source the live `mesh.transform_global`
71
- // for the post-DQ position cancellation (see commentary in main).
72
- .addStorageBuffer('scene_database', WebGPUArray.from(u32), false);
73
-
74
- // One workgroup per (binding, meshlet) pair. The host builds
75
- // `dispatch_lookup` as a flat (binding_index, meshlet_local) pair
76
- // table and dispatches one workgroup per pair, so workgroup_id.x
77
- // directly indexes the table.
78
- //
79
- // Skinning math is dual-quaternion: each of the 4 per-vertex joints
80
- // contributes a DQ (built from its skin matrix), the four DQs blend
81
- // by weight (with antipodal correction), and the result transforms
82
- // position via the full screw motion and normal/tangent via just the
83
- // rotation part. DQ blending avoids the candy-wrapper artifacts of
84
- // linear matrix blending and lets normals + tangents transform with
85
- // the same blended frame, no matrix inversion or gimbal-style
86
- // interpolation issues.
87
- //
88
- // Per-attribute compression handling: Position is always
89
- // uncompressed (one entry per vertex, vertex_count*3 words). For
90
- // Normal and Tangent, the meshlet flags say whether they were
91
- // collapsed to a single shared entry across all vertices. Per-vertex
92
- // skinning into a shared slot would race, so the shader skips the
93
- // write for any attribute where the flag is set — the cloned slot
94
- // keeps the source's value and lighting on those vertices uses an
95
- // undeformed direction. For typical character meshes
96
- // normals/tangents vary per vertex and so don't get the all-equal
97
- // collapse, so this skip rarely engages in practice.
98
- //
99
- // SkinningJoints + SkinningWeights are read-only here. They CAN be
100
- // compressed — a meshlet where every vertex shares the same joint
101
- // palette (e.g. simple test meshes that bind every vertex to the
102
- // same two bones) collapses Joints to one shared u32-pair, and the
103
- // shader then has to broadcast that single entry across all vertex
104
- // reads instead of striding by 2 words per vertex. Same logic for
105
- // Weights (less common in practice — weights usually vary per
106
- // vertex even on simple meshes — but the flag handling is free).
107
- const body = CodeChunk.from(
108
- //language=WGSL
109
- `
110
- @compute @workgroup_size(${SKINNING_WORKGROUP_SIZE},1,1)
111
- fn main(
112
- @builtin(workgroup_id) wg_id: vec3<u32>,
113
- @builtin(local_invocation_index) local_id: u32,
114
- ) {
115
- // dispatch_offset lets the host paginate large dispatches —
116
- // WebGPU's per-dimension cap is 65535 workgroups, but a busy
117
- // scene's (binding, meshlet) pair total can exceed that.
118
- let pair_index = wg_id.x + dispatch_offset;
119
- let lookup_base = pair_index * 2u;
120
- let binding_index = dispatch_lookup[lookup_base];
121
- let meshlet_local = dispatch_lookup[lookup_base + 1u];
122
-
123
- let binding = skinning_bindings[binding_index];
124
-
125
- // The glTF skinning formula's leftmost factor is
126
- // inverse(meshNode.worldMatrix), which lands the per-vertex
127
- // output in mesh-local space ready for the rasterizer's
128
- // mesh.world re-application (see
129
- // chunk_mesh_resolve_vertex_position_world.js). It goes into
130
- // each *matrix*, not onto the blended position — see
131
- // chunk_skin_blend_mesh_local for why the difference is the
132
- // whole ball game. Both positions and directions therefore come
133
- // out of the blend already in mesh-local space, and the
134
- // rasterizer's own transforms take them to world.
135
- //
136
- // mesh_instance_index is the row of the SkinnedMesh in the
137
- // meshes table; mesh.node is its transforms-table row.
138
- // Workgroup-uniform (one binding per workgroup), so the load +
139
- // inverse amortize across every vertex this workgroup
140
- // processes.
141
- let mesh = scene_read_mesh(&scene_database, binding.mesh_instance_index);
142
- let mesh_node = scene_read_node(&scene_database, mesh.node);
143
- let inv_mesh_world = mat4_inverse(mesh_node.global);
144
-
145
- let source_meshlet = meshlet_metadata[binding.source_meshlet_metadata_offset + meshlet_local];
146
- let clone_meshlet = meshlet_metadata[binding.clone_meshlet_metadata_offset + meshlet_local];
147
-
148
- let vertex_count = source_meshlet.vertex_count;
149
-
150
- // Both source and clone share an attribute layout (the clone is a
151
- // memcpy of the source's bytes with addresses patched), so attribute
152
- // offsets relative to each meshlet's attribute section are identical.
153
- let source_attr_section = meshlet_compute_attribute_section_offset(source_meshlet);
154
- let clone_attr_section = meshlet_compute_attribute_section_offset(clone_meshlet);
155
-
156
- // Walk the per-attribute layout, capturing the offset of each
157
- // attribute we'll need. Order matches ENCODED_ORDERED_ATTRIBUTES:
158
- // Position, Normal, Tangent, Color, UV0, UV1, SkinningJoints,
159
- // SkinningWeights. Conditional skips for the compressible ones —
160
- // when collapsed, the slot is a single shared entry rather than
161
- // vertex_count entries.
162
- let position_offset = 0u;
163
- var attr_offset: u32 = vertex_count * 3u;
164
-
165
- let normal_offset = attr_offset;
166
- let normal_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_NORMAL}u) != 0u;
167
- attr_offset = attr_offset + select(vertex_count, 1u, normal_compressed);
168
-
169
- let tangent_offset = attr_offset;
170
- let tangent_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_TANGENT}u) != 0u;
171
- attr_offset = attr_offset + select(vertex_count, 1u, tangent_compressed);
172
-
173
- let color_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_COLOR}u) != 0u;
174
- attr_offset = attr_offset + select(vertex_count, 1u, color_compressed);
175
-
176
- let uv0_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_TEXTURE_COORDINATES_0}u) != 0u;
177
- attr_offset = attr_offset + select(vertex_count * 2u, 2u, uv0_compressed);
178
-
179
- let uv1_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_TEXTURE_COORDINATES_1}u) != 0u;
180
- attr_offset = attr_offset + select(vertex_count, 1u, uv1_compressed);
181
-
182
- let joints_offset = attr_offset;
183
- let joints_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_SKINNING_JOINTS}u) != 0u;
184
- attr_offset = attr_offset + select(vertex_count * 2u, 2u, joints_compressed);
185
-
186
- let weights_offset = attr_offset;
187
- let weights_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_SKINNING_WEIGHTS}u) != 0u;
188
-
189
- let skin_base = binding.skin_matrix_offset;
190
-
191
- // Resolve the clone meshlet's per-meshlet base offset in the
192
- // prev_positions side-buffer (or sentinel if this meshlet
193
- // somehow isn't a clone — shouldn't happen in practice since
194
- // the skinning shader only runs on (clone, skinned) pairs, but
195
- // the check costs one load and one branch). Lifted out of the
196
- // vertex loop because it's per-meshlet, not per-vertex.
197
- let clone_meshlet_abs = binding.clone_meshlet_metadata_offset + meshlet_local;
198
- let prev_pos_meshlet_base = prev_position_offsets[clone_meshlet_abs];
199
- let has_prev_positions = prev_pos_meshlet_base != 0xFFFFFFFFu;
200
-
201
- // Stride loop — one thread per WORKGROUP_SIZE-stride'd vertex slot.
202
- // Most meshlets fit in a single iteration (vertex_count <=
203
- // WORKGROUP_SIZE); larger ones cycle the workgroup over them.
204
- var v: u32 = local_id;
205
- loop {
206
- if v >= vertex_count { break; }
207
-
208
- // Joint indices: vec4<u16> packed into 2 u32s. When the
209
- // attribute is compressed (every vertex of this meshlet
210
- // shares the same palette), there's one shared pair at
211
- // joints_offset rather than per-vertex strides; broadcast
212
- // that single entry to every thread.
213
- let joints_local_offset = select(v * 2u, 0u, joints_compressed);
214
- let joints_addr = source_attr_section + joints_offset + joints_local_offset;
215
- let raw_j0 = meshlet_data[joints_addr];
216
- let raw_j1 = meshlet_data[joints_addr + 1u];
217
- let j0 = raw_j0 & 0xFFFFu;
218
- let j1 = (raw_j0 >> 16u) & 0xFFFFu;
219
- let j2 = raw_j1 & 0xFFFFu;
220
- let j3 = (raw_j1 >> 16u) & 0xFFFFu;
221
-
222
- // Joint weights: vec4<unorm8> packed into 1 u32. Half the
223
- // bandwidth of the previous f16×4 layout, sufficient
224
- // precision for typical character skinning (step size
225
- // ~0.4%, well under any visible artefact threshold).
226
- // unpack4x8unorm returns vec4<f32> in [0, 1] with
227
- // components matching byte 0..3 of the packed u32.
228
- let weights_local_offset = select(v, 0u, weights_compressed);
229
- let weights_addr = source_attr_section + weights_offset + weights_local_offset;
230
- let weights = unpack4x8unorm(meshlet_data[weights_addr]);
231
-
232
- // Build per-joint dual quaternions from the joint matrices, then
233
- // blend with antipodal correction. The result represents the
234
- // weighted-average screw motion the four matrices encode.
235
- let dq_blend = skin_blend_mesh_local(
236
- inv_mesh_world,
237
- skin_matrices[skin_base + j0],
238
- skin_matrices[skin_base + j1],
239
- skin_matrices[skin_base + j2],
240
- skin_matrices[skin_base + j3],
241
- weights,
242
- );
243
-
244
- // Position: full screw motion (rotation + translation).
245
- let pos_addr = source_attr_section + position_offset + v * 3u;
246
- let p = vec3f(
247
- bitcast<f32>(meshlet_data[pos_addr]),
248
- bitcast<f32>(meshlet_data[pos_addr + 1u]),
249
- bitcast<f32>(meshlet_data[pos_addr + 2u]),
250
- );
251
- // Position: full screw motion, already mesh-local — the
252
- // rasterizer reapplies mesh.world to every mesh's vertices,
253
- // skinned or not.
254
- let p_skinned = dual_quat_transform_point(dq_blend, p);
255
-
256
- let clone_pos_addr = clone_attr_section + position_offset + v * 3u;
257
- meshlet_data[clone_pos_addr] = bitcast<u32>(p_skinned.x);
258
- meshlet_data[clone_pos_addr + 1u] = bitcast<u32>(p_skinned.y);
259
- meshlet_data[clone_pos_addr + 2u] = bitcast<u32>(p_skinned.z);
260
-
261
- // Previous-frame mesh-local position: same dual-quat math,
262
- // but driven by prev_skin_matrices instead of skin_matrices.
263
- // Written to the side-buffer at the per-meshlet base
264
- // offset + v * 3 u32 words. The velocity post-pass reads
265
- // these to interpolate per-vertex skin deformation across
266
- // the rasterized triangle (vs. just the rigid mesh.global
267
- // → mesh.prev_global delta that Stage 1's path captures).
268
- //
269
- // Skipping the write when there's no slot for this meshlet
270
- // (non-clone — shouldn't be hit by this shader's dispatch
271
- // set, but the guard is cheap). The dual-quat build is
272
- // also skipped to save the per-joint work.
273
- if has_prev_positions {
274
- // Mesh-local for the same reason the current-frame
275
- // position is — the velocity pass reads these through
276
- // the same rasterizer transform, so the space they live
277
- // in has to match.
278
- let prev_dq_blend = skin_blend_mesh_local(
279
- inv_mesh_world,
280
- prev_skin_matrices[skin_base + j0],
281
- prev_skin_matrices[skin_base + j1],
282
- prev_skin_matrices[skin_base + j2],
283
- prev_skin_matrices[skin_base + j3],
284
- weights,
285
- );
286
-
287
- let p_prev_skinned = dual_quat_transform_point(prev_dq_blend, p);
288
-
289
- let prev_addr = prev_pos_meshlet_base + v * 3u;
290
- prev_positions[prev_addr] = bitcast<u32>(p_prev_skinned.x);
291
- prev_positions[prev_addr + 1u] = bitcast<u32>(p_prev_skinned.y);
292
- prev_positions[prev_addr + 2u] = bitcast<u32>(p_prev_skinned.z);
293
- }
294
-
295
- // Normal: rotation only. Skip when the source compressed it
296
- // down to a single shared slot — per-vertex writes to that
297
- // slot would race, and the rotated direction would be
298
- // mostly-meaningless anyway since every vertex would compute
299
- // a different one.
300
- //
301
- // Mesh-local like the position, and left there: the
302
- // rasterizer applies the inverse-transpose of mesh.world's
303
- // 3x3 to it, which is the glTF normal transform and takes a
304
- // mesh-local direction to world (see fragment_gbuffer.js).
305
- if !normal_compressed {
306
- let n_raw_addr = source_attr_section + normal_offset + v;
307
- let n = decode_vertex_normal(meshlet_data[n_raw_addr]);
308
- let n_skinned = normalize(dual_quat_transform_direction(dq_blend, n));
309
-
310
- let clone_n_addr = clone_attr_section + normal_offset + v;
311
- meshlet_data[clone_n_addr] = encode_vertex_normal(n_skinned);
312
- }
313
-
314
- // Tangent: rotation only on the xyz; w (handedness) is a
315
- // topological property, copied through unchanged.
316
- if !tangent_compressed {
317
- let t_raw_addr = source_attr_section + tangent_offset + v;
318
- let t = decode_vertex_tangent(meshlet_data[t_raw_addr]);
319
- let t_skinned_dir = normalize(dual_quat_transform_direction(dq_blend, t.xyz));
320
-
321
- let clone_t_addr = clone_attr_section + tangent_offset + v;
322
- meshlet_data[clone_t_addr] = encode_vertex_tangent(vec4f(t_skinned_dir, t.w));
323
- }
324
-
325
- v = v + ${SKINNING_WORKGROUP_SIZE}u;
326
- }
327
- }
328
- `, [
329
- MESHLET_METADATA_STRUCT.declaration_chunk,
330
- SKINNING_BINDING_STRUCT.declaration_chunk,
331
- chunk_meshlet_compute_attribute_section_offset,
332
- chunk_skin_blend_mesh_local,
333
- chunk_dual_quat_transform_point,
334
- chunk_dual_quat_transform_direction,
335
- chunk_decode_vertex_normal,
336
- chunk_encode_vertex_normal,
337
- chunk_decode_vertex_tangent,
338
- chunk_encode_vertex_tangent,
339
- chunk_scene_database_access,
340
- chunk_mat4_inverse,
341
- ]
342
- );
343
-
344
- /**
345
- * Compute shader that deforms cloned meshlet vertex regions in place
346
- * using the per-frame skin matrices the prep pass produced. One
347
- * workgroup per (binding, meshlet) pair, dispatched against a flat
348
- * `dispatch_lookup` table the host builds when bindings change.
349
- *
350
- * Skins position (full transform) plus normal and tangent (rotation
351
- * only) per vertex via dual-quaternion blending — the blended DQ
352
- * captures the four per-vertex joints' screw motions weighted by
353
- * the per-vertex `SkinningWeights`, and applies cleanly to both
354
- * positions and unit-direction attributes without the matrix-blend
355
- * candy-wrapper artifacts that would otherwise show up in the
356
- * normal-transformed lighting.
357
- *
358
- * Source bytes stay untouched — other instances pointed at the
359
- * source render normally. Per-meshlet bounds aren't refreshed by
360
- * this pass; meshlets that animate outside the source bounds may
361
- * cull incorrectly until a future bounds-refresh phase lands.
362
- *
363
- * Dispatch via `shader.dispatch({ group_count_x: total_meshlet_count, ... })`
364
- * where `total_meshlet_count` is the sum of `meshlet_count` across
365
- * every registered binding. Skip when `total_meshlet_count === 0`.
366
- */
367
- export const shader_meshlet_apply_skinning = ComputeShader.from({
368
- label: "Skinning/MeshletApplySkinning",
369
- resources,
370
- body,
371
- group_size: [SKINNING_WORKGROUP_SIZE, 1, 1],
372
- });
1
+ import { mat4x4f, u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
3
+ import {
4
+ MESHLET_METADATA_FLAGS
5
+ } from "../../geometry/meshlet/encoding/MESHLET_METADATA_FLAGS.js";
6
+ import {
7
+ MESHLET_METADATA_STRUCT
8
+ } from "../../geometry/meshlet/encoding/MESHLET_METADATA_STRUCT.js";
9
+ import { chunk_scene_database_access } from "../../scene/chunk_scene_database_access.js";
10
+ import { chunk_mat4_inverse } from "../../shader/chunk/geometry/mat4/chunk_mat4_inverse.js";
11
+ import {
12
+ chunk_meshlet_compute_attribute_section_offset
13
+ } from "../../shader/chunk/geometry/meshlet/chunk_meshlet_compute_attribute_section_offset.js";
14
+ import {
15
+ chunk_decode_vertex_normal
16
+ } from "../../shader/chunk/geometry/normal/chunk_decode_vertex_normal.js";
17
+ import {
18
+ chunk_encode_vertex_normal
19
+ } from "../../shader/chunk/geometry/normal/chunk_encode_vertex_normal.js";
20
+ import {
21
+ chunk_decode_vertex_tangent
22
+ } from "../../shader/chunk/geometry/normal/tangent/chunk_decode_vertex_tangent.js";
23
+ import {
24
+ chunk_encode_vertex_tangent
25
+ } from "../../shader/chunk/geometry/normal/tangent/chunk_encode_vertex_tangent.js";
26
+ import {
27
+ chunk_dual_quat_transform_direction
28
+ } from "../../shader/chunk/geometry/quaternion/dual/chunk_dual_quat_transform_direction.js";
29
+ import {
30
+ chunk_dual_quat_transform_point
31
+ } from "../../shader/chunk/geometry/quaternion/dual/chunk_dual_quat_transform_point.js";
32
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
33
+ import { ComputeShader } from "../../shader/ComputeShader.js";
34
+ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
35
+ import { chunk_skin_blend_mesh_local } from "./chunk_skin_blend_mesh_local.js";
36
+ import { SKINNING_BINDING_STRUCT } from "./SKINNING_BINDING_STRUCT.js";
37
+
38
+ /**
39
+ * Workgroup size — also the per-meshlet vertex stride. Each thread
40
+ * handles vertex `local_id`, then loops by `WORKGROUP_SIZE` for
41
+ * meshlets larger than the workgroup.
42
+ */
43
+ export const SKINNING_WORKGROUP_SIZE = 64;
44
+
45
+ const resources = new ShaderResourceSetDescriptor();
46
+ resources.createGroup()
47
+ // First workgroup of the current sub-dispatch. WebGPU caps
48
+ // `dispatchWorkgroups` along each dimension at the device's
49
+ // `maxComputeWorkgroupsPerDimension` (65535 minimum per the
50
+ // spec, often higher in practice), so the host paginates large
51
+ // totals into multiple dispatches and increments this offset
52
+ // between them. The shader adds it to `wg_id.x` before indexing
53
+ // `dispatch_lookup`, so the per-pair mapping stays a flat array
54
+ // regardless of how many sub-dispatches it gets split into.
55
+ .addUniform('dispatch_offset', u32)
56
+ .addStorageBuffer('meshlet_data', WebGPUArray.from(u32), true)
57
+ .addStorageBuffer('meshlet_metadata', WebGPUArray.from(MESHLET_METADATA_STRUCT), false)
58
+ .addStorageBuffer('skin_matrices', WebGPUArray.from(mat4x4f), false)
59
+ .addStorageBuffer('prev_skin_matrices', WebGPUArray.from(mat4x4f), false)
60
+ .addStorageBuffer('skinning_bindings', WebGPUArray.from(SKINNING_BINDING_STRUCT), false)
61
+ .addStorageBuffer('dispatch_lookup', WebGPUArray.from(u32), false)
62
+ // Per-meshlet base u32-word offset into the side-buffer that
63
+ // holds previous-frame mesh-local positions. Sentinel
64
+ // `0xFFFFFFFF` for non-clone meshlets — those skip the
65
+ // prev-position write entirely, since the velocity post-pass
66
+ // will fall back to per-object math for them.
67
+ .addStorageBuffer('prev_position_offsets', WebGPUArray.from(u32), false)
68
+ .addStorageBuffer('prev_positions', WebGPUArray.from(u32), true)
69
+ // Scene-graph state — read-only. We need the SkinnedMesh's
70
+ // `transforms` row to source the live `mesh.transform_global`
71
+ // for the post-DQ position cancellation (see commentary in main).
72
+ .addStorageBuffer('scene_database', WebGPUArray.from(u32), false);
73
+
74
+ // One workgroup per (binding, meshlet) pair. The host builds
75
+ // `dispatch_lookup` as a flat (binding_index, meshlet_local) pair
76
+ // table and dispatches one workgroup per pair, so workgroup_id.x
77
+ // directly indexes the table.
78
+ //
79
+ // Skinning math is dual-quaternion: each of the 4 per-vertex joints
80
+ // contributes a DQ (built from its skin matrix), the four DQs blend
81
+ // by weight (with antipodal correction), and the result transforms
82
+ // position via the full screw motion and normal/tangent via just the
83
+ // rotation part. DQ blending avoids the candy-wrapper artifacts of
84
+ // linear matrix blending and lets normals + tangents transform with
85
+ // the same blended frame, no matrix inversion or gimbal-style
86
+ // interpolation issues.
87
+ //
88
+ // Per-attribute compression handling: Position is always
89
+ // uncompressed (one entry per vertex, vertex_count*3 words). For
90
+ // Normal and Tangent, the meshlet flags say whether they were
91
+ // collapsed to a single shared entry across all vertices. Per-vertex
92
+ // skinning into a shared slot would race, so the shader skips the
93
+ // write for any attribute where the flag is set — the cloned slot
94
+ // keeps the source's value and lighting on those vertices uses an
95
+ // undeformed direction. For typical character meshes
96
+ // normals/tangents vary per vertex and so don't get the all-equal
97
+ // collapse, so this skip rarely engages in practice.
98
+ //
99
+ // SkinningJoints + SkinningWeights are read-only here. They CAN be
100
+ // compressed — a meshlet where every vertex shares the same joint
101
+ // palette (e.g. simple test meshes that bind every vertex to the
102
+ // same two bones) collapses Joints to one shared u32-pair, and the
103
+ // shader then has to broadcast that single entry across all vertex
104
+ // reads instead of striding by 2 words per vertex. Same logic for
105
+ // Weights (less common in practice — weights usually vary per
106
+ // vertex even on simple meshes — but the flag handling is free).
107
+ const body = CodeChunk.from(
108
+ //language=WGSL
109
+ `
110
+ @compute @workgroup_size(${SKINNING_WORKGROUP_SIZE},1,1)
111
+ fn main(
112
+ @builtin(workgroup_id) wg_id: vec3<u32>,
113
+ @builtin(local_invocation_index) local_id: u32,
114
+ ) {
115
+ // dispatch_offset lets the host paginate large dispatches —
116
+ // WebGPU's per-dimension cap is 65535 workgroups, but a busy
117
+ // scene's (binding, meshlet) pair total can exceed that.
118
+ let pair_index = wg_id.x + dispatch_offset;
119
+ let lookup_base = pair_index * 2u;
120
+ let binding_index = dispatch_lookup[lookup_base];
121
+ let meshlet_local = dispatch_lookup[lookup_base + 1u];
122
+
123
+ let binding = skinning_bindings[binding_index];
124
+
125
+ // The glTF skinning formula's leftmost factor is
126
+ // inverse(meshNode.worldMatrix), which lands the per-vertex
127
+ // output in mesh-local space ready for the rasterizer's
128
+ // mesh.world re-application (see
129
+ // chunk_mesh_resolve_vertex_position_world.js). It goes into
130
+ // each *matrix*, not onto the blended position — see
131
+ // chunk_skin_blend_mesh_local for why the difference is the
132
+ // whole ball game. Both positions and directions therefore come
133
+ // out of the blend already in mesh-local space, and the
134
+ // rasterizer's own transforms take them to world.
135
+ //
136
+ // mesh_instance_index is the row of the SkinnedMesh in the
137
+ // meshes table; mesh.node is its transforms-table row.
138
+ // Workgroup-uniform (one binding per workgroup), so the load +
139
+ // inverse amortize across every vertex this workgroup
140
+ // processes.
141
+ let mesh = scene_read_mesh(&scene_database, binding.mesh_instance_index);
142
+ let mesh_node = scene_read_node(&scene_database, mesh.node);
143
+ let inv_mesh_world = mat4_inverse(mesh_node.global);
144
+
145
+ let source_meshlet = meshlet_metadata[binding.source_meshlet_metadata_offset + meshlet_local];
146
+ let clone_meshlet = meshlet_metadata[binding.clone_meshlet_metadata_offset + meshlet_local];
147
+
148
+ let vertex_count = source_meshlet.vertex_count;
149
+
150
+ // Both source and clone share an attribute layout (the clone is a
151
+ // memcpy of the source's bytes with addresses patched), so attribute
152
+ // offsets relative to each meshlet's attribute section are identical.
153
+ let source_attr_section = meshlet_compute_attribute_section_offset(source_meshlet);
154
+ let clone_attr_section = meshlet_compute_attribute_section_offset(clone_meshlet);
155
+
156
+ // Walk the per-attribute layout, capturing the offset of each
157
+ // attribute we'll need. Order matches ENCODED_ORDERED_ATTRIBUTES:
158
+ // Position, Normal, Tangent, Color, UV0, UV1, SkinningJoints,
159
+ // SkinningWeights. Conditional skips for the compressible ones —
160
+ // when collapsed, the slot is a single shared entry rather than
161
+ // vertex_count entries.
162
+ let position_offset = 0u;
163
+ var attr_offset: u32 = vertex_count * 3u;
164
+
165
+ let normal_offset = attr_offset;
166
+ let normal_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_NORMAL}u) != 0u;
167
+ attr_offset = attr_offset + select(vertex_count, 1u, normal_compressed);
168
+
169
+ let tangent_offset = attr_offset;
170
+ let tangent_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_TANGENT}u) != 0u;
171
+ attr_offset = attr_offset + select(vertex_count, 1u, tangent_compressed);
172
+
173
+ let color_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_COLOR}u) != 0u;
174
+ attr_offset = attr_offset + select(vertex_count, 1u, color_compressed);
175
+
176
+ let uv0_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_TEXTURE_COORDINATES_0}u) != 0u;
177
+ attr_offset = attr_offset + select(vertex_count * 2u, 2u, uv0_compressed);
178
+
179
+ let uv1_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_TEXTURE_COORDINATES_1}u) != 0u;
180
+ attr_offset = attr_offset + select(vertex_count, 1u, uv1_compressed);
181
+
182
+ let joints_offset = attr_offset;
183
+ let joints_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_SKINNING_JOINTS}u) != 0u;
184
+ attr_offset = attr_offset + select(vertex_count * 2u, 2u, joints_compressed);
185
+
186
+ let weights_offset = attr_offset;
187
+ let weights_compressed = (source_meshlet.flags & ${MESHLET_METADATA_FLAGS.ATTRIBUTE_COMPRESSED_SKINNING_WEIGHTS}u) != 0u;
188
+
189
+ let skin_base = binding.skin_matrix_offset;
190
+
191
+ // Resolve the clone meshlet's per-meshlet base offset in the
192
+ // prev_positions side-buffer (or sentinel if this meshlet
193
+ // somehow isn't a clone — shouldn't happen in practice since
194
+ // the skinning shader only runs on (clone, skinned) pairs, but
195
+ // the check costs one load and one branch). Lifted out of the
196
+ // vertex loop because it's per-meshlet, not per-vertex.
197
+ let clone_meshlet_abs = binding.clone_meshlet_metadata_offset + meshlet_local;
198
+ let prev_pos_meshlet_base = prev_position_offsets[clone_meshlet_abs];
199
+ let has_prev_positions = prev_pos_meshlet_base != 0xFFFFFFFFu;
200
+
201
+ // Stride loop — one thread per WORKGROUP_SIZE-stride'd vertex slot.
202
+ // Most meshlets fit in a single iteration (vertex_count <=
203
+ // WORKGROUP_SIZE); larger ones cycle the workgroup over them.
204
+ var v: u32 = local_id;
205
+ loop {
206
+ if v >= vertex_count { break; }
207
+
208
+ // Joint indices: vec4<u16> packed into 2 u32s. When the
209
+ // attribute is compressed (every vertex of this meshlet
210
+ // shares the same palette), there's one shared pair at
211
+ // joints_offset rather than per-vertex strides; broadcast
212
+ // that single entry to every thread.
213
+ let joints_local_offset = select(v * 2u, 0u, joints_compressed);
214
+ let joints_addr = source_attr_section + joints_offset + joints_local_offset;
215
+ let raw_j0 = meshlet_data[joints_addr];
216
+ let raw_j1 = meshlet_data[joints_addr + 1u];
217
+ let j0 = raw_j0 & 0xFFFFu;
218
+ let j1 = (raw_j0 >> 16u) & 0xFFFFu;
219
+ let j2 = raw_j1 & 0xFFFFu;
220
+ let j3 = (raw_j1 >> 16u) & 0xFFFFu;
221
+
222
+ // Joint weights: vec4<unorm8> packed into 1 u32. Half the
223
+ // bandwidth of the previous f16×4 layout, sufficient
224
+ // precision for typical character skinning (step size
225
+ // ~0.4%, well under any visible artefact threshold).
226
+ // unpack4x8unorm returns vec4<f32> in [0, 1] with
227
+ // components matching byte 0..3 of the packed u32.
228
+ let weights_local_offset = select(v, 0u, weights_compressed);
229
+ let weights_addr = source_attr_section + weights_offset + weights_local_offset;
230
+ let weights = unpack4x8unorm(meshlet_data[weights_addr]);
231
+
232
+ // Build per-joint dual quaternions from the joint matrices, then
233
+ // blend with antipodal correction. The result represents the
234
+ // weighted-average screw motion the four matrices encode.
235
+ let dq_blend = skin_blend_mesh_local(
236
+ inv_mesh_world,
237
+ skin_matrices[skin_base + j0],
238
+ skin_matrices[skin_base + j1],
239
+ skin_matrices[skin_base + j2],
240
+ skin_matrices[skin_base + j3],
241
+ weights,
242
+ );
243
+
244
+ // Position: full screw motion (rotation + translation).
245
+ let pos_addr = source_attr_section + position_offset + v * 3u;
246
+ let p = vec3f(
247
+ bitcast<f32>(meshlet_data[pos_addr]),
248
+ bitcast<f32>(meshlet_data[pos_addr + 1u]),
249
+ bitcast<f32>(meshlet_data[pos_addr + 2u]),
250
+ );
251
+ // Position: full screw motion, already mesh-local — the
252
+ // rasterizer reapplies mesh.world to every mesh's vertices,
253
+ // skinned or not.
254
+ let p_skinned = dual_quat_transform_point(dq_blend, p);
255
+
256
+ let clone_pos_addr = clone_attr_section + position_offset + v * 3u;
257
+ meshlet_data[clone_pos_addr] = bitcast<u32>(p_skinned.x);
258
+ meshlet_data[clone_pos_addr + 1u] = bitcast<u32>(p_skinned.y);
259
+ meshlet_data[clone_pos_addr + 2u] = bitcast<u32>(p_skinned.z);
260
+
261
+ // Previous-frame mesh-local position: same dual-quat math,
262
+ // but driven by prev_skin_matrices instead of skin_matrices.
263
+ // Written to the side-buffer at the per-meshlet base
264
+ // offset + v * 3 u32 words. The velocity post-pass reads
265
+ // these to interpolate per-vertex skin deformation across
266
+ // the rasterized triangle (vs. just the rigid mesh.global
267
+ // → mesh.prev_global delta that Stage 1's path captures).
268
+ //
269
+ // Skipping the write when there's no slot for this meshlet
270
+ // (non-clone — shouldn't be hit by this shader's dispatch
271
+ // set, but the guard is cheap). The dual-quat build is
272
+ // also skipped to save the per-joint work.
273
+ if has_prev_positions {
274
+ // Mesh-local for the same reason the current-frame
275
+ // position is — the velocity pass reads these through
276
+ // the same rasterizer transform, so the space they live
277
+ // in has to match.
278
+ let prev_dq_blend = skin_blend_mesh_local(
279
+ inv_mesh_world,
280
+ prev_skin_matrices[skin_base + j0],
281
+ prev_skin_matrices[skin_base + j1],
282
+ prev_skin_matrices[skin_base + j2],
283
+ prev_skin_matrices[skin_base + j3],
284
+ weights,
285
+ );
286
+
287
+ let p_prev_skinned = dual_quat_transform_point(prev_dq_blend, p);
288
+
289
+ let prev_addr = prev_pos_meshlet_base + v * 3u;
290
+ prev_positions[prev_addr] = bitcast<u32>(p_prev_skinned.x);
291
+ prev_positions[prev_addr + 1u] = bitcast<u32>(p_prev_skinned.y);
292
+ prev_positions[prev_addr + 2u] = bitcast<u32>(p_prev_skinned.z);
293
+ }
294
+
295
+ // Normal: rotation only. Skip when the source compressed it
296
+ // down to a single shared slot — per-vertex writes to that
297
+ // slot would race, and the rotated direction would be
298
+ // mostly-meaningless anyway since every vertex would compute
299
+ // a different one.
300
+ //
301
+ // Mesh-local like the position, and left there: the
302
+ // rasterizer applies the inverse-transpose of mesh.world's
303
+ // 3x3 to it, which is the glTF normal transform and takes a
304
+ // mesh-local direction to world (see fragment_gbuffer.js).
305
+ if !normal_compressed {
306
+ let n_raw_addr = source_attr_section + normal_offset + v;
307
+ let n = decode_vertex_normal(meshlet_data[n_raw_addr]);
308
+ let n_skinned = normalize(dual_quat_transform_direction(dq_blend, n));
309
+
310
+ let clone_n_addr = clone_attr_section + normal_offset + v;
311
+ meshlet_data[clone_n_addr] = encode_vertex_normal(n_skinned);
312
+ }
313
+
314
+ // Tangent: rotation only on the xyz; w (handedness) is a
315
+ // topological property, copied through unchanged.
316
+ if !tangent_compressed {
317
+ let t_raw_addr = source_attr_section + tangent_offset + v;
318
+ let t = decode_vertex_tangent(meshlet_data[t_raw_addr]);
319
+ let t_skinned_dir = normalize(dual_quat_transform_direction(dq_blend, t.xyz));
320
+
321
+ let clone_t_addr = clone_attr_section + tangent_offset + v;
322
+ meshlet_data[clone_t_addr] = encode_vertex_tangent(vec4f(t_skinned_dir, t.w));
323
+ }
324
+
325
+ v = v + ${SKINNING_WORKGROUP_SIZE}u;
326
+ }
327
+ }
328
+ `, [
329
+ MESHLET_METADATA_STRUCT.declaration_chunk,
330
+ SKINNING_BINDING_STRUCT.declaration_chunk,
331
+ chunk_meshlet_compute_attribute_section_offset,
332
+ chunk_skin_blend_mesh_local,
333
+ chunk_dual_quat_transform_point,
334
+ chunk_dual_quat_transform_direction,
335
+ chunk_decode_vertex_normal,
336
+ chunk_encode_vertex_normal,
337
+ chunk_decode_vertex_tangent,
338
+ chunk_encode_vertex_tangent,
339
+ chunk_scene_database_access,
340
+ chunk_mat4_inverse,
341
+ ]
342
+ );
343
+
344
+ /**
345
+ * Compute shader that deforms cloned meshlet vertex regions in place
346
+ * using the per-frame skin matrices the prep pass produced. One
347
+ * workgroup per (binding, meshlet) pair, dispatched against a flat
348
+ * `dispatch_lookup` table the host builds when bindings change.
349
+ *
350
+ * Skins position (full transform) plus normal and tangent (rotation
351
+ * only) per vertex via dual-quaternion blending — the blended DQ
352
+ * captures the four per-vertex joints' screw motions weighted by
353
+ * the per-vertex `SkinningWeights`, and applies cleanly to both
354
+ * positions and unit-direction attributes without the matrix-blend
355
+ * candy-wrapper artifacts that would otherwise show up in the
356
+ * normal-transformed lighting.
357
+ *
358
+ * Source bytes stay untouched — other instances pointed at the
359
+ * source render normally. Per-meshlet bounds aren't refreshed by
360
+ * this pass; meshlets that animate outside the source bounds may
361
+ * cull incorrectly until a future bounds-refresh phase lands.
362
+ *
363
+ * Dispatch via `shader.dispatch({ group_count_x: total_meshlet_count, ... })`
364
+ * where `total_meshlet_count` is the sum of `meshlet_count` across
365
+ * every registered binding. Skip when `total_meshlet_count === 0`.
366
+ */
367
+ export const shader_meshlet_apply_skinning = ComputeShader.from({
368
+ label: "Skinning/MeshletApplySkinning",
369
+ resources,
370
+ body,
371
+ });