@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,528 @@
|
|
|
1
|
+
import { BUFFER_BINDING_BASE } from './bindings.js';
|
|
2
|
+
import { reportGpuError } from './diagnostics.js';
|
|
3
|
+
import { VERTEX_LAYOUT_2D } from './mesh.js';
|
|
4
|
+
/**
|
|
5
|
+
* Create a shader module and surface compile errors with file/line context. Compilation is
|
|
6
|
+
* async in the browser; errors are logged as soon as they are known.
|
|
7
|
+
*/
|
|
8
|
+
export function createShaderModule(device, code, label) {
|
|
9
|
+
const module = device.createShaderModule({ code, label });
|
|
10
|
+
module.getCompilationInfo().then((info) => {
|
|
11
|
+
if (!info.messages.length)
|
|
12
|
+
return;
|
|
13
|
+
const lines = code.split('\n');
|
|
14
|
+
for (const m of info.messages) {
|
|
15
|
+
const src = lines[m.lineNum - 1] ?? '';
|
|
16
|
+
const caret = `${' '.repeat(Math.max(0, m.linePos - 1))}^`;
|
|
17
|
+
const text = `[wgsl] ${label}:${m.lineNum}:${m.linePos} ${m.type}: ${m.message}\n ${src}\n ${caret}`;
|
|
18
|
+
if (m.type === 'error')
|
|
19
|
+
reportGpuError(text);
|
|
20
|
+
else
|
|
21
|
+
console.warn(text);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return module;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Per-frame engine bindings for every material and drawable, in `@group(0)`:
|
|
28
|
+
*
|
|
29
|
+
* - `@binding(0) globals`: `logicalSize`, `targetSize` (scene target px), `time`, `dt`.
|
|
30
|
+
* - `@binding(1) camera` (the camera block): `view`, `proj`, `view_proj` (world → clip),
|
|
31
|
+
* `camera_pos` (world eye position, w = 1), `viewport` (target px: x, y, w, h),
|
|
32
|
+
* `view_index` (`camera.viewIndex`: 0, or the eye index of an XR view), `inv_view_proj`
|
|
33
|
+
* (clip → world, the inverse of `view_proj`; `camera.invViewProj` on the CPU side),
|
|
34
|
+
* `prev_view_proj` and `prev_view` (last frame's unjittered `view_proj` and `view`) and
|
|
35
|
+
* `jitter` (clip-space dx, dy; the pixel offset x, y).
|
|
36
|
+
*/
|
|
37
|
+
export const WGSL_GLOBALS = /* wgsl */ `
|
|
38
|
+
struct EngineGlobals {
|
|
39
|
+
logicalSize: vec2f,
|
|
40
|
+
targetSize: vec2f,
|
|
41
|
+
time: f32,
|
|
42
|
+
dt: f32,
|
|
43
|
+
_pad: vec2f,
|
|
44
|
+
};
|
|
45
|
+
@group(0) @binding(0) var<uniform> globals: EngineGlobals;
|
|
46
|
+
struct EngineCamera {
|
|
47
|
+
view: mat4x4f,
|
|
48
|
+
proj: mat4x4f,
|
|
49
|
+
view_proj: mat4x4f,
|
|
50
|
+
camera_pos: vec4f,
|
|
51
|
+
viewport: vec4f,
|
|
52
|
+
view_index: u32,
|
|
53
|
+
_pad0: u32, _pad1: u32, _pad2: u32,
|
|
54
|
+
inv_view_proj: mat4x4f,
|
|
55
|
+
prev_view_proj: mat4x4f,
|
|
56
|
+
prev_view: mat4x4f,
|
|
57
|
+
jitter: vec4f,
|
|
58
|
+
};
|
|
59
|
+
@group(0) @binding(1) var<uniform> camera: EngineCamera;
|
|
60
|
+
`;
|
|
61
|
+
/**
|
|
62
|
+
* The Lambert BRDF for `wgslLightLoop`: `N·L` clamped at 0, the reflected fraction of a light's
|
|
63
|
+
* colour before the albedo (the light's colour × this is what `engine_lambert` returns per light).
|
|
64
|
+
*/
|
|
65
|
+
export const WGSL_LAMBERT_BRDF = 'vec3f(max(dot(normal, l), 0.0))';
|
|
66
|
+
/**
|
|
67
|
+
* Generate the engine light loop as a WGSL function `name(world_pos: vec3f, normal: vec3f,
|
|
68
|
+
* layer_mask: u32${params}) -> vec3f`: the sum over the lights whose `layers` share a bit with
|
|
69
|
+
* `layer_mask` of the light's colour × its attenuation × `brdf`. The sun (× `engine_shadow`),
|
|
70
|
+
* the `(1 - d/radius)²` point falloff and the spot cone (`engine_spot_cone` × the same falloff)
|
|
71
|
+
* are the loop's; the BRDF is the material's.
|
|
72
|
+
*
|
|
73
|
+
* WGSL has no function pointers, so the material supplies `brdf` as a WGSL expression that the
|
|
74
|
+
* loop body inlines once per light kind. In it, `l` is the unit direction from the surface to
|
|
75
|
+
* the light, `normal` and `world_pos` are the function's parameters and `params` (`', v: vec3f,
|
|
76
|
+
* f0: vec3f'` and so on; leading comma) adds whatever else it needs to the signature. The
|
|
77
|
+
* expression must be finite for any `l` (it is multiplied by 0 for lights that do not reach).
|
|
78
|
+
* `WGSL_LIGHTS` instantiates it as `engine_light_accum` with `WGSL_LAMBERT_BRDF`; `WGSL_PBR` as
|
|
79
|
+
* `engine_pbr_accum` with `engine_brdf(...)`. Generate rather than copy: the loop then changes
|
|
80
|
+
* in one place when the block gains a light kind.
|
|
81
|
+
*/
|
|
82
|
+
export function wgslLightLoop(name, brdf, params = '') {
|
|
83
|
+
return /* wgsl */ `fn ${name}(world_pos: vec3f, normal: vec3f, layer_mask: u32${params}) -> vec3f {
|
|
84
|
+
var sum = vec3f(0.0);
|
|
85
|
+
if ((lights.sun_layers & layer_mask) != 0u) {
|
|
86
|
+
let l = -lights.sun_dir;
|
|
87
|
+
sum += lights.sun_color * (${brdf}) * engine_shadow(world_pos);
|
|
88
|
+
}
|
|
89
|
+
for (var i = 0u; i < lights.point_count; i++) {
|
|
90
|
+
if ((lights.point_layers[i >> 2u][i & 3u] & layer_mask) == 0u) { continue; }
|
|
91
|
+
let light = lights.points[i];
|
|
92
|
+
let to = light.position - world_pos;
|
|
93
|
+
let d = length(to);
|
|
94
|
+
let falloff = saturate(1.0 - d / max(light.radius, 1e-4));
|
|
95
|
+
if (falloff <= 0.0) { continue; }
|
|
96
|
+
let l = to / max(d, 1e-4);
|
|
97
|
+
sum += light.color * (falloff * falloff * (${brdf}));
|
|
98
|
+
}
|
|
99
|
+
for (var i = 0u; i < lights.spot_count; i++) {
|
|
100
|
+
let light = lights.spots[i];
|
|
101
|
+
if ((light.layers & layer_mask) == 0u) { continue; }
|
|
102
|
+
let to = light.position - world_pos;
|
|
103
|
+
let d = length(to);
|
|
104
|
+
let l = to / max(d, 1e-4);
|
|
105
|
+
let falloff = saturate(1.0 - d / max(light.radius, 1e-4));
|
|
106
|
+
if (falloff <= 0.0) { continue; }
|
|
107
|
+
let cone = engine_spot_cone(dot(-l, light.direction), light.cos_outer, light.cos_inner);
|
|
108
|
+
sum += light.color * (falloff * falloff * cone * (${brdf}));
|
|
109
|
+
}
|
|
110
|
+
return sum;
|
|
111
|
+
}`;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The lighting block, `@group(0) @binding(2)` (see `Lights` / `lights.ts`), in every material
|
|
115
|
+
* and drawable prelude: `lights.ambient`, `lights.point_count`, `lights.sun_dir` (the way
|
|
116
|
+
* the light travels), `lights.sun_color`, `lights.points[i]` (`position`, `radius`, `color`),
|
|
117
|
+
* `lights.sun_view_proj` (world → sun clip), `lights.shadow_params` (bias, map texel size,
|
|
118
|
+
* enabled, pad), `lights.fog` (rgb, density), `lights.fog_range` (near, far, pad, pad),
|
|
119
|
+
* `lights.spot_count`, `lights.sun_layers` (the sun's layer mask), `lights.point_layers`
|
|
120
|
+
* (`array<vec4u, 4>`: the mask of point `i` is `point_layers[i >> 2u][i & 3u]`) and
|
|
121
|
+
* `lights.spots[i]` (`position`, `radius`, `direction`, `cos_outer`, `color`, `cos_inner`,
|
|
122
|
+
* `layers`). The sun's shadow map (`texture_depth_2d`) and its comparison sampler sit at
|
|
123
|
+
* `@binding(3)` and `@binding(4)`; with no shadow pass a 1×1 depth texture is bound there.
|
|
124
|
+
*
|
|
125
|
+
* Helpers a game may call or ignore: `engine_point_lights(normal, world_pos)` sums the point
|
|
126
|
+
* lights' diffuse (Lambert × a smooth falloff that reaches zero at `radius`), all layers;
|
|
127
|
+
* `engine_spot_cone(cos_theta, cos_outer, cos_inner)` is a spot's cone factor;
|
|
128
|
+
* `engine_instance_layers(flags)` is the instance's layer bits from `VSOut.flags`;
|
|
129
|
+
* `engine_light_accum(world_pos, normal, layer_mask)` sums the sun (× `engine_shadow`), point
|
|
130
|
+
* and spot Lambert terms of every light whose `layers` share a bit with `layer_mask`;
|
|
131
|
+
* `engine_shadow(world_pos)` is the sun's visibility, 0..1 (3×3 PCF over the shadow map; 1
|
|
132
|
+
* outside the map or when there is no shadow pass); `engine_fog(color, world_pos)` blends
|
|
133
|
+
* `color` toward the fog colour by the distance to the camera (linear over `fog_range` when
|
|
134
|
+
* `far > near`, else exponential past `near`; identity when density is 0);
|
|
135
|
+
* `engine_lambert(normal, world_pos)` is ambient + `engine_light_accum` over every layer, so
|
|
136
|
+
* with the default block it returns `vec3f(1.0)` and `albedo * engine_lambert(...)` is unlit;
|
|
137
|
+
* `engine_lambert_layers(normal, world_pos, layer_mask)` is the same against the instance's
|
|
138
|
+
* layers (`engine_instance_layers(in.flags)`), so masked lights skip it.
|
|
139
|
+
*
|
|
140
|
+
* `engine_light_accum` is `wgslLightLoop('engine_light_accum', WGSL_LAMBERT_BRDF)`: the one
|
|
141
|
+
* light loop, generated with a Lambert BRDF; `WGSL_PBR` generates the same loop with its GGX BRDF.
|
|
142
|
+
*/
|
|
143
|
+
export const WGSL_LIGHTS = /* wgsl */ `
|
|
144
|
+
struct EnginePointLight {
|
|
145
|
+
position: vec3f,
|
|
146
|
+
radius: f32,
|
|
147
|
+
color: vec3f,
|
|
148
|
+
_pad: f32,
|
|
149
|
+
};
|
|
150
|
+
struct EngineSpotLight {
|
|
151
|
+
position: vec3f,
|
|
152
|
+
radius: f32,
|
|
153
|
+
direction: vec3f,
|
|
154
|
+
cos_outer: f32,
|
|
155
|
+
color: vec3f,
|
|
156
|
+
cos_inner: f32,
|
|
157
|
+
layers: u32,
|
|
158
|
+
_pad0: u32,
|
|
159
|
+
_pad1: u32,
|
|
160
|
+
_pad2: u32,
|
|
161
|
+
};
|
|
162
|
+
struct EngineLights {
|
|
163
|
+
ambient: vec3f,
|
|
164
|
+
point_count: u32,
|
|
165
|
+
sun_dir: vec3f,
|
|
166
|
+
_pad0: f32,
|
|
167
|
+
sun_color: vec3f,
|
|
168
|
+
_pad1: f32,
|
|
169
|
+
points: array<EnginePointLight, 16>,
|
|
170
|
+
sun_view_proj: mat4x4f,
|
|
171
|
+
shadow_params: vec4f,
|
|
172
|
+
fog: vec4f,
|
|
173
|
+
fog_range: vec4f,
|
|
174
|
+
spot_count: u32,
|
|
175
|
+
sun_layers: u32,
|
|
176
|
+
_pad2: vec2u,
|
|
177
|
+
point_layers: array<vec4u, 4>,
|
|
178
|
+
spots: array<EngineSpotLight, 8>,
|
|
179
|
+
};
|
|
180
|
+
@group(0) @binding(2) var<uniform> lights: EngineLights;
|
|
181
|
+
@group(0) @binding(3) var engine_shadow_map: texture_depth_2d;
|
|
182
|
+
@group(0) @binding(4) var engine_shadow_sampler: sampler_comparison;
|
|
183
|
+
fn engine_point_lights(normal: vec3f, world_pos: vec3f) -> vec3f {
|
|
184
|
+
var sum = vec3f(0.0);
|
|
185
|
+
for (var i = 0u; i < lights.point_count; i++) {
|
|
186
|
+
let l = lights.points[i];
|
|
187
|
+
let to = l.position - world_pos;
|
|
188
|
+
let d = length(to);
|
|
189
|
+
let falloff = saturate(1.0 - d / max(l.radius, 1e-4));
|
|
190
|
+
let diffuse = max(dot(normal, to / max(d, 1e-4)), 0.0);
|
|
191
|
+
sum += l.color * (falloff * falloff * diffuse);
|
|
192
|
+
}
|
|
193
|
+
return sum;
|
|
194
|
+
}
|
|
195
|
+
fn engine_shadow(world_pos: vec3f) -> f32 {
|
|
196
|
+
if (lights.shadow_params.z == 0.0) { return 1.0; }
|
|
197
|
+
let clip = lights.sun_view_proj * vec4f(world_pos, 1.0);
|
|
198
|
+
let ndc = clip.xyz / clip.w;
|
|
199
|
+
if (any(abs(ndc.xy) > vec2f(1.0)) || ndc.z < 0.0 || ndc.z > 1.0) { return 1.0; }
|
|
200
|
+
let uv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
|
201
|
+
let depth = ndc.z - lights.shadow_params.x;
|
|
202
|
+
let texel = lights.shadow_params.y;
|
|
203
|
+
var lit = 0.0;
|
|
204
|
+
for (var y = -1; y <= 1; y++) {
|
|
205
|
+
for (var x = -1; x <= 1; x++) {
|
|
206
|
+
let o = vec2f(f32(x), f32(y)) * texel;
|
|
207
|
+
lit += textureSampleCompareLevel(engine_shadow_map, engine_shadow_sampler, uv + o, depth);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return lit / 9.0;
|
|
211
|
+
}
|
|
212
|
+
fn engine_fog(color: vec3f, world_pos: vec3f) -> vec3f {
|
|
213
|
+
let density = lights.fog.w;
|
|
214
|
+
if (density == 0.0) { return color; }
|
|
215
|
+
let d = distance(world_pos, camera.camera_pos.xyz);
|
|
216
|
+
let near = lights.fog_range.x;
|
|
217
|
+
let far = lights.fog_range.y;
|
|
218
|
+
let linear = saturate((d - near) / max(far - near, 1e-4)) * saturate(density);
|
|
219
|
+
let expo = 1.0 - exp(-density * max(d - near, 0.0));
|
|
220
|
+
let f = select(expo, linear, far > near);
|
|
221
|
+
return mix(color, lights.fog.rgb, f);
|
|
222
|
+
}
|
|
223
|
+
fn engine_spot_cone(cos_theta: f32, cos_outer: f32, cos_inner: f32) -> f32 {
|
|
224
|
+
let t = saturate((cos_theta - cos_outer) / max(cos_inner - cos_outer, 1e-4));
|
|
225
|
+
return t * t * (3.0 - 2.0 * t);
|
|
226
|
+
}
|
|
227
|
+
fn engine_instance_layers(flags: u32) -> u32 {
|
|
228
|
+
return flags >> 1u;
|
|
229
|
+
}
|
|
230
|
+
${wgslLightLoop('engine_light_accum', WGSL_LAMBERT_BRDF)}
|
|
231
|
+
fn engine_lambert_layers(normal: vec3f, world_pos: vec3f, layer_mask: u32) -> vec3f {
|
|
232
|
+
return lights.ambient + engine_light_accum(world_pos, normal, layer_mask);
|
|
233
|
+
}
|
|
234
|
+
fn engine_lambert(normal: vec3f, world_pos: vec3f) -> vec3f {
|
|
235
|
+
return engine_lambert_layers(normal, world_pos, 0xffffffffu);
|
|
236
|
+
}
|
|
237
|
+
`;
|
|
238
|
+
/** Hash / value-noise / fbm helpers available to every material and fullscreen pass. */
|
|
239
|
+
export const WGSL_NOISE = /* wgsl */ `
|
|
240
|
+
fn engine_hash21(p: vec2f) -> f32 {
|
|
241
|
+
var p3 = fract(vec3f(p.x, p.y, p.x) * 0.1031);
|
|
242
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
243
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
244
|
+
}
|
|
245
|
+
fn engine_hash22(p: vec2f) -> vec2f {
|
|
246
|
+
var p3 = fract(vec3f(p.x, p.y, p.x) * vec3f(0.1031, 0.1030, 0.0973));
|
|
247
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
248
|
+
return fract((p3.xx + p3.yz) * p3.zy);
|
|
249
|
+
}
|
|
250
|
+
fn engine_noise(p: vec2f) -> f32 {
|
|
251
|
+
let i = floor(p);
|
|
252
|
+
let f = fract(p);
|
|
253
|
+
let u = f * f * (3.0 - 2.0 * f);
|
|
254
|
+
let a = engine_hash21(i);
|
|
255
|
+
let b = engine_hash21(i + vec2f(1.0, 0.0));
|
|
256
|
+
let c = engine_hash21(i + vec2f(0.0, 1.0));
|
|
257
|
+
let d = engine_hash21(i + vec2f(1.0, 1.0));
|
|
258
|
+
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
|
|
259
|
+
}
|
|
260
|
+
fn engine_fbm(p: vec2f, octaves: i32) -> f32 {
|
|
261
|
+
var v = 0.0;
|
|
262
|
+
var amp = 0.5;
|
|
263
|
+
var q = p;
|
|
264
|
+
for (var i = 0; i < octaves; i++) {
|
|
265
|
+
v += amp * engine_noise(q);
|
|
266
|
+
q = q * 2.03 + vec2f(17.1, 9.2);
|
|
267
|
+
amp *= 0.5;
|
|
268
|
+
}
|
|
269
|
+
return v;
|
|
270
|
+
}
|
|
271
|
+
fn engine_luma(c: vec3f) -> f32 {
|
|
272
|
+
return dot(c, vec3f(0.2126, 0.7152, 0.0722));
|
|
273
|
+
}
|
|
274
|
+
`;
|
|
275
|
+
/** The `SkinPalette` binding inside the material's group: `@group(1) @binding(16)`. */
|
|
276
|
+
export const SKIN_PALETTE_BINDING = BUFFER_BINDING_BASE;
|
|
277
|
+
/**
|
|
278
|
+
* GPU skinning, emitted by `materialPrelude` for a layout with `skinned: true` (after
|
|
279
|
+
* `VertexIn`, which it reads). The palette is the material's storage buffer slot 0
|
|
280
|
+
* (`SkinPalette.buffer` passed as `buffers: [palette.buffer]`): a header (`joints` per
|
|
281
|
+
* instance, `instances`, `history`) and `rows`, three `vec4f` rows per joint (row-major 3×4, the layout
|
|
282
|
+
* `anim`'s `skinMatrices` writes), instance after instance. `engine_skin(v, position, normal)`
|
|
283
|
+
* sums the four weighted joint matrices of the vertex (`v.joints`, `v.weights`) for the
|
|
284
|
+
* instance's palette slot `u32(v.params.w)` and applies them to an object-space position and
|
|
285
|
+
* normal, before the instance matrix. A weight of 0 skips the fetch.
|
|
286
|
+
*/
|
|
287
|
+
export const WGSL_SKIN = /* wgsl */ `struct EngineSkinPalette {
|
|
288
|
+
joints: u32,
|
|
289
|
+
instances: u32,
|
|
290
|
+
history: u32,
|
|
291
|
+
_pad1: u32,
|
|
292
|
+
rows: array<vec4f>,
|
|
293
|
+
};
|
|
294
|
+
@group(1) @binding(${SKIN_PALETTE_BINDING}) var<storage, read> engine_skin_palette: EngineSkinPalette;
|
|
295
|
+
struct EngineSkinned {
|
|
296
|
+
position: vec3f,
|
|
297
|
+
normal: vec3f,
|
|
298
|
+
};
|
|
299
|
+
fn engine_skin(v: VertexIn, position: vec3f, normal: vec3f) -> EngineSkinned {
|
|
300
|
+
let base = u32(v.params.w) * engine_skin_palette.joints * 3u;
|
|
301
|
+
let p = vec4f(position, 1.0);
|
|
302
|
+
var skinned: EngineSkinned;
|
|
303
|
+
skinned.position = vec3f(0.0);
|
|
304
|
+
skinned.normal = vec3f(0.0);
|
|
305
|
+
for (var k = 0u; k < 4u; k++) {
|
|
306
|
+
let w = v.weights[k];
|
|
307
|
+
if (w == 0.0) { continue; }
|
|
308
|
+
let r = base + v.joints[k] * 3u;
|
|
309
|
+
let r0 = engine_skin_palette.rows[r];
|
|
310
|
+
let r1 = engine_skin_palette.rows[r + 1u];
|
|
311
|
+
let r2 = engine_skin_palette.rows[r + 2u];
|
|
312
|
+
skinned.position += w * vec3f(dot(r0, p), dot(r1, p), dot(r2, p));
|
|
313
|
+
skinned.normal += w * vec3f(dot(r0.xyz, normal), dot(r1.xyz, normal), dot(r2.xyz, normal));
|
|
314
|
+
}
|
|
315
|
+
return skinned;
|
|
316
|
+
}
|
|
317
|
+
// The previous frame's skinned position from the palette's history block (SkinPalette
|
|
318
|
+
// with history), w = 1; w = 0 when the palette keeps none (velocity reads zero).
|
|
319
|
+
fn engine_skin_previous(v: VertexIn, position: vec3f) -> vec4f {
|
|
320
|
+
if (engine_skin_palette.history == 0u) { return vec4f(0.0); }
|
|
321
|
+
let base = (engine_skin_palette.instances + u32(v.params.w)) * engine_skin_palette.joints * 3u;
|
|
322
|
+
let p = vec4f(position, 1.0);
|
|
323
|
+
var out = vec3f(0.0);
|
|
324
|
+
for (var k = 0u; k < 4u; k++) {
|
|
325
|
+
let w = v.weights[k];
|
|
326
|
+
if (w == 0.0) { continue; }
|
|
327
|
+
let r = base + v.joints[k] * 3u;
|
|
328
|
+
out += w * vec3f(dot(engine_skin_palette.rows[r], p), dot(engine_skin_palette.rows[r + 1u], p), dot(engine_skin_palette.rows[r + 2u], p));
|
|
329
|
+
}
|
|
330
|
+
return vec4f(out, 1.0);
|
|
331
|
+
}`;
|
|
332
|
+
/** The plain variant: what every material compiled with before aux targets. */
|
|
333
|
+
export const PLAIN_VARIANT = Object.freeze({});
|
|
334
|
+
/**
|
|
335
|
+
* Three vertex locations in 10..15 the layout's attributes leave free, for the previous-matrix
|
|
336
|
+
* lane (`prevLane`), as `[p0, p1, p2]`.
|
|
337
|
+
*/
|
|
338
|
+
export function prevLaneLocations(layout) {
|
|
339
|
+
const used = new Set();
|
|
340
|
+
for (const a of layout.buffer.attributes)
|
|
341
|
+
used.add(a.shaderLocation);
|
|
342
|
+
const out = [];
|
|
343
|
+
for (let loc = 10; loc <= 15 && out.length < 3; loc++)
|
|
344
|
+
if (!used.has(loc))
|
|
345
|
+
out.push(loc);
|
|
346
|
+
if (out.length < 3)
|
|
347
|
+
throw new Error(`layout ${layout.name}: no free locations for a previous-matrix lane`);
|
|
348
|
+
return [out[0], out[1], out[2]];
|
|
349
|
+
}
|
|
350
|
+
/** The previous-matrix vertex buffer layout (slot 2) for `layout`: 48 bytes per instance. */
|
|
351
|
+
export function prevLaneBufferLayout(layout) {
|
|
352
|
+
let lane = laneLayouts.get(layout);
|
|
353
|
+
if (lane)
|
|
354
|
+
return lane;
|
|
355
|
+
const [a, b, c] = prevLaneLocations(layout);
|
|
356
|
+
lane = {
|
|
357
|
+
arrayStride: 48,
|
|
358
|
+
stepMode: 'instance',
|
|
359
|
+
attributes: [
|
|
360
|
+
{ shaderLocation: a, offset: 0, format: 'float32x4' },
|
|
361
|
+
{ shaderLocation: b, offset: 16, format: 'float32x4' },
|
|
362
|
+
{ shaderLocation: c, offset: 32, format: 'float32x4' },
|
|
363
|
+
],
|
|
364
|
+
};
|
|
365
|
+
laneLayouts.set(layout, lane);
|
|
366
|
+
return lane;
|
|
367
|
+
}
|
|
368
|
+
const laneLayouts = new WeakMap();
|
|
369
|
+
/**
|
|
370
|
+
* Prelude prepended to every material, generated per vertex layout (and `PreludeVariant`).
|
|
371
|
+
* Declares `VertexIn` (the layout's vertex fields plus the 28-float instance: 3×4 world matrix
|
|
372
|
+
* rows `m0..m2`, `uvRect`, `tint`, `params`, `misc` = emissive, flags, size.xy), the default
|
|
373
|
+
* vertex entry `vs_main`, the `VSOut` varyings (`flags` is the instance's flag bits: bit 0 set
|
|
374
|
+
* means `receiveShadow: false`, bits 1..23 are its layers; `tangent` the world-space file
|
|
375
|
+
* tangent, w = 0 without one; `uv1` the second uv set, `uv` without one) and the `FragOut` MRT
|
|
376
|
+
* struct.
|
|
377
|
+
*
|
|
378
|
+
* Helpers: `engine_local_position(v)` / `engine_local_normal(v)` / `engine_local_tangent(v)`
|
|
379
|
+
* (object space; skinned for a `skinned` layout), `engine_world_position(v)`,
|
|
380
|
+
* `engine_previous_world_position(v)` (last frame's, `vec4f`, w = 0 when unknown),
|
|
381
|
+
* `engine_vertex(v)`, `engine_velocity(in)` (screen-space uv motion since last frame, zero
|
|
382
|
+
* without a velocity target) and `engine_write_aux(&o, rough_metal, velocity)` (fills the
|
|
383
|
+
* target's aux outputs, a no-op without them); the lighting block and `engine_lambert` /
|
|
384
|
+
* `engine_point_lights` from `WGSL_LIGHTS`; `WGSL_SKIN` (`engine_skin`, the palette binding)
|
|
385
|
+
* for a skinned layout only. The text for the 2D and 3D layouts does not change with skinning
|
|
386
|
+
* (E-008).
|
|
387
|
+
*/
|
|
388
|
+
export function materialPrelude(layout, variant = PLAIN_VARIANT) {
|
|
389
|
+
const velocity = variant.velocity === true;
|
|
390
|
+
const prevLane = variant.prevLane === true;
|
|
391
|
+
const roughMetal = variant.roughMetal === true;
|
|
392
|
+
let auxFields = '';
|
|
393
|
+
let auxLoc = 2;
|
|
394
|
+
if (roughMetal)
|
|
395
|
+
auxFields += `\n @location(${auxLoc++}) rough_metal: vec2f,`;
|
|
396
|
+
if (velocity)
|
|
397
|
+
auxFields += `\n @location(${auxLoc++}) velocity: vec2f,`;
|
|
398
|
+
let laneFields = '';
|
|
399
|
+
if (prevLane) {
|
|
400
|
+
const [a, b, c] = prevLaneLocations(layout);
|
|
401
|
+
laneFields = `\n @location(${a}) p0: vec4f,\n @location(${b}) p1: vec4f,\n @location(${c}) p2: vec4f,`;
|
|
402
|
+
}
|
|
403
|
+
const prevRows = prevLane ? 'v.p0, v.p1, v.p2' : 'v.m0, v.m1, v.m2';
|
|
404
|
+
const prevPos = layout.wgslPreviousPosition ?? 'vec4f(engine_local_position(v), 1.0)';
|
|
405
|
+
return /* wgsl */ `
|
|
406
|
+
${WGSL_GLOBALS}
|
|
407
|
+
${WGSL_LIGHTS}
|
|
408
|
+
${WGSL_NOISE}
|
|
409
|
+
struct VertexIn {
|
|
410
|
+
${layout.wgslFields}
|
|
411
|
+
@location(3) m0: vec4f,
|
|
412
|
+
@location(4) m1: vec4f,
|
|
413
|
+
@location(5) m2: vec4f,
|
|
414
|
+
@location(6) uvRect: vec4f,
|
|
415
|
+
@location(7) tint: vec4f,
|
|
416
|
+
@location(8) params: vec4f,
|
|
417
|
+
@location(9) misc: vec4f,${laneFields}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
struct VSOut {
|
|
421
|
+
@builtin(position) clip: vec4f,
|
|
422
|
+
@location(0) uv: vec2f,
|
|
423
|
+
@location(1) local: vec2f,
|
|
424
|
+
@location(2) color: vec4f,
|
|
425
|
+
@location(3) params: vec4f,
|
|
426
|
+
@location(4) world: vec2f,
|
|
427
|
+
@location(5) emissive: f32,
|
|
428
|
+
@location(6) size: vec2f,
|
|
429
|
+
@location(7) normal: vec3f,
|
|
430
|
+
@location(8) worldPos: vec3f,
|
|
431
|
+
@location(9) @interpolate(flat) flags: u32,
|
|
432
|
+
@location(10) tangent: vec4f,
|
|
433
|
+
@location(12) uv1: vec2f,${velocity ? '\n @location(11) prev_clip: vec4f,' : ''}
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
struct FragOut {
|
|
437
|
+
@location(0) color: vec4f,
|
|
438
|
+
@location(1) emissive: vec4f,${auxFields}
|
|
439
|
+
};
|
|
440
|
+
${layout.skinned ? `\n${WGSL_SKIN}\n` : ''}
|
|
441
|
+
fn engine_local_position(v: VertexIn) -> vec3f {
|
|
442
|
+
return ${layout.wgslPosition};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
fn engine_local_normal(v: VertexIn) -> vec3f {
|
|
446
|
+
return ${layout.wgslNormal};
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
fn engine_local_tangent(v: VertexIn) -> vec4f {
|
|
450
|
+
return ${layout.wgslTangent ?? 'vec4f(0.0)'};
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
fn engine_world_position(v: VertexIn) -> vec3f {
|
|
454
|
+
let p = vec4f(engine_local_position(v), 1.0);
|
|
455
|
+
return vec3f(dot(v.m0, p), dot(v.m1, p), dot(v.m2, p));
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
fn engine_previous_world_position(v: VertexIn) -> vec4f {
|
|
459
|
+
let lp = ${prevPos};
|
|
460
|
+
let p = vec4f(lp.xyz, 1.0);
|
|
461
|
+
let rows = array<vec4f, 3>(${prevRows});
|
|
462
|
+
return vec4f(dot(rows[0], p), dot(rows[1], p), dot(rows[2], p), lp.w);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
fn engine_vertex(v: VertexIn) -> VSOut {
|
|
466
|
+
let world3 = engine_world_position(v);
|
|
467
|
+
let world = world3.xy;
|
|
468
|
+
let n = engine_local_normal(v);
|
|
469
|
+
let t = engine_local_tangent(v);
|
|
470
|
+
var o: VSOut;
|
|
471
|
+
o.clip = camera.view_proj * vec4f(world3, 1.0);
|
|
472
|
+
o.uv = mix(v.uvRect.xy, v.uvRect.zw, v.uv);
|
|
473
|
+
o.local = v.uv;
|
|
474
|
+
o.color = v.color * v.tint;
|
|
475
|
+
o.params = v.params;
|
|
476
|
+
o.world = world;
|
|
477
|
+
o.emissive = v.misc.x;
|
|
478
|
+
o.size = v.misc.zw;
|
|
479
|
+
o.normal = normalize(vec3f(dot(v.m0.xyz, n), dot(v.m1.xyz, n), dot(v.m2.xyz, n)));
|
|
480
|
+
o.worldPos = world3;
|
|
481
|
+
o.flags = u32(v.misc.y);
|
|
482
|
+
o.tangent = vec4f(vec3f(dot(v.m0.xyz, t.xyz), dot(v.m1.xyz, t.xyz), dot(v.m2.xyz, t.xyz)), t.w);
|
|
483
|
+
o.uv1 = mix(v.uvRect.xy, v.uvRect.zw, ${layout.wgslUv1 ?? 'v.uv'});${velocity
|
|
484
|
+
? `
|
|
485
|
+
let prev = engine_previous_world_position(v);
|
|
486
|
+
o.prev_clip = select(vec4f(0.0), camera.prev_view_proj * vec4f(prev.xyz, 1.0), prev.w != 0.0);`
|
|
487
|
+
: ''}
|
|
488
|
+
return o;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Screen-space motion since the previous frame in uv units (+x right, +y down), jitter
|
|
492
|
+
// removed; zero when the target has no velocity attachment or the previous position is unknown.
|
|
493
|
+
fn engine_velocity(in: VSOut) -> vec2f {${velocity
|
|
494
|
+
? `
|
|
495
|
+
if (in.prev_clip.w == 0.0) { return vec2f(0.0); }
|
|
496
|
+
let cur = (in.clip.xy - camera.viewport.xy) / camera.viewport.zw - camera.jitter.xy * vec2f(0.5, -0.5);
|
|
497
|
+
let pn = in.prev_clip.xy / in.prev_clip.w;
|
|
498
|
+
let prev = vec2f(pn.x * 0.5 + 0.5, 0.5 - pn.y * 0.5);
|
|
499
|
+
return cur - prev;`
|
|
500
|
+
: '\n return vec2f(0.0);'}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Write the aux outputs the target has (roughness, metalness; velocity); nothing otherwise.
|
|
504
|
+
fn engine_write_aux(o: ptr<function, FragOut>, rough_metal: vec2f, velocity: vec2f) {${roughMetal ? '\n (*o).rough_metal = rough_metal;' : ''}${velocity ? '\n (*o).velocity = velocity;' : ''}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
@vertex fn vs_main(v: VertexIn) -> VSOut {
|
|
508
|
+
return engine_vertex(v);
|
|
509
|
+
}
|
|
510
|
+
`;
|
|
511
|
+
}
|
|
512
|
+
/** The material prelude for the 2D vertex layout (what every 2D material compiles with). */
|
|
513
|
+
export const WGSL_MATERIAL_PRELUDE = materialPrelude(VERTEX_LAYOUT_2D);
|
|
514
|
+
/** Prelude for fullscreen passes: `vs_fullscreen` emits one triangle covering the target. */
|
|
515
|
+
export const WGSL_FULLSCREEN_PRELUDE = /* wgsl */ `
|
|
516
|
+
${WGSL_NOISE}
|
|
517
|
+
struct FullscreenIn {
|
|
518
|
+
@builtin(position) pos: vec4f,
|
|
519
|
+
@location(0) uv: vec2f,
|
|
520
|
+
};
|
|
521
|
+
@vertex fn vs_fullscreen(@builtin(vertex_index) i: u32) -> FullscreenIn {
|
|
522
|
+
let p = vec2f(f32((i << 1u) & 2u), f32(i & 2u));
|
|
523
|
+
var o: FullscreenIn;
|
|
524
|
+
o.pos = vec4f(p * 2.0 - 1.0, 0.0, 1.0);
|
|
525
|
+
o.uv = vec2f(p.x, 1.0 - p.y);
|
|
526
|
+
return o;
|
|
527
|
+
}
|
|
528
|
+
`;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Save envelope, the typed-array JSON codec and the export/import string codec.
|
|
3
|
+
*
|
|
4
|
+
* Stored value: JSON `{ "v": <version>, "t": <savedAt ms>, "d": <data> }`.
|
|
5
|
+
* Export string: `TC1.<game>.<checksum>.<base64url(envelope JSON)>`. The checksum
|
|
6
|
+
* (FNV-1a, hex) catches truncated copy-paste; it is not tamper protection.
|
|
7
|
+
*
|
|
8
|
+
* Typed arrays inside the data are stored as `{ "$b": <base64url bytes>, "$t"?: <kind> }`
|
|
9
|
+
* (`$t` omitted for `Uint8Array`) by `saveReplacer` and turned back by `saveReviver`, so a
|
|
10
|
+
* tilemap or a voxel chunk never goes through a JSON number array. Bytes are in platform byte
|
|
11
|
+
* order (little-endian everywhere WebGPU runs). A plain object of the player's data that has
|
|
12
|
+
* its own `$b` key is escaped as `$$b` (one more `$` per level) and unescaped on load.
|
|
13
|
+
*/
|
|
14
|
+
export interface Envelope {
|
|
15
|
+
v: number;
|
|
16
|
+
t: number;
|
|
17
|
+
d: unknown;
|
|
18
|
+
}
|
|
19
|
+
export declare function isEnvelope(x: unknown): x is Envelope;
|
|
20
|
+
/** 32-bit FNV-1a over UTF-16 code units, as 8 hex chars. */
|
|
21
|
+
export declare function fnv1a(text: string): string;
|
|
22
|
+
/** Element kinds a typed array can be tagged with in stored JSON. */
|
|
23
|
+
export type TypedKind = 'u8' | 'u16' | 'u32' | 'i8' | 'i16' | 'i32' | 'f32' | 'f64';
|
|
24
|
+
export type TypedArrayOf<K extends TypedKind> = K extends 'u8' ? Uint8Array : K extends 'u16' ? Uint16Array : K extends 'u32' ? Uint32Array : K extends 'i8' ? Int8Array : K extends 'i16' ? Int16Array : K extends 'i32' ? Int32Array : K extends 'f32' ? Float32Array : Float64Array;
|
|
25
|
+
type TypedCtor = {
|
|
26
|
+
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): ArrayBufferView;
|
|
27
|
+
readonly BYTES_PER_ELEMENT: number;
|
|
28
|
+
};
|
|
29
|
+
/** Typed-array kind → constructor. Internal: `schema.ts` and the tests import it from here. */
|
|
30
|
+
export declare const TYPED_KIND_CTORS: Record<TypedKind, TypedCtor>;
|
|
31
|
+
/** The tag kind for `value` if it is one of the eight supported typed arrays, else null. */
|
|
32
|
+
export declare function typedKindOf(value: unknown): TypedKind | null;
|
|
33
|
+
/**
|
|
34
|
+
* `JSON.stringify` replacer: typed arrays become `{ $b, $t? }`; a plain object with a key
|
|
35
|
+
* matching `/^\$+b$/` gets that key prefixed with one more `$`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function saveReplacer(_key: string, value: unknown): unknown;
|
|
38
|
+
/** `JSON.parse` reviver undoing `saveReplacer`. Bad tags (damaged base64) are left as objects. */
|
|
39
|
+
export declare function saveReviver(_key: string, value: unknown): unknown;
|
|
40
|
+
export declare function encodeExport(game: string, env: Envelope): string;
|
|
41
|
+
export type DecodeResult = {
|
|
42
|
+
ok: true;
|
|
43
|
+
envelope: Envelope;
|
|
44
|
+
} | {
|
|
45
|
+
ok: false;
|
|
46
|
+
error: string;
|
|
47
|
+
};
|
|
48
|
+
export declare function decodeExport(game: string, text: string): DecodeResult;
|
|
49
|
+
export {};
|