@woosh/meep-engine 3.15.0 → 3.16.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.
- package/editor/Editor.js +7 -7
- package/editor/actions/concrete/TransformModifyAction.d.ts +4 -4
- package/editor/actions/concrete/TransformModifyAction.d.ts.map +1 -1
- package/editor/actions/concrete/TransformModifyAction.js +4 -4
- package/editor/camera/camera_framing.js +7 -7
- package/editor/ecs/component/editors/ecs/Transform64Editor.d.ts +20 -0
- package/editor/ecs/component/editors/ecs/Transform64Editor.d.ts.map +1 -0
- package/editor/ecs/component/editors/ecs/Transform64Editor.js +70 -0
- package/editor/ecs/component/prototypeObjectEditor.js +2 -2
- package/editor/ecs/component/registerEngineComponentEditors.js +3 -3
- package/editor/particles/effect/ParticleEffectDocument.d.ts +396 -0
- package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -0
- package/editor/particles/effect/ParticleEffectDocument.js +989 -0
- package/editor/particles/effect/ParticleReferenceSimulation.d.ts +113 -0
- package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -0
- package/editor/particles/effect/ParticleReferenceSimulation.js +377 -0
- package/editor/particles/effect/actions/ParticleGroupDefineAction.d.ts +35 -0
- package/editor/particles/effect/actions/ParticleGroupDefineAction.d.ts.map +1 -0
- package/editor/particles/effect/actions/ParticleGroupDefineAction.js +45 -0
- package/editor/particles/effect/make_starter_particle_effect.d.ts +23 -0
- package/editor/particles/effect/make_starter_particle_effect.d.ts.map +1 -0
- package/editor/particles/effect/make_starter_particle_effect.js +177 -0
- package/editor/persistence/buildNewSceneDataset.d.ts.map +1 -1
- package/editor/persistence/buildNewSceneDataset.js +10 -8
- package/editor/process/symbolic/AudioEmitterSymbolicDisplay.js +67 -67
- package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
- package/editor/process/symbolic/GridPositionSymbolicDisplay.js +6 -6
- package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
- package/editor/process/symbolic/ParticleEmitterSymbolicDisplay.d.ts.map +1 -1
- package/editor/process/symbolic/ParticleEmitterSymbolicDisplay.js +6 -3
- package/editor/process/symbolic/PositionedMarkerSymbolicDisplay.js +6 -6
- package/editor/selection/editor_pick.js +130 -130
- package/editor/templates/entity_templates.js +7 -7
- package/editor/tools/TransformToolV2.d.ts +3 -3
- package/editor/tools/TransformToolV2.d.ts.map +1 -1
- package/editor/tools/TransformToolV2.js +58 -25
- package/editor/tools/paint/TerrainHeightPaintTool.d.ts.map +1 -1
- package/editor/tools/paint/TerrainHeightPaintTool.js +11 -9
- package/editor/tools/v2/GizmoNode.js +2 -2
- package/editor/tools/v2/TransformControls.d.ts +3 -3
- package/editor/tools/v2/TransformControls.d.ts.map +1 -1
- package/editor/tools/v2/TransformControls.js +1003 -971
- package/editor/tools/v2/handle/gizmo_drag_plane.d.ts.map +1 -1
- package/editor/tools/v2/handle/gizmo_drag_plane.js +6 -1
- package/editor/view/ecs/components/common/AutoCanvasView.js +17 -0
- package/editor/view/node-graph/NodeGraphEditorView.d.ts +143 -2
- package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphEditorView.js +358 -6
- package/editor/view/node-graph/NodeGraphMinimapView.d.ts +120 -0
- package/editor/view/node-graph/NodeGraphMinimapView.d.ts.map +1 -0
- package/editor/view/node-graph/NodeGraphMinimapView.js +859 -0
- package/editor/view/node-graph/NodeGraphPaletteView.d.ts +112 -0
- package/editor/view/node-graph/NodeGraphPaletteView.d.ts.map +1 -0
- package/editor/view/node-graph/NodeGraphPaletteView.js +352 -0
- package/editor/view/node-graph/NodeGraphSearchMenuView.d.ts +76 -0
- package/editor/view/node-graph/NodeGraphSearchMenuView.d.ts.map +1 -0
- package/editor/view/node-graph/NodeGraphSearchMenuView.js +247 -0
- package/editor/view/node-graph/NodeGraphView.d.ts +147 -5
- package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphView.js +809 -76
- package/editor/view/node-graph/NodeIconView.d.ts +33 -0
- package/editor/view/node-graph/NodeIconView.d.ts.map +1 -0
- package/editor/view/node-graph/NodeIconView.js +54 -0
- package/editor/view/node-graph/NodeView.d.ts +71 -1
- package/editor/view/node-graph/NodeView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeView.js +318 -17
- package/editor/view/node-graph/PortView.d.ts +41 -1
- package/editor/view/node-graph/PortView.d.ts.map +1 -1
- package/editor/view/node-graph/PortView.js +121 -69
- package/editor/view/node-graph/actions/ConnectionDeleteAction.d.ts +16 -3
- package/editor/view/node-graph/actions/ConnectionDeleteAction.d.ts.map +1 -1
- package/editor/view/node-graph/actions/ConnectionDeleteAction.js +29 -3
- package/editor/view/node-graph/actions/NodeCreateAction.d.ts +65 -0
- package/editor/view/node-graph/actions/NodeCreateAction.d.ts.map +1 -0
- package/editor/view/node-graph/actions/NodeCreateAction.js +108 -0
- package/editor/view/node-graph/actions/NodeDeleteAction.d.ts +6 -0
- package/editor/view/node-graph/actions/NodeDeleteAction.d.ts.map +1 -1
- package/editor/view/node-graph/actions/NodeDeleteAction.js +24 -2
- package/editor/view/node-graph/connection_wire_geometry.d.ts +34 -0
- package/editor/view/node-graph/connection_wire_geometry.d.ts.map +1 -1
- package/editor/view/node-graph/connection_wire_geometry.js +79 -3
- package/editor/view/node-graph/node-graph.css +678 -0
- package/editor/view/particles/effect/ParticleCodeEditorView.d.ts +37 -0
- package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleCodeEditorView.js +479 -0
- package/editor/view/particles/effect/ParticleEffectEditorView.d.ts +61 -0
- package/editor/view/particles/effect/ParticleEffectEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleEffectEditorView.js +223 -0
- package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts +25 -0
- package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleEmitterInspectorView.js +606 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +156 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.js +1636 -0
- package/editor/view/particles/effect/ParticleNodeParametersView.d.ts +22 -0
- package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleNodeParametersView.js +520 -0
- package/editor/view/particles/effect/ParticlePreviewView.d.ts +52 -0
- package/editor/view/particles/effect/ParticlePreviewView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticlePreviewView.js +533 -0
- package/editor/view/particles/effect/particle-editor.css +556 -0
- package/editor/view/prepareMeshLibrary.d.ts.map +1 -1
- package/editor/view/prepareMeshLibrary.js +8 -4
- package/package.json +1 -1
- package/samples/engine/first-scene/main.js +152 -152
- package/samples/generation/generators/mir_generator_place_bases.js +3 -3
- package/src/core/assert.d.ts +28 -24
- package/src/core/assert.d.ts.map +1 -1
- package/src/core/assert.js +34 -26
- package/src/core/geom/3d/shape/PosedShape3D.d.ts +17 -0
- package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/PosedShape3D.js +34 -2
- package/src/core/graph/format/graphviz/graphviz_escape_html_label.d.ts +17 -0
- package/src/core/graph/format/graphviz/graphviz_escape_html_label.d.ts.map +1 -0
- package/src/core/graph/format/graphviz/graphviz_escape_html_label.js +25 -0
- package/src/core/graph/format/graphviz/graphviz_escape_quoted.d.ts +16 -0
- package/src/core/graph/format/graphviz/graphviz_escape_quoted.d.ts.map +1 -0
- package/src/core/graph/format/graphviz/graphviz_escape_quoted.js +24 -0
- package/src/core/model/node-graph/NodeGraph.d.ts +12 -0
- package/src/core/model/node-graph/NodeGraph.d.ts.map +1 -1
- package/src/core/model/node-graph/NodeGraph.js +21 -6
- package/src/core/model/node-graph/node/NodeDescription.d.ts +36 -0
- package/src/core/model/node-graph/node/NodeDescription.d.ts.map +1 -1
- package/src/core/model/node-graph/node/NodeDescription.js +41 -0
- package/src/core/model/node-graph/visual/ConnectionVisualData.d.ts +119 -0
- package/src/core/model/node-graph/visual/ConnectionVisualData.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/ConnectionVisualData.js +317 -0
- package/src/core/model/node-graph/visual/NodeDescriptionVisualRegistry.d.ts +4 -0
- package/src/core/model/node-graph/visual/NodeDescriptionVisualRegistry.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/NodeDescriptionVisualRegistry.js +125 -22
- package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts +91 -2
- package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/NodeGraphVisualData.js +164 -113
- package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts +162 -0
- package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.js +288 -0
- package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +109 -0
- package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/LayoutProblem.js +141 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +149 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +175 -0
- package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +137 -0
- package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/RouteGrid.js +242 -0
- package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +114 -0
- package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/RouteSearch.js +300 -0
- package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +86 -0
- package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/RouteSet.js +168 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts +48 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +555 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts +34 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_layers.js +202 -0
- package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts +34 -0
- package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/layout_break_cycles.js +254 -0
- package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts +29 -0
- package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/layout_build_problem.js +184 -0
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +29 -0
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +95 -0
- package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +56 -0
- package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/layout_node_graph.js +131 -0
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +36 -0
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/layout_order_layers.js +415 -0
- package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts +21 -0
- package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/layout_orient_links.js +49 -0
- package/src/core/model/node-graph/visual/layout/route_connections.d.ts +41 -0
- package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/route_connections.js +309 -0
- package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +33 -0
- package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/route_grid_build.js +237 -0
- package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +25 -0
- package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/route_nudge.js +220 -0
- package/src/core/model/node-graph/visual/layout/route_to_spline.d.ts +29 -0
- package/src/core/model/node-graph/visual/layout/route_to_spline.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/route_to_spline.js +120 -0
- package/src/engine/EngineHarness.d.ts.map +1 -1
- package/src/engine/EngineHarness.js +593 -586
- package/src/engine/EntityCreator.js +116 -116
- package/src/engine/achievements/AchievementManager.js +437 -437
- package/src/engine/animation/AnimatedActions.js +111 -111
- package/src/engine/animation/AnimationUtils.d.ts.map +1 -1
- package/src/engine/animation/AnimationUtils.js +246 -234
- package/src/engine/animation/Animations.d.ts +1 -0
- package/src/engine/animation/Animations.d.ts.map +1 -1
- package/src/engine/animation/Animations.js +13 -5
- package/src/engine/animation/clip/bind_property_writer.d.ts.map +1 -1
- package/src/engine/animation/clip/bind_property_writer.js +12 -5
- package/src/engine/animation/curve/binding/BoundTransform64Writer.d.ts +29 -0
- package/src/engine/animation/curve/binding/BoundTransform64Writer.d.ts.map +1 -0
- package/src/engine/animation/curve/binding/BoundTransform64Writer.js +80 -0
- package/src/engine/animation/removeEntityWithMeshParticlesEffect.js +4 -4
- package/src/engine/asset/loaders/gltf_test_fixtures.d.ts.map +1 -1
- package/src/engine/asset/loaders/gltf_test_fixtures.js +5 -4
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +12 -12
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +77 -44
- package/src/engine/control/first-person/abilities/LedgeGrab.js +1 -1
- package/src/engine/control/first-person/abilities/Mantle.js +1 -1
- package/src/engine/control/first-person/abilities/Slide.js +1 -1
- package/src/engine/control/first-person/collision/KinematicMover.d.ts +5 -9
- package/src/engine/control/first-person/collision/KinematicMover.d.ts.map +1 -1
- package/src/engine/control/first-person/collision/KinematicMover.js +59 -29
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +2 -2
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +7 -7
- package/src/engine/ecs/EventType.d.ts +1 -0
- package/src/engine/ecs/EventType.js +35 -10
- package/src/engine/ecs/dynamic_actions/actions/definition/SendRequestActionDescription.d.ts.map +1 -1
- package/src/engine/ecs/dynamic_actions/actions/definition/SendRequestActionDescription.js +12 -4
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts +4 -4
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +10 -11
- package/src/engine/ecs/grid/pick.js +1 -1
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.d.ts +1 -1
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +13 -13
- package/src/engine/ecs/gui/hud/testHudEdgeStick.js +3 -3
- package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts +10 -10
- package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +1 -1
- package/src/engine/ecs/ik/InverseKinematicsSystem.js +8 -8
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts.map +1 -1
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +120 -97
- package/src/engine/ecs/ik/ik_bone_chain.d.ts +16 -5
- package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +1 -1
- package/src/engine/ecs/ik/ik_bone_chain.js +16 -4
- package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts +7 -3
- package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts.map +1 -1
- package/src/engine/ecs/ik/ik_probe_terrain_contact.js +20 -16
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +18 -0
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -0
- package/src/engine/ecs/ik/ik_write_local_rotation.js +30 -0
- package/src/engine/ecs/parent/EntityNode.d.ts +24 -6
- package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
- package/src/engine/ecs/parent/EntityNode.js +54 -42
- package/src/engine/ecs/parent/EntityNodeFlags.d.ts +0 -1
- package/src/engine/ecs/parent/EntityNodeFlags.js +7 -8
- package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
- package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
- package/src/engine/ecs/speaker/VoiceSystem.js +4 -4
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +2 -0
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts +5 -2
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/Terrain.js +7 -4
- package/src/engine/ecs/terrain/ecs/TerrainSystem.js +3 -3
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts +7 -7
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +84 -36
- package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +513 -0
- package/src/engine/ecs/transform/Transform64.d.ts +48 -11
- package/src/engine/ecs/transform/Transform64.d.ts.map +1 -1
- package/src/engine/ecs/transform/Transform64.js +54 -15
- package/src/engine/ecs/transform/Transform64SerializationAdapter.d.ts +37 -0
- package/src/engine/ecs/transform/Transform64SerializationAdapter.d.ts.map +1 -0
- package/src/engine/ecs/transform/Transform64SerializationAdapter.js +75 -0
- package/src/engine/ecs/transform/__probe.d.ts +4 -0
- package/src/engine/ecs/transform/__probe.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_allocation_probe.d.ts +31 -0
- package/src/engine/ecs/transform/t64_allocation_probe.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_allocation_probe.js +78 -0
- package/src/engine/ecs/transform/t64_announce_change.d.ts +33 -0
- package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_announce_change.js +39 -0
- package/src/engine/ecs/transform/t64_equals_components.d.ts +30 -0
- package/src/engine/ecs/transform/t64_equals_components.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_equals_components.js +59 -0
- package/src/engine/ecs/transform/t64_read_rotation.d.ts +13 -0
- package/src/engine/ecs/transform/t64_read_rotation.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_read_rotation.js +16 -0
- package/src/engine/ecs/transform/t64_read_translation.d.ts +14 -0
- package/src/engine/ecs/transform/t64_read_translation.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_read_translation.js +17 -0
- package/src/engine/ecs/transform-attachment/TransformAttachment.d.ts +5 -5
- package/src/engine/ecs/transform-attachment/TransformAttachment.d.ts.map +1 -1
- package/src/engine/ecs/transform-attachment/TransformAttachment.js +4 -4
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts +10 -10
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +71 -20
- package/src/engine/graphics/debug/createDebugLabel.js +3 -3
- package/src/engine/graphics/ecs/camera/pp/PerfectPanner.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +5 -4
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +8 -3
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +6 -6
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +25 -13
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraLanderSystem.js +1 -1
- package/src/engine/graphics/ecs/mesh/setMesh.js +2 -2
- package/src/engine/graphics/ecs/path/entity/EntityPath.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/entity/EntityPath.js +21 -7
- package/src/engine/graphics/ecs/path/entity/EntityPathMarkerDefinition.d.ts +4 -4
- package/src/engine/graphics/ecs/path/entity/EntityPathMarkerDefinition.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/entity/EntityPathMarkerDefinition.js +4 -4
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts +2 -2
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +145 -135
- package/src/engine/graphics/geometry/MikkT/Build4RuleGroups.js +2 -2
- package/src/engine/graphics/geometry/MikkT/DegenEpilogue.js +1 -1
- package/src/engine/graphics/geometry/MikkT/DegenPrologue.js +1 -1
- package/src/engine/graphics/geometry/MikkT/EvalTspace.js +1 -1
- package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +3 -3
- package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +659 -0
- package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +21 -5
- package/src/engine/graphics/render/frame_graph/FrameGraph.d.ts +45 -0
- package/src/engine/graphics/render/frame_graph/FrameGraph.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FrameGraph.js +282 -60
- package/src/engine/graphics/render/frame_graph/FramePassBuilder.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FramePassBuilder.js +20 -9
- package/src/engine/graphics/render/frame_graph/FramePassNode.d.ts +12 -0
- package/src/engine/graphics/render/frame_graph/FramePassNode.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FramePassNode.js +13 -0
- package/src/engine/graphics/render/frame_graph/FramePassResources.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FramePassResources.js +5 -0
- package/src/engine/graphics/render/frame_graph/ResourceEntry.d.ts +19 -1
- package/src/engine/graphics/render/frame_graph/ResourceEntry.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/ResourceEntry.js +23 -1
- package/src/engine/graphics/render/frame_graph/backend/void/VoidRenderContext.d.ts +15 -1
- package/src/engine/graphics/render/frame_graph/backend/void/VoidRenderContext.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/backend/void/VoidRenderContext.js +33 -16
- package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.js +19 -1
- package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +6 -6
- package/src/engine/graphics3/CameraSystem.d.ts +6 -6
- package/src/engine/graphics3/CameraSystem.d.ts.map +1 -1
- package/src/engine/graphics3/CameraSystem.js +170 -170
- package/src/engine/graphics3/DecalSystem.d.ts +6 -6
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem.js +449 -449
- package/src/engine/graphics3/LightSystem.d.ts +6 -6
- package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
- package/src/engine/graphics3/LightSystem.js +234 -221
- package/src/engine/graphics3/MeshSystem.d.ts +6 -6
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem.js +53 -22
- package/src/engine/graphics3/ParticipatingMediaSystem.d.ts +20 -15
- package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -1
- package/src/engine/graphics3/ParticipatingMediaSystem.js +198 -184
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts +6 -6
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/ParticleEmitterSystem.js +310 -289
- package/src/engine/graphics3/PickingSystem.d.ts +6 -6
- package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
- package/src/engine/graphics3/PickingSystem.js +273 -273
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -6
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem.js +180 -169
- package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -1
- package/src/engine/graphics3/TerrainSystem.js +565 -566
- package/src/engine/graphics3/Trail3DSystem.d.ts +6 -6
- package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
- package/src/engine/graphics3/Trail3DSystem.js +221 -221
- package/src/engine/graphics3/camera_sync_from_transform.d.ts +2 -2
- package/src/engine/graphics3/camera_sync_from_transform.d.ts.map +1 -1
- package/src/engine/graphics3/camera_sync_from_transform.js +2 -1
- package/src/engine/graphics3/debug/gizmo_view_from_camera.js +4 -4
- package/src/engine/graphics3/particles/GPUParticularRenderer.d.ts +6 -0
- package/src/engine/graphics3/particles/GPUParticularRenderer.d.ts.map +1 -1
- package/src/engine/graphics3/particles/GPUParticularRenderer.js +82 -53
- package/src/engine/graphics3/particles/particle_gpu_records.d.ts +12 -8
- package/src/engine/graphics3/particles/particle_gpu_records.d.ts.map +1 -1
- package/src/engine/graphics3/particles/particle_gpu_records.js +53 -45
- package/src/engine/graphics3/preview/make_model_preview_scene.js +1 -1
- package/src/engine/graphics3/shade_camera_projection_ray.js +4 -4
- package/src/engine/graphics3/shade_node_to_entity_composition.d.ts.map +1 -1
- package/src/engine/graphics3/shade_node_to_entity_composition.js +88 -84
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts +7 -7
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +8 -8
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +9 -8
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +29 -8
- package/src/engine/input/ecs/controllers/KeyboardCameraController.js +2 -2
- package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +35 -21
- package/src/engine/intelligence/behavior/util/RotationBehavior.js +5 -5
- package/src/engine/intelligence/mcts/StateNode.js +1 -1
- package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +7 -7
- package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -1
- package/src/engine/interpolation/TransformPoseSerializationAdapter.js +14 -15
- package/src/engine/interpolation/pose_interpoland.d.ts +2 -2
- package/src/engine/interpolation/pose_interpoland.js +4 -4
- package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts +4 -4
- package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts.map +1 -1
- package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +39 -14
- package/src/engine/network/adapters/TransformReplicationAdapter.d.ts +7 -7
- package/src/engine/network/adapters/TransformReplicationAdapter.d.ts.map +1 -1
- package/src/engine/network/adapters/TransformReplicationAdapter.js +19 -20
- package/src/engine/network/replication/Replicator.d.ts +5 -3
- package/src/engine/network/replication/Replicator.d.ts.map +1 -1
- package/src/engine/network/replication/Replicator.js +65 -16
- package/src/engine/physics/broadphase/compute_fat_world_aabb.js +3 -3
- package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
- package/src/engine/physics/ccd/linear_sweep.js +9 -3
- package/src/engine/physics/constraint/solve_constraints.js +10 -10
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +8 -8
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/ColliderObserverSystem.js +6 -6
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +22 -32
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +2337 -2310
- package/src/engine/physics/ecs/find_non_finite_physics_state.js +6 -6
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +7 -7
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +16 -8
- package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +4 -4
- package/src/engine/physics/fluid/ecs/FluidSystem.d.ts.map +1 -1
- package/src/engine/physics/fluid/ecs/FluidSystem.js +6 -6
- package/src/engine/physics/fluid/ecs/WorkerFluidSystem.d.ts +2 -2
- package/src/engine/physics/fluid/ecs/WorkerFluidSystem.d.ts.map +1 -1
- package/src/engine/physics/fluid/ecs/WorkerFluidSystem.js +4 -4
- package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +7 -7
- package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +4 -4
- package/src/engine/physics/fluid/effector/WakeFluidEffector.js +7 -7
- package/src/engine/physics/inertia/world_inverse_inertia.js +1 -1
- package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_position.js +13 -12
- package/src/engine/physics/inverse_kinematics/fabrik/fabrik_solve.d.ts.map +1 -1
- package/src/engine/physics/inverse_kinematics/fabrik/fabrik_solve.js +23 -5
- package/src/engine/physics/narrowphase/compute_penetration.js +18 -14
- package/src/engine/physics/narrowphase/convex_convex_manifold.js +2 -2
- package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +9 -9
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +95 -68
- package/src/engine/physics/narrowphase/refine_ray_concave.js +1 -1
- package/src/engine/physics/narrowphase/refine_ray_hit.js +3 -3
- package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -1
- package/src/engine/physics/queries/overlap_shape.js +19 -7
- package/src/engine/physics/queries/raycast.js +3 -3
- package/src/engine/physics/queries/shape_cast.d.ts.map +1 -1
- package/src/engine/physics/queries/shape_cast.js +628 -620
- package/src/engine/physics/solver/solve_contacts.js +10 -10
- package/src/engine/physics/vehicle/RaycastVehicle.d.ts +6 -5
- package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
- package/src/engine/physics/vehicle/RaycastVehicle.js +10 -5
- package/src/engine/sound/ecs/SoundListenerSystem.d.ts +16 -4
- package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/SoundListenerSystem.js +70 -11
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts +7 -7
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.js +343 -338
- package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts +2 -2
- package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts.map +1 -1
- package/src/engine/sound/ecs/audio/LiveEmitterSet.js +356 -345
- package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts +23 -2
- package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts.map +1 -1
- package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +174 -140
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.d.ts +6 -6
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.js +185 -184
- package/src/engine/sound/material/detector/terrain/TerrainSoundMaterialSurfaceDetector.js +1 -1
- package/src/engine/sound/simulation/core/AcousticRegionIndex.d.ts +2 -1
- package/src/engine/sound/simulation/core/AcousticRegionIndex.d.ts.map +1 -1
- package/src/engine/sound/simulation/core/AcousticRegionIndex.js +4 -3
- package/src/engine/sound/simulation/core/AcousticVolumeRegion.d.ts +3 -2
- package/src/engine/sound/simulation/core/AcousticVolumeRegion.d.ts.map +1 -1
- package/src/engine/sound/simulation/core/AcousticVolumeRegion.js +6 -4
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +10 -6
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +32 -7
- package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.d.ts +7 -7
- package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.d.ts.map +1 -1
- package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.js +6 -6
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/EventInstance.js +8 -2
- package/src/format/scene/gltf/gltf_component_type.d.ts.map +1 -1
- package/src/format/scene/gltf/gltf_component_type.js +3 -1
- package/src/format/texture/ktx2/ktx2_read.d.ts.map +1 -1
- package/src/format/texture/ktx2/ktx2_read.js +2 -1
- package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.d.ts.map +1 -1
- package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +8 -1
- package/src/generation/markers/GridCellActionPlaceMarker.d.ts +4 -4
- package/src/generation/markers/GridCellActionPlaceMarker.d.ts.map +1 -1
- package/src/generation/markers/GridCellActionPlaceMarker.js +16 -6
- package/src/generation/markers/MarkerNode.d.ts +3 -3
- package/src/generation/markers/MarkerNode.d.ts.map +1 -1
- package/src/generation/markers/MarkerNode.js +3 -3
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.d.ts +4 -4
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.d.ts.map +1 -1
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +7 -7
- package/src/generation/markers/actions/MarkerNodeActionImaginary.d.ts.map +1 -1
- package/src/generation/markers/actions/MarkerNodeActionImaginary.js +20 -2
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.js +1 -1
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.d.ts.map +1 -1
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.js +13 -3
- package/src/generation/markers/transform/MarkerNodeTransformRotateRandom.d.ts.map +1 -1
- package/src/generation/markers/transform/MarkerNodeTransformRotateRandom.js +11 -1
- package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.d.ts.map +1 -1
- package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.js +8 -4
- package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.d.ts.map +1 -1
- package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +13 -5
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.d.ts.map +1 -1
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js +8 -2
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.d.ts.map +1 -1
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.js +16 -2
- package/src/shade/device/graph/BufferResourceDescriptor.d.ts.map +1 -1
- package/src/shade/device/graph/BufferResourceDescriptor.js +193 -184
- package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
- package/src/shade/device/graph/TextureResourceDescriptor.js +12 -0
- package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUDevice.js +8 -0
- package/src/shade/playground/avboit/main.js +3 -3
- package/src/shade/playground/basis_textures/main.js +1 -1
- package/src/shade/playground/ground_seam/main.js +1 -1
- package/src/shade/playground/particle_editor/README.md +175 -0
- package/src/shade/playground/particle_editor/index.html +76 -0
- package/src/shade/playground/particle_editor/main.d.ts +2 -0
- package/src/shade/playground/particle_editor/main.d.ts.map +1 -0
- package/src/shade/playground/particle_editor/main.js +139 -0
- package/src/shade/playground/particle_system/README.md +92 -62
- package/src/shade/playground/particle_system/index.html +67 -21
- package/src/shade/playground/particle_system/main.js +247 -102
- package/src/shade/{renderer/particles → playground/particle_system}/particle_prototype.d.ts +21 -18
- package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -0
- package/src/shade/{renderer/particles → playground/particle_system}/particle_prototype.js +197 -181
- package/src/shade/playground/particle_system/particle_scene.d.ts +136 -20
- package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_scene.js +487 -670
- package/src/shade/playground/skinned_blas_refit/sweep_views.js +2 -2
- package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.js +2 -1
- package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +2 -1
- package/src/shade/playground/sponza_path_trace/main.js +1 -1
- package/src/shade/playground/volumetrics_froxel/main.js +917 -917
- package/src/shade/playground/volumetrics_froxel/measure.js +559 -559
- package/src/shade/renderer/Renderer.d.ts +28 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +140 -8
- package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/GPUSky.js +4 -2
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts.map +1 -1
- package/src/shade/renderer/buffer/graph_read_buffer.js +8 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts +30 -0
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.js +84 -0
- package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +27 -0
- package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/gpu_database_words.d.ts +24 -0
- package/src/shade/renderer/buffer/table/gpu_database_words.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/gpu_database_words.js +92 -0
- package/src/shade/renderer/camera/Camera.d.ts +2 -2
- package/src/shade/renderer/camera/Camera.d.ts.map +1 -1
- package/src/shade/renderer/camera/Camera.js +11 -5
- package/src/shade/renderer/camera/GPUCameraContext.d.ts.map +1 -1
- package/src/shade/renderer/camera/GPUCameraContext.js +2 -1
- package/src/shade/renderer/camera/OrbitalCameraController.d.ts +3 -3
- package/src/shade/renderer/camera/OrbitalCameraController.d.ts.map +1 -1
- package/src/shade/renderer/camera/OrbitalCameraController.js +31 -16
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +2 -2
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +4 -3
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +10 -5
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +8 -4
- package/src/shade/renderer/extension/FrameContext.d.ts.map +1 -1
- package/src/shade/renderer/extension/FrameContext.js +5 -0
- package/src/shade/renderer/extension/FrameRecord.d.ts +16 -0
- package/src/shade/renderer/extension/FrameRecord.d.ts.map +1 -1
- package/src/shade/renderer/extension/FrameRecord.js +31 -0
- package/src/shade/renderer/extension/GBufferTextures.d.ts +11 -0
- package/src/shade/renderer/extension/GBufferTextures.d.ts.map +1 -1
- package/src/shade/renderer/extension/GBufferTextures.js +14 -0
- package/src/shade/renderer/geometry/attribute/gpu_vertex_buffer_layout_from_spec.js +1 -1
- package/src/shade/renderer/geometry/util/geometry_stripify.js +6 -6
- package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.js +8 -8
- package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.js +14 -5
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +17 -9
- package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.js +4 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +11 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/graph_lpv_shade.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/graph_lpv_shade.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/graph_lpv_shade.js +4 -2
- package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js +5 -1
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +35 -11
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/particles/DESIGN.md +271 -112
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +251 -86
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +822 -146
- package/src/shade/renderer/particles/ParticleConstants.d.ts +96 -3
- package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
- package/src/shade/renderer/particles/ParticleConstants.js +103 -4
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +5 -4
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +11 -15
- package/src/shade/renderer/particles/coherence/shader_particle_bucket.d.ts +2 -2
- package/src/shade/renderer/particles/coherence/shader_particle_bucket.d.ts.map +1 -1
- package/src/shade/renderer/particles/coherence/shader_particle_bucket.js +20 -15
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts +7 -8
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.js +7 -17
- package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.d.ts +56 -0
- package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.d.ts.map +1 -0
- package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.js +68 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts +39 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts.map +1 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.js +52 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +83 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +166 -0
- package/src/shade/renderer/particles/data/chunk_particle_emitter.d.ts +21 -5
- package/src/shade/renderer/particles/data/chunk_particle_emitter.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/chunk_particle_emitter.js +44 -85
- package/src/shade/renderer/particles/data/particle_header.d.ts +62 -0
- package/src/shade/renderer/particles/data/particle_header.d.ts.map +1 -0
- package/src/shade/renderer/particles/data/particle_header.js +103 -0
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +179 -0
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -0
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +120 -1
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +90 -1
- package/src/shade/renderer/particles/graph/ParticleNodeGroup.d.ts +283 -0
- package/src/shade/renderer/particles/graph/ParticleNodeGroup.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/ParticleNodeGroup.js +419 -0
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +44 -2
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +476 -40
- package/src/shade/renderer/particles/graph/ParticleValueType.d.ts +188 -0
- package/src/shade/renderer/particles/graph/ParticleValueType.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/ParticleValueType.js +287 -0
- package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts +16 -9
- package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/compile_particle_graph.js +464 -205
- package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts +11 -0
- package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/flatten_particle_graph.js +213 -0
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts +27 -0
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +75 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts +83 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +319 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts +22 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +517 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_utility.d.ts +70 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_utility.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_utility.js +161 -0
- package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts +8 -0
- package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/groups/simplex_reference.js +159 -0
- package/src/shade/renderer/particles/graph/infer_particle_graph_types.d.ts +88 -0
- package/src/shade/renderer/particles/graph/infer_particle_graph_types.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/infer_particle_graph_types.js +234 -0
- package/src/shade/renderer/particles/graph/make_particle_group.d.ts +98 -0
- package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/make_particle_group.js +427 -0
- package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts +11 -4
- package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_graph_authoring.js +121 -108
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +38 -0
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +25 -0
- package/src/shade/renderer/particles/graph/particle_graph_distributions.d.ts +29 -0
- package/src/shade/renderer/particles/graph/particle_graph_distributions.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_graph_distributions.js +170 -0
- package/src/shade/renderer/particles/graph/particle_graph_json.d.ts +87 -0
- package/src/shade/renderer/particles/graph/particle_graph_json.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_graph_json.js +196 -0
- package/src/shade/renderer/particles/graph/particle_group_json.d.ts +86 -0
- package/src/shade/renderer/particles/graph/particle_group_json.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_group_json.js +182 -0
- package/src/shade/renderer/particles/graph/particle_group_library.d.ts +33 -0
- package/src/shade/renderer/particles/graph/particle_group_library.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_group_library.js +75 -0
- package/src/shade/renderer/particles/graph/particle_node_library.d.ts +37 -0
- package/src/shade/renderer/particles/graph/particle_node_library.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_node_library.js +64 -0
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +146 -0
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_node_parameters.js +234 -0
- package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts +30 -0
- package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_node_presentation.js +286 -0
- package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +66 -0
- package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/validate_particle_graph.js +439 -0
- package/src/shade/renderer/particles/graph_particles.d.ts +143 -68
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +424 -71
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts +107 -0
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph_particles_avboit.js +312 -0
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts +41 -8
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/InstructionStream.js +111 -33
- package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts +13 -10
- package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleAssembler.js +30 -26
- package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +27 -15
- package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleProgram.js +139 -34
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +117 -9
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleVMISA.js +296 -37
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts +149 -0
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -0
- package/src/shade/renderer/particles/isa/particle_assembly.js +999 -0
- package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +25 -3
- package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
- package/src/shade/renderer/particles/layout/ParticleLayout.js +33 -5
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +160 -0
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +478 -0
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +291 -0
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +647 -0
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +95 -0
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +213 -0
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +16 -0
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +223 -0
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +121 -0
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +206 -0
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +11 -0
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +197 -0
- package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.js +51 -0
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +561 -0
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +72 -0
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +86 -0
- package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_peephole.js +271 -0
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +268 -0
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +151 -0
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts +131 -0
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -0
- package/src/shade/renderer/particles/particle_test_fixtures.js +203 -0
- package/src/shade/renderer/particles/runtime/Emitter.d.ts +219 -0
- package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +128 -60
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/EmitterRegistry.js +286 -117
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +264 -0
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/ParticleEmitter.js +404 -0
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +49 -15
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +51 -18
- package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ProgramArena.js +72 -32
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +4 -4
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/create_particle_effect.js +4 -4
- package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +15 -0
- package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.d.ts +17 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js +75 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts +20 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +94 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +15 -5
- package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts +1 -2
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.js +1 -2
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts +11 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.js +13 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_age.d.ts +17 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_age.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_age.js +22 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts +14 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.js +23 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_scene_view_depth.d.ts +18 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_scene_view_depth.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_scene_view_depth.js +24 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.d.ts +26 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.js +59 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts +14 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +153 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.d.ts +3 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.js +124 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts +19 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.js +147 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -8
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +72 -37
- package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.d.ts +5 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.js +216 -0
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +7 -3
- package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_render.js +132 -197
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +78 -24
- package/src/shade/renderer/particles/shaders/shader_particle_spawn_commands.d.ts +26 -0
- package/src/shade/renderer/particles/shaders/shader_particle_spawn_commands.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_spawn_commands.js +66 -0
- package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts +1 -1
- package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
- package/src/shade/renderer/particles/sort/shader_particle_sort.js +21 -36
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +2 -2
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.js +100 -90
- package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/chunk_particle_vm.js +270 -138
- package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.d.ts +1 -2
- package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.js +0 -3
- package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.js +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.js +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.js +3 -2
- package/src/shade/renderer/postprocess/nss/generate_NSS_WEIGHTS_ACTUAL.js +3 -2
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +87 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +61 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +179 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +27 -2
- package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts +9 -2
- package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +12 -3
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.d.ts +18 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.js +58 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +25 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +69 -10
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js +10 -4
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +4 -39
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts +7 -2
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +16 -2
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts +3 -3
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.js +29 -23
- package/src/shade/renderer/scene/optimization/geometry/internal/anchor_grow_topological.d.ts +2 -2
- package/src/shade/renderer/scene/optimization/geometry/internal/anchor_grow_topological.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/internal/anchor_grow_topological.js +3 -3
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts +4 -4
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.js +2 -2
- package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.d.ts +2 -2
- package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.js +2 -2
- package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.d.ts +7 -7
- package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.js +79 -71
- package/src/shade/renderer/shader/chunk/math/chunk_lower_bound_branchless.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/math/chunk_lower_bound_branchless.js +3 -1
- package/src/shade/renderer/shader/chunk/random/chunk_hash_to_float01.d.ts +13 -3
- package/src/shade/renderer/shader/chunk/random/chunk_hash_to_float01.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/random/chunk_hash_to_float01.js +15 -5
- package/src/shade/renderer/shader/chunk/random/chunk_random_uint.d.ts +8 -0
- package/src/shade/renderer/shader/chunk/random/chunk_random_uint.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/random/chunk_random_uint.js +15 -5
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg.d.ts +7 -0
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg.js +17 -7
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_advance.d.ts +17 -0
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_advance.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_advance.js +26 -0
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_output.d.ts +15 -0
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_output.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_output.js +26 -0
- package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +8 -2
- package/src/shade/renderer/shadow/map/PointLightShadowmap.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/PointLightShadowmap.js +7 -2
- package/src/shade/renderer/shadow/map/SpotLightShadowmap.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +3 -15
- package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +10 -4
- package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.d.ts.map +1 -1
- package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.js +7 -2
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +2 -2
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +3 -3
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +3 -3
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +66 -5
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +35 -4
- package/src/view/minimap/Minimap.d.ts.map +1 -1
- package/src/view/minimap/Minimap.js +227 -225
- package/src/view/minimap/MinimapCanvasView.js +3 -3
- package/src/view/minimap/MinimapMarker.d.ts +45 -0
- package/src/view/minimap/MinimapMarker.d.ts.map +1 -0
- package/src/view/minimap/MinimapMarker.js +80 -0
- package/src/view/minimap/MinimapMarkerCollection.d.ts +6 -5
- package/src/view/minimap/MinimapMarkerCollection.d.ts.map +1 -1
- package/src/view/minimap/MinimapMarkerCollection.js +6 -6
- package/src/view/minimap/MinimapMarkerSerializationAdapter.d.ts +19 -0
- package/src/view/minimap/MinimapMarkerSerializationAdapter.d.ts.map +1 -0
- package/src/view/minimap/MinimapMarkerSerializationAdapter.js +42 -0
- package/src/view/minimap/dom/MinimapCameraView.d.ts +1 -1
- package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapCameraView.js +23 -4
- package/src/view/minimap/dom/MinimapMarkerView.js +3 -3
- package/src/view/minimap/gl/MarkerGL.js +3 -3
- package/src/view/util/DomLayoutFrame.d.ts +53 -0
- package/src/view/util/DomLayoutFrame.d.ts.map +1 -0
- package/src/view/util/DomLayoutFrame.js +122 -0
- package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.js +0 -19
- package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.js +0 -241
- package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.js +0 -40
- package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.js +0 -28
- package/src/engine/ecs/util/hideEntityGracefully.js +0 -196
- package/src/shade/renderer/particles/cull/chunk_particle_cull.js +0 -38
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.js +0 -214
- package/src/shade/renderer/particles/particle_prototype.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.js +0 -86
- package/src/shade/renderer/particles/runtime/spawn_request_encoding.js +0 -52
- package/src/shade/renderer/particles/shaders/chunk_particle_context.js +0 -58
|
@@ -1,559 +1,559 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The measurement protocol from this page's README, as code.
|
|
3
|
-
*
|
|
4
|
-
* Not imported by the page — it is loaded from the console when there is something to measure:
|
|
5
|
-
*
|
|
6
|
-
* ```js
|
|
7
|
-
* const m = await (await import('./measure.js')).attach();
|
|
8
|
-
* await m.ab(v => globalThis.__VOL_TAA_ENABLED = v, false, true);
|
|
9
|
-
* ```
|
|
10
|
-
*
|
|
11
|
-
* It exists because every trap the README lists is a trap about *procedure*, and a procedure
|
|
12
|
-
* written down in prose gets followed differently each time. Three of them are structural and are
|
|
13
|
-
* dealt with here rather than left to the operator:
|
|
14
|
-
*
|
|
15
|
-
* - **The canvas cannot be read back.** A canvas texture is configured by the presentation path,
|
|
16
|
-
* cannot carry `COPY_SRC`, and is rotated away the moment the frame is presented — a `drawImage`
|
|
17
|
-
* off it a task later returns an empty bitmap, and a comparison of two blanks reports perfect
|
|
18
|
-
* agreement. Everything here renders into a texture this module owns, via
|
|
19
|
-
* `Renderer.render_to_target`, which shares the view context (and therefore all the temporal
|
|
20
|
-
* history) with the canvas path.
|
|
21
|
-
*
|
|
22
|
-
* - **Presentation throttling.** Whole-frame timing off the page's own loop is paced by the swap
|
|
23
|
-
* chain, which is why the README says two settings that plainly differ can report the same
|
|
24
|
-
* number. Driving the frames from here removes the swap chain from the measurement entirely.
|
|
25
|
-
*
|
|
26
|
-
* - **The noise floor has to pay the same costs the signal does.** `ab` takes the floor by making
|
|
27
|
-
* an identical no-op change and settling exactly as the real change does, and it interleaves the
|
|
28
|
-
* two sides so drift lands on both.
|
|
29
|
-
*
|
|
30
|
-
* The camera-path helpers exist for a narrower reason: a structure that is fitted to the camera can
|
|
31
|
-
* be perfectly correct standing still and swim under motion, and the froxel volume then goes
|
|
32
|
-
* through a 0.95-blend temporal filter that turns swimming into either ghosting or flicker. Neither
|
|
33
|
-
* is visible in a still. `fly` drives a pose sequence one frame at a time and records what the
|
|
34
|
-
* image does while it happens.
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param {object} [context] defaults to the globals the page publishes
|
|
39
|
-
* @param {Renderer} [context.renderer]
|
|
40
|
-
* @param {Scene} [context.scene]
|
|
41
|
-
* @param {PerspectiveCamera} [context.camera]
|
|
42
|
-
* @param {OrbitalCameraController} [context.controller]
|
|
43
|
-
*/
|
|
44
|
-
export async function attach({
|
|
45
|
-
renderer = globalThis.renderer,
|
|
46
|
-
scene = globalThis.scene,
|
|
47
|
-
camera = globalThis.camera,
|
|
48
|
-
controller = globalThis.controller,
|
|
49
|
-
} = {}) {
|
|
50
|
-
|
|
51
|
-
const { GPUTextureContext } = await import('../../renderer/texture/GPUTextureContext.js');
|
|
52
|
-
|
|
53
|
-
const device = renderer.device;
|
|
54
|
-
|
|
55
|
-
/** @type {object|null} */
|
|
56
|
-
let capture = null;
|
|
57
|
-
|
|
58
|
-
// The page's loop must stop, and not only so the frame count is ours: it also assigns
|
|
59
|
-
// `renderer.pixel_ratio = window.devicePixelRatio` on every tick, ahead of its own pause check,
|
|
60
|
-
// so a raised pixel ratio would be undone before the next frame.
|
|
61
|
-
const pause_button = document.getElementById('pause');
|
|
62
|
-
|
|
63
|
-
if (pause_button !== null && pause_button.textContent === 'Pause') {
|
|
64
|
-
pause_button.click();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// A/B is meaningless with eye adaptation running — it keeps drifting for seconds after any
|
|
68
|
-
// change, by more than most changes to this pass are worth.
|
|
69
|
-
renderer.feature_automatic_exposure_enabled = false;
|
|
70
|
-
|
|
71
|
-
function make_target() {
|
|
72
|
-
if (capture !== null) {
|
|
73
|
-
capture.destroy();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const resolution = renderer.output_resolution;
|
|
77
|
-
|
|
78
|
-
const width = resolution.x;
|
|
79
|
-
const height = resolution.y;
|
|
80
|
-
|
|
81
|
-
// the rule the renderer's own context configuration follows
|
|
82
|
-
const format = window.matchMedia('(dynamic-range: high)').matches
|
|
83
|
-
? 'rgba16float'
|
|
84
|
-
: navigator.gpu.getPreferredCanvasFormat();
|
|
85
|
-
|
|
86
|
-
const texture = device.createTexture({
|
|
87
|
-
label: 'measure/capture',
|
|
88
|
-
size: [width, height, 1],
|
|
89
|
-
format,
|
|
90
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
91
|
-
| GPUTextureUsage.COPY_SRC
|
|
92
|
-
| GPUTextureUsage.COPY_DST
|
|
93
|
-
| GPUTextureUsage.TEXTURE_BINDING,
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const bytes_per_pixel = format === 'rgba16float' ? 8 : 4;
|
|
97
|
-
|
|
98
|
-
// copyTextureToBuffer wants rows on a 256-byte boundary
|
|
99
|
-
const bytes_per_row = Math.ceil(width * bytes_per_pixel / 256) * 256;
|
|
100
|
-
|
|
101
|
-
capture = {
|
|
102
|
-
texture,
|
|
103
|
-
target: GPUTextureContext.fromTexture(texture, device),
|
|
104
|
-
width,
|
|
105
|
-
height,
|
|
106
|
-
format,
|
|
107
|
-
bytes_per_row,
|
|
108
|
-
buffer: device.createBuffer({
|
|
109
|
-
label: 'measure/readback',
|
|
110
|
-
size: bytes_per_row * height,
|
|
111
|
-
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
112
|
-
}),
|
|
113
|
-
destroy() {
|
|
114
|
-
this.texture.destroy();
|
|
115
|
-
this.buffer.destroy();
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
return capture;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function target() {
|
|
123
|
-
const resolution = renderer.output_resolution;
|
|
124
|
-
|
|
125
|
-
if (capture === null || capture.width !== resolution.x || capture.height !== resolution.y) {
|
|
126
|
-
make_target();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return capture;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function half_to_float(h) {
|
|
133
|
-
const sign = (h & 0x8000) !== 0 ? -1 : 1;
|
|
134
|
-
const exponent = (h & 0x7C00) >> 10;
|
|
135
|
-
const fraction = h & 0x03FF;
|
|
136
|
-
|
|
137
|
-
if (exponent === 0) {
|
|
138
|
-
return sign * Math.pow(2, -14) * (fraction / 1024);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (exponent === 31) {
|
|
142
|
-
return fraction !== 0 ? NaN : sign * Infinity;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return sign * Math.pow(2, exponent - 15) * (1 + fraction / 1024);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/** One frame into the owned target. */
|
|
149
|
-
function frame(time_delta_s = 1 / 60) {
|
|
150
|
-
renderer.render_to_target(camera, scene, time_delta_s, target().target);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/** `n` frames, awaited, with nothing read back — for letting the temporal filter converge. */
|
|
154
|
-
async function settle(n) {
|
|
155
|
-
for (let i = 0; i < n; i++) {
|
|
156
|
-
frame();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
await device.queue.onSubmittedWorkDone();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Per-pixel luminance of whatever is in the capture texture, added into `out`.
|
|
164
|
-
*
|
|
165
|
-
* @param {Float32Array} out length width*height
|
|
166
|
-
*/
|
|
167
|
-
async function accumulate_luminance(out) {
|
|
168
|
-
const c = target();
|
|
169
|
-
|
|
170
|
-
const encoder = device.createCommandEncoder({ label: 'measure/readback' });
|
|
171
|
-
|
|
172
|
-
encoder.copyTextureToBuffer(
|
|
173
|
-
{ texture: c.texture },
|
|
174
|
-
{ buffer: c.buffer, bytesPerRow: c.bytes_per_row },
|
|
175
|
-
[c.width, c.height, 1]
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
device.queue.submit([encoder.finish()]);
|
|
179
|
-
|
|
180
|
-
await c.buffer.mapAsync(GPUMapMode.READ);
|
|
181
|
-
|
|
182
|
-
const raw = c.buffer.getMappedRange();
|
|
183
|
-
|
|
184
|
-
// The channel order is not cosmetic here: the preferred canvas format on Windows is
|
|
185
|
-
// bgra8unorm, and weighting it as if it were rgba silently swaps the 0.2126 and 0.0722
|
|
186
|
-
// coefficients — still a usable difference metric, but not the luminance it claims to be.
|
|
187
|
-
if (c.format === 'rgba16float') {
|
|
188
|
-
const source = new Uint16Array(raw);
|
|
189
|
-
const stride = c.bytes_per_row / 2;
|
|
190
|
-
|
|
191
|
-
for (let y = 0; y < c.height; y++) {
|
|
192
|
-
for (let x = 0; x < c.width; x++) {
|
|
193
|
-
const i = y * stride + x * 4;
|
|
194
|
-
|
|
195
|
-
out[y * c.width + x] += 0.2126 * half_to_float(source[i])
|
|
196
|
-
+ 0.7152 * half_to_float(source[i + 1])
|
|
197
|
-
+ 0.0722 * half_to_float(source[i + 2]);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
} else {
|
|
201
|
-
const source = new Uint8Array(raw);
|
|
202
|
-
const bgra = c.format.startsWith('bgra');
|
|
203
|
-
|
|
204
|
-
for (let y = 0; y < c.height; y++) {
|
|
205
|
-
for (let x = 0; x < c.width; x++) {
|
|
206
|
-
const i = y * c.bytes_per_row + x * 4;
|
|
207
|
-
|
|
208
|
-
const r = bgra ? source[i + 2] : source[i];
|
|
209
|
-
const b = bgra ? source[i] : source[i + 2];
|
|
210
|
-
|
|
211
|
-
out[y * c.width + x] += 0.2126 * r + 0.7152 * source[i + 1] + 0.0722 * b;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
c.buffer.unmap();
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Settle, then average. The two numbers are the README's protocol: ~45 frames of
|
|
221
|
-
* re-convergence after any change that resets temporal accumulation, then a multi-frame average
|
|
222
|
-
* because the column jitter and the sample RNG both key on the frame index and consecutive
|
|
223
|
-
* frames genuinely differ.
|
|
224
|
-
*
|
|
225
|
-
* @returns {Promise<Float32Array>} mean luminance per pixel
|
|
226
|
-
*/
|
|
227
|
-
async function capture_average({ settle: settle_frames = 45, average = 32 } = {}) {
|
|
228
|
-
await settle(settle_frames);
|
|
229
|
-
|
|
230
|
-
const c = target();
|
|
231
|
-
const accumulator = new Float32Array(c.width * c.height);
|
|
232
|
-
|
|
233
|
-
for (let i = 0; i < average; i++) {
|
|
234
|
-
frame();
|
|
235
|
-
await device.queue.onSubmittedWorkDone();
|
|
236
|
-
await accumulate_luminance(accumulator);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
for (let i = 0; i < accumulator.length; i++) {
|
|
240
|
-
accumulator[i] /= average;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return accumulator;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function mean(values) {
|
|
247
|
-
let sum = 0;
|
|
248
|
-
|
|
249
|
-
for (let i = 0; i < values.length; i++) {
|
|
250
|
-
sum += values[i];
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return sum / values.length;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Prefer the signed mean when the change has a direction — it discriminates far better than the
|
|
258
|
-
* mean absolute, which is dominated by noise.
|
|
259
|
-
*/
|
|
260
|
-
function compare(a, b) {
|
|
261
|
-
let signed = 0;
|
|
262
|
-
let absolute = 0;
|
|
263
|
-
let largest = 0;
|
|
264
|
-
|
|
265
|
-
for (let i = 0; i < a.length; i++) {
|
|
266
|
-
const d = b[i] - a[i];
|
|
267
|
-
|
|
268
|
-
signed += d;
|
|
269
|
-
absolute += Math.abs(d);
|
|
270
|
-
|
|
271
|
-
if (Math.abs(d) > largest) {
|
|
272
|
-
largest = Math.abs(d);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return {
|
|
277
|
-
signed_mean: signed / a.length,
|
|
278
|
-
mean_abs: absolute / a.length,
|
|
279
|
-
max_abs: largest,
|
|
280
|
-
mean_a: mean(a),
|
|
281
|
-
mean_b: mean(b),
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* An interleaved A/B with its own noise floor.
|
|
287
|
-
*
|
|
288
|
-
* `apply` is called with `a` and with `b`; it must be the whole of the change, and cheap enough
|
|
289
|
-
* that the two sides pay the same fixed costs. Both sides then go through the identical
|
|
290
|
-
* settle-and-average, and the floor comes from the two captures of the *same* setting, which is
|
|
291
|
-
* what makes a small result readable — anything at or below the floor has not been shown.
|
|
292
|
-
*/
|
|
293
|
-
async function ab(apply, a, b, options = {}) {
|
|
294
|
-
const run = async (value) => {
|
|
295
|
-
apply(value);
|
|
296
|
-
renderer.indicate_view_change();
|
|
297
|
-
return capture_average(options);
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
const a1 = await run(a);
|
|
301
|
-
const b1 = await run(b);
|
|
302
|
-
const a2 = await run(a);
|
|
303
|
-
const b2 = await run(b);
|
|
304
|
-
|
|
305
|
-
return {
|
|
306
|
-
floor: [compare(a1, a2), compare(b1, b2)],
|
|
307
|
-
signal: [compare(a1, b1), compare(a2, b2)],
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// -----------------------------------------------------------------------------------------
|
|
312
|
-
// camera paths
|
|
313
|
-
// -----------------------------------------------------------------------------------------
|
|
314
|
-
|
|
315
|
-
function read_pose() {
|
|
316
|
-
const t = camera.transform;
|
|
317
|
-
|
|
318
|
-
return {
|
|
319
|
-
position: [t.
|
|
320
|
-
rotation: [t.
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
function write_pose(pose) {
|
|
325
|
-
camera.transform.
|
|
326
|
-
camera.transform.
|
|
327
|
-
|
|
328
|
-
// the controller keeps its own spherical state and would otherwise pull the camera back on
|
|
329
|
-
// its next tick — the page's loop still runs it while paused
|
|
330
|
-
controller.from_transform(camera.transform);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/** Straight-line interpolation between two poses, with the rotation slerped. */
|
|
334
|
-
function interpolate(from, to, t) {
|
|
335
|
-
const position = from.position.map((c, i) => c + (to.position[i] - c) * t);
|
|
336
|
-
|
|
337
|
-
let dot = from.rotation.reduce((s, c, i) => s + c * to.rotation[i], 0);
|
|
338
|
-
let target_rotation = to.rotation;
|
|
339
|
-
|
|
340
|
-
if (dot < 0) {
|
|
341
|
-
dot = -dot;
|
|
342
|
-
target_rotation = to.rotation.map(c => -c);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
let rotation;
|
|
346
|
-
|
|
347
|
-
if (dot > 0.9995) {
|
|
348
|
-
rotation = from.rotation.map((c, i) => c + (target_rotation[i] - c) * t);
|
|
349
|
-
} else {
|
|
350
|
-
const theta = Math.acos(dot);
|
|
351
|
-
const s0 = Math.sin((1 - t) * theta) / Math.sin(theta);
|
|
352
|
-
const s1 = Math.sin(t * theta) / Math.sin(theta);
|
|
353
|
-
rotation = from.rotation.map((c, i) => c * s0 + target_rotation[i] * s1);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
const length = Math.hypot(...rotation);
|
|
357
|
-
|
|
358
|
-
return { position, rotation: rotation.map(c => c / length) };
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Fly the camera from its current pose to `to` over `frames` frames, rendering every one of
|
|
363
|
-
* them, and record the frame-average luminance as it goes.
|
|
364
|
-
*
|
|
365
|
-
* The per-frame series is the point. A structure that swims under motion shows up as
|
|
366
|
-
* frame-to-frame jitter in it that a static capture cannot contain; ghosting shows up as a tail
|
|
367
|
-
* after the motion stops.
|
|
368
|
-
*
|
|
369
|
-
* @returns {Promise<number[]>} mean luminance, one entry per frame
|
|
370
|
-
*/
|
|
371
|
-
async function fly(to, { frames = 60, hold = 0 } = {}) {
|
|
372
|
-
const from = read_pose();
|
|
373
|
-
const series = [];
|
|
374
|
-
|
|
375
|
-
const c = target();
|
|
376
|
-
const scratch = new Float32Array(c.width * c.height);
|
|
377
|
-
|
|
378
|
-
for (let i = 0; i <= frames + hold; i++) {
|
|
379
|
-
const t = Math.min(1, i / frames);
|
|
380
|
-
|
|
381
|
-
write_pose(interpolate(from, to, t));
|
|
382
|
-
|
|
383
|
-
frame();
|
|
384
|
-
await device.queue.onSubmittedWorkDone();
|
|
385
|
-
|
|
386
|
-
scratch.fill(0);
|
|
387
|
-
await accumulate_luminance(scratch);
|
|
388
|
-
|
|
389
|
-
series.push(mean(scratch));
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
return series;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* How noisy a per-frame series is, and how much of it is a trend rather than flicker.
|
|
397
|
-
*
|
|
398
|
-
* `flicker` is the mean absolute successive difference — a temporal-noise measure that is blind
|
|
399
|
-
* to a smooth ramp, which is what makes it usable while the camera is still moving. `drift` is
|
|
400
|
-
* the total change across the window.
|
|
401
|
-
*/
|
|
402
|
-
function series_stats(series) {
|
|
403
|
-
let successive = 0;
|
|
404
|
-
let largest = 0;
|
|
405
|
-
|
|
406
|
-
for (let i = 1; i < series.length; i++) {
|
|
407
|
-
const d = Math.abs(series[i] - series[i - 1]);
|
|
408
|
-
successive += d;
|
|
409
|
-
|
|
410
|
-
if (d > largest) {
|
|
411
|
-
largest = d;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
return {
|
|
416
|
-
frames: series.length,
|
|
417
|
-
mean: mean(series),
|
|
418
|
-
flicker: successive / Math.max(1, series.length - 1),
|
|
419
|
-
max_step: largest,
|
|
420
|
-
drift: series[series.length - 1] - series[0],
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/** Teleport, reset history and converge — the reference a flown-into pose is judged against. */
|
|
425
|
-
async function converge_at(pose, options = {}) {
|
|
426
|
-
write_pose(pose);
|
|
427
|
-
renderer.indicate_view_change();
|
|
428
|
-
return capture_average(options);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* GPU-bound frame time, with the swap chain out of the measurement.
|
|
433
|
-
*
|
|
434
|
-
* Submits `frames` frames back to back and waits once, so the queue stays full and the number
|
|
435
|
-
* is throughput rather than latency. Interleave the settings being compared and take medians —
|
|
436
|
-
* a single reading here is worth nothing.
|
|
437
|
-
*/
|
|
438
|
-
async function time_frames({ frames = 120 } = {}) {
|
|
439
|
-
await settle(8);
|
|
440
|
-
|
|
441
|
-
const started = performance.now();
|
|
442
|
-
|
|
443
|
-
for (let i = 0; i < frames; i++) {
|
|
444
|
-
frame();
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
await device.queue.onSubmittedWorkDone();
|
|
448
|
-
|
|
449
|
-
return (performance.now() - started) / frames;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Per-pass GPU durations, recorded and decoded in the page.
|
|
454
|
-
*
|
|
455
|
-
* This is the number to believe about cost, and the README says why in one line: at 1080p,
|
|
456
|
-
* whole-frame timing of Q-04 came back with the wrong sign three runs in a row while the
|
|
457
|
-
* per-pass capture read it cleanly. `time` measures a frame; this measures the passes the change
|
|
458
|
-
* is supposed to move.
|
|
459
|
-
*
|
|
460
|
-
* The `.sgpt` never reaches disk — the session's bytes go straight through `sgpt_read_capture`.
|
|
461
|
-
* A downloaded capture is the right artefact when the point is to keep it; when the point is a
|
|
462
|
-
* number, a file the browser may decline to save the second time is a step to skip.
|
|
463
|
-
*
|
|
464
|
-
* Two things about the draining. A frame is committed when its timestamp readback lands, a
|
|
465
|
-
* `mapAsync` a frame or two behind submit, so stopping the instant the last frame is encoded
|
|
466
|
-
* discards exactly the frames you asked for. And the readback resolves on a task, not on
|
|
467
|
-
* `onSubmittedWorkDone`, so the drain has to yield to the event loop rather than only to the
|
|
468
|
-
* queue.
|
|
469
|
-
*
|
|
470
|
-
* @param {object} [options]
|
|
471
|
-
* @param {number} [options.frames] frames to record
|
|
472
|
-
* @param {number} [options.settle] frames to run before recording starts
|
|
473
|
-
* @returns {Promise<Object<string, number>>} median duration in ms per pass label, plus
|
|
474
|
-
* `__frames` and `__defects`
|
|
475
|
-
*/
|
|
476
|
-
async function profile_passes({ frames = 40, settle: settle_frames = 20 } = {}) {
|
|
477
|
-
const { GPUProfileSession } = await import('../../device/timing/profile/GPUProfileSession.js');
|
|
478
|
-
const { GPUProfileLevel } = await import('../../device/timing/profile/GPUProfileLevel.js');
|
|
479
|
-
const { sgpt_read_capture } = await import('../../device/timing/profile/sgpt_read_capture.js');
|
|
480
|
-
|
|
481
|
-
await settle(settle_frames);
|
|
482
|
-
|
|
483
|
-
const session = new GPUProfileSession({ level: GPUProfileLevel.WORKLOAD, note: 'measure.js' });
|
|
484
|
-
|
|
485
|
-
renderer.profile_session = session;
|
|
486
|
-
session.start();
|
|
487
|
-
|
|
488
|
-
await settle(frames);
|
|
489
|
-
|
|
490
|
-
for (let i = 0; i < 20; i++) {
|
|
491
|
-
await new Promise(resolve => setTimeout(resolve, 40));
|
|
492
|
-
frame();
|
|
493
|
-
await device.queue.onSubmittedWorkDone();
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
renderer.profile_session = null;
|
|
497
|
-
|
|
498
|
-
await device.queue.onSubmittedWorkDone();
|
|
499
|
-
await new Promise(resolve => setTimeout(resolve, 200));
|
|
500
|
-
|
|
501
|
-
const bytes = session.stop();
|
|
502
|
-
|
|
503
|
-
const buffer = bytes instanceof ArrayBuffer
|
|
504
|
-
? bytes
|
|
505
|
-
: bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
506
|
-
|
|
507
|
-
const capture = sgpt_read_capture(buffer);
|
|
508
|
-
|
|
509
|
-
// Summed per frame before the median is taken across frames, because one frame graph pass
|
|
510
|
-
// routinely opens several GPU passes and a label is not unique — see GPUProfileSpan.
|
|
511
|
-
const per_frame = new Map();
|
|
512
|
-
|
|
513
|
-
for (const recorded of capture.frames) {
|
|
514
|
-
const totals = new Map();
|
|
515
|
-
|
|
516
|
-
for (const span of recorded.spans) {
|
|
517
|
-
totals.set(span.label, (totals.get(span.label) ?? 0) + span.duration_ns * 1e-6);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
for (const [label, ms] of totals) {
|
|
521
|
-
if (!per_frame.has(label)) {
|
|
522
|
-
per_frame.set(label, []);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
per_frame.get(label).push(ms);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
const out = { __frames: capture.frames.length, __defects: capture.defects.length };
|
|
530
|
-
|
|
531
|
-
for (const [label, values] of per_frame) {
|
|
532
|
-
values.sort((a, b) => a - b);
|
|
533
|
-
out[label] = values[values.length >> 1];
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
return out;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Raise the internal resolution until the GPU is the bottleneck. The page's loop assigns
|
|
541
|
-
* `renderer.pixel_ratio` from `window.devicePixelRatio` every tick, so the property has to go
|
|
542
|
-
* rather than the field.
|
|
543
|
-
*/
|
|
544
|
-
function set_pixel_ratio(ratio) {
|
|
545
|
-
Object.defineProperty(window, 'devicePixelRatio', { get: () => ratio, configurable: true });
|
|
546
|
-
renderer.pixel_ratio = ratio;
|
|
547
|
-
make_target();
|
|
548
|
-
renderer.indicate_view_change();
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
return {
|
|
552
|
-
renderer, scene, camera, controller, device,
|
|
553
|
-
get capture() { return capture; },
|
|
554
|
-
make_target, target, frame, settle, accumulate_luminance,
|
|
555
|
-
capture: capture_average, compare, mean, ab,
|
|
556
|
-
read_pose, write_pose, interpolate, fly, series_stats, converge_at,
|
|
557
|
-
time: time_frames, profile: profile_passes, set_pixel_ratio,
|
|
558
|
-
};
|
|
559
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* The measurement protocol from this page's README, as code.
|
|
3
|
+
*
|
|
4
|
+
* Not imported by the page — it is loaded from the console when there is something to measure:
|
|
5
|
+
*
|
|
6
|
+
* ```js
|
|
7
|
+
* const m = await (await import('./measure.js')).attach();
|
|
8
|
+
* await m.ab(v => globalThis.__VOL_TAA_ENABLED = v, false, true);
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* It exists because every trap the README lists is a trap about *procedure*, and a procedure
|
|
12
|
+
* written down in prose gets followed differently each time. Three of them are structural and are
|
|
13
|
+
* dealt with here rather than left to the operator:
|
|
14
|
+
*
|
|
15
|
+
* - **The canvas cannot be read back.** A canvas texture is configured by the presentation path,
|
|
16
|
+
* cannot carry `COPY_SRC`, and is rotated away the moment the frame is presented — a `drawImage`
|
|
17
|
+
* off it a task later returns an empty bitmap, and a comparison of two blanks reports perfect
|
|
18
|
+
* agreement. Everything here renders into a texture this module owns, via
|
|
19
|
+
* `Renderer.render_to_target`, which shares the view context (and therefore all the temporal
|
|
20
|
+
* history) with the canvas path.
|
|
21
|
+
*
|
|
22
|
+
* - **Presentation throttling.** Whole-frame timing off the page's own loop is paced by the swap
|
|
23
|
+
* chain, which is why the README says two settings that plainly differ can report the same
|
|
24
|
+
* number. Driving the frames from here removes the swap chain from the measurement entirely.
|
|
25
|
+
*
|
|
26
|
+
* - **The noise floor has to pay the same costs the signal does.** `ab` takes the floor by making
|
|
27
|
+
* an identical no-op change and settling exactly as the real change does, and it interleaves the
|
|
28
|
+
* two sides so drift lands on both.
|
|
29
|
+
*
|
|
30
|
+
* The camera-path helpers exist for a narrower reason: a structure that is fitted to the camera can
|
|
31
|
+
* be perfectly correct standing still and swim under motion, and the froxel volume then goes
|
|
32
|
+
* through a 0.95-blend temporal filter that turns swimming into either ghosting or flicker. Neither
|
|
33
|
+
* is visible in a still. `fly` drives a pose sequence one frame at a time and records what the
|
|
34
|
+
* image does while it happens.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {object} [context] defaults to the globals the page publishes
|
|
39
|
+
* @param {Renderer} [context.renderer]
|
|
40
|
+
* @param {Scene} [context.scene]
|
|
41
|
+
* @param {PerspectiveCamera} [context.camera]
|
|
42
|
+
* @param {OrbitalCameraController} [context.controller]
|
|
43
|
+
*/
|
|
44
|
+
export async function attach({
|
|
45
|
+
renderer = globalThis.renderer,
|
|
46
|
+
scene = globalThis.scene,
|
|
47
|
+
camera = globalThis.camera,
|
|
48
|
+
controller = globalThis.controller,
|
|
49
|
+
} = {}) {
|
|
50
|
+
|
|
51
|
+
const { GPUTextureContext } = await import('../../renderer/texture/GPUTextureContext.js');
|
|
52
|
+
|
|
53
|
+
const device = renderer.device;
|
|
54
|
+
|
|
55
|
+
/** @type {object|null} */
|
|
56
|
+
let capture = null;
|
|
57
|
+
|
|
58
|
+
// The page's loop must stop, and not only so the frame count is ours: it also assigns
|
|
59
|
+
// `renderer.pixel_ratio = window.devicePixelRatio` on every tick, ahead of its own pause check,
|
|
60
|
+
// so a raised pixel ratio would be undone before the next frame.
|
|
61
|
+
const pause_button = document.getElementById('pause');
|
|
62
|
+
|
|
63
|
+
if (pause_button !== null && pause_button.textContent === 'Pause') {
|
|
64
|
+
pause_button.click();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// A/B is meaningless with eye adaptation running — it keeps drifting for seconds after any
|
|
68
|
+
// change, by more than most changes to this pass are worth.
|
|
69
|
+
renderer.feature_automatic_exposure_enabled = false;
|
|
70
|
+
|
|
71
|
+
function make_target() {
|
|
72
|
+
if (capture !== null) {
|
|
73
|
+
capture.destroy();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const resolution = renderer.output_resolution;
|
|
77
|
+
|
|
78
|
+
const width = resolution.x;
|
|
79
|
+
const height = resolution.y;
|
|
80
|
+
|
|
81
|
+
// the rule the renderer's own context configuration follows
|
|
82
|
+
const format = window.matchMedia('(dynamic-range: high)').matches
|
|
83
|
+
? 'rgba16float'
|
|
84
|
+
: navigator.gpu.getPreferredCanvasFormat();
|
|
85
|
+
|
|
86
|
+
const texture = device.createTexture({
|
|
87
|
+
label: 'measure/capture',
|
|
88
|
+
size: [width, height, 1],
|
|
89
|
+
format,
|
|
90
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
91
|
+
| GPUTextureUsage.COPY_SRC
|
|
92
|
+
| GPUTextureUsage.COPY_DST
|
|
93
|
+
| GPUTextureUsage.TEXTURE_BINDING,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const bytes_per_pixel = format === 'rgba16float' ? 8 : 4;
|
|
97
|
+
|
|
98
|
+
// copyTextureToBuffer wants rows on a 256-byte boundary
|
|
99
|
+
const bytes_per_row = Math.ceil(width * bytes_per_pixel / 256) * 256;
|
|
100
|
+
|
|
101
|
+
capture = {
|
|
102
|
+
texture,
|
|
103
|
+
target: GPUTextureContext.fromTexture(texture, device),
|
|
104
|
+
width,
|
|
105
|
+
height,
|
|
106
|
+
format,
|
|
107
|
+
bytes_per_row,
|
|
108
|
+
buffer: device.createBuffer({
|
|
109
|
+
label: 'measure/readback',
|
|
110
|
+
size: bytes_per_row * height,
|
|
111
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
112
|
+
}),
|
|
113
|
+
destroy() {
|
|
114
|
+
this.texture.destroy();
|
|
115
|
+
this.buffer.destroy();
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return capture;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function target() {
|
|
123
|
+
const resolution = renderer.output_resolution;
|
|
124
|
+
|
|
125
|
+
if (capture === null || capture.width !== resolution.x || capture.height !== resolution.y) {
|
|
126
|
+
make_target();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return capture;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function half_to_float(h) {
|
|
133
|
+
const sign = (h & 0x8000) !== 0 ? -1 : 1;
|
|
134
|
+
const exponent = (h & 0x7C00) >> 10;
|
|
135
|
+
const fraction = h & 0x03FF;
|
|
136
|
+
|
|
137
|
+
if (exponent === 0) {
|
|
138
|
+
return sign * Math.pow(2, -14) * (fraction / 1024);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (exponent === 31) {
|
|
142
|
+
return fraction !== 0 ? NaN : sign * Infinity;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return sign * Math.pow(2, exponent - 15) * (1 + fraction / 1024);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** One frame into the owned target. */
|
|
149
|
+
function frame(time_delta_s = 1 / 60) {
|
|
150
|
+
renderer.render_to_target(camera, scene, time_delta_s, target().target);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** `n` frames, awaited, with nothing read back — for letting the temporal filter converge. */
|
|
154
|
+
async function settle(n) {
|
|
155
|
+
for (let i = 0; i < n; i++) {
|
|
156
|
+
frame();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await device.queue.onSubmittedWorkDone();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Per-pixel luminance of whatever is in the capture texture, added into `out`.
|
|
164
|
+
*
|
|
165
|
+
* @param {Float32Array} out length width*height
|
|
166
|
+
*/
|
|
167
|
+
async function accumulate_luminance(out) {
|
|
168
|
+
const c = target();
|
|
169
|
+
|
|
170
|
+
const encoder = device.createCommandEncoder({ label: 'measure/readback' });
|
|
171
|
+
|
|
172
|
+
encoder.copyTextureToBuffer(
|
|
173
|
+
{ texture: c.texture },
|
|
174
|
+
{ buffer: c.buffer, bytesPerRow: c.bytes_per_row },
|
|
175
|
+
[c.width, c.height, 1]
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
device.queue.submit([encoder.finish()]);
|
|
179
|
+
|
|
180
|
+
await c.buffer.mapAsync(GPUMapMode.READ);
|
|
181
|
+
|
|
182
|
+
const raw = c.buffer.getMappedRange();
|
|
183
|
+
|
|
184
|
+
// The channel order is not cosmetic here: the preferred canvas format on Windows is
|
|
185
|
+
// bgra8unorm, and weighting it as if it were rgba silently swaps the 0.2126 and 0.0722
|
|
186
|
+
// coefficients — still a usable difference metric, but not the luminance it claims to be.
|
|
187
|
+
if (c.format === 'rgba16float') {
|
|
188
|
+
const source = new Uint16Array(raw);
|
|
189
|
+
const stride = c.bytes_per_row / 2;
|
|
190
|
+
|
|
191
|
+
for (let y = 0; y < c.height; y++) {
|
|
192
|
+
for (let x = 0; x < c.width; x++) {
|
|
193
|
+
const i = y * stride + x * 4;
|
|
194
|
+
|
|
195
|
+
out[y * c.width + x] += 0.2126 * half_to_float(source[i])
|
|
196
|
+
+ 0.7152 * half_to_float(source[i + 1])
|
|
197
|
+
+ 0.0722 * half_to_float(source[i + 2]);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
const source = new Uint8Array(raw);
|
|
202
|
+
const bgra = c.format.startsWith('bgra');
|
|
203
|
+
|
|
204
|
+
for (let y = 0; y < c.height; y++) {
|
|
205
|
+
for (let x = 0; x < c.width; x++) {
|
|
206
|
+
const i = y * c.bytes_per_row + x * 4;
|
|
207
|
+
|
|
208
|
+
const r = bgra ? source[i + 2] : source[i];
|
|
209
|
+
const b = bgra ? source[i] : source[i + 2];
|
|
210
|
+
|
|
211
|
+
out[y * c.width + x] += 0.2126 * r + 0.7152 * source[i + 1] + 0.0722 * b;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
c.buffer.unmap();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Settle, then average. The two numbers are the README's protocol: ~45 frames of
|
|
221
|
+
* re-convergence after any change that resets temporal accumulation, then a multi-frame average
|
|
222
|
+
* because the column jitter and the sample RNG both key on the frame index and consecutive
|
|
223
|
+
* frames genuinely differ.
|
|
224
|
+
*
|
|
225
|
+
* @returns {Promise<Float32Array>} mean luminance per pixel
|
|
226
|
+
*/
|
|
227
|
+
async function capture_average({ settle: settle_frames = 45, average = 32 } = {}) {
|
|
228
|
+
await settle(settle_frames);
|
|
229
|
+
|
|
230
|
+
const c = target();
|
|
231
|
+
const accumulator = new Float32Array(c.width * c.height);
|
|
232
|
+
|
|
233
|
+
for (let i = 0; i < average; i++) {
|
|
234
|
+
frame();
|
|
235
|
+
await device.queue.onSubmittedWorkDone();
|
|
236
|
+
await accumulate_luminance(accumulator);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
for (let i = 0; i < accumulator.length; i++) {
|
|
240
|
+
accumulator[i] /= average;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return accumulator;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function mean(values) {
|
|
247
|
+
let sum = 0;
|
|
248
|
+
|
|
249
|
+
for (let i = 0; i < values.length; i++) {
|
|
250
|
+
sum += values[i];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return sum / values.length;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Prefer the signed mean when the change has a direction — it discriminates far better than the
|
|
258
|
+
* mean absolute, which is dominated by noise.
|
|
259
|
+
*/
|
|
260
|
+
function compare(a, b) {
|
|
261
|
+
let signed = 0;
|
|
262
|
+
let absolute = 0;
|
|
263
|
+
let largest = 0;
|
|
264
|
+
|
|
265
|
+
for (let i = 0; i < a.length; i++) {
|
|
266
|
+
const d = b[i] - a[i];
|
|
267
|
+
|
|
268
|
+
signed += d;
|
|
269
|
+
absolute += Math.abs(d);
|
|
270
|
+
|
|
271
|
+
if (Math.abs(d) > largest) {
|
|
272
|
+
largest = Math.abs(d);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
signed_mean: signed / a.length,
|
|
278
|
+
mean_abs: absolute / a.length,
|
|
279
|
+
max_abs: largest,
|
|
280
|
+
mean_a: mean(a),
|
|
281
|
+
mean_b: mean(b),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* An interleaved A/B with its own noise floor.
|
|
287
|
+
*
|
|
288
|
+
* `apply` is called with `a` and with `b`; it must be the whole of the change, and cheap enough
|
|
289
|
+
* that the two sides pay the same fixed costs. Both sides then go through the identical
|
|
290
|
+
* settle-and-average, and the floor comes from the two captures of the *same* setting, which is
|
|
291
|
+
* what makes a small result readable — anything at or below the floor has not been shown.
|
|
292
|
+
*/
|
|
293
|
+
async function ab(apply, a, b, options = {}) {
|
|
294
|
+
const run = async (value) => {
|
|
295
|
+
apply(value);
|
|
296
|
+
renderer.indicate_view_change();
|
|
297
|
+
return capture_average(options);
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const a1 = await run(a);
|
|
301
|
+
const b1 = await run(b);
|
|
302
|
+
const a2 = await run(a);
|
|
303
|
+
const b2 = await run(b);
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
floor: [compare(a1, a2), compare(b1, b2)],
|
|
307
|
+
signal: [compare(a1, b1), compare(a2, b2)],
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// -----------------------------------------------------------------------------------------
|
|
312
|
+
// camera paths
|
|
313
|
+
// -----------------------------------------------------------------------------------------
|
|
314
|
+
|
|
315
|
+
function read_pose() {
|
|
316
|
+
const t = camera.transform;
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
position: [t.translation_x, t.translation_y, t.translation_z],
|
|
320
|
+
rotation: [t.rotation_x, t.rotation_y, t.rotation_z, t.rotation_w],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function write_pose(pose) {
|
|
325
|
+
camera.transform.setTranslation(pose.position[0], pose.position[1], pose.position[2]);
|
|
326
|
+
camera.transform.setRotation(pose.rotation[0], pose.rotation[1], pose.rotation[2], pose.rotation[3]);
|
|
327
|
+
|
|
328
|
+
// the controller keeps its own spherical state and would otherwise pull the camera back on
|
|
329
|
+
// its next tick — the page's loop still runs it while paused
|
|
330
|
+
controller.from_transform(camera.transform);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Straight-line interpolation between two poses, with the rotation slerped. */
|
|
334
|
+
function interpolate(from, to, t) {
|
|
335
|
+
const position = from.position.map((c, i) => c + (to.position[i] - c) * t);
|
|
336
|
+
|
|
337
|
+
let dot = from.rotation.reduce((s, c, i) => s + c * to.rotation[i], 0);
|
|
338
|
+
let target_rotation = to.rotation;
|
|
339
|
+
|
|
340
|
+
if (dot < 0) {
|
|
341
|
+
dot = -dot;
|
|
342
|
+
target_rotation = to.rotation.map(c => -c);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
let rotation;
|
|
346
|
+
|
|
347
|
+
if (dot > 0.9995) {
|
|
348
|
+
rotation = from.rotation.map((c, i) => c + (target_rotation[i] - c) * t);
|
|
349
|
+
} else {
|
|
350
|
+
const theta = Math.acos(dot);
|
|
351
|
+
const s0 = Math.sin((1 - t) * theta) / Math.sin(theta);
|
|
352
|
+
const s1 = Math.sin(t * theta) / Math.sin(theta);
|
|
353
|
+
rotation = from.rotation.map((c, i) => c * s0 + target_rotation[i] * s1);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const length = Math.hypot(...rotation);
|
|
357
|
+
|
|
358
|
+
return { position, rotation: rotation.map(c => c / length) };
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Fly the camera from its current pose to `to` over `frames` frames, rendering every one of
|
|
363
|
+
* them, and record the frame-average luminance as it goes.
|
|
364
|
+
*
|
|
365
|
+
* The per-frame series is the point. A structure that swims under motion shows up as
|
|
366
|
+
* frame-to-frame jitter in it that a static capture cannot contain; ghosting shows up as a tail
|
|
367
|
+
* after the motion stops.
|
|
368
|
+
*
|
|
369
|
+
* @returns {Promise<number[]>} mean luminance, one entry per frame
|
|
370
|
+
*/
|
|
371
|
+
async function fly(to, { frames = 60, hold = 0 } = {}) {
|
|
372
|
+
const from = read_pose();
|
|
373
|
+
const series = [];
|
|
374
|
+
|
|
375
|
+
const c = target();
|
|
376
|
+
const scratch = new Float32Array(c.width * c.height);
|
|
377
|
+
|
|
378
|
+
for (let i = 0; i <= frames + hold; i++) {
|
|
379
|
+
const t = Math.min(1, i / frames);
|
|
380
|
+
|
|
381
|
+
write_pose(interpolate(from, to, t));
|
|
382
|
+
|
|
383
|
+
frame();
|
|
384
|
+
await device.queue.onSubmittedWorkDone();
|
|
385
|
+
|
|
386
|
+
scratch.fill(0);
|
|
387
|
+
await accumulate_luminance(scratch);
|
|
388
|
+
|
|
389
|
+
series.push(mean(scratch));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return series;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* How noisy a per-frame series is, and how much of it is a trend rather than flicker.
|
|
397
|
+
*
|
|
398
|
+
* `flicker` is the mean absolute successive difference — a temporal-noise measure that is blind
|
|
399
|
+
* to a smooth ramp, which is what makes it usable while the camera is still moving. `drift` is
|
|
400
|
+
* the total change across the window.
|
|
401
|
+
*/
|
|
402
|
+
function series_stats(series) {
|
|
403
|
+
let successive = 0;
|
|
404
|
+
let largest = 0;
|
|
405
|
+
|
|
406
|
+
for (let i = 1; i < series.length; i++) {
|
|
407
|
+
const d = Math.abs(series[i] - series[i - 1]);
|
|
408
|
+
successive += d;
|
|
409
|
+
|
|
410
|
+
if (d > largest) {
|
|
411
|
+
largest = d;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return {
|
|
416
|
+
frames: series.length,
|
|
417
|
+
mean: mean(series),
|
|
418
|
+
flicker: successive / Math.max(1, series.length - 1),
|
|
419
|
+
max_step: largest,
|
|
420
|
+
drift: series[series.length - 1] - series[0],
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/** Teleport, reset history and converge — the reference a flown-into pose is judged against. */
|
|
425
|
+
async function converge_at(pose, options = {}) {
|
|
426
|
+
write_pose(pose);
|
|
427
|
+
renderer.indicate_view_change();
|
|
428
|
+
return capture_average(options);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* GPU-bound frame time, with the swap chain out of the measurement.
|
|
433
|
+
*
|
|
434
|
+
* Submits `frames` frames back to back and waits once, so the queue stays full and the number
|
|
435
|
+
* is throughput rather than latency. Interleave the settings being compared and take medians —
|
|
436
|
+
* a single reading here is worth nothing.
|
|
437
|
+
*/
|
|
438
|
+
async function time_frames({ frames = 120 } = {}) {
|
|
439
|
+
await settle(8);
|
|
440
|
+
|
|
441
|
+
const started = performance.now();
|
|
442
|
+
|
|
443
|
+
for (let i = 0; i < frames; i++) {
|
|
444
|
+
frame();
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
await device.queue.onSubmittedWorkDone();
|
|
448
|
+
|
|
449
|
+
return (performance.now() - started) / frames;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Per-pass GPU durations, recorded and decoded in the page.
|
|
454
|
+
*
|
|
455
|
+
* This is the number to believe about cost, and the README says why in one line: at 1080p,
|
|
456
|
+
* whole-frame timing of Q-04 came back with the wrong sign three runs in a row while the
|
|
457
|
+
* per-pass capture read it cleanly. `time` measures a frame; this measures the passes the change
|
|
458
|
+
* is supposed to move.
|
|
459
|
+
*
|
|
460
|
+
* The `.sgpt` never reaches disk — the session's bytes go straight through `sgpt_read_capture`.
|
|
461
|
+
* A downloaded capture is the right artefact when the point is to keep it; when the point is a
|
|
462
|
+
* number, a file the browser may decline to save the second time is a step to skip.
|
|
463
|
+
*
|
|
464
|
+
* Two things about the draining. A frame is committed when its timestamp readback lands, a
|
|
465
|
+
* `mapAsync` a frame or two behind submit, so stopping the instant the last frame is encoded
|
|
466
|
+
* discards exactly the frames you asked for. And the readback resolves on a task, not on
|
|
467
|
+
* `onSubmittedWorkDone`, so the drain has to yield to the event loop rather than only to the
|
|
468
|
+
* queue.
|
|
469
|
+
*
|
|
470
|
+
* @param {object} [options]
|
|
471
|
+
* @param {number} [options.frames] frames to record
|
|
472
|
+
* @param {number} [options.settle] frames to run before recording starts
|
|
473
|
+
* @returns {Promise<Object<string, number>>} median duration in ms per pass label, plus
|
|
474
|
+
* `__frames` and `__defects`
|
|
475
|
+
*/
|
|
476
|
+
async function profile_passes({ frames = 40, settle: settle_frames = 20 } = {}) {
|
|
477
|
+
const { GPUProfileSession } = await import('../../device/timing/profile/GPUProfileSession.js');
|
|
478
|
+
const { GPUProfileLevel } = await import('../../device/timing/profile/GPUProfileLevel.js');
|
|
479
|
+
const { sgpt_read_capture } = await import('../../device/timing/profile/sgpt_read_capture.js');
|
|
480
|
+
|
|
481
|
+
await settle(settle_frames);
|
|
482
|
+
|
|
483
|
+
const session = new GPUProfileSession({ level: GPUProfileLevel.WORKLOAD, note: 'measure.js' });
|
|
484
|
+
|
|
485
|
+
renderer.profile_session = session;
|
|
486
|
+
session.start();
|
|
487
|
+
|
|
488
|
+
await settle(frames);
|
|
489
|
+
|
|
490
|
+
for (let i = 0; i < 20; i++) {
|
|
491
|
+
await new Promise(resolve => setTimeout(resolve, 40));
|
|
492
|
+
frame();
|
|
493
|
+
await device.queue.onSubmittedWorkDone();
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
renderer.profile_session = null;
|
|
497
|
+
|
|
498
|
+
await device.queue.onSubmittedWorkDone();
|
|
499
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
500
|
+
|
|
501
|
+
const bytes = session.stop();
|
|
502
|
+
|
|
503
|
+
const buffer = bytes instanceof ArrayBuffer
|
|
504
|
+
? bytes
|
|
505
|
+
: bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
506
|
+
|
|
507
|
+
const capture = sgpt_read_capture(buffer);
|
|
508
|
+
|
|
509
|
+
// Summed per frame before the median is taken across frames, because one frame graph pass
|
|
510
|
+
// routinely opens several GPU passes and a label is not unique — see GPUProfileSpan.
|
|
511
|
+
const per_frame = new Map();
|
|
512
|
+
|
|
513
|
+
for (const recorded of capture.frames) {
|
|
514
|
+
const totals = new Map();
|
|
515
|
+
|
|
516
|
+
for (const span of recorded.spans) {
|
|
517
|
+
totals.set(span.label, (totals.get(span.label) ?? 0) + span.duration_ns * 1e-6);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
for (const [label, ms] of totals) {
|
|
521
|
+
if (!per_frame.has(label)) {
|
|
522
|
+
per_frame.set(label, []);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
per_frame.get(label).push(ms);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
const out = { __frames: capture.frames.length, __defects: capture.defects.length };
|
|
530
|
+
|
|
531
|
+
for (const [label, values] of per_frame) {
|
|
532
|
+
values.sort((a, b) => a - b);
|
|
533
|
+
out[label] = values[values.length >> 1];
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return out;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Raise the internal resolution until the GPU is the bottleneck. The page's loop assigns
|
|
541
|
+
* `renderer.pixel_ratio` from `window.devicePixelRatio` every tick, so the property has to go
|
|
542
|
+
* rather than the field.
|
|
543
|
+
*/
|
|
544
|
+
function set_pixel_ratio(ratio) {
|
|
545
|
+
Object.defineProperty(window, 'devicePixelRatio', { get: () => ratio, configurable: true });
|
|
546
|
+
renderer.pixel_ratio = ratio;
|
|
547
|
+
make_target();
|
|
548
|
+
renderer.indicate_view_change();
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return {
|
|
552
|
+
renderer, scene, camera, controller, device,
|
|
553
|
+
get capture() { return capture; },
|
|
554
|
+
make_target, target, frame, settle, accumulate_luminance,
|
|
555
|
+
capture: capture_average, compare, mean, ab,
|
|
556
|
+
read_pose, write_pose, interpolate, fly, series_stats, converge_at,
|
|
557
|
+
time: time_frames, profile: profile_passes, set_pixel_ratio,
|
|
558
|
+
};
|
|
559
|
+
}
|