@thunderclap-engine/engine 0.0.0-stage → 1.1.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/CHANGELOG.md +390 -0
- package/LICENSE +21 -0
- package/README.md +333 -2
- package/dist/analytics/analytics.d.ts +80 -0
- package/dist/analytics/analytics.js +129 -0
- package/dist/analytics/index.d.ts +1 -0
- package/dist/analytics/index.js +1 -0
- package/dist/anim/aim.d.ts +43 -0
- package/dist/anim/aim.js +157 -0
- package/dist/anim/clip.d.ts +98 -0
- package/dist/anim/clip.js +282 -0
- package/dist/anim/compress.d.ts +65 -0
- package/dist/anim/compress.js +339 -0
- package/dist/anim/foot-ik.d.ts +74 -0
- package/dist/anim/foot-ik.js +241 -0
- package/dist/anim/graph.d.ts +153 -0
- package/dist/anim/graph.js +532 -0
- package/dist/anim/ik.d.ts +105 -0
- package/dist/anim/ik.js +435 -0
- package/dist/anim/index.d.ts +36 -0
- package/dist/anim/index.js +21 -0
- package/dist/anim/match.d.ts +66 -0
- package/dist/anim/match.js +153 -0
- package/dist/anim/mixer.d.ts +113 -0
- package/dist/anim/mixer.js +314 -0
- package/dist/anim/morph.d.ts +41 -0
- package/dist/anim/morph.js +94 -0
- package/dist/anim/pose.d.ts +74 -0
- package/dist/anim/pose.js +254 -0
- package/dist/anim/quat.d.ts +44 -0
- package/dist/anim/quat.js +187 -0
- package/dist/anim/retarget.d.ts +97 -0
- package/dist/anim/retarget.js +366 -0
- package/dist/anim/root-motion.d.ts +44 -0
- package/dist/anim/root-motion.js +224 -0
- package/dist/anim/skin-pose.d.ts +39 -0
- package/dist/anim/skin-pose.js +53 -0
- package/dist/anim/socket.d.ts +47 -0
- package/dist/anim/socket.js +84 -0
- package/dist/anim/spring-chain.d.ts +73 -0
- package/dist/anim/spring-chain.js +294 -0
- package/dist/assets/atlas.d.ts +90 -0
- package/dist/assets/atlas.js +212 -0
- package/dist/assets/baked.d.ts +33 -0
- package/dist/assets/baked.js +38 -0
- package/dist/assets/bundle.d.ts +88 -0
- package/dist/assets/bundle.js +464 -0
- package/dist/assets/cache.d.ts +56 -0
- package/dist/assets/cache.js +123 -0
- package/dist/assets/gltf-load.d.ts +252 -0
- package/dist/assets/gltf-load.js +661 -0
- package/dist/assets/gltf-skin.d.ts +36 -0
- package/dist/assets/gltf-skin.js +109 -0
- package/dist/assets/gltf.d.ts +706 -0
- package/dist/assets/gltf.js +1376 -0
- package/dist/assets/index.d.ts +20 -0
- package/dist/assets/index.js +10 -0
- package/dist/assets/ktx2.d.ts +71 -0
- package/dist/assets/ktx2.js +213 -0
- package/dist/assets/manifest.d.ts +79 -0
- package/dist/assets/manifest.js +7 -0
- package/dist/assets/meshopt.d.ts +23 -0
- package/dist/assets/meshopt.js +403 -0
- package/dist/audio/audio.d.ts +733 -0
- package/dist/audio/audio.js +2013 -0
- package/dist/audio/dsp.d.ts +61 -0
- package/dist/audio/dsp.js +159 -0
- package/dist/audio/duck.d.ts +44 -0
- package/dist/audio/duck.js +101 -0
- package/dist/audio/envelope.d.ts +53 -0
- package/dist/audio/envelope.js +106 -0
- package/dist/audio/index.d.ts +13 -0
- package/dist/audio/index.js +14 -0
- package/dist/audio/music.d.ts +113 -0
- package/dist/audio/music.js +548 -0
- package/dist/audio/occlusion.d.ts +55 -0
- package/dist/audio/occlusion.js +61 -0
- package/dist/audio/persist.d.ts +23 -0
- package/dist/audio/persist.js +27 -0
- package/dist/audio/recipes.d.ts +55 -0
- package/dist/audio/recipes.js +227 -0
- package/dist/audio/send.d.ts +41 -0
- package/dist/audio/send.js +118 -0
- package/dist/audio/sprites.d.ts +59 -0
- package/dist/audio/sprites.js +43 -0
- package/dist/audio/synth.d.ts +103 -0
- package/dist/audio/synth.js +197 -0
- package/dist/audio/variations.d.ts +25 -0
- package/dist/audio/variations.js +55 -0
- package/dist/audio/zones.d.ts +100 -0
- package/dist/audio/zones.js +167 -0
- package/dist/core/detached-surface.d.ts +44 -0
- package/dist/core/detached-surface.js +104 -0
- package/dist/core/events.d.ts +24 -0
- package/dist/core/events.js +43 -0
- package/dist/core/game.d.ts +409 -0
- package/dist/core/game.js +530 -0
- package/dist/core/hash.d.ts +24 -0
- package/dist/core/hash.js +49 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.js +9 -0
- package/dist/core/loop.d.ts +113 -0
- package/dist/core/loop.js +185 -0
- package/dist/core/math.d.ts +58 -0
- package/dist/core/math.js +210 -0
- package/dist/core/noise.d.ts +40 -0
- package/dist/core/noise.js +247 -0
- package/dist/core/pool.d.ts +42 -0
- package/dist/core/pool.js +85 -0
- package/dist/core/random.d.ts +61 -0
- package/dist/core/random.js +199 -0
- package/dist/core/scene.d.ts +79 -0
- package/dist/core/scene.js +195 -0
- package/dist/core/timer.d.ts +66 -0
- package/dist/core/timer.js +286 -0
- package/dist/fx/billboard-wgsl.d.ts +29 -0
- package/dist/fx/billboard-wgsl.js +158 -0
- package/dist/fx/billboard.d.ts +249 -0
- package/dist/fx/billboard.js +702 -0
- package/dist/fx/debug-draw.d.ts +127 -0
- package/dist/fx/debug-draw.js +523 -0
- package/dist/fx/debug-wgsl.d.ts +7 -0
- package/dist/fx/debug-wgsl.js +32 -0
- package/dist/fx/decals-wgsl.d.ts +15 -0
- package/dist/fx/decals-wgsl.js +173 -0
- package/dist/fx/decals.d.ts +216 -0
- package/dist/fx/decals.js +607 -0
- package/dist/fx/effect.d.ts +129 -0
- package/dist/fx/effect.js +349 -0
- package/dist/fx/effects/hit-spark.json +48 -0
- package/dist/fx/effects/index.d.ts +8 -0
- package/dist/fx/effects/index.js +9 -0
- package/dist/fx/effects/magic-aura.json +47 -0
- package/dist/fx/effects/smoke-puff.json +34 -0
- package/dist/fx/emit-surface.d.ts +40 -0
- package/dist/fx/emit-surface.js +124 -0
- package/dist/fx/flicker.d.ts +30 -0
- package/dist/fx/flicker.js +42 -0
- package/dist/fx/index.d.ts +31 -0
- package/dist/fx/index.js +20 -0
- package/dist/fx/particles-wgsl.d.ts +57 -0
- package/dist/fx/particles-wgsl.js +828 -0
- package/dist/fx/particles.d.ts +566 -0
- package/dist/fx/particles.js +1533 -0
- package/dist/fx/random.d.ts +15 -0
- package/dist/fx/random.js +20 -0
- package/dist/fx/sky-wgsl.d.ts +23 -0
- package/dist/fx/sky-wgsl.js +127 -0
- package/dist/fx/sky.d.ts +96 -0
- package/dist/fx/sky.js +175 -0
- package/dist/fx/text-atlas.d.ts +143 -0
- package/dist/fx/text-atlas.js +327 -0
- package/dist/fx/trail-wgsl.d.ts +11 -0
- package/dist/fx/trail-wgsl.js +42 -0
- package/dist/fx/trail.d.ts +194 -0
- package/dist/fx/trail.js +555 -0
- package/dist/fx/water-wgsl.d.ts +34 -0
- package/dist/fx/water-wgsl.js +197 -0
- package/dist/fx/water.d.ts +176 -0
- package/dist/fx/water.js +371 -0
- package/dist/geom/collide/bvh.d.ts +151 -0
- package/dist/geom/collide/bvh.js +493 -0
- package/dist/geom/collide/debug.d.ts +14 -0
- package/dist/geom/collide/debug.js +74 -0
- package/dist/geom/collide/grid.d.ts +26 -0
- package/dist/geom/collide/grid.js +91 -0
- package/dist/geom/collide/index.d.ts +8 -0
- package/dist/geom/collide/index.js +8 -0
- package/dist/geom/collide/queries.d.ts +70 -0
- package/dist/geom/collide/queries.js +583 -0
- package/dist/geom/collide/serialize.d.ts +14 -0
- package/dist/geom/collide/serialize.js +145 -0
- package/dist/geom/collide/shapes.d.ts +161 -0
- package/dist/geom/collide/shapes.js +686 -0
- package/dist/geom/collide/slide.d.ts +66 -0
- package/dist/geom/collide/slide.js +375 -0
- package/dist/geom/collide/tile-slide.d.ts +88 -0
- package/dist/geom/collide/tile-slide.js +255 -0
- package/dist/geom/geometry.d.ts +95 -0
- package/dist/geom/geometry.js +322 -0
- package/dist/geom/heightfield.d.ts +72 -0
- package/dist/geom/heightfield.js +295 -0
- package/dist/geom/hull.d.ts +27 -0
- package/dist/geom/hull.js +279 -0
- package/dist/geom/index.d.ts +35 -0
- package/dist/geom/index.js +23 -0
- package/dist/geom/iso.d.ts +74 -0
- package/dist/geom/iso.js +89 -0
- package/dist/geom/lod.d.ts +29 -0
- package/dist/geom/lod.js +27 -0
- package/dist/geom/ops.d.ts +47 -0
- package/dist/geom/ops.js +285 -0
- package/dist/geom/primitives.d.ts +97 -0
- package/dist/geom/primitives.js +359 -0
- package/dist/geom/shapes.d.ts +43 -0
- package/dist/geom/shapes.js +88 -0
- package/dist/geom/simplify.d.ts +38 -0
- package/dist/geom/simplify.js +519 -0
- package/dist/geom/split.d.ts +37 -0
- package/dist/geom/split.js +413 -0
- package/dist/geom/sweep.d.ts +83 -0
- package/dist/geom/sweep.js +534 -0
- package/dist/geom/tangents.d.ts +16 -0
- package/dist/geom/tangents.js +124 -0
- package/dist/geom/triangulate.d.ts +19 -0
- package/dist/geom/triangulate.js +147 -0
- package/dist/host/default.d.ts +10 -0
- package/dist/host/default.js +10 -0
- package/dist/host/index.d.ts +4 -0
- package/dist/host/index.js +3 -0
- package/dist/host/types.d.ts +144 -0
- package/dist/host/types.js +1 -0
- package/dist/host/web-links.d.ts +38 -0
- package/dist/host/web-links.js +110 -0
- package/dist/host/web.d.ts +30 -0
- package/dist/host/web.js +216 -0
- package/dist/host/xr.d.ts +24 -0
- package/dist/host/xr.js +59 -0
- package/dist/i18n/i18n.d.ts +59 -0
- package/dist/i18n/i18n.js +241 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/message.d.ts +72 -0
- package/dist/i18n/message.js +369 -0
- package/dist/i18n/negotiate.d.ts +17 -0
- package/dist/i18n/negotiate.js +58 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -0
- package/dist/input/bindings.d.ts +31 -0
- package/dist/input/bindings.js +141 -0
- package/dist/input/clock.d.ts +44 -0
- package/dist/input/clock.js +49 -0
- package/dist/input/follow.d.ts +133 -0
- package/dist/input/follow.js +218 -0
- package/dist/input/gestures.d.ts +281 -0
- package/dist/input/gestures.js +662 -0
- package/dist/input/glyphs.d.ts +35 -0
- package/dist/input/glyphs.js +216 -0
- package/dist/input/gyro.d.ts +85 -0
- package/dist/input/gyro.js +140 -0
- package/dist/input/index.d.ts +19 -0
- package/dist/input/index.js +16 -0
- package/dist/input/input.d.ts +543 -0
- package/dist/input/input.js +1492 -0
- package/dist/input/look.d.ts +327 -0
- package/dist/input/look.js +681 -0
- package/dist/input/magnify.d.ts +177 -0
- package/dist/input/magnify.js +131 -0
- package/dist/input/pointer-dispatch.d.ts +138 -0
- package/dist/input/pointer-dispatch.js +180 -0
- package/dist/input/pointer-router.d.ts +204 -0
- package/dist/input/pointer-router.js +533 -0
- package/dist/input/pointer-sources.d.ts +164 -0
- package/dist/input/pointer-sources.js +306 -0
- package/dist/input/rays.d.ts +138 -0
- package/dist/input/rays.js +615 -0
- package/dist/input/record.d.ts +209 -0
- package/dist/input/record.js +601 -0
- package/dist/input/touch-zones.d.ts +147 -0
- package/dist/input/touch-zones.js +300 -0
- package/dist/input/types.d.ts +158 -0
- package/dist/input/types.js +1 -0
- package/dist/input/xr-source.d.ts +53 -0
- package/dist/input/xr-source.js +164 -0
- package/dist/nav/astar.d.ts +45 -0
- package/dist/nav/astar.js +182 -0
- package/dist/nav/corridor.d.ts +40 -0
- package/dist/nav/corridor.js +95 -0
- package/dist/nav/crowd.d.ts +94 -0
- package/dist/nav/crowd.js +624 -0
- package/dist/nav/flow.d.ts +61 -0
- package/dist/nav/flow.js +193 -0
- package/dist/nav/grid.d.ts +108 -0
- package/dist/nav/grid.js +210 -0
- package/dist/nav/heap.d.ts +22 -0
- package/dist/nav/heap.js +92 -0
- package/dist/nav/index.d.ts +37 -0
- package/dist/nav/index.js +19 -0
- package/dist/nav/mesh/areas.d.ts +44 -0
- package/dist/nav/mesh/areas.js +98 -0
- package/dist/nav/mesh/bake-options.d.ts +33 -0
- package/dist/nav/mesh/bake-options.js +76 -0
- package/dist/nav/mesh/contour.d.ts +22 -0
- package/dist/nav/mesh/contour.js +323 -0
- package/dist/nav/mesh/flow3.d.ts +35 -0
- package/dist/nav/mesh/flow3.js +229 -0
- package/dist/nav/mesh/links.d.ts +38 -0
- package/dist/nav/mesh/links.js +72 -0
- package/dist/nav/mesh/mesh-path.d.ts +152 -0
- package/dist/nav/mesh/mesh-path.js +643 -0
- package/dist/nav/mesh/mesh-reach.d.ts +78 -0
- package/dist/nav/mesh/mesh-reach.js +450 -0
- package/dist/nav/mesh/navmesh.d.ts +117 -0
- package/dist/nav/mesh/navmesh.js +647 -0
- package/dist/nav/mesh/polymesh.d.ts +24 -0
- package/dist/nav/mesh/polymesh.js +384 -0
- package/dist/nav/mesh/regions.d.ts +12 -0
- package/dist/nav/mesh/regions.js +367 -0
- package/dist/nav/mesh/serialize.d.ts +13 -0
- package/dist/nav/mesh/serialize.js +197 -0
- package/dist/nav/mesh/voxelize.d.ts +111 -0
- package/dist/nav/mesh/voxelize.js +552 -0
- package/dist/nav/obstacles.d.ts +75 -0
- package/dist/nav/obstacles.js +294 -0
- package/dist/nav/path.d.ts +59 -0
- package/dist/nav/path.js +177 -0
- package/dist/nav/query-queue.d.ts +46 -0
- package/dist/nav/query-queue.js +308 -0
- package/dist/nav/reach.d.ts +53 -0
- package/dist/nav/reach.js +148 -0
- package/dist/nav/steer.d.ts +36 -0
- package/dist/nav/steer.js +78 -0
- package/dist/platform/boot.d.ts +28 -0
- package/dist/platform/boot.js +43 -0
- package/dist/platform/device-mode.d.ts +40 -0
- package/dist/platform/device-mode.js +104 -0
- package/dist/platform/device.d.ts +31 -0
- package/dist/platform/device.js +91 -0
- package/dist/platform/environment.d.ts +42 -0
- package/dist/platform/environment.js +82 -0
- package/dist/platform/gpu.d.ts +40 -0
- package/dist/platform/gpu.js +57 -0
- package/dist/platform/index.d.ts +18 -0
- package/dist/platform/index.js +10 -0
- package/dist/platform/letterbox.d.ts +43 -0
- package/dist/platform/letterbox.js +57 -0
- package/dist/platform/links.d.ts +20 -0
- package/dist/platform/links.js +43 -0
- package/dist/platform/screens.d.ts +36 -0
- package/dist/platform/screens.js +138 -0
- package/dist/platform/surface.d.ts +72 -0
- package/dist/platform/surface.js +157 -0
- package/dist/platform/xr-fake.d.ts +168 -0
- package/dist/platform/xr-fake.js +434 -0
- package/dist/platform/xr-surface.d.ts +120 -0
- package/dist/platform/xr-surface.js +214 -0
- package/dist/platform/xr-types.d.ts +262 -0
- package/dist/post/ao.d.ts +12 -0
- package/dist/post/ao.js +136 -0
- package/dist/post/blend.d.ts +27 -0
- package/dist/post/blend.js +129 -0
- package/dist/post/depth-pass.d.ts +43 -0
- package/dist/post/depth-pass.js +118 -0
- package/dist/post/dof.d.ts +1 -0
- package/dist/post/dof.js +66 -0
- package/dist/post/exposure.d.ts +80 -0
- package/dist/post/exposure.js +322 -0
- package/dist/post/index.d.ts +12 -0
- package/dist/post/index.js +11 -0
- package/dist/post/lens-dirt.d.ts +13 -0
- package/dist/post/lens-dirt.js +91 -0
- package/dist/post/lut.d.ts +19 -0
- package/dist/post/lut.js +50 -0
- package/dist/post/motion-blur.d.ts +9 -0
- package/dist/post/motion-blur.js +78 -0
- package/dist/post/post-stack.d.ts +302 -0
- package/dist/post/post-stack.js +1137 -0
- package/dist/post/settings.d.ts +485 -0
- package/dist/post/settings.js +416 -0
- package/dist/post/shaders.d.ts +25 -0
- package/dist/post/shaders.js +410 -0
- package/dist/post/ssr.d.ts +16 -0
- package/dist/post/ssr.js +155 -0
- package/dist/post/taa.d.ts +74 -0
- package/dist/post/taa.js +235 -0
- package/dist/post/white-balance.d.ts +25 -0
- package/dist/post/white-balance.js +98 -0
- package/dist/render/bindings.d.ts +98 -0
- package/dist/render/bindings.js +281 -0
- package/dist/render/blend.d.ts +13 -0
- package/dist/render/blend.js +26 -0
- package/dist/render/camera-2d.d.ts +72 -0
- package/dist/render/camera-2d.js +92 -0
- package/dist/render/camera.d.ts +302 -0
- package/dist/render/camera.js +671 -0
- package/dist/render/color.d.ts +16 -0
- package/dist/render/color.js +41 -0
- package/dist/render/compressed.d.ts +104 -0
- package/dist/render/compressed.js +248 -0
- package/dist/render/diagnostics.d.ts +15 -0
- package/dist/render/diagnostics.js +43 -0
- package/dist/render/dynamic-resolution.d.ts +70 -0
- package/dist/render/dynamic-resolution.js +126 -0
- package/dist/render/fake-gpu.d.ts +204 -0
- package/dist/render/fake-gpu.js +426 -0
- package/dist/render/flipbook.d.ts +56 -0
- package/dist/render/flipbook.js +87 -0
- package/dist/render/frame.d.ts +278 -0
- package/dist/render/frame.js +174 -0
- package/dist/render/fullscreen.d.ts +54 -0
- package/dist/render/fullscreen.js +91 -0
- package/dist/render/gpu-timer.d.ts +73 -0
- package/dist/render/gpu-timer.js +186 -0
- package/dist/render/index.d.ts +53 -0
- package/dist/render/index.js +29 -0
- package/dist/render/instance-list.d.ts +185 -0
- package/dist/render/instance-list.js +547 -0
- package/dist/render/lights.d.ts +181 -0
- package/dist/render/lights.js +233 -0
- package/dist/render/lod.d.ts +54 -0
- package/dist/render/lod.js +52 -0
- package/dist/render/material.d.ts +165 -0
- package/dist/render/material.js +292 -0
- package/dist/render/mesh.d.ts +284 -0
- package/dist/render/mesh.js +472 -0
- package/dist/render/mipmap.d.ts +16 -0
- package/dist/render/mipmap.js +121 -0
- package/dist/render/parallax.d.ts +50 -0
- package/dist/render/parallax.js +47 -0
- package/dist/render/pbr-wgsl.d.ts +31 -0
- package/dist/render/pbr-wgsl.js +119 -0
- package/dist/render/ping-pong.d.ts +42 -0
- package/dist/render/ping-pong.js +74 -0
- package/dist/render/renderer.d.ts +741 -0
- package/dist/render/renderer.js +2486 -0
- package/dist/render/scene-pipelines.d.ts +44 -0
- package/dist/render/scene-pipelines.js +92 -0
- package/dist/render/scene-target.d.ts +170 -0
- package/dist/render/scene-target.js +450 -0
- package/dist/render/shadow.d.ts +74 -0
- package/dist/render/shadow.js +208 -0
- package/dist/render/skin.d.ts +112 -0
- package/dist/render/skin.js +240 -0
- package/dist/render/snapshot.d.ts +36 -0
- package/dist/render/snapshot.js +34 -0
- package/dist/render/standard.d.ts +162 -0
- package/dist/render/standard.js +263 -0
- package/dist/render/texture.d.ts +142 -0
- package/dist/render/texture.js +228 -0
- package/dist/render/tile-layer.d.ts +110 -0
- package/dist/render/tile-layer.js +304 -0
- package/dist/render/transform.d.ts +115 -0
- package/dist/render/transform.js +318 -0
- package/dist/render/wgsl.d.ts +131 -0
- package/dist/render/wgsl.js +528 -0
- package/dist/save/codec.d.ts +49 -0
- package/dist/save/codec.js +169 -0
- package/dist/save/index.d.ts +8 -0
- package/dist/save/index.js +8 -0
- package/dist/save/journal.d.ts +24 -0
- package/dist/save/journal.js +102 -0
- package/dist/save/migrate.d.ts +15 -0
- package/dist/save/migrate.js +37 -0
- package/dist/save/schema.d.ts +72 -0
- package/dist/save/schema.js +154 -0
- package/dist/save/settings.d.ts +28 -0
- package/dist/save/settings.js +59 -0
- package/dist/save/slots.d.ts +56 -0
- package/dist/save/slots.js +200 -0
- package/dist/save/storage.d.ts +35 -0
- package/dist/save/storage.js +62 -0
- package/dist/save/store.d.ts +114 -0
- package/dist/save/store.js +269 -0
- package/dist/testing/fake-host.d.ts +103 -0
- package/dist/testing/fake-host.js +163 -0
- package/dist/testing/fixed-clock.d.ts +25 -0
- package/dist/testing/fixed-clock.js +30 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/test-game.d.ts +76 -0
- package/dist/testing/test-game.js +92 -0
- package/dist/tween/ease.d.ts +77 -0
- package/dist/tween/ease.js +192 -0
- package/dist/tween/index.d.ts +8 -0
- package/dist/tween/index.js +7 -0
- package/dist/tween/timeline.d.ts +78 -0
- package/dist/tween/timeline.js +269 -0
- package/dist/tween/tween.d.ts +168 -0
- package/dist/tween/tween.js +320 -0
- package/dist/ui/anchor.d.ts +206 -0
- package/dist/ui/anchor.js +307 -0
- package/dist/ui/caption.d.ts +122 -0
- package/dist/ui/caption.js +286 -0
- package/dist/ui/cursor.d.ts +105 -0
- package/dist/ui/cursor.js +261 -0
- package/dist/ui/dom.d.ts +30 -0
- package/dist/ui/dom.js +92 -0
- package/dist/ui/floats.d.ts +86 -0
- package/dist/ui/floats.js +260 -0
- package/dist/ui/hud.d.ts +198 -0
- package/dist/ui/hud.js +431 -0
- package/dist/ui/index.d.ts +37 -0
- package/dist/ui/index.js +34 -0
- package/dist/ui/inventory-card.d.ts +52 -0
- package/dist/ui/inventory-card.js +173 -0
- package/dist/ui/inventory-context.d.ts +29 -0
- package/dist/ui/inventory-context.js +125 -0
- package/dist/ui/inventory-drag.d.ts +63 -0
- package/dist/ui/inventory-drag.js +394 -0
- package/dist/ui/inventory-grid.d.ts +66 -0
- package/dist/ui/inventory-grid.js +625 -0
- package/dist/ui/inventory-radial.d.ts +39 -0
- package/dist/ui/inventory-radial.js +168 -0
- package/dist/ui/inventory.d.ts +128 -0
- package/dist/ui/inventory.js +154 -0
- package/dist/ui/layout.d.ts +356 -0
- package/dist/ui/layout.js +856 -0
- package/dist/ui/link.d.ts +64 -0
- package/dist/ui/link.js +155 -0
- package/dist/ui/loading.d.ts +40 -0
- package/dist/ui/loading.js +157 -0
- package/dist/ui/loupe.d.ts +74 -0
- package/dist/ui/loupe.js +164 -0
- package/dist/ui/menu-nav.d.ts +33 -0
- package/dist/ui/menu-nav.js +28 -0
- package/dist/ui/minimap-canvas.d.ts +145 -0
- package/dist/ui/minimap-canvas.js +460 -0
- package/dist/ui/notify.d.ts +40 -0
- package/dist/ui/notify.js +141 -0
- package/dist/ui/orb.d.ts +53 -0
- package/dist/ui/orb.js +304 -0
- package/dist/ui/overlay.d.ts +213 -0
- package/dist/ui/overlay.js +394 -0
- package/dist/ui/padnav.d.ts +53 -0
- package/dist/ui/padnav.js +146 -0
- package/dist/ui/perf.d.ts +130 -0
- package/dist/ui/perf.js +329 -0
- package/dist/ui/rotate-card.d.ts +54 -0
- package/dist/ui/rotate-card.js +97 -0
- package/dist/ui/stack.d.ts +128 -0
- package/dist/ui/stack.js +312 -0
- package/dist/ui/styles.d.ts +13 -0
- package/dist/ui/styles.js +200 -0
- package/dist/ui/text-scale.d.ts +67 -0
- package/dist/ui/text-scale.js +102 -0
- package/dist/ui/theme.d.ts +70 -0
- package/dist/ui/theme.js +98 -0
- package/dist/ui/toast.d.ts +23 -0
- package/dist/ui/toast.js +46 -0
- package/dist/ui/tooltip.d.ts +89 -0
- package/dist/ui/tooltip.js +333 -0
- package/dist/ui/widgets-2.d.ts +134 -0
- package/dist/ui/widgets-2.js +399 -0
- package/dist/ui/widgets-3.d.ts +91 -0
- package/dist/ui/widgets-3.js +212 -0
- package/dist/ui/widgets.d.ts +34 -0
- package/dist/ui/widgets.js +50 -0
- package/dist/ui/world-panel/index.d.ts +5 -0
- package/dist/ui/world-panel/index.js +5 -0
- package/dist/ui/world-panel/layout.d.ts +38 -0
- package/dist/ui/world-panel/layout.js +68 -0
- package/dist/ui/world-panel/paint.d.ts +96 -0
- package/dist/ui/world-panel/paint.js +136 -0
- package/dist/ui/world-panel/panel.d.ts +235 -0
- package/dist/ui/world-panel/panel.js +762 -0
- package/dist/ui/world-panel/wgsl.d.ts +10 -0
- package/dist/ui/world-panel/wgsl.js +52 -0
- package/dist/ui/world-panel/widgets.d.ts +207 -0
- package/dist/ui/world-panel/widgets.js +569 -0
- package/dist/voxel/chunks.d.ts +77 -0
- package/dist/voxel/chunks.js +149 -0
- package/dist/voxel/grid.d.ts +84 -0
- package/dist/voxel/grid.js +223 -0
- package/dist/voxel/index.d.ts +22 -0
- package/dist/voxel/index.js +7 -0
- package/dist/voxel/mesher-worker.d.ts +14 -0
- package/dist/voxel/mesher-worker.js +47 -0
- package/dist/voxel/mesher.d.ts +73 -0
- package/dist/voxel/mesher.js +306 -0
- package/dist/voxel/ray.d.ts +32 -0
- package/dist/voxel/ray.js +73 -0
- package/dist/voxel/wgsl.d.ts +16 -0
- package/dist/voxel/wgsl.js +28 -0
- package/dist/voxel/worker-client.d.ts +79 -0
- package/dist/voxel/worker-client.js +122 -0
- package/package.json +177 -3
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fx module's default randomness (ws/fx-4). Every random draw in `src/fx` goes through a
|
|
3
|
+
* core `Random`; an object built without one forks its own stream from one module default,
|
|
4
|
+
* seeded once with `FX_DEFAULT_SEED`. Forks are named by kind and creation index
|
|
5
|
+
* (`particles#0`, `decals#1`, …), so a page that builds the same objects in the same order gets
|
|
6
|
+
* the same numbers on every load. Pass `random` (`createRandom(seed)` or a fork of a game's
|
|
7
|
+
* own stream) to make an object independent of construction order.
|
|
8
|
+
*/
|
|
9
|
+
import { type Random } from '../core/random.js';
|
|
10
|
+
/** The seed of the fx module's default stream. */
|
|
11
|
+
export declare const FX_DEFAULT_SEED = "thunderclap-fx";
|
|
12
|
+
/** Largest particle spawn seed (exactly representable in a `f32`). */
|
|
13
|
+
export declare const SPAWN_SEED_MAX = 16777214;
|
|
14
|
+
/** A fork of the module default (`FX_DEFAULT_SEED`) for one object of `kind`. */
|
|
15
|
+
export declare function defaultFxRandom(kind: string): Random;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fx module's default randomness (ws/fx-4). Every random draw in `src/fx` goes through a
|
|
3
|
+
* core `Random`; an object built without one forks its own stream from one module default,
|
|
4
|
+
* seeded once with `FX_DEFAULT_SEED`. Forks are named by kind and creation index
|
|
5
|
+
* (`particles#0`, `decals#1`, …), so a page that builds the same objects in the same order gets
|
|
6
|
+
* the same numbers on every load. Pass `random` (`createRandom(seed)` or a fork of a game's
|
|
7
|
+
* own stream) to make an object independent of construction order.
|
|
8
|
+
*/
|
|
9
|
+
import { createRandom } from '../core/random.js';
|
|
10
|
+
/** The seed of the fx module's default stream. */
|
|
11
|
+
export const FX_DEFAULT_SEED = 'thunderclap-fx';
|
|
12
|
+
/** Largest particle spawn seed (exactly representable in a `f32`). */
|
|
13
|
+
export const SPAWN_SEED_MAX = 16777214;
|
|
14
|
+
let root = null;
|
|
15
|
+
let forks = 0;
|
|
16
|
+
/** A fork of the module default (`FX_DEFAULT_SEED`) for one object of `kind`. */
|
|
17
|
+
export function defaultFxRandom(kind) {
|
|
18
|
+
root ??= createRandom(FX_DEFAULT_SEED);
|
|
19
|
+
return root.fork(`${kind}#${forks++}`);
|
|
20
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sky shader: one fullscreen triangle at the far plane whose fragment reconstructs the view
|
|
3
|
+
* ray from the camera block and shades a procedural dome.
|
|
4
|
+
*
|
|
5
|
+
* View ray. The camera block carries `proj` and `view`, no inverse. A perspective projection
|
|
6
|
+
* (including an off-centre XR one) inverts analytically: with `vz = -1`,
|
|
7
|
+
* `ndc.x = (p00 * vx + p20 * vz) / (p23 * vz)` gives `vx = (p20 - p23 * ndc.x) / p00`, and y the
|
|
8
|
+
* same with `p11`, `p21`. The world direction is the view rotation's transpose applied to that
|
|
9
|
+
* (`dot(view[i].xyz, d)` per component, the view's columns). An orthographic projection
|
|
10
|
+
* (`p23 == 0`) has one view direction, the camera's forward (`-z`, or `+z` when `p22 > 0`, the
|
|
11
|
+
* 2D camera's convention). `skyRay` in `sky.ts` is the same
|
|
12
|
+
* math in TypeScript, tested against `Camera.screenToWorld`.
|
|
13
|
+
*
|
|
14
|
+
* Colour, all in linear space: zenith → horizon → ground by the ray's elevation; a band around
|
|
15
|
+
* the horizon mixes towards `lights.fog` (scaled by its density) so fogged geometry meets the
|
|
16
|
+
* sky; the sun disc (`sunSize` radians of angular radius, `sky.horizon.w`) and two glow lobes
|
|
17
|
+
* (`sunGlow`, `sky.ground.w`) tinted by `lights.sun_color` at `-lights.sun_dir`; when the sun
|
|
18
|
+
* is below the horizon the dome darkens and the stars (a hash of the direction on a grid of
|
|
19
|
+
* `density` cells per unit) appear. Without a sun (colour all zero) the dome is as set and the
|
|
20
|
+
* stars, if on, are full. The sun disc and the stars also go to the emissive target so bloom
|
|
21
|
+
* picks them up.
|
|
22
|
+
*/
|
|
23
|
+
export declare const SKY_WGSL: string;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { WGSL_GLOBALS, WGSL_LIGHTS, WGSL_NOISE } from '../render/wgsl.js';
|
|
2
|
+
/**
|
|
3
|
+
* The sky shader: one fullscreen triangle at the far plane whose fragment reconstructs the view
|
|
4
|
+
* ray from the camera block and shades a procedural dome.
|
|
5
|
+
*
|
|
6
|
+
* View ray. The camera block carries `proj` and `view`, no inverse. A perspective projection
|
|
7
|
+
* (including an off-centre XR one) inverts analytically: with `vz = -1`,
|
|
8
|
+
* `ndc.x = (p00 * vx + p20 * vz) / (p23 * vz)` gives `vx = (p20 - p23 * ndc.x) / p00`, and y the
|
|
9
|
+
* same with `p11`, `p21`. The world direction is the view rotation's transpose applied to that
|
|
10
|
+
* (`dot(view[i].xyz, d)` per component, the view's columns). An orthographic projection
|
|
11
|
+
* (`p23 == 0`) has one view direction, the camera's forward (`-z`, or `+z` when `p22 > 0`, the
|
|
12
|
+
* 2D camera's convention). `skyRay` in `sky.ts` is the same
|
|
13
|
+
* math in TypeScript, tested against `Camera.screenToWorld`.
|
|
14
|
+
*
|
|
15
|
+
* Colour, all in linear space: zenith → horizon → ground by the ray's elevation; a band around
|
|
16
|
+
* the horizon mixes towards `lights.fog` (scaled by its density) so fogged geometry meets the
|
|
17
|
+
* sky; the sun disc (`sunSize` radians of angular radius, `sky.horizon.w`) and two glow lobes
|
|
18
|
+
* (`sunGlow`, `sky.ground.w`) tinted by `lights.sun_color` at `-lights.sun_dir`; when the sun
|
|
19
|
+
* is below the horizon the dome darkens and the stars (a hash of the direction on a grid of
|
|
20
|
+
* `density` cells per unit) appear. Without a sun (colour all zero) the dome is as set and the
|
|
21
|
+
* stars, if on, are full. The sun disc and the stars also go to the emissive target so bloom
|
|
22
|
+
* picks them up.
|
|
23
|
+
*/
|
|
24
|
+
export const SKY_WGSL = /* wgsl */ `
|
|
25
|
+
${WGSL_GLOBALS}
|
|
26
|
+
${WGSL_LIGHTS}
|
|
27
|
+
${WGSL_NOISE}
|
|
28
|
+
struct SkyParams {
|
|
29
|
+
zenith: vec4f, // rgb, exposure
|
|
30
|
+
horizon: vec4f, // rgb, sun angular radius (radians)
|
|
31
|
+
ground: vec4f, // rgb, sun glow
|
|
32
|
+
stars: vec4f, // density, seed, enabled, night floor
|
|
33
|
+
};
|
|
34
|
+
@group(1) @binding(0) var<uniform> sky: SkyParams;
|
|
35
|
+
|
|
36
|
+
struct SkyOut {
|
|
37
|
+
@builtin(position) clip: vec4f,
|
|
38
|
+
@location(0) ndc: vec2f,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
struct FragOut {
|
|
42
|
+
@location(0) color: vec4f,
|
|
43
|
+
@location(1) emissive: vec4f,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// One triangle covering clip space, at the far plane (z = 1): with depth compare less-equal
|
|
47
|
+
// and no depth write, geometry drawn before or after it always wins.
|
|
48
|
+
@vertex fn vs(@builtin(vertex_index) i: u32) -> SkyOut {
|
|
49
|
+
let x = f32(i32(i & 1u) * 4 - 1);
|
|
50
|
+
let y = f32(i32(i >> 1u) * 4 - 1);
|
|
51
|
+
var o: SkyOut;
|
|
52
|
+
o.clip = vec4f(x, y, 1.0, 1.0);
|
|
53
|
+
o.ndc = vec2f(x, y);
|
|
54
|
+
return o;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fn sky_ray(ndc: vec2f) -> vec3f {
|
|
58
|
+
let p = camera.proj;
|
|
59
|
+
var d = vec3f(0.0, 0.0, -1.0);
|
|
60
|
+
if (p[2][3] != 0.0) {
|
|
61
|
+
d.x = (p[2][0] - p[2][3] * ndc.x) / p[0][0];
|
|
62
|
+
d.y = (p[2][1] - p[2][3] * ndc.y) / p[1][1];
|
|
63
|
+
} else if (p[2][2] > 0.0) {
|
|
64
|
+
d.z = 1.0; // an orthographic view that looks down +z (the 2D camera)
|
|
65
|
+
}
|
|
66
|
+
let v = camera.view;
|
|
67
|
+
return normalize(vec3f(dot(v[0].xyz, d), dot(v[1].xyz, d), dot(v[2].xyz, d)));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
fn sky_stars(d: vec3f, density: f32, seed: f32) -> f32 {
|
|
71
|
+
let p = d * density;
|
|
72
|
+
let cell = floor(p);
|
|
73
|
+
let key = cell.xy + vec2f(cell.z * 37.0 + seed, cell.z * 11.0 - seed);
|
|
74
|
+
let h = engine_hash22(key);
|
|
75
|
+
let hz = engine_hash21(key + 17.0);
|
|
76
|
+
let bright = engine_hash21(key + 41.0);
|
|
77
|
+
if (bright < 0.72) { return 0.0; }
|
|
78
|
+
let centre = normalize(cell + 0.5 + (vec3f(h, hz) - 0.5) * 0.8);
|
|
79
|
+
let r = 0.07 / density;
|
|
80
|
+
let c = dot(d, centre);
|
|
81
|
+
let edge = 1.0 - r * r * 0.5;
|
|
82
|
+
let s = smoothstep(edge, edge + r * r * 0.4, c);
|
|
83
|
+
return s * (0.4 + 0.6 * (bright - 0.72) / 0.28);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@fragment fn fs(in: SkyOut) -> FragOut {
|
|
87
|
+
let d = sky_ray(in.ndc);
|
|
88
|
+
let up = d.y;
|
|
89
|
+
let exposure = sky.zenith.w;
|
|
90
|
+
|
|
91
|
+
// The dome.
|
|
92
|
+
let above = mix(sky.horizon.rgb, sky.zenith.rgb, pow(saturate(up), 0.6));
|
|
93
|
+
let below = mix(sky.horizon.rgb, sky.ground.rgb, smoothstep(0.0, 0.25, -up));
|
|
94
|
+
var col = select(below, above, up >= 0.0);
|
|
95
|
+
|
|
96
|
+
// Horizon haze towards the fog colour, so fogged ground meets the sky.
|
|
97
|
+
let haze = saturate(lights.fog.w) * exp(-abs(up) * 6.0);
|
|
98
|
+
col = mix(col, lights.fog.rgb, haze);
|
|
99
|
+
|
|
100
|
+
// Day and night from the sun's elevation; no sun at all leaves the dome as set.
|
|
101
|
+
let to_sun = -lights.sun_dir;
|
|
102
|
+
let sun_color = lights.sun_color;
|
|
103
|
+
let has_sun = dot(sun_color, vec3f(1.0)) > 0.0;
|
|
104
|
+
let day = select(1.0, smoothstep(-0.12, 0.08, to_sun.y), has_sun);
|
|
105
|
+
col *= mix(sky.stars.w, 1.0, day);
|
|
106
|
+
|
|
107
|
+
// Sun disc and glow.
|
|
108
|
+
let cos_a = dot(d, to_sun);
|
|
109
|
+
let cos_disc = cos(sky.horizon.w);
|
|
110
|
+
let disc = smoothstep(cos_disc - 0.0004, cos_disc, cos_a) * smoothstep(-0.02, 0.0, up);
|
|
111
|
+
let glow = sky.ground.w * (0.3 * pow(saturate(cos_a), 16.0) + pow(saturate(cos_a), 256.0));
|
|
112
|
+
let sun = sun_color * (disc * 12.0 + glow);
|
|
113
|
+
col += sun;
|
|
114
|
+
|
|
115
|
+
// Stars at night.
|
|
116
|
+
var stars = 0.0;
|
|
117
|
+
if (sky.stars.z > 0.5) {
|
|
118
|
+
stars = sky_stars(d, sky.stars.x, sky.stars.y) * (1.0 - day) * smoothstep(-0.05, 0.05, up);
|
|
119
|
+
}
|
|
120
|
+
col += vec3f(stars * 2.0);
|
|
121
|
+
|
|
122
|
+
var o: FragOut;
|
|
123
|
+
o.color = vec4f(col * exposure, 1.0);
|
|
124
|
+
o.emissive = vec4f((sun_color * disc * 2.0 + vec3f(stars * 1.5)) * exposure, 1.0);
|
|
125
|
+
return o;
|
|
126
|
+
}
|
|
127
|
+
`;
|
package/dist/fx/sky.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Camera } from '../render/camera.js';
|
|
2
|
+
import type { Drawable, Frame } from '../render/frame.js';
|
|
3
|
+
import type { Renderer } from '../render/renderer.js';
|
|
4
|
+
/** Floats in the sky's params block (4 × vec4f, 64 bytes). */
|
|
5
|
+
export declare const SKY_PARAMS_FLOATS = 16;
|
|
6
|
+
/** Starfield settings (`Sky.stars`). */
|
|
7
|
+
export interface SkyStars {
|
|
8
|
+
/** Grid cells per unit of direction; more cells, more and smaller stars. Default 24. */
|
|
9
|
+
density: number;
|
|
10
|
+
/** Shuffles the field. Default 0. */
|
|
11
|
+
seed: number;
|
|
12
|
+
}
|
|
13
|
+
export interface SkyOptions {
|
|
14
|
+
/** Linear RGB straight up. Default a clear blue. */
|
|
15
|
+
zenith?: ArrayLike<number>;
|
|
16
|
+
/** Linear RGB at the horizon. Default a pale haze. */
|
|
17
|
+
horizon?: ArrayLike<number>;
|
|
18
|
+
/** Linear RGB below the horizon (where no geometry covers the dome). Default a dark earth. */
|
|
19
|
+
ground?: ArrayLike<number>;
|
|
20
|
+
/** Angular radius of the sun disc, radians. Default 0.03. */
|
|
21
|
+
sunSize?: number;
|
|
22
|
+
/** Strength of the glow around the sun (0 for none). Default 1. */
|
|
23
|
+
sunGlow?: number;
|
|
24
|
+
/** Stars at night: `true` for the defaults, or `{ density, seed }`. Default off. */
|
|
25
|
+
stars?: boolean | Partial<SkyStars>;
|
|
26
|
+
/** Multiplier on the whole dome. Default 1. */
|
|
27
|
+
exposure?: number;
|
|
28
|
+
/**
|
|
29
|
+
* How dark the dome goes at night, as a fraction of its daytime colour (the floor of the
|
|
30
|
+
* day/night fade driven by the sun's elevation). Default 0.06. Raise it for brighter nights,
|
|
31
|
+
* lower it towards 0 for black skies behind the stars.
|
|
32
|
+
*/
|
|
33
|
+
ambientFloor?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A procedural sky: a gradient dome with a sun disc and glow that follow `frame.lights.sun`,
|
|
37
|
+
* horizon haze towards `frame.lights.fog.color`, and stars once the sun sets. One fullscreen
|
|
38
|
+
* triangle, no asset, no instance; `frame.drawable(sky)` draws it.
|
|
39
|
+
*
|
|
40
|
+
* It reads the sun and fog from the lights block the renderer uploads with every view, so its
|
|
41
|
+
* only upload is the 64-byte params block, written once per frame in `prepare`. The fields are
|
|
42
|
+
* live: mutate `zenith`, `sunSize`, `stars`... and the next frame shows it.
|
|
43
|
+
*
|
|
44
|
+
* Depth: under a depth camera the triangle sits at the far plane with depth compare
|
|
45
|
+
* `less-equal` and no depth write (the test-only state, `DepthMode` 1), so geometry drawn before
|
|
46
|
+
* or after it wins wherever it wrote depth and the sky fills the rest. Without depth (a 2D
|
|
47
|
+
* camera) it paints the whole view; give it the lowest `order` then. Nothing to cull.
|
|
48
|
+
*/
|
|
49
|
+
export declare class Sky implements Drawable {
|
|
50
|
+
/** Linear RGB straight up. Live. */
|
|
51
|
+
readonly zenith: Float32Array<ArrayBuffer>;
|
|
52
|
+
/** Linear RGB at the horizon. Live. */
|
|
53
|
+
readonly horizon: Float32Array<ArrayBuffer>;
|
|
54
|
+
/** Linear RGB below the horizon. Live. */
|
|
55
|
+
readonly ground: Float32Array<ArrayBuffer>;
|
|
56
|
+
/** Angular radius of the sun disc, radians. Live. */
|
|
57
|
+
sunSize: number;
|
|
58
|
+
/** Glow strength around the sun. Live. */
|
|
59
|
+
sunGlow: number;
|
|
60
|
+
/** Starfield settings, or null for no stars. Live (replace or mutate). */
|
|
61
|
+
stars: SkyStars | null;
|
|
62
|
+
/** Multiplier on the whole dome. Live. */
|
|
63
|
+
exposure: number;
|
|
64
|
+
/** Night brightness as a fraction of day (`SkyOptions.ambientFloor`). Live. */
|
|
65
|
+
ambientFloor: number;
|
|
66
|
+
private readonly device;
|
|
67
|
+
private readonly params;
|
|
68
|
+
private readonly paramsBuffer;
|
|
69
|
+
private readonly group;
|
|
70
|
+
private readonly desc;
|
|
71
|
+
private readonly renderer;
|
|
72
|
+
/**
|
|
73
|
+
* Pipelines per depth format (null: none; a depth one tests without writing) × the view
|
|
74
|
+
* target's aux key, built on first use from `renderer.sceneTargets` (ws/render-10).
|
|
75
|
+
*/
|
|
76
|
+
private readonly pipelines;
|
|
77
|
+
constructor(renderer: Renderer, opts?: SkyOptions);
|
|
78
|
+
/**
|
|
79
|
+
* Pack the live fields into the params block (`SKY_PARAMS_FLOATS` floats: zenith rgb +
|
|
80
|
+
* exposure, horizon rgb + sunSize, ground rgb + sunGlow, stars density, seed, enabled,
|
|
81
|
+
* ambientFloor) and
|
|
82
|
+
* upload it. Called by the renderer once per frame. No allocation.
|
|
83
|
+
*/
|
|
84
|
+
prepare(_encoder: GPUCommandEncoder, _frame?: Frame): void;
|
|
85
|
+
/** Draw inside the scene pass: one 3-vertex draw, a depth pipeline when the frame has depth. */
|
|
86
|
+
draw(pass: GPURenderPassEncoder, frame?: Frame): void;
|
|
87
|
+
private pipelineFor;
|
|
88
|
+
destroy(): void;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The world-space view direction through clip point (`nx`, `ny`) (NDC, -1..1, y up) of
|
|
92
|
+
* `camera`, into `out` (normalised): the math the sky shader runs per pixel, from the camera's
|
|
93
|
+
* `projection` and `view` alone. A perspective projection is inverted analytically (its
|
|
94
|
+
* off-centre terms included); an orthographic one gives the camera's forward for every pixel.
|
|
95
|
+
*/
|
|
96
|
+
export declare function skyRay(camera: Camera, nx: number, ny: number, out: Float32Array): Float32Array;
|
package/dist/fx/sky.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { auxSuffix, ScenePipelineCache, sceneVariant } from '../render/scene-pipelines.js';
|
|
2
|
+
import { createShaderModule } from '../render/wgsl.js';
|
|
3
|
+
import { SKY_WGSL } from './sky-wgsl.js';
|
|
4
|
+
/** Floats in the sky's params block (4 × vec4f, 64 bytes). */
|
|
5
|
+
export const SKY_PARAMS_FLOATS = 16;
|
|
6
|
+
const DEFAULT_ZENITH = [0.18, 0.38, 0.85];
|
|
7
|
+
const DEFAULT_HORIZON = [0.62, 0.72, 0.9];
|
|
8
|
+
const DEFAULT_GROUND = [0.22, 0.2, 0.18];
|
|
9
|
+
const DEFAULT_STARS = { density: 24, seed: 0 };
|
|
10
|
+
/**
|
|
11
|
+
* A procedural sky: a gradient dome with a sun disc and glow that follow `frame.lights.sun`,
|
|
12
|
+
* horizon haze towards `frame.lights.fog.color`, and stars once the sun sets. One fullscreen
|
|
13
|
+
* triangle, no asset, no instance; `frame.drawable(sky)` draws it.
|
|
14
|
+
*
|
|
15
|
+
* It reads the sun and fog from the lights block the renderer uploads with every view, so its
|
|
16
|
+
* only upload is the 64-byte params block, written once per frame in `prepare`. The fields are
|
|
17
|
+
* live: mutate `zenith`, `sunSize`, `stars`... and the next frame shows it.
|
|
18
|
+
*
|
|
19
|
+
* Depth: under a depth camera the triangle sits at the far plane with depth compare
|
|
20
|
+
* `less-equal` and no depth write (the test-only state, `DepthMode` 1), so geometry drawn before
|
|
21
|
+
* or after it wins wherever it wrote depth and the sky fills the rest. Without depth (a 2D
|
|
22
|
+
* camera) it paints the whole view; give it the lowest `order` then. Nothing to cull.
|
|
23
|
+
*/
|
|
24
|
+
export class Sky {
|
|
25
|
+
/** Linear RGB straight up. Live. */
|
|
26
|
+
zenith = new Float32Array(3);
|
|
27
|
+
/** Linear RGB at the horizon. Live. */
|
|
28
|
+
horizon = new Float32Array(3);
|
|
29
|
+
/** Linear RGB below the horizon. Live. */
|
|
30
|
+
ground = new Float32Array(3);
|
|
31
|
+
/** Angular radius of the sun disc, radians. Live. */
|
|
32
|
+
sunSize;
|
|
33
|
+
/** Glow strength around the sun. Live. */
|
|
34
|
+
sunGlow;
|
|
35
|
+
/** Starfield settings, or null for no stars. Live (replace or mutate). */
|
|
36
|
+
stars;
|
|
37
|
+
/** Multiplier on the whole dome. Live. */
|
|
38
|
+
exposure;
|
|
39
|
+
/** Night brightness as a fraction of day (`SkyOptions.ambientFloor`). Live. */
|
|
40
|
+
ambientFloor;
|
|
41
|
+
device;
|
|
42
|
+
params;
|
|
43
|
+
paramsBuffer;
|
|
44
|
+
group;
|
|
45
|
+
desc;
|
|
46
|
+
renderer;
|
|
47
|
+
/**
|
|
48
|
+
* Pipelines per depth format (null: none; a depth one tests without writing) × the view
|
|
49
|
+
* target's aux key, built on first use from `renderer.sceneTargets` (ws/render-10).
|
|
50
|
+
*/
|
|
51
|
+
pipelines = new ScenePipelineCache();
|
|
52
|
+
constructor(renderer, opts = {}) {
|
|
53
|
+
const device = renderer.device;
|
|
54
|
+
this.device = device;
|
|
55
|
+
this.renderer = renderer;
|
|
56
|
+
set3(this.zenith, opts.zenith ?? DEFAULT_ZENITH);
|
|
57
|
+
set3(this.horizon, opts.horizon ?? DEFAULT_HORIZON);
|
|
58
|
+
set3(this.ground, opts.ground ?? DEFAULT_GROUND);
|
|
59
|
+
this.sunSize = opts.sunSize ?? 0.03;
|
|
60
|
+
this.sunGlow = opts.sunGlow ?? 1;
|
|
61
|
+
this.exposure = opts.exposure ?? 1;
|
|
62
|
+
this.ambientFloor = opts.ambientFloor ?? 0.06;
|
|
63
|
+
const s = opts.stars;
|
|
64
|
+
this.stars = s
|
|
65
|
+
? {
|
|
66
|
+
density: (s === true ? undefined : s.density) ?? DEFAULT_STARS.density,
|
|
67
|
+
seed: (s === true ? undefined : s.seed) ?? DEFAULT_STARS.seed,
|
|
68
|
+
}
|
|
69
|
+
: null;
|
|
70
|
+
this.params = new Float32Array(SKY_PARAMS_FLOATS);
|
|
71
|
+
this.paramsBuffer = device.createBuffer({
|
|
72
|
+
label: 'sky-params',
|
|
73
|
+
size: this.params.byteLength,
|
|
74
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
75
|
+
});
|
|
76
|
+
const layout = device.createBindGroupLayout({
|
|
77
|
+
label: 'sky-layout',
|
|
78
|
+
entries: [{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: {} }],
|
|
79
|
+
});
|
|
80
|
+
this.group = device.createBindGroup({
|
|
81
|
+
label: 'sky',
|
|
82
|
+
layout,
|
|
83
|
+
entries: [{ binding: 0, resource: { buffer: this.paramsBuffer } }],
|
|
84
|
+
});
|
|
85
|
+
const module = createShaderModule(device, SKY_WGSL, 'sky');
|
|
86
|
+
this.desc = {
|
|
87
|
+
label: 'sky',
|
|
88
|
+
layout: device.createPipelineLayout({ bindGroupLayouts: [renderer.globalsLayout, layout] }),
|
|
89
|
+
vertex: { module, entryPoint: 'vs' },
|
|
90
|
+
fragment: {
|
|
91
|
+
module,
|
|
92
|
+
entryPoint: 'fs',
|
|
93
|
+
targets: renderer.sceneTargets(),
|
|
94
|
+
},
|
|
95
|
+
primitive: { topology: 'triangle-list', cullMode: 'none' },
|
|
96
|
+
};
|
|
97
|
+
this.pipelines.set(null, renderer.target.auxKey, device.createRenderPipeline(this.desc));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Pack the live fields into the params block (`SKY_PARAMS_FLOATS` floats: zenith rgb +
|
|
101
|
+
* exposure, horizon rgb + sunSize, ground rgb + sunGlow, stars density, seed, enabled,
|
|
102
|
+
* ambientFloor) and
|
|
103
|
+
* upload it. Called by the renderer once per frame. No allocation.
|
|
104
|
+
*/
|
|
105
|
+
prepare(_encoder, _frame) {
|
|
106
|
+
const p = this.params;
|
|
107
|
+
p[0] = this.zenith[0];
|
|
108
|
+
p[1] = this.zenith[1];
|
|
109
|
+
p[2] = this.zenith[2];
|
|
110
|
+
p[3] = this.exposure;
|
|
111
|
+
p[4] = this.horizon[0];
|
|
112
|
+
p[5] = this.horizon[1];
|
|
113
|
+
p[6] = this.horizon[2];
|
|
114
|
+
p[7] = this.sunSize;
|
|
115
|
+
p[8] = this.ground[0];
|
|
116
|
+
p[9] = this.ground[1];
|
|
117
|
+
p[10] = this.ground[2];
|
|
118
|
+
p[11] = this.sunGlow;
|
|
119
|
+
const s = this.stars;
|
|
120
|
+
p[12] = s ? s.density : 0;
|
|
121
|
+
p[13] = s ? s.seed : 0;
|
|
122
|
+
p[14] = s ? 1 : 0;
|
|
123
|
+
p[15] = this.ambientFloor;
|
|
124
|
+
this.device.queue.writeBuffer(this.paramsBuffer, 0, p);
|
|
125
|
+
}
|
|
126
|
+
/** Draw inside the scene pass: one 3-vertex draw, a depth pipeline when the frame has depth. */
|
|
127
|
+
draw(pass, frame) {
|
|
128
|
+
const fmt = frame?.depthFormat ?? null;
|
|
129
|
+
pass.setPipeline(this.pipelineFor(fmt, frame ? frame.auxKey : this.renderer.target.auxKey));
|
|
130
|
+
pass.setBindGroup(1, this.group);
|
|
131
|
+
pass.draw(3);
|
|
132
|
+
}
|
|
133
|
+
pipelineFor(format, aux) {
|
|
134
|
+
const p = this.pipelines.get(format, aux);
|
|
135
|
+
if (p)
|
|
136
|
+
return p;
|
|
137
|
+
return this.pipelines.set(format, aux, this.device.createRenderPipeline(sceneVariant(this.desc, this.renderer.sceneTargets(undefined, aux), `sky${format ? `:${format}` : ''}${auxSuffix(aux)}`, format ? { format, depthWriteEnabled: false, depthCompare: 'less-equal' } : undefined)));
|
|
138
|
+
}
|
|
139
|
+
destroy() {
|
|
140
|
+
this.paramsBuffer.destroy();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The world-space view direction through clip point (`nx`, `ny`) (NDC, -1..1, y up) of
|
|
145
|
+
* `camera`, into `out` (normalised): the math the sky shader runs per pixel, from the camera's
|
|
146
|
+
* `projection` and `view` alone. A perspective projection is inverted analytically (its
|
|
147
|
+
* off-centre terms included); an orthographic one gives the camera's forward for every pixel.
|
|
148
|
+
*/
|
|
149
|
+
export function skyRay(camera, nx, ny, out) {
|
|
150
|
+
const p = camera.projection;
|
|
151
|
+
const v = camera.view;
|
|
152
|
+
// Column-major: p[c * 4 + r].
|
|
153
|
+
const p23 = p[11];
|
|
154
|
+
let dx = 0;
|
|
155
|
+
let dy = 0;
|
|
156
|
+
if (p23 !== 0) {
|
|
157
|
+
dx = (p[8] - p23 * nx) / p[0];
|
|
158
|
+
dy = (p[9] - p23 * ny) / p[5];
|
|
159
|
+
}
|
|
160
|
+
// Orthographic: every pixel looks along the camera's forward (+z for the 2D camera).
|
|
161
|
+
const dz = p23 === 0 && p[10] > 0 ? 1 : -1;
|
|
162
|
+
const wx = v[0] * dx + v[1] * dy + v[2] * dz;
|
|
163
|
+
const wy = v[4] * dx + v[5] * dy + v[6] * dz;
|
|
164
|
+
const wz = v[8] * dx + v[9] * dy + v[10] * dz;
|
|
165
|
+
const k = 1 / Math.hypot(wx, wy, wz);
|
|
166
|
+
out[0] = wx * k;
|
|
167
|
+
out[1] = wy * k;
|
|
168
|
+
out[2] = wz * k;
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
function set3(out, v) {
|
|
172
|
+
out[0] = v[0] ?? 0;
|
|
173
|
+
out[1] = v[1] ?? 0;
|
|
174
|
+
out[2] = v[2] ?? 0;
|
|
175
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A canvas text atlas: strings rasterised once with `CanvasRenderingContext2D.fillText` into
|
|
3
|
+
* one square canvas, packed on shelves, cached by text and style, with least-recently-used
|
|
4
|
+
* eviction when the canvas is full. No GPU and no DOM beyond the canvas itself: the owner
|
|
5
|
+
* uploads `canvas` when `dirty` is set (`Billboards` does it once per frame at most).
|
|
6
|
+
*/
|
|
7
|
+
/** How a string is drawn into the atlas. Colours are CSS colour strings (the canvas's). */
|
|
8
|
+
export interface TextStyle {
|
|
9
|
+
/** CSS font family (and weight), e.g. `'bold sans-serif'`. Default: the atlas's font. */
|
|
10
|
+
font?: string;
|
|
11
|
+
/** Font size in atlas px. Default 32. */
|
|
12
|
+
size?: number;
|
|
13
|
+
/** Fill colour. Default `'#fff'`. */
|
|
14
|
+
color?: string;
|
|
15
|
+
/** Outline colour; none when unset. */
|
|
16
|
+
stroke?: string;
|
|
17
|
+
/** Outline width in atlas px. Default 0 (none even with `stroke`). */
|
|
18
|
+
strokeWidth?: number;
|
|
19
|
+
/** Transparent px kept around the glyphs on every side. Default 2. */
|
|
20
|
+
padding?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A rectangle of the atlas: the uv rect to sample (`u0, v0` top left, `u1, v1` bottom right, v
|
|
24
|
+
* down as in the canvas) and its size in atlas px, for a billboard's aspect ratio.
|
|
25
|
+
*/
|
|
26
|
+
export interface AtlasRegion {
|
|
27
|
+
u0: number;
|
|
28
|
+
v0: number;
|
|
29
|
+
u1: number;
|
|
30
|
+
v1: number;
|
|
31
|
+
/** Size in atlas px. */
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
}
|
|
35
|
+
/** The subset of the canvas 2D context the atlas draws with (so tests can stub it). */
|
|
36
|
+
export interface AtlasContext2D {
|
|
37
|
+
font: string;
|
|
38
|
+
textBaseline: CanvasTextBaseline;
|
|
39
|
+
textAlign: CanvasTextAlign;
|
|
40
|
+
fillStyle: string | CanvasGradient | CanvasPattern;
|
|
41
|
+
strokeStyle: string | CanvasGradient | CanvasPattern;
|
|
42
|
+
lineWidth: number;
|
|
43
|
+
lineJoin: CanvasLineJoin;
|
|
44
|
+
measureText(text: string): {
|
|
45
|
+
width: number;
|
|
46
|
+
};
|
|
47
|
+
fillText(text: string, x: number, y: number): void;
|
|
48
|
+
strokeText(text: string, x: number, y: number): void;
|
|
49
|
+
clearRect(x: number, y: number, w: number, h: number): void;
|
|
50
|
+
}
|
|
51
|
+
/** The canvas the atlas draws into: an `OffscreenCanvas`, an `HTMLCanvasElement` or a stub. */
|
|
52
|
+
export interface AtlasCanvas {
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
getContext(kind: '2d'): AtlasContext2D | null;
|
|
56
|
+
}
|
|
57
|
+
export interface TextAtlasOptions {
|
|
58
|
+
/** Canvas side in px (square). Default 1024. */
|
|
59
|
+
size?: number;
|
|
60
|
+
/** Default font family for styles without one. Default `'sans-serif'`. */
|
|
61
|
+
font?: string;
|
|
62
|
+
/**
|
|
63
|
+
* The canvas to draw into. Default: an `OffscreenCanvas` when the platform has one, else a
|
|
64
|
+
* `document.createElement('canvas')`. Tests pass a stub with a fake 2D context.
|
|
65
|
+
*/
|
|
66
|
+
canvas?: AtlasCanvas;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Text rendered once into a canvas and shared by every quad that shows it. `text(text, style)`
|
|
70
|
+
* returns the cached `AtlasRegion` or rasterises and packs a new one; when the canvas is full the
|
|
71
|
+
* least recently used shelf is cleared and reused. Read `dirty` and `canvas` to upload, then
|
|
72
|
+
* call `markUploaded()`.
|
|
73
|
+
*/
|
|
74
|
+
export declare class TextAtlas {
|
|
75
|
+
readonly size: number;
|
|
76
|
+
readonly canvas: AtlasCanvas;
|
|
77
|
+
/** The canvas has text the GPU has not seen yet. */
|
|
78
|
+
dirty: boolean;
|
|
79
|
+
/** Strings currently cached. */
|
|
80
|
+
count: number;
|
|
81
|
+
/** Evictions so far (shelves cleared because the canvas was full). */
|
|
82
|
+
evictions: number;
|
|
83
|
+
private readonly ctx;
|
|
84
|
+
private readonly font;
|
|
85
|
+
private readonly cache;
|
|
86
|
+
private readonly shelves;
|
|
87
|
+
/** Next free y for a new shelf. */
|
|
88
|
+
private top;
|
|
89
|
+
private tick;
|
|
90
|
+
/** Owned cells made so far (their cache keys). */
|
|
91
|
+
private cells;
|
|
92
|
+
constructor(opts?: TextAtlasOptions);
|
|
93
|
+
/** Atlas px in use, as a share of the canvas (shelf area, 0..1). */
|
|
94
|
+
get used(): number;
|
|
95
|
+
/**
|
|
96
|
+
* The region for `text` in `style`: cached, or rasterised now. Returns `null` only when the
|
|
97
|
+
* string is wider or taller than the whole canvas.
|
|
98
|
+
*/
|
|
99
|
+
text(text: string, style?: TextStyle): AtlasRegion | null;
|
|
100
|
+
/**
|
|
101
|
+
* An **owned** cell for text that changes (ws/fx-4): not shared through the cache, its width
|
|
102
|
+
* rounded up for headroom, the region covering the whole cell with `text` centred in it.
|
|
103
|
+
* Change its text with `rewrite`; `release` it when done. Evicted like any string when the
|
|
104
|
+
* canvas is full and it is the least recently used (`touch` keeps it). Returns `null` only
|
|
105
|
+
* when the text is larger than the whole canvas.
|
|
106
|
+
*/
|
|
107
|
+
cell(text: string, style?: TextStyle): AtlasRegion | null;
|
|
108
|
+
/** The size in atlas px `cell(text, style)` would get, without placing anything. */
|
|
109
|
+
cellSize(text: string, style?: TextStyle): {
|
|
110
|
+
width: number;
|
|
111
|
+
height: number;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Redraw an owned cell with `text`, in place (the same region object, nothing allocated) when
|
|
115
|
+
* it fits the cell, else in a new wider cell (the old one released). Also a new cell when
|
|
116
|
+
* `cell` was evicted since. Returns `null` when the text is larger than the whole canvas.
|
|
117
|
+
*/
|
|
118
|
+
rewrite(cell: AtlasRegion, text: string): AtlasRegion | null;
|
|
119
|
+
/** Give back an owned cell (a no-op for a cached string or one already released/evicted). */
|
|
120
|
+
release(cell: AtlasRegion): void;
|
|
121
|
+
/** Mark `region` as used now, so a live quad's text is not the first evicted. */
|
|
122
|
+
touch(region: AtlasRegion): void;
|
|
123
|
+
/** Is `region` still what it was made for (not evicted since)? */
|
|
124
|
+
has(region: AtlasRegion): boolean;
|
|
125
|
+
/** The owner uploaded `canvas`. */
|
|
126
|
+
markUploaded(): void;
|
|
127
|
+
/** Forget every string and clear the canvas. */
|
|
128
|
+
clear(): void;
|
|
129
|
+
private resolve;
|
|
130
|
+
private measure;
|
|
131
|
+
private lineHeight;
|
|
132
|
+
private makeCell;
|
|
133
|
+
/** Place, size and cache a `w × h` entry under `key`. */
|
|
134
|
+
private make;
|
|
135
|
+
/** Clear `e`'s rect and draw `text` centred in it. */
|
|
136
|
+
private draw;
|
|
137
|
+
/** Find or make room for a `w × h` rect: a fitting shelf, a new shelf, or an evicted one. */
|
|
138
|
+
private place;
|
|
139
|
+
private fit;
|
|
140
|
+
private alloc;
|
|
141
|
+
private evict;
|
|
142
|
+
private recycle;
|
|
143
|
+
}
|