@driftengine/core 3.61.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/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +9 -0
- package/dist/behavior/behaviorTree.d.ts +140 -0
- package/dist/behavior/behaviorTree.js +289 -0
- package/dist/build/shaderComments.d.ts +64 -0
- package/dist/build/shaderComments.js +0 -0
- package/dist/cinematic/player.d.ts +80 -0
- package/dist/cinematic/player.js +184 -0
- package/dist/cinematic/script.d.ts +63 -0
- package/dist/cinematic/script.js +141 -0
- package/dist/core/bootGate.d.ts +37 -0
- package/dist/core/bootGate.js +47 -0
- package/dist/core/loadTracker.d.ts +78 -0
- package/dist/core/loadTracker.js +106 -0
- package/dist/core/loop.d.ts +118 -0
- package/dist/core/loop.js +84 -0
- package/dist/core/messageQueue.d.ts +61 -0
- package/dist/core/messageQueue.js +104 -0
- package/dist/core/onceSet.d.ts +27 -0
- package/dist/core/onceSet.js +62 -0
- package/dist/core/preferences.d.ts +47 -0
- package/dist/core/preferences.js +140 -0
- package/dist/core/remoteSave.d.ts +154 -0
- package/dist/core/remoteSave.js +249 -0
- package/dist/core/rng.d.ts +64 -0
- package/dist/core/rng.js +72 -0
- package/dist/core/stepBudget.d.ts +91 -0
- package/dist/core/stepBudget.js +105 -0
- package/dist/core/storage.d.ts +52 -0
- package/dist/core/storage.js +85 -0
- package/dist/core/tickTrace.d.ts +72 -0
- package/dist/core/tickTrace.js +102 -0
- package/dist/core/timeCurve.d.ts +83 -0
- package/dist/core/timeCurve.js +107 -0
- package/dist/core/withDefaults.d.ts +21 -0
- package/dist/core/withDefaults.js +29 -0
- package/dist/dev/contactProbe.d.ts +41 -0
- package/dist/dev/contactProbe.js +58 -0
- package/dist/dev/fpsMeter.d.ts +45 -0
- package/dist/dev/fpsMeter.js +86 -0
- package/dist/environment/celestialClock.d.ts +141 -0
- package/dist/environment/celestialClock.js +262 -0
- package/dist/geometry/decal.d.ts +61 -0
- package/dist/geometry/decal.js +178 -0
- package/dist/geometry/filmPatch.d.ts +35 -0
- package/dist/geometry/filmPatch.js +112 -0
- package/dist/geometry/growable.d.ts +70 -0
- package/dist/geometry/growable.js +167 -0
- package/dist/geometry/lightVolume.d.ts +76 -0
- package/dist/geometry/lightVolume.js +65 -0
- package/dist/geometry/meshBuilder.d.ts +426 -0
- package/dist/geometry/meshBuilder.js +1184 -0
- package/dist/geometry/pixelFont.d.ts +59 -0
- package/dist/geometry/pixelFont.js +179 -0
- package/dist/geometry/ribbon.d.ts +101 -0
- package/dist/geometry/ribbon.js +546 -0
- package/dist/geometry/shellFill.d.ts +101 -0
- package/dist/geometry/shellFill.js +203 -0
- package/dist/geometry/spline.d.ts +162 -0
- package/dist/geometry/spline.js +527 -0
- package/dist/geometry/tangents.d.ts +30 -0
- package/dist/geometry/tangents.js +142 -0
- package/dist/geometry/textMesh.d.ts +51 -0
- package/dist/geometry/textMesh.js +57 -0
- package/dist/geometry/treeBuilder.d.ts +37 -0
- package/dist/geometry/treeBuilder.js +56 -0
- package/dist/host/display.d.ts +135 -0
- package/dist/host/display.js +114 -0
- package/dist/host/files.d.ts +25 -0
- package/dist/host/files.js +44 -0
- package/dist/host/lifecycle.d.ts +45 -0
- package/dist/host/lifecycle.js +28 -0
- package/dist/host/platformServices.d.ts +23 -0
- package/dist/host/platformServices.js +1 -0
- package/dist/host/screen.d.ts +49 -0
- package/dist/host/screen.js +90 -0
- package/dist/index.d.ts +289 -0
- package/dist/index.js +320 -0
- package/dist/input/actionMap.d.ts +181 -0
- package/dist/input/actionMap.js +314 -0
- package/dist/input/activeDevice.d.ts +55 -0
- package/dist/input/activeDevice.js +83 -0
- package/dist/input/gamepadIdentity.d.ts +43 -0
- package/dist/input/gamepadIdentity.js +108 -0
- package/dist/input/gamepadMapping.d.ts +56 -0
- package/dist/input/gamepadMapping.js +91 -0
- package/dist/input/input.d.ts +281 -0
- package/dist/input/input.js +703 -0
- package/dist/input/inputHarness.d.ts +42 -0
- package/dist/input/inputHarness.js +193 -0
- package/dist/input/rightGesture.d.ts +57 -0
- package/dist/input/rightGesture.js +49 -0
- package/dist/input/rumble.d.ts +71 -0
- package/dist/input/rumble.js +119 -0
- package/dist/input/touchControls.d.ts +138 -0
- package/dist/input/touchControls.js +352 -0
- package/dist/input/typingTarget.d.ts +6 -0
- package/dist/input/typingTarget.js +27 -0
- package/dist/math/bounds.d.ts +61 -0
- package/dist/math/bounds.js +121 -0
- package/dist/math/color.d.ts +8 -0
- package/dist/math/color.js +35 -0
- package/dist/math/exact.d.ts +66 -0
- package/dist/math/exact.js +262 -0
- package/dist/math/frustum.d.ts +44 -0
- package/dist/math/frustum.js +90 -0
- package/dist/math/intersect.d.ts +76 -0
- package/dist/math/intersect.js +185 -0
- package/dist/math/scalar.d.ts +51 -0
- package/dist/math/scalar.js +99 -0
- package/dist/math/spring.d.ts +59 -0
- package/dist/math/spring.js +88 -0
- package/dist/nav/navGraph.d.ts +71 -0
- package/dist/nav/navGraph.js +111 -0
- package/dist/nav/navPath.d.ts +93 -0
- package/dist/nav/navPath.js +162 -0
- package/dist/nav/navSearch.d.ts +74 -0
- package/dist/nav/navSearch.js +198 -0
- package/dist/physics/boxSurface.d.ts +48 -0
- package/dist/physics/boxSurface.js +73 -0
- package/dist/physics/colliderSurface.d.ts +46 -0
- package/dist/physics/colliderSurface.js +146 -0
- package/dist/physics/compositeSurface.d.ts +33 -0
- package/dist/physics/compositeSurface.js +108 -0
- package/dist/physics/heightSurface.d.ts +103 -0
- package/dist/physics/heightSurface.js +153 -0
- package/dist/physics/ribbonSurface.d.ts +239 -0
- package/dist/physics/ribbonSurface.js +522 -0
- package/dist/render/ambientOcclusionPass.d.ts +53 -0
- package/dist/render/ambientOcclusionPass.js +179 -0
- package/dist/render/areaLights.d.ts +116 -0
- package/dist/render/areaLights.js +91 -0
- package/dist/render/areaShadowSet.d.ts +184 -0
- package/dist/render/areaShadowSet.js +277 -0
- package/dist/render/atmosphere.d.ts +94 -0
- package/dist/render/atmosphere.js +91 -0
- package/dist/render/backend/api.d.ts +496 -0
- package/dist/render/backend/api.js +1 -0
- package/dist/render/backend/budget.d.ts +82 -0
- package/dist/render/backend/budget.js +99 -0
- package/dist/render/backend/createRenderer.d.ts +135 -0
- package/dist/render/backend/createRenderer.js +201 -0
- package/dist/render/backend/deadline.d.ts +24 -0
- package/dist/render/backend/deadline.js +38 -0
- package/dist/render/backend/probe.d.ts +30 -0
- package/dist/render/backend/probe.js +129 -0
- package/dist/render/backend/select.d.ts +70 -0
- package/dist/render/backend/select.js +249 -0
- package/dist/render/backend/timer.d.ts +50 -0
- package/dist/render/backend/timer.js +1 -0
- package/dist/render/backend/webgl2/instanced.d.ts +21 -0
- package/dist/render/backend/webgl2/instanced.js +42 -0
- package/dist/render/backend/webgl2/morphTexture.d.ts +21 -0
- package/dist/render/backend/webgl2/morphTexture.js +55 -0
- package/dist/render/backend/webgl2/renderer.d.ts +3027 -0
- package/dist/render/backend/webgl2/renderer.js +6041 -0
- package/dist/render/backend/webgl2/skinPaletteTexture.d.ts +32 -0
- package/dist/render/backend/webgl2/skinPaletteTexture.js +68 -0
- package/dist/render/backend/webgpu/boltPass.d.ts +42 -0
- package/dist/render/backend/webgpu/boltPass.js +160 -0
- package/dist/render/backend/webgpu/buffers.d.ts +159 -0
- package/dist/render/backend/webgpu/buffers.js +402 -0
- package/dist/render/backend/webgpu/causticsPass.d.ts +36 -0
- package/dist/render/backend/webgpu/causticsPass.js +138 -0
- package/dist/render/backend/webgpu/clusterBinner.d.ts +51 -0
- package/dist/render/backend/webgpu/clusterBinner.js +206 -0
- package/dist/render/backend/webgpu/depthPass.d.ts +114 -0
- package/dist/render/backend/webgpu/depthPass.js +228 -0
- package/dist/render/backend/webgpu/device.d.ts +52 -0
- package/dist/render/backend/webgpu/device.js +121 -0
- package/dist/render/backend/webgpu/drawCommand.d.ts +43 -0
- package/dist/render/backend/webgpu/drawCommand.js +54 -0
- package/dist/render/backend/webgpu/environmentTexels.d.ts +28 -0
- package/dist/render/backend/webgpu/environmentTexels.js +79 -0
- package/dist/render/backend/webgpu/filmPass.d.ts +29 -0
- package/dist/render/backend/webgpu/filmPass.js +97 -0
- package/dist/render/backend/webgpu/flatPass.d.ts +213 -0
- package/dist/render/backend/webgpu/flatPass.js +482 -0
- package/dist/render/backend/webgpu/flockPass.d.ts +34 -0
- package/dist/render/backend/webgpu/flockPass.js +129 -0
- package/dist/render/backend/webgpu/gpuTimestamps.d.ts +94 -0
- package/dist/render/backend/webgpu/gpuTimestamps.js +213 -0
- package/dist/render/backend/webgpu/insetPass.d.ts +19 -0
- package/dist/render/backend/webgpu/insetPass.js +108 -0
- package/dist/render/backend/webgpu/instanced.d.ts +27 -0
- package/dist/render/backend/webgpu/instanced.js +49 -0
- package/dist/render/backend/webgpu/lightVolumePass.d.ts +75 -0
- package/dist/render/backend/webgpu/lightVolumePass.js +154 -0
- package/dist/render/backend/webgpu/linePass.d.ts +90 -0
- package/dist/render/backend/webgpu/linePass.js +220 -0
- package/dist/render/backend/webgpu/morphTexture.d.ts +18 -0
- package/dist/render/backend/webgpu/morphTexture.js +51 -0
- package/dist/render/backend/webgpu/panelPass.d.ts +37 -0
- package/dist/render/backend/webgpu/panelPass.js +114 -0
- package/dist/render/backend/webgpu/particlePass.d.ts +89 -0
- package/dist/render/backend/webgpu/particlePass.js +280 -0
- package/dist/render/backend/webgpu/pipelineCache.d.ts +93 -0
- package/dist/render/backend/webgpu/pipelineCache.js +140 -0
- package/dist/render/backend/webgpu/plumePass.d.ts +69 -0
- package/dist/render/backend/webgpu/plumePass.js +213 -0
- package/dist/render/backend/webgpu/pointShadowPass.d.ts +88 -0
- package/dist/render/backend/webgpu/pointShadowPass.js +280 -0
- package/dist/render/backend/webgpu/postPass.d.ts +342 -0
- package/dist/render/backend/webgpu/postPass.js +366 -0
- package/dist/render/backend/webgpu/probePass.d.ts +108 -0
- package/dist/render/backend/webgpu/probePass.js +188 -0
- package/dist/render/backend/webgpu/reflectionPass.d.ts +29 -0
- package/dist/render/backend/webgpu/reflectionPass.js +87 -0
- package/dist/render/backend/webgpu/renderer.d.ts +3082 -0
- package/dist/render/backend/webgpu/renderer.js +10911 -0
- package/dist/render/backend/webgpu/scatterPass.d.ts +95 -0
- package/dist/render/backend/webgpu/scatterPass.js +266 -0
- package/dist/render/backend/webgpu/sdfTextPass.d.ts +86 -0
- package/dist/render/backend/webgpu/sdfTextPass.js +190 -0
- package/dist/render/backend/webgpu/shaderModules.d.ts +9 -0
- package/dist/render/backend/webgpu/shaderModules.js +45 -0
- package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.d.ts +23 -0
- package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.js +208 -0
- package/dist/render/backend/webgpu/skinPaletteRing.d.ts +67 -0
- package/dist/render/backend/webgpu/skinPaletteRing.js +97 -0
- package/dist/render/backend/webgpu/skinPaletteTexture.d.ts +17 -0
- package/dist/render/backend/webgpu/skinPaletteTexture.js +68 -0
- package/dist/render/backend/webgpu/skyPass.d.ts +102 -0
- package/dist/render/backend/webgpu/skyPass.js +70 -0
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +41 -0
- package/dist/render/backend/webgpu/surfaceTexturePass.js +228 -0
- package/dist/render/backend/webgpu/textPass.d.ts +73 -0
- package/dist/render/backend/webgpu/textPass.js +190 -0
- package/dist/render/backend/webgpu/uniformRing.d.ts +133 -0
- package/dist/render/backend/webgpu/uniformRing.js +208 -0
- package/dist/render/backend/webgpu/waterPass.d.ts +73 -0
- package/dist/render/backend/webgpu/waterPass.js +160 -0
- package/dist/render/backend/webgpu/windStreakPass.d.ts +46 -0
- package/dist/render/backend/webgpu/windStreakPass.js +153 -0
- package/dist/render/billboard.d.ts +27 -0
- package/dist/render/billboard.js +79 -0
- package/dist/render/bloomChain.d.ts +66 -0
- package/dist/render/bloomChain.js +83 -0
- package/dist/render/bloomPass.d.ts +54 -0
- package/dist/render/bloomPass.js +219 -0
- package/dist/render/boltBatch.d.ts +39 -0
- package/dist/render/boltBatch.js +121 -0
- package/dist/render/boltPool.d.ts +135 -0
- package/dist/render/boltPool.js +259 -0
- package/dist/render/boom.d.ts +46 -0
- package/dist/render/boom.js +81 -0
- package/dist/render/camera.d.ts +119 -0
- package/dist/render/camera.js +304 -0
- package/dist/render/causticsRenderer.d.ts +63 -0
- package/dist/render/causticsRenderer.js +119 -0
- package/dist/render/cinematicCamera.d.ts +102 -0
- package/dist/render/cinematicCamera.js +227 -0
- package/dist/render/clusteredLights.d.ts +260 -0
- package/dist/render/clusteredLights.js +479 -0
- package/dist/render/colourGrade.d.ts +62 -0
- package/dist/render/colourGrade.js +91 -0
- package/dist/render/compute.d.ts +74 -0
- package/dist/render/compute.js +8 -0
- package/dist/render/contextLoss.d.ts +32 -0
- package/dist/render/contextLoss.js +46 -0
- package/dist/render/debugLines.d.ts +75 -0
- package/dist/render/debugLines.js +281 -0
- package/dist/render/decalPass.d.ts +34 -0
- package/dist/render/decalPass.js +103 -0
- package/dist/render/decalProjector.d.ts +140 -0
- package/dist/render/decalProjector.js +282 -0
- package/dist/render/decalQueue.d.ts +53 -0
- package/dist/render/decalQueue.js +87 -0
- package/dist/render/depthConvention.d.ts +314 -0
- package/dist/render/depthConvention.js +346 -0
- package/dist/render/drawingBuffer.d.ts +52 -0
- package/dist/render/drawingBuffer.js +67 -0
- package/dist/render/emptyTexture.d.ts +60 -0
- package/dist/render/emptyTexture.js +103 -0
- package/dist/render/envProbeArray.d.ts +85 -0
- package/dist/render/envProbeArray.js +164 -0
- package/dist/render/equirectToCube.d.ts +54 -0
- package/dist/render/equirectToCube.js +123 -0
- package/dist/render/flockGeometry.d.ts +23 -0
- package/dist/render/flockGeometry.js +43 -0
- package/dist/render/flockRenderer.d.ts +37 -0
- package/dist/render/flockRenderer.js +70 -0
- package/dist/render/frame/arena.d.ts +32 -0
- package/dist/render/frame/arena.js +65 -0
- package/dist/render/frame/index.d.ts +18 -0
- package/dist/render/frame/index.js +4 -0
- package/dist/render/frame/replay.d.ts +34 -0
- package/dist/render/frame/replay.js +48 -0
- package/dist/render/frame/resources.d.ts +25 -0
- package/dist/render/frame/resources.js +55 -0
- package/dist/render/frame/schedule.d.ts +37 -0
- package/dist/render/frame/schedule.js +61 -0
- package/dist/render/frameView.d.ts +19 -0
- package/dist/render/frameView.js +1 -0
- package/dist/render/gizmo.d.ts +236 -0
- package/dist/render/gizmo.js +727 -0
- package/dist/render/globalMedium.d.ts +124 -0
- package/dist/render/globalMedium.js +100 -0
- package/dist/render/globalMediumPass.d.ts +101 -0
- package/dist/render/globalMediumPass.js +250 -0
- package/dist/render/gpuCapability.d.ts +111 -0
- package/dist/render/gpuCapability.js +194 -0
- package/dist/render/gpuTimer.d.ts +87 -0
- package/dist/render/gpuTimer.js +145 -0
- package/dist/render/halfFloat.d.ts +4 -0
- package/dist/render/halfFloat.js +38 -0
- package/dist/render/handleRegistry.d.ts +54 -0
- package/dist/render/handleRegistry.js +84 -0
- package/dist/render/iesProfile.d.ts +64 -0
- package/dist/render/iesProfile.js +179 -0
- package/dist/render/imageTexels.d.ts +50 -0
- package/dist/render/imageTexels.js +91 -0
- package/dist/render/instancedMesh.d.ts +48 -0
- package/dist/render/instancedMesh.js +127 -0
- package/dist/render/instances.d.ts +69 -0
- package/dist/render/instances.js +52 -0
- package/dist/render/lightBudget.d.ts +397 -0
- package/dist/render/lightBudget.js +524 -0
- package/dist/render/lightMatrix.d.ts +3 -0
- package/dist/render/lightMatrix.js +45 -0
- package/dist/render/lightVolumeDraw.d.ts +132 -0
- package/dist/render/lightVolumeDraw.js +181 -0
- package/dist/render/lineBatch.d.ts +60 -0
- package/dist/render/lineBatch.js +160 -0
- package/dist/render/linePoints.d.ts +33 -0
- package/dist/render/linePoints.js +46 -0
- package/dist/render/livePointShadowSet.d.ts +72 -0
- package/dist/render/livePointShadowSet.js +258 -0
- package/dist/render/lod.d.ts +35 -0
- package/dist/render/lod.js +65 -0
- package/dist/render/mesh.d.ts +177 -0
- package/dist/render/mesh.js +466 -0
- package/dist/render/occlusion.d.ts +81 -0
- package/dist/render/occlusion.js +378 -0
- package/dist/render/oitPass.d.ts +67 -0
- package/dist/render/oitPass.js +213 -0
- package/dist/render/orderIndependent.d.ts +92 -0
- package/dist/render/orderIndependent.js +108 -0
- package/dist/render/particleBatch.d.ts +140 -0
- package/dist/render/particleBatch.js +186 -0
- package/dist/render/particleMaterial.d.ts +54 -0
- package/dist/render/particleMaterial.js +42 -0
- package/dist/render/particlePool.d.ts +124 -0
- package/dist/render/particlePool.js +182 -0
- package/dist/render/pass.d.ts +195 -0
- package/dist/render/pass.js +9 -0
- package/dist/render/passTarget.d.ts +86 -0
- package/dist/render/passTarget.js +121 -0
- package/dist/render/pickable.d.ts +31 -0
- package/dist/render/pickable.js +172 -0
- package/dist/render/planarReflection.d.ts +59 -0
- package/dist/render/planarReflection.js +194 -0
- package/dist/render/planarReflectionDraw.d.ts +31 -0
- package/dist/render/planarReflectionDraw.js +65 -0
- package/dist/render/plumeGeometry.d.ts +25 -0
- package/dist/render/plumeGeometry.js +61 -0
- package/dist/render/plumeMaterial.d.ts +31 -0
- package/dist/render/plumeMaterial.js +64 -0
- package/dist/render/plumeRenderer.d.ts +96 -0
- package/dist/render/plumeRenderer.js +185 -0
- package/dist/render/pointLightSelection.d.ts +175 -0
- package/dist/render/pointLightSelection.js +301 -0
- package/dist/render/pointShadowArray.d.ts +95 -0
- package/dist/render/pointShadowArray.js +219 -0
- package/dist/render/pointShadowBudget.d.ts +118 -0
- package/dist/render/pointShadowBudget.js +221 -0
- package/dist/render/pointShadowImage.d.ts +265 -0
- package/dist/render/pointShadowImage.js +339 -0
- package/dist/render/pointShadowMap.d.ts +93 -0
- package/dist/render/pointShadowMap.js +167 -0
- package/dist/render/pointShadowSystem.d.ts +195 -0
- package/dist/render/pointShadowSystem.js +336 -0
- package/dist/render/prefilterEnvMap.d.ts +124 -0
- package/dist/render/prefilterEnvMap.js +146 -0
- package/dist/render/prefilterPass.d.ts +44 -0
- package/dist/render/prefilterPass.js +98 -0
- package/dist/render/probeGrid.d.ts +122 -0
- package/dist/render/probeGrid.js +174 -0
- package/dist/render/rainField.d.ts +99 -0
- package/dist/render/rainField.js +168 -0
- package/dist/render/reflectionProbe.d.ts +188 -0
- package/dist/render/reflectionProbe.js +437 -0
- package/dist/render/renderQuality.d.ts +699 -0
- package/dist/render/renderQuality.js +293 -0
- package/dist/render/rendererHarness.d.ts +39 -0
- package/dist/render/rendererHarness.js +185 -0
- package/dist/render/resolutionGovernor.d.ts +107 -0
- package/dist/render/resolutionGovernor.js +144 -0
- package/dist/render/scatterDeform.d.ts +17 -0
- package/dist/render/scatterDeform.js +46 -0
- package/dist/render/sceneTarget.d.ts +288 -0
- package/dist/render/sceneTarget.js +856 -0
- package/dist/render/screenSpaceReflection.d.ts +233 -0
- package/dist/render/screenSpaceReflection.js +415 -0
- package/dist/render/sdfFont.d.ts +77 -0
- package/dist/render/sdfFont.js +86 -0
- package/dist/render/sdfTextLayout.d.ts +46 -0
- package/dist/render/sdfTextLayout.js +145 -0
- package/dist/render/sdfTextRenderer.d.ts +75 -0
- package/dist/render/sdfTextRenderer.js +194 -0
- package/dist/render/seaState.d.ts +25 -0
- package/dist/render/seaState.js +34 -0
- package/dist/render/segmentQuads.d.ts +29 -0
- package/dist/render/segmentQuads.js +75 -0
- package/dist/render/shader.d.ts +5 -0
- package/dist/render/shader.js +172 -0
- package/dist/render/shaders/ambientOcclusion.d.ts +45 -0
- package/dist/render/shaders/ambientOcclusion.js +352 -0
- package/dist/render/shaders/arcane.d.ts +19 -0
- package/dist/render/shaders/arcane.js +102 -0
- package/dist/render/shaders/bloom.d.ts +70 -0
- package/dist/render/shaders/bloom.js +227 -0
- package/dist/render/shaders/bolt.d.ts +17 -0
- package/dist/render/shaders/bolt.js +161 -0
- package/dist/render/shaders/caustics.d.ts +38 -0
- package/dist/render/shaders/caustics.js +167 -0
- package/dist/render/shaders/conditionals.d.ts +21 -0
- package/dist/render/shaders/conditionals.js +55 -0
- package/dist/render/shaders/decalProject.d.ts +25 -0
- package/dist/render/shaders/decalProject.js +125 -0
- package/dist/render/shaders/depth.d.ts +14 -0
- package/dist/render/shaders/depth.js +114 -0
- package/dist/render/shaders/depthOfField.d.ts +41 -0
- package/dist/render/shaders/depthOfField.js +139 -0
- package/dist/render/shaders/film.d.ts +15 -0
- package/dist/render/shaders/film.js +283 -0
- package/dist/render/shaders/fire.d.ts +12 -0
- package/dist/render/shaders/fire.js +178 -0
- package/dist/render/shaders/flat/directionalShadow.d.ts +1 -0
- package/dist/render/shaders/flat/directionalShadow.js +195 -0
- package/dist/render/shaders/flat/index.d.ts +135 -0
- package/dist/render/shaders/flat/index.js +387 -0
- package/dist/render/shaders/flat/lobes.d.ts +1 -0
- package/dist/render/shaders/flat/lobes.js +398 -0
- package/dist/render/shaders/flat/main.d.ts +2 -0
- package/dist/render/shaders/flat/main.js +1630 -0
- package/dist/render/shaders/flat/pointShadow.d.ts +1 -0
- package/dist/render/shaders/flat/pointShadow.js +322 -0
- package/dist/render/shaders/flat/preamble.d.ts +15 -0
- package/dist/render/shaders/flat/preamble.js +864 -0
- package/dist/render/shaders/flat/probeGrid.d.ts +21 -0
- package/dist/render/shaders/flat/probeGrid.js +151 -0
- package/dist/render/shaders/flat/surface.d.ts +2 -0
- package/dist/render/shaders/flat/surface.js +40 -0
- package/dist/render/shaders/flock.d.ts +11 -0
- package/dist/render/shaders/flock.js +102 -0
- package/dist/render/shaders/fog.d.ts +37 -0
- package/dist/render/shaders/fog.js +98 -0
- package/dist/render/shaders/fullscreen.d.ts +16 -0
- package/dist/render/shaders/fullscreen.js +27 -0
- package/dist/render/shaders/generated/ambientOcclusion.wgsl.d.ts +65 -0
- package/dist/render/shaders/generated/ambientOcclusion.wgsl.js +71 -0
- package/dist/render/shaders/generated/arcane.wgsl.d.ts +90 -0
- package/dist/render/shaders/generated/arcane.wgsl.js +96 -0
- package/dist/render/shaders/generated/bloom.wgsl.d.ts +69 -0
- package/dist/render/shaders/generated/bloom.wgsl.js +75 -0
- package/dist/render/shaders/generated/bolt.wgsl.d.ts +118 -0
- package/dist/render/shaders/generated/bolt.wgsl.js +124 -0
- package/dist/render/shaders/generated/caustics.wgsl.d.ts +118 -0
- package/dist/render/shaders/generated/caustics.wgsl.js +124 -0
- package/dist/render/shaders/generated/decalProject.wgsl.d.ts +61 -0
- package/dist/render/shaders/generated/decalProject.wgsl.js +67 -0
- package/dist/render/shaders/generated/depth.wgsl.d.ts +131 -0
- package/dist/render/shaders/generated/depth.wgsl.js +137 -0
- package/dist/render/shaders/generated/film.wgsl.d.ts +134 -0
- package/dist/render/shaders/generated/film.wgsl.js +140 -0
- package/dist/render/shaders/generated/fire.wgsl.d.ts +128 -0
- package/dist/render/shaders/generated/fire.wgsl.js +134 -0
- package/dist/render/shaders/generated/flat.wgsl.d.ts +9163 -0
- package/dist/render/shaders/generated/flat.wgsl.js +9192 -0
- package/dist/render/shaders/generated/flock.wgsl.d.ts +73 -0
- package/dist/render/shaders/generated/flock.wgsl.js +79 -0
- package/dist/render/shaders/generated/fullscreen.wgsl.d.ts +12 -0
- package/dist/render/shaders/generated/fullscreen.wgsl.js +18 -0
- package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +130 -0
- package/dist/render/shaders/generated/globalMedium.wgsl.js +136 -0
- package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +230 -0
- package/dist/render/shaders/generated/lightVolume.wgsl.js +239 -0
- package/dist/render/shaders/generated/line.wgsl.d.ts +128 -0
- package/dist/render/shaders/generated/line.wgsl.js +134 -0
- package/dist/render/shaders/generated/octahedralResolve.wgsl.d.ts +51 -0
- package/dist/render/shaders/generated/octahedralResolve.wgsl.js +57 -0
- package/dist/render/shaders/generated/oitResolve.wgsl.d.ts +23 -0
- package/dist/render/shaders/generated/oitResolve.wgsl.js +29 -0
- package/dist/render/shaders/generated/panel.wgsl.d.ts +48 -0
- package/dist/render/shaders/generated/panel.wgsl.js +54 -0
- package/dist/render/shaders/generated/particle.wgsl.d.ts +332 -0
- package/dist/render/shaders/generated/particle.wgsl.js +338 -0
- package/dist/render/shaders/generated/prefilter.wgsl.d.ts +61 -0
- package/dist/render/shaders/generated/prefilter.wgsl.js +67 -0
- package/dist/render/shaders/generated/rush.wgsl.d.ts +131 -0
- package/dist/render/shaders/generated/rush.wgsl.js +137 -0
- package/dist/render/shaders/generated/scatter.wgsl.d.ts +195 -0
- package/dist/render/shaders/generated/scatter.wgsl.js +201 -0
- package/dist/render/shaders/generated/sdfText.wgsl.d.ts +69 -0
- package/dist/render/shaders/generated/sdfText.wgsl.js +75 -0
- package/dist/render/shaders/generated/sky.wgsl.d.ts +100 -0
- package/dist/render/shaders/generated/sky.wgsl.js +106 -0
- package/dist/render/shaders/generated/smoke.wgsl.d.ts +85 -0
- package/dist/render/shaders/generated/smoke.wgsl.js +91 -0
- package/dist/render/shaders/generated/ssrResolve.wgsl.d.ts +18 -0
- package/dist/render/shaders/generated/ssrResolve.wgsl.js +24 -0
- package/dist/render/shaders/generated/ssrTrace.wgsl.d.ts +86 -0
- package/dist/render/shaders/generated/ssrTrace.wgsl.js +92 -0
- package/dist/render/shaders/generated/temporalResolve.wgsl.d.ts +46 -0
- package/dist/render/shaders/generated/temporalResolve.wgsl.js +52 -0
- package/dist/render/shaders/generated/text.wgsl.d.ts +98 -0
- package/dist/render/shaders/generated/text.wgsl.js +104 -0
- package/dist/render/shaders/generated/water.wgsl.d.ts +247 -0
- package/dist/render/shaders/generated/water.wgsl.js +253 -0
- package/dist/render/shaders/generated/windStreaks.wgsl.d.ts +73 -0
- package/dist/render/shaders/generated/windStreaks.wgsl.js +79 -0
- package/dist/render/shaders/gerstner.d.ts +21 -0
- package/dist/render/shaders/gerstner.js +110 -0
- package/dist/render/shaders/globalMedium.d.ts +56 -0
- package/dist/render/shaders/globalMedium.js +393 -0
- package/dist/render/shaders/lightVolume.d.ts +61 -0
- package/dist/render/shaders/lightVolume.js +527 -0
- package/dist/render/shaders/line.d.ts +18 -0
- package/dist/render/shaders/line.js +122 -0
- package/dist/render/shaders/morph.d.ts +26 -0
- package/dist/render/shaders/morph.js +61 -0
- package/dist/render/shaders/octahedral.d.ts +76 -0
- package/dist/render/shaders/octahedral.js +161 -0
- package/dist/render/shaders/octahedralResolve.d.ts +25 -0
- package/dist/render/shaders/octahedralResolve.js +81 -0
- package/dist/render/shaders/oitResolve.d.ts +17 -0
- package/dist/render/shaders/oitResolve.js +42 -0
- package/dist/render/shaders/outputTransform.d.ts +37 -0
- package/dist/render/shaders/outputTransform.js +106 -0
- package/dist/render/shaders/panel.d.ts +17 -0
- package/dist/render/shaders/panel.js +50 -0
- package/dist/render/shaders/particle.d.ts +82 -0
- package/dist/render/shaders/particle.js +431 -0
- package/dist/render/shaders/prefilter.d.ts +37 -0
- package/dist/render/shaders/prefilter.js +276 -0
- package/dist/render/shaders/rush.d.ts +21 -0
- package/dist/render/shaders/rush.js +355 -0
- package/dist/render/shaders/scatter.d.ts +14 -0
- package/dist/render/shaders/scatter.js +206 -0
- package/dist/render/shaders/sdfText.d.ts +9 -0
- package/dist/render/shaders/sdfText.js +65 -0
- package/dist/render/shaders/skinning.d.ts +17 -0
- package/dist/render/shaders/skinning.js +59 -0
- package/dist/render/shaders/sky.d.ts +10 -0
- package/dist/render/shaders/sky.js +242 -0
- package/dist/render/shaders/smoke.d.ts +8 -0
- package/dist/render/shaders/smoke.js +88 -0
- package/dist/render/shaders/ssrResolve.d.ts +15 -0
- package/dist/render/shaders/ssrResolve.js +28 -0
- package/dist/render/shaders/ssrTrace.d.ts +22 -0
- package/dist/render/shaders/ssrTrace.js +230 -0
- package/dist/render/shaders/tangentFrame.d.ts +17 -0
- package/dist/render/shaders/tangentFrame.js +70 -0
- package/dist/render/shaders/temporalResolve.d.ts +1 -0
- package/dist/render/shaders/temporalResolve.js +150 -0
- package/dist/render/shaders/text.d.ts +17 -0
- package/dist/render/shaders/text.js +155 -0
- package/dist/render/shaders/vertexChannel.d.ts +39 -0
- package/dist/render/shaders/vertexChannel.js +69 -0
- package/dist/render/shaders/water.d.ts +18 -0
- package/dist/render/shaders/water.js +354 -0
- package/dist/render/shaders/windStreaks.d.ts +14 -0
- package/dist/render/shaders/windStreaks.js +129 -0
- package/dist/render/shadowCasters.d.ts +107 -0
- package/dist/render/shadowCasters.js +1 -0
- package/dist/render/shadowMap.d.ts +10 -0
- package/dist/render/shadowMap.js +80 -0
- package/dist/render/shotPlacement.d.ts +80 -0
- package/dist/render/shotPlacement.js +183 -0
- package/dist/render/skinPalette.d.ts +90 -0
- package/dist/render/skinPalette.js +136 -0
- package/dist/render/ssrPass.d.ts +59 -0
- package/dist/render/ssrPass.js +196 -0
- package/dist/render/surfaceSheet.d.ts +52 -0
- package/dist/render/surfaceSheet.js +99 -0
- package/dist/render/surfaceTexture.d.ts +197 -0
- package/dist/render/surfaceTexture.js +116 -0
- package/dist/render/temporalAa.d.ts +104 -0
- package/dist/render/temporalAa.js +194 -0
- package/dist/render/temporalPass.d.ts +54 -0
- package/dist/render/temporalPass.js +135 -0
- package/dist/render/textLayout.d.ts +88 -0
- package/dist/render/textLayout.js +201 -0
- package/dist/render/textRenderer.d.ts +32 -0
- package/dist/render/textRenderer.js +176 -0
- package/dist/render/thirdPersonCamera.d.ts +272 -0
- package/dist/render/thirdPersonCamera.js +479 -0
- package/dist/render/trample.d.ts +57 -0
- package/dist/render/trample.js +134 -0
- package/dist/render/translucentQueue.d.ts +76 -0
- package/dist/render/translucentQueue.js +90 -0
- package/dist/render/uniformVectorBudget.d.ts +105 -0
- package/dist/render/uniformVectorBudget.js +201 -0
- package/dist/render/uploadStep.d.ts +14 -0
- package/dist/render/uploadStep.js +14 -0
- package/dist/render/vertexDefaults.d.ts +48 -0
- package/dist/render/vertexDefaults.js +111 -0
- package/dist/render/visibility.d.ts +22 -0
- package/dist/render/visibility.js +47 -0
- package/dist/render/waterDraw.d.ts +57 -0
- package/dist/render/waterDraw.js +102 -0
- package/dist/render/waterGrid.d.ts +62 -0
- package/dist/render/waterGrid.js +151 -0
- package/dist/render/waterRenderer.d.ts +163 -0
- package/dist/render/waterRenderer.js +165 -0
- package/dist/render/wind.d.ts +45 -0
- package/dist/render/wind.js +32 -0
- package/dist/render/windField.d.ts +34 -0
- package/dist/render/windField.js +13 -0
- package/dist/render/windStreakDraw.d.ts +73 -0
- package/dist/render/windStreakDraw.js +86 -0
- package/dist/render/windStreakRenderer.d.ts +37 -0
- package/dist/render/windStreakRenderer.js +86 -0
- package/dist/scene/node.d.ts +128 -0
- package/dist/scene/node.js +319 -0
- package/dist/scene/visit.d.ts +38 -0
- package/dist/scene/visit.js +43 -0
- package/dist/ui/clipMime.d.ts +46 -0
- package/dist/ui/clipMime.js +88 -0
- package/dist/ui/exportTarget.d.ts +305 -0
- package/dist/ui/exportTarget.js +368 -0
- package/dist/ui/frameOverlay.d.ts +59 -0
- package/dist/ui/frameOverlay.js +76 -0
- package/dist/ui/framePacer.d.ts +142 -0
- package/dist/ui/framePacer.js +284 -0
- package/dist/ui/frameRecorder.d.ts +188 -0
- package/dist/ui/frameRecorder.js +221 -0
- package/dist/ui/fullscreen.d.ts +72 -0
- package/dist/ui/fullscreen.js +92 -0
- package/dist/ui/pixelCursor.d.ts +28 -0
- package/dist/ui/pixelCursor.js +66 -0
- package/dist/ui/splash.d.ts +86 -0
- package/dist/ui/splash.js +300 -0
- package/dist/ui/stillFrame.d.ts +22 -0
- package/dist/ui/stillFrame.js +40 -0
- package/package.json +60 -0
- package/src/behavior/behaviorTree.ts +346 -0
- package/src/build/shaderComments.ts +0 -0
- package/src/cinematic/player.ts +209 -0
- package/src/cinematic/script.ts +231 -0
- package/src/core/bootGate.ts +49 -0
- package/src/core/loadTracker.ts +144 -0
- package/src/core/loop.ts +211 -0
- package/src/core/messageQueue.ts +145 -0
- package/src/core/onceSet.ts +65 -0
- package/src/core/preferences.ts +177 -0
- package/src/core/remoteSave.ts +347 -0
- package/src/core/rng.ts +101 -0
- package/src/core/stepBudget.ts +136 -0
- package/src/core/storage.ts +114 -0
- package/src/core/tickTrace.ts +129 -0
- package/src/core/timeCurve.ts +175 -0
- package/src/core/withDefaults.ts +28 -0
- package/src/dev/contactProbe.ts +115 -0
- package/src/dev/fpsMeter.ts +101 -0
- package/src/environment/celestialClock.ts +385 -0
- package/src/geometry/decal.ts +260 -0
- package/src/geometry/filmPatch.ts +158 -0
- package/src/geometry/growable.ts +165 -0
- package/src/geometry/lightVolume.ts +161 -0
- package/src/geometry/meshBuilder.ts +1397 -0
- package/src/geometry/pixelFont.ts +189 -0
- package/src/geometry/ribbon.ts +790 -0
- package/src/geometry/shellFill.ts +265 -0
- package/src/geometry/spline.ts +659 -0
- package/src/geometry/tangents.ts +173 -0
- package/src/geometry/textMesh.ts +96 -0
- package/src/geometry/treeBuilder.ts +114 -0
- package/src/host/display.ts +180 -0
- package/src/host/files.ts +77 -0
- package/src/host/lifecycle.ts +63 -0
- package/src/host/platformServices.ts +23 -0
- package/src/host/screen.ts +134 -0
- package/src/index.ts +730 -0
- package/src/input/actionMap.ts +377 -0
- package/src/input/activeDevice.ts +86 -0
- package/src/input/gamepadIdentity.ts +131 -0
- package/src/input/gamepadMapping.ts +121 -0
- package/src/input/input.ts +872 -0
- package/src/input/inputHarness.ts +226 -0
- package/src/input/rightGesture.ts +76 -0
- package/src/input/rumble.ts +138 -0
- package/src/input/touchControls.ts +451 -0
- package/src/input/typingTarget.ts +26 -0
- package/src/math/bounds.ts +153 -0
- package/src/math/color.ts +37 -0
- package/src/math/exact.ts +274 -0
- package/src/math/frustum.ts +115 -0
- package/src/math/intersect.ts +228 -0
- package/src/math/scalar.ts +109 -0
- package/src/math/spring.ts +106 -0
- package/src/nav/navGraph.ts +168 -0
- package/src/nav/navPath.ts +217 -0
- package/src/nav/navSearch.ts +200 -0
- package/src/physics/boxSurface.ts +96 -0
- package/src/physics/colliderSurface.ts +213 -0
- package/src/physics/compositeSurface.ts +111 -0
- package/src/physics/heightSurface.ts +234 -0
- package/src/physics/ribbonSurface.ts +642 -0
- package/src/render/ambientOcclusionPass.ts +200 -0
- package/src/render/areaLights.ts +194 -0
- package/src/render/areaShadowSet.ts +405 -0
- package/src/render/atmosphere.ts +186 -0
- package/src/render/backend/api.ts +802 -0
- package/src/render/backend/budget.ts +139 -0
- package/src/render/backend/createRenderer.ts +343 -0
- package/src/render/backend/deadline.ts +37 -0
- package/src/render/backend/probe.ts +152 -0
- package/src/render/backend/select.ts +288 -0
- package/src/render/backend/timer.ts +59 -0
- package/src/render/backend/webgl2/instanced.ts +46 -0
- package/src/render/backend/webgl2/morphTexture.ts +58 -0
- package/src/render/backend/webgl2/renderer.ts +7484 -0
- package/src/render/backend/webgl2/skinPaletteTexture.ts +70 -0
- package/src/render/backend/webgpu/boltPass.ts +205 -0
- package/src/render/backend/webgpu/buffers.ts +553 -0
- package/src/render/backend/webgpu/causticsPass.ts +174 -0
- package/src/render/backend/webgpu/clusterBinner.ts +259 -0
- package/src/render/backend/webgpu/depthPass.ts +261 -0
- package/src/render/backend/webgpu/device.ts +148 -0
- package/src/render/backend/webgpu/drawCommand.ts +79 -0
- package/src/render/backend/webgpu/environmentTexels.ts +96 -0
- package/src/render/backend/webgpu/filmPass.ts +123 -0
- package/src/render/backend/webgpu/flatPass.ts +635 -0
- package/src/render/backend/webgpu/flockPass.ts +163 -0
- package/src/render/backend/webgpu/gpuTimestamps.ts +255 -0
- package/src/render/backend/webgpu/insetPass.ts +123 -0
- package/src/render/backend/webgpu/instanced.ts +55 -0
- package/src/render/backend/webgpu/lightVolumePass.ts +203 -0
- package/src/render/backend/webgpu/linePass.ts +270 -0
- package/src/render/backend/webgpu/morphTexture.ts +61 -0
- package/src/render/backend/webgpu/panelPass.ts +138 -0
- package/src/render/backend/webgpu/particlePass.ts +370 -0
- package/src/render/backend/webgpu/pipelineCache.ts +152 -0
- package/src/render/backend/webgpu/plumePass.ts +292 -0
- package/src/render/backend/webgpu/pointShadowPass.ts +368 -0
- package/src/render/backend/webgpu/postPass.ts +470 -0
- package/src/render/backend/webgpu/probePass.ts +218 -0
- package/src/render/backend/webgpu/reflectionPass.ts +137 -0
- package/src/render/backend/webgpu/renderer.ts +13004 -0
- package/src/render/backend/webgpu/scatterPass.ts +354 -0
- package/src/render/backend/webgpu/sdfTextPass.ts +220 -0
- package/src/render/backend/webgpu/shaderModules.ts +49 -0
- package/src/render/backend/webgpu/shaders/clusterBin.wgsl.ts +219 -0
- package/src/render/backend/webgpu/skinPaletteRing.ts +105 -0
- package/src/render/backend/webgpu/skinPaletteTexture.ts +79 -0
- package/src/render/backend/webgpu/skyPass.ts +85 -0
- package/src/render/backend/webgpu/surfaceTexturePass.ts +257 -0
- package/src/render/backend/webgpu/textPass.ts +224 -0
- package/src/render/backend/webgpu/uniformRing.ts +228 -0
- package/src/render/backend/webgpu/waterPass.ts +211 -0
- package/src/render/backend/webgpu/windStreakPass.ts +196 -0
- package/src/render/billboard.ts +108 -0
- package/src/render/bloomChain.ts +101 -0
- package/src/render/bloomPass.ts +256 -0
- package/src/render/boltBatch.ts +141 -0
- package/src/render/boltPool.ts +360 -0
- package/src/render/boom.ts +123 -0
- package/src/render/camera.ts +348 -0
- package/src/render/causticsRenderer.ts +171 -0
- package/src/render/cinematicCamera.ts +278 -0
- package/src/render/clusteredLights.ts +598 -0
- package/src/render/colourGrade.ts +109 -0
- package/src/render/compute.ts +83 -0
- package/src/render/contextLoss.ts +50 -0
- package/src/render/debugLines.ts +411 -0
- package/src/render/decalPass.ts +124 -0
- package/src/render/decalProjector.ts +390 -0
- package/src/render/decalQueue.ts +110 -0
- package/src/render/depthConvention.ts +383 -0
- package/src/render/drawingBuffer.ts +89 -0
- package/src/render/emptyTexture.ts +130 -0
- package/src/render/envProbeArray.ts +201 -0
- package/src/render/equirectToCube.ts +160 -0
- package/src/render/flockGeometry.ts +53 -0
- package/src/render/flockRenderer.ts +111 -0
- package/src/render/frame/arena.ts +93 -0
- package/src/render/frame/index.ts +29 -0
- package/src/render/frame/replay.ts +50 -0
- package/src/render/frame/resources.ts +61 -0
- package/src/render/frame/schedule.ts +85 -0
- package/src/render/frameView.ts +20 -0
- package/src/render/gizmo.ts +923 -0
- package/src/render/globalMedium.ts +154 -0
- package/src/render/globalMediumPass.ts +323 -0
- package/src/render/gpuCapability.ts +244 -0
- package/src/render/gpuTimer.ts +182 -0
- package/src/render/halfFloat.ts +39 -0
- package/src/render/handleRegistry.ts +96 -0
- package/src/render/iesProfile.ts +215 -0
- package/src/render/imageTexels.ts +109 -0
- package/src/render/instancedMesh.ts +187 -0
- package/src/render/instances.ts +92 -0
- package/src/render/lightBudget.ts +655 -0
- package/src/render/lightMatrix.ts +69 -0
- package/src/render/lightVolumeDraw.ts +216 -0
- package/src/render/lineBatch.ts +180 -0
- package/src/render/linePoints.ts +61 -0
- package/src/render/livePointShadowSet.ts +285 -0
- package/src/render/lod.ts +86 -0
- package/src/render/mesh.ts +536 -0
- package/src/render/occlusion.ts +406 -0
- package/src/render/oitPass.ts +230 -0
- package/src/render/orderIndependent.ts +136 -0
- package/src/render/particleBatch.ts +299 -0
- package/src/render/particleMaterial.ts +84 -0
- package/src/render/particlePool.ts +291 -0
- package/src/render/pass.ts +203 -0
- package/src/render/passTarget.ts +225 -0
- package/src/render/pickable.ts +222 -0
- package/src/render/planarReflection.ts +233 -0
- package/src/render/planarReflectionDraw.ts +87 -0
- package/src/render/plumeGeometry.ts +75 -0
- package/src/render/plumeMaterial.ts +99 -0
- package/src/render/plumeRenderer.ts +272 -0
- package/src/render/pointLightSelection.ts +447 -0
- package/src/render/pointShadowArray.ts +276 -0
- package/src/render/pointShadowBudget.ts +305 -0
- package/src/render/pointShadowImage.ts +470 -0
- package/src/render/pointShadowMap.ts +228 -0
- package/src/render/pointShadowSystem.ts +408 -0
- package/src/render/prefilterEnvMap.ts +162 -0
- package/src/render/prefilterPass.ts +115 -0
- package/src/render/probeGrid.ts +248 -0
- package/src/render/rainField.ts +240 -0
- package/src/render/reflectionProbe.ts +530 -0
- package/src/render/renderQuality.ts +1054 -0
- package/src/render/rendererHarness.ts +214 -0
- package/src/render/resolutionGovernor.ts +189 -0
- package/src/render/scatterDeform.ts +72 -0
- package/src/render/sceneTarget.ts +1032 -0
- package/src/render/screenSpaceReflection.ts +524 -0
- package/src/render/sdfFont.ts +157 -0
- package/src/render/sdfTextLayout.ts +206 -0
- package/src/render/sdfTextRenderer.ts +233 -0
- package/src/render/seaState.ts +55 -0
- package/src/render/segmentQuads.ts +92 -0
- package/src/render/shader.ts +190 -0
- package/src/render/shaders/ambientOcclusion.ts +354 -0
- package/src/render/shaders/arcane.ts +103 -0
- package/src/render/shaders/bloom.ts +232 -0
- package/src/render/shaders/bolt.ts +164 -0
- package/src/render/shaders/caustics.ts +169 -0
- package/src/render/shaders/conditionals.ts +58 -0
- package/src/render/shaders/decalProject.ts +127 -0
- package/src/render/shaders/depth.ts +131 -0
- package/src/render/shaders/depthOfField.ts +141 -0
- package/src/render/shaders/film.ts +285 -0
- package/src/render/shaders/fire.ts +180 -0
- package/src/render/shaders/flat/directionalShadow.ts +196 -0
- package/src/render/shaders/flat/index.ts +502 -0
- package/src/render/shaders/flat/lobes.ts +399 -0
- package/src/render/shaders/flat/main.ts +1631 -0
- package/src/render/shaders/flat/pointShadow.ts +323 -0
- package/src/render/shaders/flat/preamble.ts +875 -0
- package/src/render/shaders/flat/probeGrid.ts +152 -0
- package/src/render/shaders/flat/surface.ts +41 -0
- package/src/render/shaders/flock.ts +103 -0
- package/src/render/shaders/fog.ts +99 -0
- package/src/render/shaders/fullscreen.ts +28 -0
- package/src/render/shaders/generated/ambientOcclusion.wgsl.ts +74 -0
- package/src/render/shaders/generated/arcane.wgsl.ts +98 -0
- package/src/render/shaders/generated/bloom.wgsl.ts +79 -0
- package/src/render/shaders/generated/bolt.wgsl.ts +127 -0
- package/src/render/shaders/generated/caustics.wgsl.ts +127 -0
- package/src/render/shaders/generated/decalProject.wgsl.ts +69 -0
- package/src/render/shaders/generated/depth.wgsl.ts +142 -0
- package/src/render/shaders/generated/film.wgsl.ts +143 -0
- package/src/render/shaders/generated/fire.wgsl.ts +137 -0
- package/src/render/shaders/generated/flat.wgsl.ts +9195 -0
- package/src/render/shaders/generated/flock.wgsl.ts +82 -0
- package/src/render/shaders/generated/fullscreen.wgsl.ts +20 -0
- package/src/render/shaders/generated/globalMedium.wgsl.ts +139 -0
- package/src/render/shaders/generated/lightVolume.wgsl.ts +242 -0
- package/src/render/shaders/generated/line.wgsl.ts +137 -0
- package/src/render/shaders/generated/octahedralResolve.wgsl.ts +60 -0
- package/src/render/shaders/generated/oitResolve.wgsl.ts +31 -0
- package/src/render/shaders/generated/panel.wgsl.ts +57 -0
- package/src/render/shaders/generated/particle.wgsl.ts +343 -0
- package/src/render/shaders/generated/prefilter.wgsl.ts +69 -0
- package/src/render/shaders/generated/rush.wgsl.ts +139 -0
- package/src/render/shaders/generated/scatter.wgsl.ts +205 -0
- package/src/render/shaders/generated/sdfText.wgsl.ts +78 -0
- package/src/render/shaders/generated/sky.wgsl.ts +109 -0
- package/src/render/shaders/generated/smoke.wgsl.ts +93 -0
- package/src/render/shaders/generated/ssrResolve.wgsl.ts +26 -0
- package/src/render/shaders/generated/ssrTrace.wgsl.ts +94 -0
- package/src/render/shaders/generated/temporalResolve.wgsl.ts +54 -0
- package/src/render/shaders/generated/text.wgsl.ts +107 -0
- package/src/render/shaders/generated/water.wgsl.ts +256 -0
- package/src/render/shaders/generated/windStreaks.wgsl.ts +82 -0
- package/src/render/shaders/gerstner.ts +110 -0
- package/src/render/shaders/globalMedium.ts +396 -0
- package/src/render/shaders/lightVolume.ts +546 -0
- package/src/render/shaders/line.ts +125 -0
- package/src/render/shaders/morph.ts +62 -0
- package/src/render/shaders/octahedral.ts +170 -0
- package/src/render/shaders/octahedralResolve.ts +83 -0
- package/src/render/shaders/oitResolve.ts +42 -0
- package/src/render/shaders/outputTransform.ts +107 -0
- package/src/render/shaders/panel.ts +51 -0
- package/src/render/shaders/particle.ts +438 -0
- package/src/render/shaders/prefilter.ts +278 -0
- package/src/render/shaders/rush.ts +357 -0
- package/src/render/shaders/scatter.ts +211 -0
- package/src/render/shaders/sdfText.ts +68 -0
- package/src/render/shaders/skinning.ts +59 -0
- package/src/render/shaders/sky.ts +243 -0
- package/src/render/shaders/smoke.ts +89 -0
- package/src/render/shaders/ssrResolve.ts +28 -0
- package/src/render/shaders/ssrTrace.ts +233 -0
- package/src/render/shaders/tangentFrame.ts +70 -0
- package/src/render/shaders/temporalResolve.ts +151 -0
- package/src/render/shaders/text.ts +156 -0
- package/src/render/shaders/vertexChannel.ts +71 -0
- package/src/render/shaders/water.ts +356 -0
- package/src/render/shaders/windStreaks.ts +130 -0
- package/src/render/shadowCasters.ts +124 -0
- package/src/render/shadowMap.ts +89 -0
- package/src/render/shotPlacement.ts +266 -0
- package/src/render/skinPalette.ts +157 -0
- package/src/render/ssrPass.ts +241 -0
- package/src/render/surfaceSheet.ts +158 -0
- package/src/render/surfaceTexture.ts +310 -0
- package/src/render/temporalAa.ts +221 -0
- package/src/render/temporalPass.ts +153 -0
- package/src/render/textLayout.ts +239 -0
- package/src/render/textRenderer.ts +201 -0
- package/src/render/thirdPersonCamera.ts +578 -0
- package/src/render/trample.ts +140 -0
- package/src/render/translucentQueue.ts +161 -0
- package/src/render/uniformVectorBudget.ts +246 -0
- package/src/render/uploadStep.ts +14 -0
- package/src/render/vertexDefaults.ts +115 -0
- package/src/render/visibility.ts +56 -0
- package/src/render/waterDraw.ts +167 -0
- package/src/render/waterGrid.ts +180 -0
- package/src/render/waterRenderer.ts +352 -0
- package/src/render/wind.ts +79 -0
- package/src/render/windField.ts +50 -0
- package/src/render/windStreakDraw.ts +131 -0
- package/src/render/windStreakRenderer.ts +130 -0
- package/src/scene/node.ts +336 -0
- package/src/scene/visit.ts +82 -0
- package/src/ui/clipMime.ts +109 -0
- package/src/ui/exportTarget.ts +491 -0
- package/src/ui/frameOverlay.ts +159 -0
- package/src/ui/framePacer.ts +351 -0
- package/src/ui/frameRecorder.ts +333 -0
- package/src/ui/fullscreen.ts +113 -0
- package/src/ui/pixelCursor.ts +99 -0
- package/src/ui/splash.ts +347 -0
- package/src/ui/stillFrame.ts +44 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
import { FramePacer } from './framePacer.ts';
|
|
2
|
+
import type { FramePacingReport } from './framePacer.ts';
|
|
3
|
+
import { bakeOverlay } from './frameOverlay.ts';
|
|
4
|
+
import type { FrameOverlay } from './frameOverlay.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The surface a clip is recorded from: a fixed-size frame, composited and paced.
|
|
8
|
+
*
|
|
9
|
+
* Three things it fixes, all of which were visible in the first export:
|
|
10
|
+
*
|
|
11
|
+
* **Aspect is rendered, not cropped.** The scene is drawn at the export's own
|
|
12
|
+
* pixel size, so a vertical clip is *framed* vertically. Cropping a 16:9 view to
|
|
13
|
+
* 9:16 throws away 44% of the width, and the subject is exactly what falls
|
|
14
|
+
* outside — the shot was composed for the other rectangle.
|
|
15
|
+
*
|
|
16
|
+
* **The frame is composited.** The scene canvas is copied into a target of
|
|
17
|
+
* exactly the requested size and the mark is stamped on top, so branding is
|
|
18
|
+
* inside the video rather than in DOM that the capture never sees.
|
|
19
|
+
*
|
|
20
|
+
* **Frames are paced.** `captureStream(0)` records nothing until asked, so every
|
|
21
|
+
* frame in the file is one the renderer actually finished. Capturing at a rate
|
|
22
|
+
* the renderer cannot hold samples some frames twice and misses the next, which
|
|
23
|
+
* is what uneven duplication looks like: judder.
|
|
24
|
+
*
|
|
25
|
+
* **The honest limit.** `MediaRecorder` timestamps by wall clock, so an export
|
|
26
|
+
* runs in real time and no amount of pacing changes that. There is no in-browser
|
|
27
|
+
* way to render slower than real time and still have the audio line up, short of
|
|
28
|
+
* shipping a muxer — which is a dependency, and the standing rule says no. What
|
|
29
|
+
* pacing *can* do is make every frame in the file the same distance from the last,
|
|
30
|
+
* by counting animation frames rather than milliseconds — see `FramePacer`. A
|
|
31
|
+
* device that cannot hold the requested rate then records a slower clip rather than
|
|
32
|
+
* a juddering one, and the measurement in `pacing` says which it was.
|
|
33
|
+
*/
|
|
34
|
+
export interface LockableSurface {
|
|
35
|
+
/** Pin the drawing buffer to an exact pixel size, ignoring CSS and DPR. */
|
|
36
|
+
lockDrawingBuffer(width: number, height: number): void;
|
|
37
|
+
unlockDrawingBuffer(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ExportTargetOptions {
|
|
41
|
+
/** The canvas the scene is drawn into. */
|
|
42
|
+
readonly source: HTMLCanvasElement;
|
|
43
|
+
/** Whoever owns that canvas's drawing-buffer size. */
|
|
44
|
+
readonly surface: LockableSurface;
|
|
45
|
+
readonly width: number;
|
|
46
|
+
readonly height: number;
|
|
47
|
+
readonly fps: number;
|
|
48
|
+
/**
|
|
49
|
+
* Stamped into every frame, and baked once.
|
|
50
|
+
*
|
|
51
|
+
* Accepts a function of the final frame size, because the size is not always
|
|
52
|
+
* the one asked for — a device that cannot hold the rate records smaller. A
|
|
53
|
+
* mark laid out for the larger frame and drawn into the smaller one lands on
|
|
54
|
+
* fractional pixels, which is the difference between a wordmark and a smudge.
|
|
55
|
+
*/
|
|
56
|
+
readonly overlay?: FrameOverlay | ((width: number, height: number) => FrameOverlay);
|
|
57
|
+
/**
|
|
58
|
+
* Drawn into every frame, live.
|
|
59
|
+
*
|
|
60
|
+
* The counterpart to `overlay`, which is baked once because a wordmark and a
|
|
61
|
+
* share code do not change. Anything that *does* change per frame — a
|
|
62
|
+
* speedometer, a clock, a lap counter — cannot go through that path at all, and
|
|
63
|
+
* re-baking an overlay each frame would allocate a canvas per frame to say so.
|
|
64
|
+
* So this is handed the composite's own context instead and draws straight into
|
|
65
|
+
* it, after the scene and after the baked mark.
|
|
66
|
+
*
|
|
67
|
+
* Called once per composed frame, including the still-image path, so a still
|
|
68
|
+
* carries whatever a clip would. Receives the *final* frame size for the same
|
|
69
|
+
* reason `overlay` does: a device that cannot hold the rate records smaller, and
|
|
70
|
+
* an instrument laid out for the larger frame lands on fractional pixels.
|
|
71
|
+
*
|
|
72
|
+
* The context is owned by the target: a hook that leaves transforms, clips or
|
|
73
|
+
* composite state behind will corrupt later frames, so it must restore what it
|
|
74
|
+
* changes. Save/restore is wrapped here so the common case needs no discipline.
|
|
75
|
+
*/
|
|
76
|
+
readonly drawFrame?: (ctx: CanvasRenderingContext2D, width: number, height: number) => void;
|
|
77
|
+
/**
|
|
78
|
+
* The renderer's own presented-frame count, e.g. `() => renderer.presentedFrames`.
|
|
79
|
+
*
|
|
80
|
+
* Optional, and reached for no reason but this: `compose()` composites once per encoded
|
|
81
|
+
* frame regardless of whether the renderer presented anything new since the call before —
|
|
82
|
+
* it has no way to ask, only to draw whatever is on `source` right now — so a scene that
|
|
83
|
+
* presents nothing between two frames of an export is composited twice, byte-identical, at
|
|
84
|
+
* two different timestamps. Passing this closes the loop: `duplicateFrame` after `compose()`
|
|
85
|
+
* says whether that just happened, read out of the renderer rather than guessed at from
|
|
86
|
+
* outside it. Omit it and `compose()` behaves exactly as before — nothing here forces or
|
|
87
|
+
* skips a draw, it only reports what already happened.
|
|
88
|
+
*/
|
|
89
|
+
readonly presentedFrames?: () => number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* How much smaller the fallback frame is, per side.
|
|
94
|
+
*
|
|
95
|
+
* Two thirds, which takes 1080x1920 to exactly 720x1280 and costs 56% of the
|
|
96
|
+
* pixels — enough to buy back a frame rate, little enough that the clip is still
|
|
97
|
+
* sharp on a phone. The choice between them is made from a *measurement* of what
|
|
98
|
+
* the renderer is actually managing, never from a device string: the same model
|
|
99
|
+
* of phone runs at two different rates depending on how warm it is.
|
|
100
|
+
*/
|
|
101
|
+
export const EXPORT_FALLBACK_SCALE = 2 / 3;
|
|
102
|
+
/**
|
|
103
|
+
* The share of the target rate the renderer has to be holding to earn the full
|
|
104
|
+
* frame. Below it, the export is already dropping frames before the extra
|
|
105
|
+
* composite work is added.
|
|
106
|
+
*/
|
|
107
|
+
const FULL_SIZE_FPS_MARGIN = 1.15;
|
|
108
|
+
|
|
109
|
+
export interface ExportSize {
|
|
110
|
+
readonly width: number;
|
|
111
|
+
readonly height: number;
|
|
112
|
+
/** True when the measurement forced the smaller frame. */
|
|
113
|
+
readonly reduced: boolean;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The size asked for, evened — for an encode whose schedule is *ours*.
|
|
118
|
+
*
|
|
119
|
+
* The counterpart to `exportSizeFor`, and the distinction is the whole point.
|
|
120
|
+
* `exportSizeFor` trades pixels for frame rate, which is the right trade for a
|
|
121
|
+
* real-time recorder: `MediaRecorder` stamps by wall clock, so a device that
|
|
122
|
+
* cannot draw an export-size frame in 16 ms produces a *worse file*, and a
|
|
123
|
+
* smaller frame it can hold is the better clip.
|
|
124
|
+
*
|
|
125
|
+
* An offline encode makes no such trade, because it has no clock to lose to.
|
|
126
|
+
* Every frame is stamped with where it belongs (see `frameTimestampUs`), so a
|
|
127
|
+
* device that needs 40 ms a frame produces the same file as one that needs 4 —
|
|
128
|
+
* it just waits longer for it. Reducing there buys nothing but a shorter wait,
|
|
129
|
+
* and it is paid for in the one thing the clip is for.
|
|
130
|
+
*
|
|
131
|
+
* That mattered most on exactly the devices least able to argue: the reduction
|
|
132
|
+
* gate is `measuredFps × windowPixels / exportPixels ≥ targetFps × 1.15`, which
|
|
133
|
+
* at a vsync-capped 60 fps needs a drawing buffer of 2.38 Mpx to clear. A phone
|
|
134
|
+
* has about 1.5 Mpx (a ~412×915 viewport at a DPR capped to 2), so *no* 60 Hz
|
|
135
|
+
* phone could ever earn the full frame: every mobile clip came out 720×1280 at
|
|
136
|
+
* 6.1 Mbit/s where a desktop's was 1080×1920 at 13.7. Same shot, same 60 fps,
|
|
137
|
+
* a quarter of the detail — which gets reported as a difference in "graphics
|
|
138
|
+
* detail" rather than in frame rate. It was neither; it was pixels.
|
|
139
|
+
*
|
|
140
|
+
* Both dimensions stay even, for the same reason as below.
|
|
141
|
+
*/
|
|
142
|
+
export function exportSizeExact(width: number, height: number): ExportSize {
|
|
143
|
+
return { width: even(width), height: even(height), reduced: false };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The frame size to record at, given what the renderer is currently managing.
|
|
148
|
+
*
|
|
149
|
+
* Both dimensions stay even: every H.264 encoder in the share path wants an even
|
|
150
|
+
* width and height, and an odd one is either rejected or silently padded.
|
|
151
|
+
*/
|
|
152
|
+
export function exportSizeFor(
|
|
153
|
+
width: number,
|
|
154
|
+
height: number,
|
|
155
|
+
measuredFps: number,
|
|
156
|
+
targetFps: number,
|
|
157
|
+
/**
|
|
158
|
+
* Pixels the measurement was taken at — the window's own drawing buffer.
|
|
159
|
+
*
|
|
160
|
+
* Without it the comparison is between a rate measured on a 1200x700 window and
|
|
161
|
+
* a demand made of a 1080x1920 frame, which is three times the pixels: a
|
|
162
|
+
* machine holding a comfortable 100 fps in the window is credited with being
|
|
163
|
+
* able to hold it at the export size, and it cannot. That optimism is why an
|
|
164
|
+
* export dropped frames on hardware whose preview was flawless. Omit for the
|
|
165
|
+
* old behaviour, which is to trust the raw number.
|
|
166
|
+
*/
|
|
167
|
+
measuredAtPixels = 0,
|
|
168
|
+
): ExportSize {
|
|
169
|
+
/*
|
|
170
|
+
* Fill rate is the binding cost here — shadow maps, water, the film pass are
|
|
171
|
+
* all per-pixel — so the estimate is linear in pixel count. Crude, and far
|
|
172
|
+
* closer than assuming the frame is free.
|
|
173
|
+
*/
|
|
174
|
+
const estimate =
|
|
175
|
+
measuredAtPixels > 0
|
|
176
|
+
? (measuredFps * measuredAtPixels) / Math.max(width * height, 1)
|
|
177
|
+
: measuredFps;
|
|
178
|
+
if (measuredFps <= 0 || estimate >= targetFps * FULL_SIZE_FPS_MARGIN) {
|
|
179
|
+
return exportSizeExact(width, height);
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
width: even(width * EXPORT_FALLBACK_SCALE),
|
|
183
|
+
height: even(height * EXPORT_FALLBACK_SCALE),
|
|
184
|
+
reduced: true,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Frame rates a clip may be recorded at, best first.
|
|
190
|
+
*
|
|
191
|
+
* A ladder rather than a constant: a clip records at 120 if it can, else 60, else 30,
|
|
192
|
+
* falling one rung at a time rather than straight to the floor.
|
|
193
|
+
* Each rung is half the one above it so a display's refresh divides cleanly by the
|
|
194
|
+
* stride the pacer ends up using, which is what keeps the cadence even.
|
|
195
|
+
*/
|
|
196
|
+
export const CLIP_FPS_LADDER: readonly number[] = [240, 165, 144, 120, 90, 60, 30];
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* The highest rate on the ladder this device can actually deliver, at this size.
|
|
200
|
+
*
|
|
201
|
+
* **The default is the device's own maximum** rather than a fixed rate. The ladder
|
|
202
|
+
* therefore starts above any
|
|
203
|
+
* panel this is likely to meet and walks down, so a 165 Hz monitor records 165 rather
|
|
204
|
+
* than being rounded to the nearest tidy number. The rungs are the rates real displays
|
|
205
|
+
* actually run at; anything between them is served by the next one down, which the
|
|
206
|
+
* pacer can hit with a whole stride.
|
|
207
|
+
*
|
|
208
|
+
* Two ceilings, and both are hard. **A clip cannot be captured faster than the game
|
|
209
|
+
* is drawn**, because `FramePacer` takes every n-th animation frame, so a 60 Hz panel
|
|
210
|
+
* cannot produce a 120 fps file however fast the machine is; asking anyway would
|
|
211
|
+
* write a file claiming 120 while holding 60, which is precisely the lie the frame
|
|
212
|
+
* schedule exists to prevent. And **the export size is not the window size**, so the
|
|
213
|
+
* measured rate is scaled by pixel count exactly as `exportSizeFor` scales it, or a
|
|
214
|
+
* machine comfortable in a small window is credited with a 1080x1920 frame it cannot
|
|
215
|
+
* push.
|
|
216
|
+
*
|
|
217
|
+
* Returns the lowest rung when nothing clears, rather than nothing: at that point the
|
|
218
|
+
* device is slow enough that `exportSizeFor` is about to reduce the frame, and the
|
|
219
|
+
* lower rate is what makes that reduction sufficient.
|
|
220
|
+
*/
|
|
221
|
+
export function clipFpsFor(
|
|
222
|
+
width: number,
|
|
223
|
+
height: number,
|
|
224
|
+
measuredFps: number,
|
|
225
|
+
/** Pixels the measurement was taken at. Zero trusts the raw number, as above. */
|
|
226
|
+
measuredAtPixels = 0,
|
|
227
|
+
ladder: readonly number[] = CLIP_FPS_LADDER,
|
|
228
|
+
): number {
|
|
229
|
+
const lowest = ladder[ladder.length - 1] ?? 30;
|
|
230
|
+
if (!Number.isFinite(measuredFps) || measuredFps <= 0) return lowest;
|
|
231
|
+
|
|
232
|
+
const estimate =
|
|
233
|
+
measuredAtPixels > 0
|
|
234
|
+
? (measuredFps * measuredAtPixels) / Math.max(width * height, 1)
|
|
235
|
+
: measuredFps;
|
|
236
|
+
|
|
237
|
+
for (const rate of ladder) {
|
|
238
|
+
// Never above what the display itself produces, and never above what the frame
|
|
239
|
+
// costs allow at export size.
|
|
240
|
+
if (rate > measuredFps) continue;
|
|
241
|
+
if (estimate >= rate * FULL_SIZE_FPS_MARGIN) return rate;
|
|
242
|
+
}
|
|
243
|
+
return lowest;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** The aspect ratio a camera must be given to frame for this export. */
|
|
247
|
+
export function exportAspect(width: number, height: number): number {
|
|
248
|
+
return width / Math.max(height, 1);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Bits per second for a frame size and rate.
|
|
253
|
+
*
|
|
254
|
+
* Scaled to the pixel count rather than fixed. A constant 8 Mbit/s is generous
|
|
255
|
+
* at 720p and thin at 1080x1920, and thin bitrate on high-motion footage reads
|
|
256
|
+
* to the eye as stutter rather than as softness — a fast-cut gameplay edit is
|
|
257
|
+
* nothing but high motion, so this is not a subtle effect. Bounded at both ends: below the
|
|
258
|
+
* floor the picture falls apart, above the ceiling the upload is the slow part
|
|
259
|
+
* of sharing.
|
|
260
|
+
*/
|
|
261
|
+
export function clipBitrate(width: number, height: number, fps: number): number {
|
|
262
|
+
const bitsPerPixel = 0.11;
|
|
263
|
+
const raw = width * height * fps * bitsPerPixel;
|
|
264
|
+
return Math.round(Math.min(Math.max(raw, 2_500_000), 24_000_000));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function even(value: number): number {
|
|
268
|
+
return Math.max(2, Math.round(value / 2) * 2);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Whether a frame read at `presentedCount` repeats the one composed at `lastPresentedCount`.
|
|
273
|
+
*
|
|
274
|
+
* `null` says nothing has been composed yet, so a first frame is never a duplicate of a frame
|
|
275
|
+
* that never happened — a literal `0` there would misread the renderer's own starting count as
|
|
276
|
+
* a repeat of it. Pulled out of `compose()` on purpose: it is the one piece of that method's
|
|
277
|
+
* job that touches no canvas, so it is the one piece a test can hold to account without a DOM —
|
|
278
|
+
* this repository's tests run in `node`, per `vitest.config.ts`, and `ExportTarget` itself
|
|
279
|
+
* creates a real `<canvas>` at construction.
|
|
280
|
+
*/
|
|
281
|
+
export function isDuplicateFrame(
|
|
282
|
+
lastPresentedCount: number | null,
|
|
283
|
+
presentedCount: number,
|
|
284
|
+
): boolean {
|
|
285
|
+
return lastPresentedCount !== null && presentedCount === lastPresentedCount;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export class ExportTarget {
|
|
289
|
+
private readonly composite: HTMLCanvasElement;
|
|
290
|
+
private readonly ctx: CanvasRenderingContext2D;
|
|
291
|
+
private readonly pacer: FramePacer;
|
|
292
|
+
private mark: HTMLCanvasElement | null = null;
|
|
293
|
+
private stream: MediaStream | null = null;
|
|
294
|
+
private videoTrack: MediaStreamTrack | null = null;
|
|
295
|
+
private acquired = false;
|
|
296
|
+
/** The instant this animation frame was decided on — see `captureDue`. */
|
|
297
|
+
private frameAtMs = 0;
|
|
298
|
+
/**
|
|
299
|
+
* The renderer's `presentedFrames` as of the last `compose()`, or null before the first one.
|
|
300
|
+
*
|
|
301
|
+
* Null rather than 0, deliberately: a renderer's own count starts at 0 too, and a first
|
|
302
|
+
* frame compared against that literal would read as a duplicate of a frame that never
|
|
303
|
+
* happened. Null can only mean "nothing composed yet".
|
|
304
|
+
*/
|
|
305
|
+
private lastPresentedFrames: number | null = null;
|
|
306
|
+
/** What the last `compose()` found. See `duplicateFrame`. */
|
|
307
|
+
private wasDuplicate = false;
|
|
308
|
+
|
|
309
|
+
constructor(private readonly options: ExportTargetOptions) {
|
|
310
|
+
const canvas = document.createElement('canvas');
|
|
311
|
+
canvas.width = options.width;
|
|
312
|
+
canvas.height = options.height;
|
|
313
|
+
const ctx = canvas.getContext('2d', { alpha: false });
|
|
314
|
+
if (ctx === null) throw new Error('This browser cannot composite an export frame.');
|
|
315
|
+
this.composite = canvas;
|
|
316
|
+
this.ctx = ctx;
|
|
317
|
+
this.pacer = new FramePacer(options.fps);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
get width(): number {
|
|
321
|
+
return this.options.width;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
get height(): number {
|
|
325
|
+
return this.options.height;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
get aspect(): number {
|
|
329
|
+
return exportAspect(this.options.width, this.options.height);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Take over the render surface and hand back the stream to record.
|
|
334
|
+
*
|
|
335
|
+
* `captureStream(0)` rather than a frame rate: the recorder then takes a frame
|
|
336
|
+
* only when `frameRendered` says one is ready, so it can never sample the same
|
|
337
|
+
* rendered frame twice.
|
|
338
|
+
*/
|
|
339
|
+
/**
|
|
340
|
+
* Take over the render surface and bake the mark, without a stream.
|
|
341
|
+
*
|
|
342
|
+
* For an offline render, which composites and encodes frames itself and has nothing to
|
|
343
|
+
* stream to. `acquire` is this plus a stream; keeping them separate means the offline
|
|
344
|
+
* path never creates a `MediaStream` it would only have to stop.
|
|
345
|
+
*/
|
|
346
|
+
lock(): void {
|
|
347
|
+
if (this.acquired) return;
|
|
348
|
+
this.options.surface.lockDrawingBuffer(this.options.width, this.options.height);
|
|
349
|
+
this.acquired = true;
|
|
350
|
+
const { overlay, width, height } = this.options;
|
|
351
|
+
const resolved = typeof overlay === 'function' ? overlay(width, height) : overlay;
|
|
352
|
+
this.mark = resolved === undefined ? null : bakeOverlay(resolved, width, height);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/** Whether the source canvas has actually taken the locked size yet. */
|
|
356
|
+
get ready(): boolean {
|
|
357
|
+
const { source, width, height } = this.options;
|
|
358
|
+
return source.width === width && source.height === height;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
acquire(): MediaStream {
|
|
362
|
+
if (this.stream !== null) return this.stream;
|
|
363
|
+
this.lock();
|
|
364
|
+
const stream = this.composite.captureStream(0);
|
|
365
|
+
this.stream = stream;
|
|
366
|
+
this.videoTrack = stream.getVideoTracks()[0] ?? null;
|
|
367
|
+
return stream;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Whether the next frame drawn will be kept.
|
|
372
|
+
*
|
|
373
|
+
* Asked *before* rendering, so the render loop can skip a frame the recorder
|
|
374
|
+
* would only throw away — see `FramePacer.due` for why that is a correctness
|
|
375
|
+
* matter and not merely a saving.
|
|
376
|
+
*
|
|
377
|
+
* **Call this once per animation frame, drawing or not.** The instant is kept and
|
|
378
|
+
* reused when the frame is handed over, so the schedule is queried and advanced
|
|
379
|
+
* on one clock. It used to take a second reading at the end of the render pass,
|
|
380
|
+
* which put the pacer's grid a whole render ahead of the frames arriving and cost
|
|
381
|
+
* most of the rate: target 60 fps on a 60 Hz display captured 59.5 when a frame
|
|
382
|
+
* cost 4 ms, 40 at 6 ms and 30 at 12 ms, and an export-size frame always costs
|
|
383
|
+
* more than 6 ms.
|
|
384
|
+
*/
|
|
385
|
+
captureDue(nowMs: number): boolean {
|
|
386
|
+
this.frameAtMs = nowMs;
|
|
387
|
+
if (this.stream === null) return true;
|
|
388
|
+
return this.pacer.due(nowMs);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* One rendered frame. Composites and offers it to the recorder if it is due.
|
|
393
|
+
*
|
|
394
|
+
* Must be called at the end of the render pass, in the same task: a WebGL
|
|
395
|
+
* drawing buffer is only guaranteed readable until the browser composites the
|
|
396
|
+
* page, so copying it from a timer produces black frames on some drivers.
|
|
397
|
+
*
|
|
398
|
+
* Takes no instant on purpose — it uses the one `captureDue` was given for this
|
|
399
|
+
* frame. There is no second clock to get wrong.
|
|
400
|
+
*
|
|
401
|
+
* Returns true when the frame was captured, so a caller can count.
|
|
402
|
+
*/
|
|
403
|
+
frameRendered(): boolean {
|
|
404
|
+
if (this.stream === null) return false;
|
|
405
|
+
/*
|
|
406
|
+
* Until the lock has actually taken effect the scene canvas is still the
|
|
407
|
+
* window's size, and copying it would stretch the first frames to the export
|
|
408
|
+
* aspect — the exact distortion this class exists to avoid. Skipping them
|
|
409
|
+
* costs a fraction of a second of clip and guarantees every recorded frame
|
|
410
|
+
* is genuinely the requested shape.
|
|
411
|
+
*/
|
|
412
|
+
const { source } = this.options;
|
|
413
|
+
if (source.width !== this.options.width || source.height !== this.options.height) return false;
|
|
414
|
+
if (!this.pacer.offer(this.frameAtMs)) return false;
|
|
415
|
+
this.compose();
|
|
416
|
+
const track = this.videoTrack;
|
|
417
|
+
if (track !== null && 'requestFrame' in track) {
|
|
418
|
+
(track as MediaStreamTrack & { requestFrame(): void }).requestFrame();
|
|
419
|
+
}
|
|
420
|
+
return true;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Draw the current scene plus the mark into the composite.
|
|
425
|
+
*
|
|
426
|
+
* Also the still-image path: a downloadable frame is the cheapest shareable
|
|
427
|
+
* artefact there is, and it must carry the same mark as the clip.
|
|
428
|
+
*
|
|
429
|
+
* **Draws unconditionally, even when `duplicateFrame` is about to say the source has not
|
|
430
|
+
* changed.** Deciding what to do with a repeated frame — drop it, hold the last one longer,
|
|
431
|
+
* encode it anyway — is a policy choice about the file being produced, and this class
|
|
432
|
+
* produces composites rather than files; see `presentedFrames` on `ExportTargetOptions` for
|
|
433
|
+
* where that decision gets the information it needs to make it.
|
|
434
|
+
*/
|
|
435
|
+
compose(): HTMLCanvasElement {
|
|
436
|
+
const { source, width, height, drawFrame, presentedFrames } = this.options;
|
|
437
|
+
if (presentedFrames !== undefined) {
|
|
438
|
+
const count = presentedFrames();
|
|
439
|
+
this.wasDuplicate = isDuplicateFrame(this.lastPresentedFrames, count);
|
|
440
|
+
this.lastPresentedFrames = count;
|
|
441
|
+
}
|
|
442
|
+
this.ctx.drawImage(source, 0, 0, width, height);
|
|
443
|
+
if (this.mark !== null) this.ctx.drawImage(this.mark, 0, 0);
|
|
444
|
+
if (drawFrame !== undefined) {
|
|
445
|
+
// Wrapped, so a hook cannot leak transform or composite state into the next
|
|
446
|
+
// frame — see `drawFrame`. Cheap: save/restore on a 2D context is a stack push.
|
|
447
|
+
this.ctx.save();
|
|
448
|
+
drawFrame(this.ctx, width, height);
|
|
449
|
+
this.ctx.restore();
|
|
450
|
+
}
|
|
451
|
+
return this.composite;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Whether the frame `compose()` just drew is byte-identical to the one before it, because
|
|
456
|
+
* the renderer's own count of presented frames did not move between the two calls.
|
|
457
|
+
*
|
|
458
|
+
* False when `presentedFrames` was never supplied, and false for the very first `compose()`
|
|
459
|
+
* regardless — a frame nothing has been compared against yet is not a repeat of anything.
|
|
460
|
+
*/
|
|
461
|
+
get duplicateFrame(): boolean {
|
|
462
|
+
return this.wasDuplicate;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
get pacing(): FramePacingReport {
|
|
466
|
+
return this.pacer.report;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/** Start the measurement over, keeping the schedule. See `FramePacer`. */
|
|
470
|
+
resetPacing(): void {
|
|
471
|
+
this.pacer.resetMeasurement();
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/** Give the surface back. Safe to call more than once. */
|
|
475
|
+
release(): void {
|
|
476
|
+
if (this.acquired) {
|
|
477
|
+
this.options.surface.unlockDrawingBuffer();
|
|
478
|
+
this.acquired = false;
|
|
479
|
+
}
|
|
480
|
+
// Only the track this class created. The audio the caller mixed in belongs
|
|
481
|
+
// to the audio graph and must survive to be recorded again.
|
|
482
|
+
this.videoTrack?.stop();
|
|
483
|
+
this.videoTrack = null;
|
|
484
|
+
this.stream = null;
|
|
485
|
+
this.mark = null;
|
|
486
|
+
/* So a caller that locks the same instance again starts with nothing to compare against,
|
|
487
|
+
rather than measuring its next frame against a session that already ended. */
|
|
488
|
+
this.lastPresentedFrames = null;
|
|
489
|
+
this.wasDuplicate = false;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GLYPH_HEIGHT,
|
|
3
|
+
GLYPH_SPACING,
|
|
4
|
+
GLYPH_WIDTH,
|
|
5
|
+
forEachCell,
|
|
6
|
+
measureText,
|
|
7
|
+
} from '../geometry/pixelFont.ts';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Baking a mark into a still image sized to a video frame.
|
|
11
|
+
*
|
|
12
|
+
* Everything is placed and sized in **fractions of the frame**, never pixels.
|
|
13
|
+
* That is the whole point of the module: the same overlay has to read correctly
|
|
14
|
+
* at 1080x1920 and at 720x1280, and a mark laid out in pixels is either
|
|
15
|
+
* illegible at the smaller size or covers a quarter of the smaller frame. Text
|
|
16
|
+
* scales against the frame's *shorter* side so a portrait and a landscape
|
|
17
|
+
* export get a mark of the same apparent size rather than one that grows with
|
|
18
|
+
* whichever dimension happens to be long.
|
|
19
|
+
*
|
|
20
|
+
* Baked once, drawn once per captured frame. Painting a few hundred glyph cells
|
|
21
|
+
* per frame would be thirty times the work for an image that never changes.
|
|
22
|
+
*
|
|
23
|
+
* Nothing here knows what the mark says. Text, colour and position are the
|
|
24
|
+
* caller's; the font is the engine's 5x7 grid, so a mark needs no asset and
|
|
25
|
+
* cannot fail to load.
|
|
26
|
+
*/
|
|
27
|
+
export interface OverlayText {
|
|
28
|
+
readonly text: string;
|
|
29
|
+
/** Left edge, as a fraction of frame width. */
|
|
30
|
+
readonly x: number;
|
|
31
|
+
/** Top edge, as a fraction of frame height. */
|
|
32
|
+
readonly y: number;
|
|
33
|
+
/** One glyph cell, as a fraction of the frame's shorter side. */
|
|
34
|
+
readonly cell: number;
|
|
35
|
+
readonly color: string;
|
|
36
|
+
readonly alpha?: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Anything a 2D context can draw and report a natural size for. */
|
|
40
|
+
export type OverlayImageSource = HTMLImageElement | HTMLCanvasElement | ImageBitmap;
|
|
41
|
+
|
|
42
|
+
export interface OverlayImage {
|
|
43
|
+
readonly image: OverlayImageSource;
|
|
44
|
+
readonly x: number;
|
|
45
|
+
readonly y: number;
|
|
46
|
+
/** Drawn height, as a fraction of the frame's shorter side. */
|
|
47
|
+
readonly height: number;
|
|
48
|
+
readonly alpha?: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface FrameOverlay {
|
|
52
|
+
readonly texts?: readonly OverlayText[];
|
|
53
|
+
readonly images?: readonly OverlayImage[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* How far the shadow sits behind the mark, in cells.
|
|
58
|
+
*
|
|
59
|
+
* A watermark has to survive both a night sky and a noon one. Light type alone
|
|
60
|
+
* disappears against a bright horizon — which in this game is most of the frame
|
|
61
|
+
* — so every glyph is stamped once in near-black first. One cell of offset,
|
|
62
|
+
* because a blur would fight the hard-edged look everything else has.
|
|
63
|
+
*/
|
|
64
|
+
const SHADOW_CELLS = 1;
|
|
65
|
+
const SHADOW_COLOR = 'rgba(2, 5, 10, 0.55)';
|
|
66
|
+
|
|
67
|
+
/** Lit cells of a string, at a cell size in device pixels. */
|
|
68
|
+
export function drawPixelText(
|
|
69
|
+
ctx: CanvasRenderingContext2D,
|
|
70
|
+
text: string,
|
|
71
|
+
left: number,
|
|
72
|
+
top: number,
|
|
73
|
+
cell: number,
|
|
74
|
+
color: string,
|
|
75
|
+
): void {
|
|
76
|
+
const height = GLYPH_HEIGHT * cell;
|
|
77
|
+
const paint = (dx: number, dy: number, fill: string): void => {
|
|
78
|
+
ctx.fillStyle = fill;
|
|
79
|
+
forEachCell(text, (cx, cy) => {
|
|
80
|
+
// Cell y counts up from the baseline; a canvas counts down from the top.
|
|
81
|
+
ctx.fillRect(
|
|
82
|
+
left + dx + cx * cell,
|
|
83
|
+
top + dy + height - (cy + 1) * cell,
|
|
84
|
+
// A hair of overlap, or antialiasing draws a seam between adjacent
|
|
85
|
+
// cells and the letters look woven rather than solid.
|
|
86
|
+
cell + 0.5,
|
|
87
|
+
cell + 0.5,
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
paint(SHADOW_CELLS * cell, SHADOW_CELLS * cell, SHADOW_COLOR);
|
|
93
|
+
paint(0, 0, color);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Pixel width and height of a string at a given cell size. */
|
|
97
|
+
export function pixelTextSize(text: string, cell: number): { width: number; height: number } {
|
|
98
|
+
return { width: measureText(text) * cell, height: GLYPH_HEIGHT * cell };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Cells a string occupies horizontally, including inter-glyph gaps. */
|
|
102
|
+
export function pixelTextCells(text: string): number {
|
|
103
|
+
return text.length === 0 ? 0 : text.length * (GLYPH_WIDTH + GLYPH_SPACING) - GLYPH_SPACING;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Paint an overlay into a transparent canvas of exactly the frame's size.
|
|
108
|
+
*
|
|
109
|
+
* Returns null when there is nothing to draw, so a caller can skip the
|
|
110
|
+
* composite entirely rather than blending a blank layer over every frame.
|
|
111
|
+
*/
|
|
112
|
+
export function bakeOverlay(
|
|
113
|
+
overlay: FrameOverlay,
|
|
114
|
+
width: number,
|
|
115
|
+
height: number,
|
|
116
|
+
): HTMLCanvasElement | null {
|
|
117
|
+
const texts = overlay.texts ?? [];
|
|
118
|
+
const images = overlay.images ?? [];
|
|
119
|
+
if (texts.length === 0 && images.length === 0) return null;
|
|
120
|
+
|
|
121
|
+
const canvas = document.createElement('canvas');
|
|
122
|
+
canvas.width = width;
|
|
123
|
+
canvas.height = height;
|
|
124
|
+
const ctx = canvas.getContext('2d');
|
|
125
|
+
if (ctx === null) return null;
|
|
126
|
+
|
|
127
|
+
const short = Math.min(width, height);
|
|
128
|
+
for (const image of images) {
|
|
129
|
+
const drawHeight = image.height * short;
|
|
130
|
+
const natural = imageAspect(image.image);
|
|
131
|
+
ctx.globalAlpha = image.alpha ?? 1;
|
|
132
|
+
ctx.drawImage(image.image, image.x * width, image.y * height, drawHeight * natural, drawHeight);
|
|
133
|
+
}
|
|
134
|
+
for (const text of texts) {
|
|
135
|
+
ctx.globalAlpha = text.alpha ?? 1;
|
|
136
|
+
/*
|
|
137
|
+
* Snapped to whole pixels. A 5x7 grid drawn on a half-pixel boundary is
|
|
138
|
+
* antialiased on every cell edge, which turns a hard-edged mark into a grey
|
|
139
|
+
* smudge — the one thing a watermark cannot be, since it is small by design.
|
|
140
|
+
*/
|
|
141
|
+
drawPixelText(
|
|
142
|
+
ctx,
|
|
143
|
+
text.text,
|
|
144
|
+
Math.round(text.x * width),
|
|
145
|
+
Math.round(text.y * height),
|
|
146
|
+
text.cell * short,
|
|
147
|
+
text.color,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
ctx.globalAlpha = 1;
|
|
151
|
+
return canvas;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function imageAspect(image: OverlayImageSource): number {
|
|
155
|
+
const width = image instanceof HTMLImageElement ? image.naturalWidth || image.width : image.width;
|
|
156
|
+
const height =
|
|
157
|
+
image instanceof HTMLImageElement ? image.naturalHeight || image.height : image.height;
|
|
158
|
+
return height > 0 ? width / height : 1;
|
|
159
|
+
}
|