@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,524 @@
|
|
|
1
|
+
import type { ReadonlyMat4, ReadonlyVec3 } from 'gl-matrix';
|
|
2
|
+
|
|
3
|
+
import { decalToWorldMatrix, worldToDecalMatrix } from './decalProjector.ts';
|
|
4
|
+
import type { DecalBox } from './decalProjector.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Screen-space reflection: the frame reflected in a surface, by marching against its own depth.
|
|
8
|
+
*
|
|
9
|
+
* **What a planar reflection cannot reach is the whole reason this exists.** `PlanarReflection`
|
|
10
|
+
* re-renders the world from a mirrored camera for one *horizontal plane at one height*, which is
|
|
11
|
+
* exactly right for a lake and gives nothing for anything else: a floor that undulates, a bonnet,
|
|
12
|
+
* a tilted pane, a wet cobbled street. It also costs a second pass over the scene. This costs one
|
|
13
|
+
* fullscreen pass over the pixels a caller says are reflective, follows the surface per pixel
|
|
14
|
+
* whatever shape it is, and is exact about contact — the point where an object meets the floor,
|
|
15
|
+
* which is the part a viewer reads first and the part a reduced-resolution mirror plane loses.
|
|
16
|
+
*
|
|
17
|
+
* **What it cannot do is see anything the frame did not draw.** A reflection of something behind
|
|
18
|
+
* the camera, or hidden behind the reflecting surface itself, is not in the colour buffer and
|
|
19
|
+
* cannot be recovered from it. That is the honest limit of every screen-space method, and the
|
|
20
|
+
* fades below are what keep it from being an obvious one: a ray that leaves the frame, that points
|
|
21
|
+
* back toward the eye, or that runs a long way before hitting anything is faded out rather than
|
|
22
|
+
* being allowed to answer with the wrong pixel.
|
|
23
|
+
*
|
|
24
|
+
* **Reflective is a region rather than a material, and that is a fact about a forward renderer.**
|
|
25
|
+
* There is no G-buffer, so by the time this pass runs nothing on screen records which surface was
|
|
26
|
+
* polished — that would be a second colour attachment written by every draw path in the engine,
|
|
27
|
+
* which is the same price the temporal row declined for a velocity buffer. A caller declares a
|
|
28
|
+
* `ReflectiveSurface` instead: a box, and a facing rule for which surfaces inside it reflect. It is
|
|
29
|
+
* the shape `DecalProjector` already has, for the same reason.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Clip Y negated, for a backend whose framebuffer rows run downward.
|
|
34
|
+
*
|
|
35
|
+
* **Premultiplied into the matrix the shader is handed rather than branched on inside it**, so one
|
|
36
|
+
* expression serves both backends and the convention lives in exactly one place. That is the lesson
|
|
37
|
+
* `DEPTH_01_TO_CLIP_Y_DOWN` records at length, arriving from the other direction: that constant
|
|
38
|
+
* turns a screen position into the world, this turns the world back into a screen position, and a
|
|
39
|
+
* pass that got one of them wrong would march along the mirror image of its own ray.
|
|
40
|
+
*
|
|
41
|
+
* The identity on WebGL2, whose framebuffer origin is the bottom left, so nothing is multiplied
|
|
42
|
+
* there at all.
|
|
43
|
+
*/
|
|
44
|
+
export const CLIP_Y_FLIP: ReadonlyMat4 = new Float32Array([
|
|
45
|
+
1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A world point to a screen position, or false where the frame cannot show it.
|
|
50
|
+
*
|
|
51
|
+
* **False rather than a clamped answer, on both counts.** A point behind the eye has a negative
|
|
52
|
+
* `w`, and dividing by it mirrors the point through the origin — so it comes back as a perfectly
|
|
53
|
+
* ordinary screen position somewhere else in the frame, and a march that believed it would read a
|
|
54
|
+
* depth belonging to a place the ray never went. A point outside the frame has no pixel at all, and
|
|
55
|
+
* sampling for one anyway takes the clamped border texel: a reflection acquires a smear of whatever
|
|
56
|
+
* is at the edge of the screen and drags it as the camera turns.
|
|
57
|
+
*
|
|
58
|
+
* `viewProjection` carries the framebuffer's Y sense already. See `CLIP_Y_FLIP`.
|
|
59
|
+
*/
|
|
60
|
+
export function projectToUv(
|
|
61
|
+
viewProjection: ReadonlyMat4,
|
|
62
|
+
x: number,
|
|
63
|
+
y: number,
|
|
64
|
+
z: number,
|
|
65
|
+
uv: Float32Array,
|
|
66
|
+
): boolean {
|
|
67
|
+
const clipX =
|
|
68
|
+
(viewProjection[0] ?? 0) * x +
|
|
69
|
+
(viewProjection[4] ?? 0) * y +
|
|
70
|
+
(viewProjection[8] ?? 0) * z +
|
|
71
|
+
(viewProjection[12] ?? 0);
|
|
72
|
+
const clipY =
|
|
73
|
+
(viewProjection[1] ?? 0) * x +
|
|
74
|
+
(viewProjection[5] ?? 0) * y +
|
|
75
|
+
(viewProjection[9] ?? 0) * z +
|
|
76
|
+
(viewProjection[13] ?? 0);
|
|
77
|
+
const clipW =
|
|
78
|
+
(viewProjection[3] ?? 0) * x +
|
|
79
|
+
(viewProjection[7] ?? 0) * y +
|
|
80
|
+
(viewProjection[11] ?? 0) * z +
|
|
81
|
+
(viewProjection[15] ?? 0);
|
|
82
|
+
if (clipW <= 0) return false;
|
|
83
|
+
const u = (clipX / clipW) * 0.5 + 0.5;
|
|
84
|
+
const v = (clipY / clipW) * 0.5 + 0.5;
|
|
85
|
+
if (u < 0 || u > 1 || v < 0 || v > 1) return false;
|
|
86
|
+
uv[0] = u;
|
|
87
|
+
uv[1] = v;
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** How a march is walked. */
|
|
92
|
+
export interface ScreenSpaceMarch {
|
|
93
|
+
/** How many samples along the ray. More is a more accurate hit and a slower pass. */
|
|
94
|
+
readonly steps: number;
|
|
95
|
+
/** How far the ray travels in world metres before it gives up. */
|
|
96
|
+
readonly reachM: number;
|
|
97
|
+
/**
|
|
98
|
+
* How deep a depth sample is treated as being, world metres.
|
|
99
|
+
*
|
|
100
|
+
* **A depth buffer holds one distance per pixel and says nothing about how thick the thing at
|
|
101
|
+
* that distance is.** A march that treats it as an infinitely deep wall reports a hit for every
|
|
102
|
+
* ray that ends up behind anything at all, so a reflection acquires a copy of whatever lies
|
|
103
|
+
* between it and the far plane. This is the number that says how far behind a surface a crossing
|
|
104
|
+
* may land and still be believed.
|
|
105
|
+
*/
|
|
106
|
+
readonly thicknessM: number;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Where a march ended. Reused rather than returned, because the pass runs per pixel. */
|
|
110
|
+
export interface ScreenSpaceHit {
|
|
111
|
+
hit: boolean;
|
|
112
|
+
/** Screen position of the hit, 0 to 1. */
|
|
113
|
+
u: number;
|
|
114
|
+
v: number;
|
|
115
|
+
/** How far along the ray it was found, world metres. */
|
|
116
|
+
distanceM: number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function newScreenSpaceHit(): ScreenSpaceHit {
|
|
120
|
+
return { hit: false, u: 0, v: 0, distanceM: 0 };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* How many times a bracketed crossing is halved.
|
|
125
|
+
*
|
|
126
|
+
* Six, and it was four until the samples stopped being evenly spaced: the brackets at the far end
|
|
127
|
+
* of a quadratic march are several metres wide, and four halvings of one of those is a hit a
|
|
128
|
+
* quarter of a metre out.
|
|
129
|
+
*/
|
|
130
|
+
const REFINE_STEPS = 6;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Where the `i`th of `steps` samples falls along a ray of length `reach`.
|
|
134
|
+
*
|
|
135
|
+
* **Quadratic rather than even, and the difference is the contact seam.** A reflection is read
|
|
136
|
+
* first at the line where an object meets the floor, and that is exactly where an evenly spaced
|
|
137
|
+
* march is worst: the first sample is a whole step out, so every pixel within a step of the contact
|
|
138
|
+
* finds its crossing already behind the object and reports nothing. Measured on
|
|
139
|
+
* `demo/dev/ssr.html`, evenly spaced: a ten-metre reach in 24 steps leaves a visible dark band
|
|
140
|
+
* along the contact and 11,826 reflected pixels, and shortening the reach to four — which is the
|
|
141
|
+
* same thing as a smaller step — closes most of the band and gives 13,184.
|
|
142
|
+
*
|
|
143
|
+
* Spacing the samples by the square of their index buys both: a first step of a few centimetres
|
|
144
|
+
* and a last one of nearly a metre, out where a reflection is faint and about to leave the frame
|
|
145
|
+
* anyway.
|
|
146
|
+
*/
|
|
147
|
+
export function marchDistance(index: number, steps: number, reachM: number): number {
|
|
148
|
+
const at = index / steps;
|
|
149
|
+
return reachM * at * at;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Scratch for a projected sample, so a march allocates nothing. */
|
|
153
|
+
const UV = new Float32Array(2);
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* March a reflected ray against the depth the frame has already drawn.
|
|
157
|
+
*
|
|
158
|
+
* **This is the arithmetic the shader runs, written where it can be tested.** No GPU is needed to
|
|
159
|
+
* decide when a crossing is a hit, how far off the coarse answer is, or what happens at the edge
|
|
160
|
+
* of the frame — and each of those is a defect that draws a plausible picture rather than failing.
|
|
161
|
+
* `orderIndependent.ts` and `temporalAa.ts` are the same split, and the shader beside this file
|
|
162
|
+
* mirrors it line for line.
|
|
163
|
+
*
|
|
164
|
+
* `project` turns a world point into a screen position and answers false where it lands outside
|
|
165
|
+
* the frame. `sceneDistance` says how far the eye is from whatever the frame drew at a screen
|
|
166
|
+
* position, and `Infinity` where it drew nothing — the sky, which is not a surface and must not be
|
|
167
|
+
* reflected as one.
|
|
168
|
+
*
|
|
169
|
+
* **A hit is a crossing and not a comparison.** The ray has to be in front of the scene at one
|
|
170
|
+
* sample and behind it at the next; a ray that is behind from the start never crossed anything and
|
|
171
|
+
* is looking at the back of the world. That is also what keeps a grazing ray off its own surface:
|
|
172
|
+
* the first sample is a whole step along, and at zero the comparison is a coin toss on rounding
|
|
173
|
+
* taken by every pixel of a reflective floor at once.
|
|
174
|
+
*/
|
|
175
|
+
export function traceScreenSpaceRay(
|
|
176
|
+
origin: ReadonlyVec3,
|
|
177
|
+
direction: ReadonlyVec3,
|
|
178
|
+
eye: ReadonlyVec3,
|
|
179
|
+
march: ScreenSpaceMarch,
|
|
180
|
+
project: (x: number, y: number, z: number, uv: Float32Array) => boolean,
|
|
181
|
+
sceneDistance: (u: number, v: number) => number,
|
|
182
|
+
out: ScreenSpaceHit,
|
|
183
|
+
): boolean {
|
|
184
|
+
out.hit = false;
|
|
185
|
+
out.u = 0;
|
|
186
|
+
out.v = 0;
|
|
187
|
+
out.distanceM = 0;
|
|
188
|
+
|
|
189
|
+
const steps = Math.max(1, Math.round(march.steps));
|
|
190
|
+
const ox = origin[0] ?? 0;
|
|
191
|
+
const oy = origin[1] ?? 0;
|
|
192
|
+
const oz = origin[2] ?? 0;
|
|
193
|
+
const dx = direction[0] ?? 0;
|
|
194
|
+
const dy = direction[1] ?? 0;
|
|
195
|
+
const dz = direction[2] ?? 0;
|
|
196
|
+
const ex = eye[0] ?? 0;
|
|
197
|
+
const ey = eye[1] ?? 0;
|
|
198
|
+
const ez = eye[2] ?? 0;
|
|
199
|
+
|
|
200
|
+
/*
|
|
201
|
+
* How far behind the scene the previous sample was; negative is in front of it.
|
|
202
|
+
*
|
|
203
|
+
* **Zero to begin with, because the ray starts on the surface it is reflecting off.** A crossing
|
|
204
|
+
* needs the previous sample strictly in front, so the first step cannot form one on its own —
|
|
205
|
+
* which is exactly the self-intersection guard a screen-space march needs. A ray leaving a
|
|
206
|
+
* surface at any angle moves in front of the scene immediately and earns its crossing on the
|
|
207
|
+
* step after; a ray hugging the surface never does, and a floor full of pixels taking that
|
|
208
|
+
* comparison on rounding is the speckle this effect is remembered for.
|
|
209
|
+
*/
|
|
210
|
+
let behind = 0;
|
|
211
|
+
let previous = 0;
|
|
212
|
+
|
|
213
|
+
for (let i = 1; i <= steps; i++) {
|
|
214
|
+
const t = marchDistance(i, steps, march.reachM);
|
|
215
|
+
const x = ox + dx * t;
|
|
216
|
+
const y = oy + dy * t;
|
|
217
|
+
const z = oz + dz * t;
|
|
218
|
+
if (!project(x, y, z, UV)) return false;
|
|
219
|
+
|
|
220
|
+
const scene = sceneDistance(UV[0] ?? 0, UV[1] ?? 0);
|
|
221
|
+
/* Nothing was drawn here, so there is no surface to cross. Carried rather than treated as a
|
|
222
|
+
miss so a ray may pass over a gap in the geometry and hit what is beyond it. */
|
|
223
|
+
if (!Number.isFinite(scene)) {
|
|
224
|
+
/* In front of nothing, which is true and is what lets a ray cross a gap in the geometry —
|
|
225
|
+
a skyline, a doorway — and land on what is beyond it. */
|
|
226
|
+
behind = -Infinity;
|
|
227
|
+
previous = t;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const ray = Math.hypot(x - ex, y - ey, z - ez);
|
|
232
|
+
const gap = ray - scene;
|
|
233
|
+
|
|
234
|
+
if (behind < 0 && gap >= 0) {
|
|
235
|
+
/*
|
|
236
|
+
* A crossing, bracketed between `previous` and `t`. Halved rather than reported: the coarse
|
|
237
|
+
* answer is a whole step out, which puts a reflection visibly beside the thing reflected.
|
|
238
|
+
*/
|
|
239
|
+
let near = previous;
|
|
240
|
+
let far = t;
|
|
241
|
+
let hitU = UV[0] ?? 0;
|
|
242
|
+
let hitV = UV[1] ?? 0;
|
|
243
|
+
let hitGap = gap;
|
|
244
|
+
for (let refine = 0; refine < REFINE_STEPS; refine++) {
|
|
245
|
+
const mid = (near + far) / 2;
|
|
246
|
+
const mx = ox + dx * mid;
|
|
247
|
+
const my = oy + dy * mid;
|
|
248
|
+
const mz = oz + dz * mid;
|
|
249
|
+
if (!project(mx, my, mz, UV)) break;
|
|
250
|
+
const midScene = sceneDistance(UV[0] ?? 0, UV[1] ?? 0);
|
|
251
|
+
if (!Number.isFinite(midScene)) break;
|
|
252
|
+
const midGap = Math.hypot(mx - ex, my - ey, mz - ez) - midScene;
|
|
253
|
+
if (midGap > 0) {
|
|
254
|
+
far = mid;
|
|
255
|
+
hitU = UV[0] ?? 0;
|
|
256
|
+
hitV = UV[1] ?? 0;
|
|
257
|
+
hitGap = midGap;
|
|
258
|
+
} else {
|
|
259
|
+
near = mid;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* Believed only if the refined crossing landed within the thickness. Further behind than
|
|
264
|
+
that and the ray flew past a thin surface rather than landing on it. */
|
|
265
|
+
if (hitGap > march.thicknessM) return false;
|
|
266
|
+
out.hit = true;
|
|
267
|
+
out.u = hitU;
|
|
268
|
+
out.v = hitV;
|
|
269
|
+
out.distanceM = far;
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
behind = gap;
|
|
274
|
+
previous = t;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* How much of a hit survives its distance from the edge of the frame.
|
|
282
|
+
*
|
|
283
|
+
* **A sample off the edge of the frame clamps to the border texel**, so a reflection acquires a
|
|
284
|
+
* smear of whatever is at the edge of the screen and drags it as the camera turns — the failure
|
|
285
|
+
* that looks most like the effect working. The march refuses to sample outside the frame at all;
|
|
286
|
+
* this is the other half, fading a hit *near* the edge so a reflection leaves rather than being
|
|
287
|
+
* cut off along a line.
|
|
288
|
+
*
|
|
289
|
+
* `band` is how much of the frame each side is fade, as a fraction.
|
|
290
|
+
*/
|
|
291
|
+
export function screenEdgeFade(u: number, v: number, band: number): number {
|
|
292
|
+
if (band <= 0) return u < 0 || u > 1 || v < 0 || v > 1 ? 0 : 1;
|
|
293
|
+
const nearest = Math.min(u, 1 - u, v, 1 - v);
|
|
294
|
+
return Math.min(1, Math.max(0, nearest / band));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* How much of a reflection survives its ray pointing back toward the eye.
|
|
299
|
+
*
|
|
300
|
+
* A ray coming back at the viewer can only find what is between the surface and the camera, which
|
|
301
|
+
* is usually nothing and occasionally the viewer's own geometry — the artefact that reads as a
|
|
302
|
+
* smear of the foreground pasted onto a floor. One at a ray running directly away from the eye,
|
|
303
|
+
* nothing at one running directly into it.
|
|
304
|
+
*/
|
|
305
|
+
export function towardCameraFade(direction: ReadonlyVec3, viewDirection: ReadonlyVec3): number {
|
|
306
|
+
const dx = direction[0] ?? 0;
|
|
307
|
+
const dy = direction[1] ?? 0;
|
|
308
|
+
const dz = direction[2] ?? 0;
|
|
309
|
+
const vx = viewDirection[0] ?? 0;
|
|
310
|
+
const vy = viewDirection[1] ?? 0;
|
|
311
|
+
const vz = viewDirection[2] ?? 0;
|
|
312
|
+
const dLength = Math.hypot(dx, dy, dz);
|
|
313
|
+
const vLength = Math.hypot(vx, vy, vz);
|
|
314
|
+
if (dLength === 0 || vLength === 0) return 0;
|
|
315
|
+
const along = (dx * vx + dy * vy + dz * vz) / (dLength * vLength);
|
|
316
|
+
return Math.min(1, Math.max(0, (along + 1) / 2));
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export interface ReflectiveSurfaceOptions extends DecalBox {
|
|
320
|
+
/** How much of what the ray finds lands on the surface, 0 to 1. */
|
|
321
|
+
readonly strength?: number;
|
|
322
|
+
/** How far a ray may travel, world metres. */
|
|
323
|
+
readonly reachM?: number;
|
|
324
|
+
/** How deep a depth sample is treated as being. See `ScreenSpaceMarch.thicknessM`. */
|
|
325
|
+
readonly thicknessM?: number;
|
|
326
|
+
/** How many samples along a ray. */
|
|
327
|
+
readonly steps?: number;
|
|
328
|
+
/** How far from facing the box's own axis a surface may be turned and still reflect. */
|
|
329
|
+
readonly facingCos?: number;
|
|
330
|
+
/** What the reflection is multiplied by, for a tinted mirror. */
|
|
331
|
+
readonly tint?: ReadonlyVec3;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* A box a consumer declares, inside which surfaces reflect what the frame drew.
|
|
336
|
+
*
|
|
337
|
+
* Held and moved, like `DecalProjector` and for the same reason: a wet patch follows the rain and
|
|
338
|
+
* a polished floor does not move at all, and rebuilding two matrices from four vectors is the whole
|
|
339
|
+
* of a pose. Both matrices live in the object and are rewritten in place.
|
|
340
|
+
*/
|
|
341
|
+
export class ReflectiveSurface {
|
|
342
|
+
/** World space into the box, `[-1, 1]` on each axis. */
|
|
343
|
+
readonly worldToSurface = new Float32Array(16);
|
|
344
|
+
/** The box back into the world, for the scissor bound. */
|
|
345
|
+
readonly surfaceToWorld = new Float32Array(16);
|
|
346
|
+
/** Which way the reflective surfaces inside the box face, normalised and pointing *into* them. */
|
|
347
|
+
readonly axis = new Float32Array(3);
|
|
348
|
+
readonly tint = new Float32Array(3);
|
|
349
|
+
|
|
350
|
+
strength: number;
|
|
351
|
+
reachM: number;
|
|
352
|
+
thicknessM: number;
|
|
353
|
+
steps: number;
|
|
354
|
+
facingCos: number;
|
|
355
|
+
|
|
356
|
+
private readonly box: {
|
|
357
|
+
center: Float32Array;
|
|
358
|
+
halfExtents: Float32Array;
|
|
359
|
+
forward: Float32Array;
|
|
360
|
+
up: Float32Array;
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
constructor(options: ReflectiveSurfaceOptions) {
|
|
364
|
+
this.box = {
|
|
365
|
+
center: Float32Array.from(options.center as ArrayLike<number>),
|
|
366
|
+
halfExtents: Float32Array.from(options.halfExtents as ArrayLike<number>),
|
|
367
|
+
forward: Float32Array.from(options.forward as ArrayLike<number>),
|
|
368
|
+
up: Float32Array.from(options.up as ArrayLike<number>),
|
|
369
|
+
};
|
|
370
|
+
this.tint.set(options.tint === undefined ? [1, 1, 1] : (options.tint as ArrayLike<number>));
|
|
371
|
+
/* Half, because a mirror is the rare case: a wet floor, polished stone and a car bonnet all
|
|
372
|
+
return a fraction of what lands on them, and a consumer who wants a mirror asks for one. */
|
|
373
|
+
this.strength = options.strength ?? 0.5;
|
|
374
|
+
/* Eight metres covers a room and a street corner. Further costs steps rather than accuracy,
|
|
375
|
+
since the step is the reach divided by them. */
|
|
376
|
+
this.reachM = options.reachM ?? 8;
|
|
377
|
+
/* A quarter of a metre. Thinner rejects a real hit on a coarsely stepped ray; thicker starts
|
|
378
|
+
reflecting what is behind a wall. */
|
|
379
|
+
this.thicknessM = options.thicknessM ?? 0.25;
|
|
380
|
+
this.steps = options.steps ?? 24;
|
|
381
|
+
/* The same 0.1 `projectDecal` and `DecalProjector` default to, and for the same reason. */
|
|
382
|
+
this.facingCos = options.facingCos ?? 0.1;
|
|
383
|
+
this.rebuild();
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/** Move the box. Allocation-free, so a wet patch may follow the weather every frame. */
|
|
387
|
+
setPose(center: ReadonlyVec3, forward: ReadonlyVec3, up: ReadonlyVec3): void {
|
|
388
|
+
this.box.center.set(center as ArrayLike<number>);
|
|
389
|
+
this.box.forward.set(forward as ArrayLike<number>);
|
|
390
|
+
this.box.up.set(up as ArrayLike<number>);
|
|
391
|
+
this.rebuild();
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
setSize(halfExtents: ReadonlyVec3): void {
|
|
395
|
+
this.box.halfExtents.set(halfExtents as ArrayLike<number>);
|
|
396
|
+
this.rebuild();
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
private rebuild(): void {
|
|
400
|
+
worldToDecalMatrix(this.worldToSurface, this.box);
|
|
401
|
+
decalToWorldMatrix(this.surfaceToWorld, this.box);
|
|
402
|
+
const f = this.box.forward;
|
|
403
|
+
const length = Math.hypot(f[0] ?? 0, f[1] ?? 0, f[2] ?? 0);
|
|
404
|
+
this.axis[0] = (f[0] ?? 0) / length;
|
|
405
|
+
this.axis[1] = (f[1] ?? 0) / length;
|
|
406
|
+
this.axis[2] = (f[2] ?? 0) / length;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* How many reflective surfaces one frame may draw.
|
|
412
|
+
*
|
|
413
|
+
* **A cap rather than an open number**, for the reason `MAX_DRAWN_DECALS` gives: each is a
|
|
414
|
+
* scissored pass with a uniform slot behind it, and the slots are one buffer written before the
|
|
415
|
+
* passes are recorded. Eight is lower than the decal cap on purpose — a mark costs a texture fetch
|
|
416
|
+
* per pixel and a reflection costs a march, so a scene wanting dozens of reflective regions is
|
|
417
|
+
* asking for something a screen-space method should refuse rather than deliver slowly.
|
|
418
|
+
*/
|
|
419
|
+
export const MAX_REFLECTIVE_SURFACES = 8;
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* How much of the frame each side fades a hit out, as a fraction.
|
|
423
|
+
*
|
|
424
|
+
* **One number for both backends**, because it decides where a reflection stops and two copies of
|
|
425
|
+
* it is a reflection that ends in a different place on each — the 2026-08-13 rule in `AGENTS.md`
|
|
426
|
+
* applied to a fade. A tenth is wide enough that a reflection leaving the frame reads as leaving
|
|
427
|
+
* rather than as being cut off, and narrow enough that the middle of the picture is untouched.
|
|
428
|
+
*/
|
|
429
|
+
export const REFLECTION_EDGE_FADE = 0.1;
|
|
430
|
+
|
|
431
|
+
/** One recorded surface. Every field is a copy of what it held when it was submitted. */
|
|
432
|
+
export interface RecordedReflection {
|
|
433
|
+
readonly worldToSurface: Float32Array;
|
|
434
|
+
readonly surfaceToWorld: Float32Array;
|
|
435
|
+
readonly axis: Float32Array;
|
|
436
|
+
readonly tint: Float32Array;
|
|
437
|
+
strength: number;
|
|
438
|
+
reachM: number;
|
|
439
|
+
thicknessM: number;
|
|
440
|
+
steps: number;
|
|
441
|
+
facingCos: number;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function newRecord(): RecordedReflection {
|
|
445
|
+
return {
|
|
446
|
+
worldToSurface: new Float32Array(16),
|
|
447
|
+
surfaceToWorld: new Float32Array(16),
|
|
448
|
+
axis: new Float32Array(3),
|
|
449
|
+
tint: new Float32Array(3),
|
|
450
|
+
strength: 0.5,
|
|
451
|
+
reachM: 8,
|
|
452
|
+
thicknessM: 0.25,
|
|
453
|
+
steps: 24,
|
|
454
|
+
facingCos: 0.1,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* The frame's reflective surfaces, held until the pass that reads the finished picture can run.
|
|
460
|
+
*
|
|
461
|
+
* **Here rather than in a file of its own**, unlike `DecalQueue`: it is the same twenty lines of
|
|
462
|
+
* pooling around a different record, and this row adds a shader as well as a pass, so the module
|
|
463
|
+
* that would hold it is one more entry in every consumer's bundle for no reader's benefit.
|
|
464
|
+
*
|
|
465
|
+
* Everything is copied, for the reason `TranslucentQueue` states: a surface is an object a consumer
|
|
466
|
+
* keeps and moves, so a queue holding the reference would replay every one of them wearing the last
|
|
467
|
+
* pose written.
|
|
468
|
+
*/
|
|
469
|
+
export class ReflectionQueue {
|
|
470
|
+
private readonly pool: RecordedReflection[] = [];
|
|
471
|
+
private count = 0;
|
|
472
|
+
private warned = false;
|
|
473
|
+
|
|
474
|
+
get length(): number {
|
|
475
|
+
return this.count;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** How many records are pooled, which a test uses to assert a steady scene stops allocating. */
|
|
479
|
+
get capacity(): number {
|
|
480
|
+
return this.pool.length;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
record(surface: ReflectiveSurface): void {
|
|
484
|
+
if (this.count >= MAX_REFLECTIVE_SURFACES) {
|
|
485
|
+
if (!this.warned) {
|
|
486
|
+
this.warned = true;
|
|
487
|
+
console.warn(
|
|
488
|
+
`driftengine: more than ${MAX_REFLECTIVE_SURFACES} reflective surfaces in one frame, so ` +
|
|
489
|
+
'the rest are dropped. Each one marches a ray per covered pixel, which is not a cost ' +
|
|
490
|
+
'to pay for a region nobody is looking at — cull them, or widen one box instead.',
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
let record = this.pool[this.count];
|
|
497
|
+
if (record === undefined) {
|
|
498
|
+
record = newRecord();
|
|
499
|
+
this.pool.push(record);
|
|
500
|
+
}
|
|
501
|
+
record.worldToSurface.set(surface.worldToSurface);
|
|
502
|
+
record.surfaceToWorld.set(surface.surfaceToWorld);
|
|
503
|
+
record.axis.set(surface.axis);
|
|
504
|
+
record.tint.set(surface.tint);
|
|
505
|
+
record.strength = Math.min(1, Math.max(0, surface.strength));
|
|
506
|
+
record.reachM = Math.max(0, surface.reachM);
|
|
507
|
+
record.thicknessM = Math.max(0, surface.thicknessM);
|
|
508
|
+
record.steps = Math.min(32, Math.max(1, Math.round(surface.steps)));
|
|
509
|
+
record.facingCos = surface.facingCos;
|
|
510
|
+
this.count++;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
replay(each: (surface: RecordedReflection) => void): void {
|
|
514
|
+
for (let i = 0; i < this.count; i++) {
|
|
515
|
+
const record = this.pool[i];
|
|
516
|
+
if (record !== undefined) each(record);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/** Empty it for the next frame, keeping the storage. */
|
|
521
|
+
reset(): void {
|
|
522
|
+
this.count = 0;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An SDF font's metrics, parsed once and asked many times.
|
|
3
|
+
*
|
|
4
|
+
* The atlas image is the consumer's business — it arrives as a `TexImageSource` like every
|
|
5
|
+
* other texture this engine takes, and the engine still fetches nothing. This owns only
|
|
6
|
+
* the numbers that turn a string into quads.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export interface SdfGlyph {
|
|
10
|
+
readonly advance: number;
|
|
11
|
+
/** The glyph's ink box in font units, y-up: `planeTop` is above `planeBottom`. */
|
|
12
|
+
readonly planeLeft: number;
|
|
13
|
+
readonly planeBottom: number;
|
|
14
|
+
readonly planeRight: number;
|
|
15
|
+
readonly planeTop: number;
|
|
16
|
+
/**
|
|
17
|
+
* The glyph's cell in the atlas texture, in texels.
|
|
18
|
+
*
|
|
19
|
+
* **The single statement of this convention — nowhere else should restate it, only rely on
|
|
20
|
+
* it.** These run the same direction the atlas PNG's own rows do, and the same direction
|
|
21
|
+
* `createSurfaceTexture` actually uploads: `SurfaceTexture` (both backends) does not flip an
|
|
22
|
+
* `ImageBitmap` source, so texture `v = 0` samples the PNG's own row 0, its top. `atlasTop`
|
|
23
|
+
* is therefore the *smaller* number — nearer row 0 — and `atlasBottom` the larger one,
|
|
24
|
+
* unlike `planeTop`/`planeBottom` above, which are a world-space quantity and stay y-up.
|
|
25
|
+
* `writeUv` in `sdfTextLayout.ts` divides these by `atlasWidth`/`atlasHeight` and uses the
|
|
26
|
+
* result as `v` directly: no flip, because these already agree with what the texture does.
|
|
27
|
+
*
|
|
28
|
+
* A version that flipped these to be y-up — matching the plane box's own sign, so that
|
|
29
|
+
* "a texel and a plane coordinate agree on which way is up" — shipped for two days
|
|
30
|
+
* (2026-08-16) and flipped every glyph onto the wrong row of its atlas, because
|
|
31
|
+
* `SurfaceTexture` had already stopped flipping the upload two days earlier. Two
|
|
32
|
+
* conventions that each sound reasonable alone cancelled into a bug neither side's unit
|
|
33
|
+
* tests could see, because neither one renders a real texture.
|
|
34
|
+
*/
|
|
35
|
+
readonly atlasLeft: number;
|
|
36
|
+
readonly atlasBottom: number;
|
|
37
|
+
readonly atlasRight: number;
|
|
38
|
+
readonly atlasTop: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface SdfFont {
|
|
42
|
+
readonly family: string;
|
|
43
|
+
readonly unitsPerEm: number;
|
|
44
|
+
readonly ascender: number;
|
|
45
|
+
readonly descender: number;
|
|
46
|
+
readonly lineHeight: number;
|
|
47
|
+
readonly distanceRange: number;
|
|
48
|
+
readonly atlasWidth: number;
|
|
49
|
+
readonly atlasHeight: number;
|
|
50
|
+
/**
|
|
51
|
+
* Keys in the glyph table that are more than one character, longest first.
|
|
52
|
+
*
|
|
53
|
+
* A *pre-shaped run*: a string the generator handed to the platform's own text stack,
|
|
54
|
+
* which joined, reordered and shaped it, baked as one atlas cell. The runtime draws
|
|
55
|
+
* quads from metrics and does no shaping at all, so a script that joins its letters or
|
|
56
|
+
* reads right to left cannot be assembled from single glyphs at draw time. `أبو` came
|
|
57
|
+
* out as three disconnected isolated forms marching the wrong way; as one run it comes
|
|
58
|
+
* out as the word.
|
|
59
|
+
*
|
|
60
|
+
* Longest first because `sdfTextLayout.ts` takes the first match at the pen, and a
|
|
61
|
+
* shorter run that is a prefix of a longer one must not win.
|
|
62
|
+
*/
|
|
63
|
+
readonly runs: readonly string[];
|
|
64
|
+
glyph(character: string): SdfGlyph | null;
|
|
65
|
+
kerning(left: string, right: string): number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const SUPPORTED_VERSION = 1;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Validate and index a metrics document.
|
|
72
|
+
*
|
|
73
|
+
* **Throws on a version it does not recognise**, which is the fail-fast-at-init rule
|
|
74
|
+
* earning its keep: the alternative is reading a field that moved and drawing text that is
|
|
75
|
+
* subtly misplaced, and misplaced text looks like a layout bug for as long as it takes to
|
|
76
|
+
* suspect the file.
|
|
77
|
+
*
|
|
78
|
+
* Required numeric fields fail at load, not draw: `unitsPerEm` scales every plane and atlas
|
|
79
|
+
* coordinate, so a missing one produces wrong sizes that look plausible until a frame lands
|
|
80
|
+
* beside a reference and they do not match. Every other required field is checked the same way.
|
|
81
|
+
*/
|
|
82
|
+
export function parseSdfFont(document: unknown): SdfFont {
|
|
83
|
+
if (typeof document !== 'object' || document === null) {
|
|
84
|
+
throw new Error('parseSdfFont: expected a metrics object');
|
|
85
|
+
}
|
|
86
|
+
const source = document as Record<string, unknown>;
|
|
87
|
+
if (source['version'] !== SUPPORTED_VERSION) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`parseSdfFont: metrics version ${String(source['version'])}, this build reads ${SUPPORTED_VERSION}`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (typeof source['atlas'] !== 'object' || source['atlas'] === null) {
|
|
94
|
+
throw new Error('parseSdfFont: atlas field must be an object');
|
|
95
|
+
}
|
|
96
|
+
const atlas = source['atlas'] as Record<string, unknown>;
|
|
97
|
+
|
|
98
|
+
if (typeof source['metrics'] !== 'object' || source['metrics'] === null) {
|
|
99
|
+
throw new Error('parseSdfFont: metrics field must be an object');
|
|
100
|
+
}
|
|
101
|
+
const metrics = source['metrics'] as Record<string, unknown>;
|
|
102
|
+
|
|
103
|
+
if (typeof source['glyphs'] !== 'object' || source['glyphs'] === null) {
|
|
104
|
+
throw new Error('parseSdfFont: glyphs field must be an object');
|
|
105
|
+
}
|
|
106
|
+
const glyphs = source['glyphs'] as Record<string, SdfGlyph>;
|
|
107
|
+
|
|
108
|
+
const kerning = (source['kerning'] ?? {}) as Record<string, number>;
|
|
109
|
+
|
|
110
|
+
// Validate required numeric fields
|
|
111
|
+
const requiredMetricsFields = ['unitsPerEm', 'ascender', 'descender', 'lineHeight'] as const;
|
|
112
|
+
for (const field of requiredMetricsFields) {
|
|
113
|
+
if (typeof metrics[field] !== 'number') {
|
|
114
|
+
throw new Error(`parseSdfFont: metrics.${field} is required and must be a number`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const requiredAtlasFields = ['distanceRange', 'width', 'height'] as const;
|
|
119
|
+
for (const field of requiredAtlasFields) {
|
|
120
|
+
if (typeof atlas[field] !== 'number') {
|
|
121
|
+
throw new Error(`parseSdfFont: atlas.${field} is required and must be a number`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
family: String(source['family'] ?? 'unnamed'),
|
|
127
|
+
unitsPerEm: metrics['unitsPerEm'] as number,
|
|
128
|
+
ascender: metrics['ascender'] as number,
|
|
129
|
+
descender: metrics['descender'] as number,
|
|
130
|
+
lineHeight: metrics['lineHeight'] as number,
|
|
131
|
+
distanceRange: atlas['distanceRange'] as number,
|
|
132
|
+
atlasWidth: atlas['width'] as number,
|
|
133
|
+
atlasHeight: atlas['height'] as number,
|
|
134
|
+
runs: multiCharacterKeys(glyphs),
|
|
135
|
+
glyph(character: string): SdfGlyph | null {
|
|
136
|
+
return glyphs[character] ?? null;
|
|
137
|
+
},
|
|
138
|
+
kerning(left: string, right: string): number {
|
|
139
|
+
return kerning[`${left}\u0000${right}`] ?? 0;
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Every key that spans more than one UTF-16 unit, longest first.
|
|
146
|
+
*
|
|
147
|
+
* Length in UTF-16 units rather than code points, because the one consumer of this order
|
|
148
|
+
* is `String.prototype.startsWith`, which counts the same way. Ties break lexicographically
|
|
149
|
+
* so that the order is a property of the table and not of the order it was written in: an
|
|
150
|
+
* atlas is committed and diffed, and a list that reshuffled when a glyph was added would
|
|
151
|
+
* make every rebake look like a change.
|
|
152
|
+
*/
|
|
153
|
+
function multiCharacterKeys(glyphs: Record<string, SdfGlyph>): readonly string[] {
|
|
154
|
+
return Object.keys(glyphs)
|
|
155
|
+
.filter((key) => key.length > 1)
|
|
156
|
+
.sort((a, b) => b.length - a.length || (a < b ? -1 : a > b ? 1 : 0));
|
|
157
|
+
}
|