@woosh/meep-engine 3.60.4 → 3.60.6

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 (419) hide show
  1. package/CHANGELOG.md +2621 -0
  2. package/CONTRIBUTING.md +7 -0
  3. package/MIGRATION_2_TO_3.md +136 -0
  4. package/SECURITY.md +4 -0
  5. package/editor/EditorCameraNavigation.d.ts +2 -1
  6. package/editor/EditorCameraNavigation.d.ts.map +1 -1
  7. package/editor/EditorCameraNavigation.js +51 -57
  8. package/package.json +6 -2
  9. package/src/engine/EngineHarness.d.ts +3 -9
  10. package/src/engine/EngineHarness.d.ts.map +1 -1
  11. package/src/engine/EngineHarness.js +6 -8
  12. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  13. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  14. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  15. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  16. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  17. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  18. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  19. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  21. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  22. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  23. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  27. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  28. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/water/Water.js +8 -0
  30. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  31. package/src/engine/graphics3/WaterSystem.js +731 -734
  32. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  33. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  34. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  35. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  36. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  37. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  38. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  39. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  40. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  41. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  42. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  43. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  44. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  45. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  46. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  47. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  48. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  49. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  50. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  51. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  52. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  53. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  54. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  55. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  56. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  57. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  58. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/shade/playground/water_refraction/README.md +5 -6
  61. package/src/shade/playground/water_refraction/index.html +1 -1
  62. package/src/shade/renderer/Renderer.d.ts +11 -0
  63. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  64. package/src/shade/renderer/Renderer.js +50 -6
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  67. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  68. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  69. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  70. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  71. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  72. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +28 -45
  74. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  75. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +111 -119
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +22 -3
  77. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  78. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +84 -3
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts +19 -0
  80. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.js +25 -0
  82. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  83. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  84. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  85. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +15 -0
  86. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -1
  87. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +38 -0
  88. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  89. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  90. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  91. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  92. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  93. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +28 -59
  94. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -1
  95. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +84 -789
  96. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  98. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +7 -6
  99. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +12 -11
  101. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -2
  102. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -2
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  108. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  109. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  110. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  111. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  112. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  113. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  114. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  115. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  116. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  117. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  118. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  119. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  120. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  121. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  122. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  123. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  124. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  125. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  126. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  127. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  128. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  129. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  130. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  131. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  132. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  133. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  134. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  135. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  136. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  137. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  138. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  139. package/src/shade/renderer/material/GPUMaterialManager.d.ts +11 -1
  140. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  141. package/src/shade/renderer/material/GPUMaterialManager.js +16 -8
  142. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  143. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  144. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  145. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +7 -3
  146. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  147. package/src/shade/renderer/postprocess/gtao/GTAO.js +26 -13
  148. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts +14 -0
  149. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  150. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +196 -68
  151. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  152. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +42 -28
  153. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  154. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +429 -414
  155. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts +16 -0
  156. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts.map +1 -0
  157. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.js +156 -0
  158. package/src/shade/renderer/scene/GPUSceneContext.d.ts +2 -2
  159. package/src/shade/renderer/scene/GPUSceneContext.js +5 -5
  160. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  161. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  162. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  163. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  164. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  165. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  166. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  167. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  168. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  169. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  170. package/src/shade/renderer/water/shader_water.js +22 -13
  171. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  172. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  173. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  174. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  175. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  176. package/editor/REWORK_PLAN_2026_08.md +0 -692
  177. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  178. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  179. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  180. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  181. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  182. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  183. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  184. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  185. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  186. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  187. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  188. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  189. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  190. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  191. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  192. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  193. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  194. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  195. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  196. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  197. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  198. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  199. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  200. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  201. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  202. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  203. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  204. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  205. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  206. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  207. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  208. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  209. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  210. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  211. package/src/REVIEW_2026_08_06/generation.md +0 -176
  212. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  213. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  214. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  215. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  216. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  217. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  218. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  219. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  220. package/src/REVIEW_2026_08_06/view.md +0 -667
  221. package/src/REVIEW_2026_08_06.md +0 -610
  222. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  223. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  224. package/src/core/bvh8/NOTES.md +0 -63
  225. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  226. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  227. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  228. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  229. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  230. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  231. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  232. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  233. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  234. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  235. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  236. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  237. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  238. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  239. package/src/engine/REVIEW_2026_07_03.md +0 -211
  240. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  241. package/src/engine/control/first-person/DESIGN.md +0 -658
  242. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  243. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  244. package/src/engine/control/first-person/TODO.md +0 -160
  245. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  246. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  247. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  248. package/src/engine/ecs/ik/PLAN.md +0 -179
  249. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  250. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  251. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  252. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  253. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  254. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  255. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  256. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  257. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  258. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  259. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  260. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  261. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  262. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  263. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  264. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  265. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  266. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  267. package/src/engine/physics/cloth/PLAN.md +0 -3056
  268. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  269. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  270. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  271. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  272. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  273. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  274. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  275. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  276. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  277. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  278. package/src/format/image/avif/DECISIONS.md +0 -545
  279. package/src/format/image/jpeg/NOTES.md +0 -3
  280. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  281. package/src/generation/COORDINATES.md +0 -54
  282. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  283. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  284. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  285. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  286. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  287. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  288. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  289. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  290. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  291. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  292. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  293. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  294. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  295. package/src/shade/RENDERER_CONTRACT.md +0 -697
  296. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  297. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  298. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  299. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  300. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  301. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  302. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  303. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  304. package/src/shade/renderer/NOTES.md +0 -78
  305. package/src/shade/renderer/PLAN.md +0 -8
  306. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  307. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  308. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  309. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  310. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  311. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  312. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  313. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  314. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  315. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  316. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  317. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  318. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  319. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  320. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  321. package/src/shade/renderer/camera/orbital/README.md +0 -81
  322. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  323. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  324. package/src/shade/renderer/camera/orbital/index.js +0 -9
  325. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  326. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  327. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  328. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  329. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  330. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  331. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  332. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  333. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  334. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  335. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  336. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  337. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  338. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  339. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  340. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  341. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  342. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  343. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +0 -47
  344. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +0 -1
  345. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +0 -80
  346. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +0 -16
  347. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +0 -1
  348. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +0 -67
  349. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +0 -17
  350. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +0 -1
  351. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +0 -145
  352. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +0 -12
  353. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +0 -1
  354. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +0 -105
  355. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  356. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  357. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  358. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  359. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  360. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  361. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  362. package/src/shade/renderer/hiz/NOTES.md +0 -3
  363. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  364. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  365. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  366. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  367. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  368. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  369. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  370. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  371. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  372. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  373. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  374. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  375. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  376. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  377. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  378. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  379. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  380. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  381. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  382. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  383. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  384. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  385. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  386. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  387. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  388. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  389. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  390. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  391. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  392. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  393. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  394. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  395. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  396. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  397. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  398. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  399. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  400. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  401. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  402. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  403. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  404. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  405. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  406. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  407. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  408. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  409. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  410. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  411. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  412. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  413. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  414. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  415. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  416. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  417. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  418. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  419. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,345 +0,0 @@
1
- # The `.sgpt` container — format specification
2
-
3
- **S**hade **G**PU **P**rofile **T**race, format version 2.
4
-
5
- This document is the normative description of the file. It is written for somebody outside Company
6
- Named who wants to read or write one without reading the engine's source. Every integer is
7
- little-endian and unsigned unless stated otherwise.
8
-
9
- ---
10
-
11
- ## 1. What the format is for, and what it is not
12
-
13
- A capture holds **what a renderer asked a GPU to do over a run of frames, and how long each piece
14
- took**: pass timings, the frame graph's structure and dependencies, declared resource sizes, and
15
- dispatch and draw counts.
16
-
17
- It deliberately does **not** hold buffer or texture contents, shader source, or anything else that
18
- scales with the size of the resources it describes. That exclusion is what keeps a frame record in
19
- the kilobytes and makes an uncapped recording practical.
20
-
21
- ### 1.1 Two properties the layout exists to provide
22
-
23
- **A truncated capture is a capture.** A recording that ended when the tab did — which is the state
24
- of every capture of a crash, a device loss, or a hang — must be readable up to the last intact
25
- record. So every record is self-framed and checksummed, symbols travel inside the record that
26
- introduces them, and the directory is an index over the stream rather than a prerequisite for
27
- reading it.
28
-
29
- **A reader may not understand everything, and must say so rather than fail.** Records carry a type
30
- and a length; an unrecognised type is skipped by length. This is what lets a newer writer add record
31
- types without a version bump, and what lets an older reader open the result and report honestly
32
- which parts it could not show.
33
-
34
- ---
35
-
36
- ## 2. File header
37
-
38
- Thirty-two bytes at offset 0.
39
-
40
- | Offset | Size | Field | Notes |
41
- |---|---|---|---|
42
- | 0 | 4 | `magic` | `0x54504753` — the ASCII bytes `S`, `G`, `P`, `T` in that order |
43
- | 4 | 2 | `format_version` | 2 for this document |
44
- | 6 | 2 | `min_reader_version` | the oldest reader that can read this file correctly |
45
- | 8 | 4 | `flags` | see below |
46
- | 12 | 4 | `header_checksum` | CRC-32 over bytes `[0, 8)` **only** |
47
- | 16 | 8 | `directory_offset` | absolute; **0 when there is no directory** |
48
- | 24 | 8 | `directory_byte_length` | 0 when absent |
49
-
50
- Records begin at offset 32.
51
-
52
- ### 2.1 Flags
53
-
54
- | Bit | Name | Meaning |
55
- |---|---|---|
56
- | 0 | `CLOSED` | the writer reached `stop()` and the file is complete as intended |
57
-
58
- ### 2.2 Why the checksum stops at byte 8
59
-
60
- Everything from `flags` onward is written twice: zeroed when the header is laid down, and patched
61
- when the session stops. A checksum covering those fields would have to be recomputed at stop — fine
62
- for a capture that stops, and exactly wrong for one that does not, which would then carry a checksum
63
- over bytes that were never written and read as corrupt.
64
-
65
- What remains under the checksum is what a reader must trust before it can do anything at all: *is
66
- this an `.sgpt`, and can this build read it.* Those never change after the header is written.
67
-
68
- **A reader must not treat a missing `CLOSED` flag or a zero `directory_offset` as damage.** Both are
69
- the normal state of an interrupted session, and such a file is fully readable by §3.
70
-
71
- ### 2.3 Version handling
72
-
73
- A reader **must** refuse a file whose `min_reader_version` exceeds the highest format version it
74
- implements, and **must** accept anything else. `min_reader_version` is raised only when a change
75
- would make an older reader produce *wrong* answers rather than incomplete ones — a new record type
76
- it would skip is incomplete; a reordered field is wrong.
77
-
78
- Format version 2 keeps `min_reader_version` at 1: it added the `TOPO` record, which a version-1
79
- reader skips by length, and appended a topology reference to the end of a frame's payload, which a
80
- version-1 reader stops before.
81
-
82
- ---
83
-
84
- ## 3. Records
85
-
86
- Every record, whatever its type, is framed identically.
87
-
88
- | Offset | Size | Field |
89
- |---|---|---|
90
- | 0 | 4 | `sync` — `0x43455253`, the ASCII bytes `S`, `R`, `E`, `C` |
91
- | 4 | 4 | `record_type` — a four-character tag as a u32 |
92
- | 8 | 4 | `payload_byte_length` |
93
- | 12 | 4 | `payload_checksum` — CRC-32 over the payload bytes only |
94
- | 16 | … | payload |
95
-
96
- `payload_byte_length` is a u32 rather than a u64 because no record describes anything that scales
97
- with resource size (§1); four gigabytes is not a ceiling anything can approach.
98
-
99
- ### 3.1 Reading, and resynchronising
100
-
101
- The canonical read is a **forward scan from offset 32**, not a walk of the directory:
102
-
103
- 1. At the current offset, a record is present if — and only if — all four hold: the sync marker
104
- matches, at least 16 bytes remain, the payload fits within the file, and the payload's CRC-32
105
- matches `payload_checksum`.
106
- 2. If it does, decode or skip it by type and advance past its payload.
107
- 3. If it does not, scan forward one byte at a time for the next offset where all four hold. Report
108
- the skipped bytes as damage; do not stop.
109
- 4. If the scan reaches the end without finding another record, the stream was truncated inside a
110
- record. Report it. Everything already decoded stands.
111
-
112
- **The sync marker alone is not sufficient and a reader must not treat it as such.** Four bytes of
113
- payload can spell `SREC` — a pass label could — and resynchronising onto a false positive
114
- desynchronises everything after it. The length and the checksum are what confirm a candidate.
115
-
116
- ### 3.2 Record types
117
-
118
- | Tag | u32 | Payload | Cardinality |
119
- |---|---|---|---|
120
- | `META` | `0x4154454D` | §4 | 1, immediately after the header |
121
- | `SYMS` | `0x534D5953` | §5 | 0..n, always before the records referencing them |
122
- | `TOPO` | `0x4F504F54` | §6 | 0..n |
123
- | `FRAM` | `0x4D415246` | §7 | 0..n |
124
- | `CNTR` | `0x52544E43` | reserved | 0..1 |
125
- | `DIRE` | `0x45524944` | §8 | 0..1, last |
126
-
127
- An unrecognised tag **must** be skipped using `payload_byte_length`.
128
-
129
- ### 3.3 Primitive encodings
130
-
131
- - `uintVar` — 7 bits per byte, low group first, high bit set on every byte but the last. Values are
132
- limited to 2³¹−1.
133
- - `utf8` — a `uintVar` byte length followed by that many UTF-8 bytes.
134
- - `f64` — IEEE 754 binary64, little-endian.
135
- - **Optional index** — a value of −1 meaning "none", written as `uintVar(value + 1)`. Zero means
136
- none.
137
-
138
- ---
139
-
140
- ## 4. `META`
141
-
142
- | Field | Type | Notes |
143
- |---|---|---|
144
- | `level` | u8 | 0 `TIMING`, 1 `STRUCTURE`, 2 `WORKLOAD`, 3 `VERBOSE` |
145
- | `wall_clock_start_ms` | f64 | `Date.now()` at session start; for ordering captures, not for timing |
146
- | `note` | utf8 | free text from whoever captured |
147
- | `engine_version` | utf8 | |
148
- | `adapter_vendor` | utf8 | from `GPUAdapterInfo`; empty where the browser withheld it |
149
- | `adapter_architecture` | utf8 | |
150
- | `adapter_device` | utf8 | |
151
- | `adapter_description` | utf8 | |
152
- | `feature_count` | uintVar | |
153
- | `features` | utf8 × count | `GPUFeatureName`s the device was created with |
154
-
155
- ### 4.1 On timestamp resolution — a deliberate absence
156
-
157
- **There is no field here describing the device's timestamp quantum, and adding one is out of
158
- scope.**
159
-
160
- Browsers quantize WebGPU timestamps as a timing-attack mitigation; Chrome to 100 µs unless
161
- `chrome://flags/#enable-webgpu-developer-features` is set. Most passes in a real renderer run below
162
- that and are reported as exactly zero.
163
-
164
- Recovering the quantum from the data — a GCD over observed timestamps, or any equivalent — *is* the
165
- timing attack the mitigation exists to prevent, and doing it imperfectly applies a wrong correction
166
- to every number in the file. So a capture records what the device reported, zeros included, and says
167
- nothing further. A reader that wants to present this honestly should aggregate across many frames
168
- rather than trust any single one, and should say so where the reader will see it.
169
-
170
- ---
171
-
172
- ## 5. `SYMS`
173
-
174
- | Field | Type |
175
- |---|---|
176
- | `first_index` | uintVar |
177
- | `count` | uintVar |
178
- | `strings` | utf8 × count |
179
-
180
- Strings occupy one index space across the whole file; a block declares where its run begins. Every
181
- later reference is a `uintVar` index into that space.
182
-
183
- A `SYMS` block **always precedes** the record that references its strings. A writer must not gather
184
- symbols into one block at the end of the file: a capture truncated before that block would resolve
185
- no names at all, which is precisely the capture of the crash somebody was trying to record.
186
-
187
- ---
188
-
189
- ## 6. `TOPO` — frame graph structure
190
-
191
- Present at capture level `STRUCTURE` and above.
192
-
193
- | Field | Type |
194
- |---|---|
195
- | `id` | uintVar — what a frame refers to |
196
- | `name` | symbol index |
197
- | `scope_count` | uintVar |
198
- | **per scope** | `name` (symbol index), `parent` (optional index) |
199
- | `pass_count` | uintVar |
200
- | **per pass** | see §6.1 |
201
- | `resource_count` | uintVar |
202
- | **per resource** | see §6.2 |
203
-
204
- A scope's parent always appears at a lower index than the scope itself, so a reader resolves the
205
- chain in one forward pass.
206
-
207
- ### 6.1 Pass
208
-
209
- | Field | Type |
210
- |---|---|
211
- | `id` | uintVar |
212
- | `name` | symbol index |
213
- | `scope` | optional index |
214
- | `flags` | u8 — bit 0 `CULLED`, bit 1 `HAS_SIDE_EFFECTS` |
215
- | `ref_count` | uintVar |
216
- | `reads` | uintVar count, then that many resource **node** ids |
217
- | `writes` | same |
218
- | `creates` | same |
219
-
220
- ### 6.2 Resource
221
-
222
- One entry per resource **node** — that is, per version. A pass records the node it touched rather
223
- than the underlying resource, so a registry-keyed model would leave every reference past version 0
224
- dangling.
225
-
226
- | Field | Type |
227
- |---|---|
228
- | `id` | uintVar |
229
- | `name` | symbol index |
230
- | `version` | uintVar |
231
- | `flags` | u8 — bit 2 `TRANSIENT`, bit 3 `IMPORTED` |
232
- | `producer` | optional index — the pass that produced this version |
233
- | `kind` | u8 — 0 none, 1 buffer, 2 texture |
234
- | `usage` | uintVar — `GPUBufferUsage` / `GPUTextureUsage` bitmask |
235
- | `byte_size` | uintVar — declared bytes, §6.3 |
236
- | **if buffer** | `size` (uintVar) |
237
- | **if texture** | `width`, `height`, `depth`, `mip_level_count`, `sample_count` (uintVar each), `format`, `dimension` (symbol indices) |
238
-
239
- ### 6.3 `byte_size` is declared, and is computed by the writer
240
-
241
- Declared, not allocated: a pooled allocator may serve a larger block, and an aliasing one may serve
242
- the same block to two resources whose lifetimes do not overlap.
243
-
244
- For a texture it covers the whole mip chain at the given sample count. **The writer computes it**
245
- rather than leaving a reader to, because working it out needs the format's block dimensions — so a
246
- reader never has to carry a copy of that table, and a format the reader has never heard of still
247
- reports a size. A writer that cannot determine a size **must** write 0.
248
-
249
- ---
250
-
251
- ## 7. `FRAM` — one frame
252
-
253
- | Field | Type |
254
- |---|---|
255
- | `frame_index` | uintVar — the renderer's own counter, not a position in the file |
256
- | `cpu_begin_ms` | f64 — `performance.now()` when encoding began |
257
- | `cpu_submit_ms` | f64 — `performance.now()` at submit |
258
- | `gpu_epoch_ns` | u64 — the earliest GPU timestamp in this frame |
259
- | `dropped_pass_count` | uintVar — passes that went untimed, §7.2 |
260
- | `span_count` | uintVar |
261
- | **per span** | §7.1 |
262
- | `topology_id` | optional index — **appended last**, absent in a format-1 file |
263
-
264
- ### 7.1 Span
265
-
266
- | Field | Type |
267
- |---|---|
268
- | `label` | symbol index |
269
- | `kind` | u8 — 0 compute, 1 render |
270
- | `query_set_id` | u8 — §7.3 |
271
- | `t_begin_ns` | u32 — nanoseconds from `gpu_epoch_ns` |
272
- | `duration_ns` | uintVar |
273
- | `graph_pass_id` | optional index — the frame graph pass that was executing when this pass opened |
274
- | `has_work` | u8 — 1 if a workload block follows |
275
- | **if `has_work`** | `dispatch_count`, `indirect_dispatch_count`, `workgroups_x/y/z`, `draw_count`, `indirect_draw_count`, `vertex_count`, `index_count`, `instance_count` (uintVar each), `pipeline` (symbol index), `workgroup_size_x/y/z` (uintVar each) |
276
-
277
- `t_begin_ns` is a u32 of nanoseconds, holding 4.29 s — three orders of magnitude past any frame, and
278
- enough to survive a stall rather than wrap. A writer **must** clamp rather than wrap, and **must**
279
- write a duration of 0 where a device reports an end before its begin.
280
-
281
- `has_work` is per span rather than per frame because a frame genuinely mixes the two: a pass opened
282
- before the recorder was attached has no workload record, and a per-frame flag would have to lie
283
- about one of them.
284
-
285
- A `workgroup_size` of `[0, 0, 0]` means **unknown** — typically an override-expression size — and is
286
- not the same as zero work. A reader must not compute an invocation count from it.
287
-
288
- ### 7.2 `dropped_pass_count`
289
-
290
- Passes the recorder could not time because the frame had more of them than its query set had slots.
291
- Carried because an untimed pass reads downstream as a free one. A reader should surface a non-zero
292
- value rather than presenting the frame as complete.
293
-
294
- ### 7.3 `query_set_id`
295
-
296
- Which of the frame's command contexts produced this span. Timestamps from two different
297
- `GPUQuerySet`s are not specified to share a clock domain, and a frame ordinarily spans several.
298
- Carried so that an anomaly following a query-set boundary is visible rather than unfalsifiable.
299
-
300
- ### 7.4 The two clocks are not one clock
301
-
302
- `cpu_*` come from `performance.now()`; `gpu_epoch_ns` and the spans come from the device. WebGPU
303
- exposes no calibration between them, and this format carries none. Anything that places the two on
304
- one axis is anchoring, not synchronising, and should say so.
305
-
306
- ---
307
-
308
- ## 8. `DIRE` — directory
309
-
310
- | Field | Type |
311
- |---|---|
312
- | `record_count` | uintVar |
313
- | **per record** | `type` (u32), `offset` (u64), `byte_length` (u32) |
314
-
315
- Written last, and does not index itself.
316
-
317
- **A reader must not require it, and must not prefer it to the records.** It exists so that a future
318
- reader can seek instead of scan. A capture that never reached `stop()` has none, and is not thereby
319
- a lesser capture.
320
-
321
- ---
322
-
323
- ## 9. Conformance summary
324
-
325
- A conforming **reader**:
326
-
327
- - refuses a file whose magic does not match or whose `min_reader_version` exceeds its own;
328
- - reads by scanning records, and does not require a directory or the `CLOSED` flag;
329
- - validates sync, length and checksum together before accepting a record;
330
- - resynchronises past damage and reports it, rather than stopping;
331
- - skips unrecognised record types by length and reports that it did;
332
- - treats `[0, 0, 0]` workgroup sizes and absent workload blocks as *unknown*, never as zero.
333
-
334
- A conforming **writer**:
335
-
336
- - emits `META` first and `DIRE` last, and patches only `flags` and the directory fields;
337
- - emits a `SYMS` block before any record referencing its strings;
338
- - never gathers symbols into a single trailing block;
339
- - clamps rather than wraps out-of-range span times, and writes 0 for an unknown size;
340
- - records what the device reported, without correcting for timestamp quantization.
341
-
342
- ---
343
-
344
- *Company Named Limited (c) 2026. The format is documented for interoperability; the engine that
345
- writes it is proprietary and source-available under its own licence.*
@@ -1,78 +0,0 @@
1
- the renderer is optimized for large number of instances, and for using PBR shader (`StandardMaterial`)
2
-
3
- ## Normalized Vertex Layout
4
-
5
- * Geometries that are used with StandardShader are expected to conform to a specific Vertex layout.
6
- * Tools are to be provided to deal with relevant conversion.
7
- * Conversion may be done automatically with logged messaged about such, to make the user aware of performance
8
- penalty
9
- * Where possible without sacrificing rendering performance - support non-normalized layouts.
10
-
11
- ## GPU-resident renderer architecture
12
-
13
- * All geometry data (vertex+index) is written into a huge buffer and sits in GPU memory
14
- * All meshes are represented by a small descriptor that resides on GPU
15
- * ⚠️*[IMPOSSIBLE]* All draw is indirect draw, indirect draw batches are prepared in a compute shader
16
- * __Impossible__ on WebGPU, `drawIndirect` as well as `drawIndexedIndirect` only execute 1 draw command from the buffer and not the whole buffer. As a result you're still stuck issuing commands on CPU
17
- * Culling is done on GPU
18
-
19
- ### references:
20
- * https://vkguide.dev/docs/gpudriven/draw_indirect/
21
- * SIGGRAPH-2015 2016 GPU-Driven Rendering Pipelines
22
- * Anti-Aliasing for specular highlights - really good paper https://blog.selfshadow.com/2011/07/22/specular-showdown/
23
-
24
- ### Unordered References
25
- Spatio-temporal variance-guided filtering:
26
- * https://research.nvidia.com/publication/2017-07_spatiotemporal-variance-guided-filtering-real-time-reconstruction-path-traced
27
- * https://diharaw.github.io/post/adventures_in_hybrid_rendering/
28
- * https://github.com/diharaw/hybrid-rendering
29
- * https://github.com/gkjohnson/three-gpu-pathtracer/issues/292
30
-
31
- ### IDEA v2:
32
-
33
- ---
34
-
35
- ### Deferred shading
36
-
37
- - make use of Visibility Buffer to remove material cost of overdraw and better support GPU-resident rendering (see "The Visibility Buffer: A Cache-Friendly Approach to Deferred Shading", 2013 JCGT)
38
- - visibility buffer structure: DEPTH, CLUSTER_ID, TRIANGLE_ID (?)
39
-
40
- #### Geometry Cluster
41
- - collection of indices (index buffer)
42
- - references vertex buffer (a geometry) by index
43
- - A cluster instance also references Mesh that it was produced from
44
-
45
- **problem**: Vertex shader doesn't allow `STORAGE` type buffers, which can have runt-time defined array length, this means that vertex shader can only accept fixed-sided data. This makes decoding of clusters inside vertex shader impossible, as we don't know ahead of time how many clusters we might have.
46
-
47
- #### Draw algorithm
48
-
49
- 1. Cull instances, takes list of instances as input, culls against various constraints, produces another, smaller list
50
- 2. Prepare instances for render by breaking them up into fixed chunks of triangles (64/128), to do this:
51
- 1. prepare buffer with clusters
52
-
53
- ### Textures
54
-
55
- - virtual textures?
56
- - compressed textures, compression support in-engine
57
- - AI texture upscaling, enlarge texture by generating in-between data using a neural network
58
- - Toksvig mapping: https://blog.selfshadow.com/2011/07/22/specular-showdown/
59
-
60
-
61
- ### Variable Rate shading
62
- - Poposal in WebGPU, not in actual standard yet as of 19/05/2024
63
- - VRS is no good for deferred :(
64
- - Adaptive Shading possible
65
- - "Adaptive Undersampling With DACS" https://graphics.geometrian.com/research/dacs.html
66
- - maybe use a similar technique to post-process by creating N number of render targets of smaller resolution and combining them in the final pass (ala checked-board pattern)
67
-
68
- ### Compute swizzling for better cache usage
69
- - https://github.com/LouisBavoil/ThreadGroupIDSwizzling/blob/master/ThreadGroupTilingX.hlsl
70
- - https://developer.nvidia.com/blog/optimizing-compute-shaders-for-l2-locality-using-thread-group-id-swizzling/
71
-
72
-
73
- ## Shadow terminator
74
- * "HACKING THE SHADOW TERMINATOR" by Johannes Hanika ( https://jo.dreggn.org/home/2021_terminator.pdf )
75
-
76
- ## VRS links
77
-
78
- * https://github.com/GameTechDev/VRS-DoF
@@ -1,8 +0,0 @@
1
- * Roll back to env-map sampling until GI is ready
2
- * Implement VRS for shadows
3
- * see "The Rendering of The Callisto Protocol" by Jorge Jimenez, SIGGRAPH 2023
4
- * see AMD VRS
5
- sample: https://github.com/GPUOpen-LibrariesAndSDKs/FidelityFX-SDK/blob/main/sdk/include/FidelityFX/gpu/vrs/ffx_variable_shading.h
6
- * Clustered lighting
7
- * Alpha-tested materials ( consider using VT for alpha(?) and as a substitute for bindless in general )
8
- * TAA at grazing angles messes up textures, need to UNDO jitter during texture sampling
@@ -1,145 +0,0 @@
1
- # Unified Rest-Anchored Delta Animation Blending
2
-
3
- **Status:** Approved & Implemented (Zero Runtime Switches / Enums)
4
-
5
- ## 1. Core Insight: Why Bone Masks, Override Layers, and Runtime Blend Enums Are Not Needed
6
-
7
- In traditional engines where animations are dense full-skeleton arrays, combining a lower-body
8
- animation with an upper-body or additive animation requires runtime **bone masks**, an explicit
9
- **override layer mode**, and a runtime **additive vs. absolute clip switch**.
10
-
11
- `meep-engine` needs none of these:
12
- 1. **`ShadeAnimationClip` is already sparse per-node and per-axis.** A clip's `channels` array only
13
- contains entries for the specific entities (joints) and axes it keys. An upper-body clip with
14
- only upper-body channels leaves every lower-body joint untouched. Any per-bone feathering (e.g.
15
- `Spine_01` moving 30% as much as `Spine_03`) is naturally authored into the keyframe curves.
16
- 2. **Every clip in the runtime is evaluated as a weighted delta from the target joint's Rest Pose
17
- ($V_{\text{rest}}$).**
18
- Instead of accumulating raw $w_i \cdot V_i(t)$ into a zero-based slot (which collapses
19
- translation and scale toward zero whenever $\sum w_i < 1$, and ignores partial weights on single
20
- rotation clips), the apply pass accumulates weighted **deltas from rest**
21
- $w_i \cdot (V_i(t) - V_{\text{rest}})$ and the resolve pass adds the accumulated delta back onto
22
- $V_{\text{rest}}$:
23
- $$V_{\text{final}} = V_{\text{rest}} + \sum_i w_i \cdot \bigl(V_i(t) - V_{\text{rest}}\bigr)$$
24
- (with $R_{\text{final}} = \text{normalize}(R_{\text{rest}} + \sum_i w_i \cdot (R_i(t) - R_{\text{rest}}))$ for rotation).
25
-
26
- ---
27
-
28
- ## 2. Adversarial Pass on the Zero-Runtime-Switch Design
29
-
30
- ### 2.1. Why Naive "Import-Only Zero-Centered Deltas" Fail on a Zero-Based Accumulator
31
- Suppose we kept the old zero-based accumulator ($V_{\text{final}} = \sum_i w_i V_i(t)$) and tried to
32
- bake additive clips at import time as raw zero-centered deltas $\Delta V(t) = V(t) - V_{\text{ref}}$:
33
- - **Failure 1 (Unkeyed Base Channels / `clip.optimize`):** `load_gltf` calls `clip.optimize(rest)`,
34
- stripping un-animated channels. In `Michelle.glb`, `SambaDancing` only keys `Translation` on 1 of
35
- 65 bones (`Hips`) and `Rotation` on 52 of 65 bones. If an additive clip keys a bone or axis that
36
- the base clip does *not* key, the zero-based accumulator receives only $0 + w_{\text{add}} \Delta T$,
37
- **wiping out the bone's rest translation and scale to zero**.
38
- - **Failure 2 (Rotation Collapse on Unkeyed Base Bones):** On a bone whose rotation is not keyed by
39
- the active base clip, a zero-centered quaternion difference $\Delta R = R(t) - R_{\text{ref}}$ has
40
- $w \approx 0$ for small angles. Normalizing $0 + w_{\text{add}} \Delta R$ without $R_{\text{rest}}$
41
- normalizes a pure-imaginary chordal vector, **snapping the bone by $90^\circ$**.
42
- - **Failure 3 (Single Partial-Weight Clip):** On a zero-based accumulator, a single clip fading in
43
- with weight $w \in (0, 1)$ scales translation and scale toward zero ($w \cdot T$, $w \cdot S$)
44
- while leaving rotation at 100% full strength ($\text{normalize}(w \cdot R) = R$), then snaps at
45
- $w = 0$.
46
-
47
- ### 2.2. How Unified Rest-Anchored Delta Accumulation Solves Every Case Without Switches
48
- Under $V_{\text{final}} = V_{\text{rest}} + \sum_i w_i \cdot (V_i(t) - V_{\text{rest}})$:
49
- 1. **Single clip at $w = 1$:**
50
- $$V_{\text{rest}} + 1 \cdot (V_1 - V_{\text{rest}}) = V_1$$
51
- 2. **Silent clip at $w = 0$ (fixes D37/E14 at the root for T, R, and S):**
52
- $$V_{\text{rest}} + 0 \cdot (V_1 - V_{\text{rest}}) = V_{\text{rest}}$$
53
- A bound clip at weight zero never clobbers non-zero rest translation or scale.
54
- 3. **Single partial-body clip fading $w: 0 \to 1$:**
55
- $$V_{\text{rest}} + w \cdot (V_1 - V_{\text{rest}}) = (1 - w) V_{\text{rest}} + w V_1$$
56
- Smoothly interpolates (lerp for T/S, nlerp for R) from the joint's rest pose to $V_1$.
57
- 4. **Two full-body clips crossfading ($w_1 + w_2 = 1$):**
58
- $$V_{\text{rest}} + w_1(V_1 - V_{\text{rest}}) + w_2(V_2 - V_{\text{rest}}) = w_1 V_1 + w_2 V_2$$
59
- Even if `clip.optimize` stripped a constant-at-rest channel from clip 1, clip 1's omitted delta
60
- is identically $0$, so clip 2 still crossfades smoothly against $V_{\text{rest}}$!
61
- 5. **Base clip ($w_{\text{base}} = 1$, or crossfading base clips summing to $1$) + Additive /
62
- Upper-Body clip ($w_{\text{add}} = w$):**
63
- $$V_{\text{rest}} + 1 \cdot (V_{\text{base}} - V_{\text{rest}}) + w \cdot (V_{\text{add}} - V_{\text{rest}}) = V_{\text{base}} + w \cdot \Delta V_{\text{add}}$$
64
- And on any bone/axis that $V_{\text{base}}$ does *not* key, it automatically evaluates to
65
- $V_{\text{rest}} + w \cdot \Delta V_{\text{add}}$.
66
-
67
- ### 2.3. Adversarial Check: Why Quaternion Hemisphere Alignment Must Happen at Import/Build Time, Not Per-Frame in the Apply Shader
68
- Suppose a base clip spins a joint past $180^\circ$ so $\text{dot}(R_{\text{base}}(t), R_{\text{rest}})$
69
- crosses $0$ mid-clip, while an additive clip contributes $w_{\text{add}} \Delta R_{\text{add}}$.
70
- If the apply shader flipped $R_{\text{base}}(t) \to -R_{\text{base}}(t)$ dynamically when
71
- $\text{dot}(R_{\text{base}}(t), R_{\text{rest}}) < 0$, then at the crossing frame the sum would flip
72
- from $+R_{\text{base}} + w_{\text{add}} \Delta R_{\text{add}}$ to
73
- $-R_{\text{base}} + w_{\text{add}} \Delta R_{\text{add}} = -(R_{\text{base}} - w_{\text{add}} \Delta R_{\text{add}})$,
74
- inverting the direction of the additive offset mid-animation!
75
- By keeping sign canonicalization strictly at clip import/creation time (`quat3_canonicalize_sign_run`
76
- anchored to $R_{\text{rest}}$ at keyframe 0 and continuous across consecutive keyframes), curves
77
- remain $C^1$-continuous everywhere and the apply shader has zero sign-flip branches.
78
-
79
- ---
80
-
81
- ## 3. Architecture
82
-
83
- ### 3.1. Accumulator Layout ([`POSE_ACCUMULATOR_LAYOUT.js`](./POSE_ACCUMULATOR_LAYOUT.js))
84
-
85
- Expand each per-row slot in `pose_accumulator` from 16 `u32`s (64 bytes) to 32 `u32`s (128 bytes,
86
- preserving power-of-two shift indexing) so rest translation and rest scale ride alongside rest
87
- rotation:
88
-
89
- ```text
90
- Word Offset Field Description
91
- ──────────────────────────────────────────────────────────────────────────────────────────
92
- [0..3] translation.xyz Σ w_i * (T_i - rest_T)
93
- [3..7] rotation.xyzw Σ w_i * (R_i - rest_R)
94
- [7..10] scale.xyz Σ w_i * (S_i - rest_S)
95
- [10] dirty_mask Bitmask of touched channels (TX, TY, TZ, R, SX, SY, SZ)
96
- [11..15] rest_rotation.xyzw Target joint's rest rotation
97
- [15..18] rest_translation.xyz Target joint's rest translation
98
- [18..21] rest_scale.xyz Target joint's rest scale
99
- [21..32] padding Power-of-two slot alignment (32 u32s = 128 bytes)
100
- ```
101
-
102
- ### 3.2. Zero-Overhead Binding Rest Value ([`ANIMATION_TRACK_BINDING_STRUCT.js`](./ANIMATION_TRACK_BINDING_STRUCT.js))
103
-
104
- Each row in `animation_bindings` targets a single `property` (`Translation`, `Rotation`, or `Scale`)
105
- and already carries a `vec4f` field (`rest_rotation`). By populating that `vec4f` with the target
106
- entity's rest value for its bound `property`—`[tx, ty, tz, 0]` for Translation, `[sx, sy, sz, 0]`
107
- for Scale, and `[rx, ry, rz, rw]` for Rotation, both at binding completion and in
108
- `GPUAnimationManager.#unmute`—the binding struct stays 32 bytes with zero extra memory overhead.
109
-
110
- ### 3.3. GPU Apply & Resolve ([`chunk_pose_accumulator.js`](./chunk_pose_accumulator.js), [`shader_animation_pose_resolve.js`](./shader_animation_pose_resolve.js))
111
-
112
- - **Apply (`chunk_pose_accumulator`):**
113
- - `pose_accumulator_add_translation(row, value, mask, weight, rest)`: for each masked axis $a$,
114
- atomic-adds `value[a] - rest[a] * weight` into `POSE_OFFSET_TRANSLATION + a` and stores
115
- `rest[a]` into `POSE_OFFSET_REST_TRANSLATION + a`.
116
- - `pose_accumulator_add_rotation(row, value, mask, weight, rest)`: substitutes `weight` for a
117
- missing $w$ curve (`let w = select(weight, value.w, (mask & 0x8u) != 0u)`), atomic-adds
118
- `(value.xyz, w) - rest * weight` into `POSE_OFFSET_ROTATION`, and stores `rest` into
119
- `POSE_OFFSET_REST_ROTATION`.
120
- - `pose_accumulator_add_scale(row, value, mask, weight, rest)`: for each masked axis $a$,
121
- atomic-adds `value[a] - rest[a] * weight` into `POSE_OFFSET_SCALE + a` and stores `rest[a]`
122
- into `POSE_OFFSET_REST_SCALE + a`.
123
- - **Resolve (`shader_animation_pose_resolve`):**
124
- - Translation (per dirty axis $a$): `t[a] = rest_t[a] + delta_t[a]`, then zeroes `delta_t[a]`.
125
- - Rotation (when `POSE_DIRTY_R` set): `r = rest_r + delta_r`, zeroes `delta_r`, and writes
126
- `normalize(r)` when `length(r) > 0.0`, else `rest_r`.
127
- - Scale (per dirty axis $a$): `s[a] = rest_s[a] + delta_s[a]`, then zeroes `delta_s[a]`.
128
-
129
- ### 3.4. CPU Twin Lockstep ([`pose_evaluate_local.js`](./pose/pose_evaluate_local.js))
130
-
131
- `pose_evaluate_local(result, target, rest, playbacks)` accumulates `(curve.evaluate(time) - rest_comp) * weight`
132
- into `SUM_TRANSLATION`, `SUM_ROTATION`, and `SUM_SCALE`, and resolves `rest + SUM` (normalizing
133
- rotation with fallback to `rest.rotation` on zero length), matching the GPU bit-for-bit.
134
-
135
- ### 3.5. Import / Authoring Stage Additive Rebasing ([`ShadeAnimationClip.js`](./ShadeAnimationClip.js))
136
-
137
- `ShadeAnimationClip.from_additive(source_clip, { reference_clip, reference_time, rest_of, name })`
138
- rebases a clip authored relative to `reference_clip` at `reference_time` onto each target's rest
139
- pose `rest_of(target)`:
140
- - $T_{\text{out}}(t) = T_{\text{rest}} + (T_{\text{src}}(t) - T_{\text{ref}})$
141
- - $S_{\text{out}}(t) = S_{\text{rest}} + (S_{\text{src}}(t) - S_{\text{ref}})$
142
- - $R_{\text{out}}(t) = (R_{\text{src}}(t) \otimes R_{\text{ref}}^{-1}) \otimes R_{\text{rest}}$,
143
- sign-canonicalized against $R_{\text{rest}}$
144
- - Automatically drops any axis curve or rotation channel whose delta from $V_{\text{ref}}$ is zero
145
- across all keyframes (within `1e-5`).