@drawcall/lod 0.2.0 → 0.4.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/README.md +6 -7
- package/dist/bake.d.ts +36 -0
- package/dist/bake.js +176 -0
- package/dist/bake.js.map +1 -0
- package/dist/baked/codec.d.ts +3 -6
- package/dist/baked/codec.js +48 -154
- package/dist/baked/codec.js.map +1 -1
- package/dist/baked/coverage.d.ts +6 -3
- package/dist/baked/coverage.js +6 -3
- package/dist/baked/coverage.js.map +1 -1
- package/dist/baked/fields.d.ts +9 -0
- package/dist/baked/fields.js +22 -0
- package/dist/baked/fields.js.map +1 -0
- package/dist/baked/index.d.ts +14 -8
- package/dist/baked/index.js +24 -22
- package/dist/baked/index.js.map +1 -1
- package/dist/baked/interior/faces.d.ts +4 -3
- package/dist/baked/interior/faces.js +16 -11
- package/dist/baked/interior/faces.js.map +1 -1
- package/dist/baked/interior/material.d.ts +7 -10
- package/dist/baked/interior/material.js +29 -36
- package/dist/baked/interior/material.js.map +1 -1
- package/dist/baked/interior/rooms.d.ts +1 -1
- package/dist/baked/interior/rooms.js +2 -2
- package/dist/baked/interior/rooms.js.map +1 -1
- package/dist/baked/low.js +5 -4
- package/dist/baked/low.js.map +1 -1
- package/dist/baked/raster.js +6 -6
- package/dist/baked/raster.js.map +1 -1
- package/dist/baked/textures.d.ts +17 -0
- package/dist/baked/textures.js +95 -0
- package/dist/baked/textures.js.map +1 -0
- package/dist/baked/transfer.js +19 -18
- package/dist/baked/transfer.js.map +1 -1
- package/dist/baked/unwrap.js +4 -3
- package/dist/baked/unwrap.js.map +1 -1
- package/dist/baked/xatlas.js.map +1 -1
- package/dist/codec/container.d.ts +8 -0
- package/dist/codec/container.js +63 -0
- package/dist/codec/container.js.map +1 -0
- package/dist/codec/mesh.d.ts +8 -0
- package/dist/{mesh/codec.js → codec/mesh.js} +80 -52
- package/dist/codec/mesh.js.map +1 -0
- package/dist/dispose.d.ts +8 -5
- package/dist/dispose.js +22 -24
- package/dist/dispose.js.map +1 -1
- package/dist/foliage.d.ts +32 -0
- package/dist/foliage.js +137 -0
- package/dist/foliage.js.map +1 -0
- package/dist/impostor/bake/atlas.d.ts +4 -4
- package/dist/impostor/bake/atlas.js +12 -12
- package/dist/impostor/bake/atlas.js.map +1 -1
- package/dist/impostor/bake/fit.d.ts +8 -0
- package/dist/impostor/bake/fit.js +28 -0
- package/dist/impostor/bake/fit.js.map +1 -0
- package/dist/impostor/bake/index.d.ts +22 -14
- package/dist/impostor/bake/index.js +50 -134
- package/dist/impostor/bake/index.js.map +1 -1
- package/dist/impostor/bake/materials.d.ts +3 -3
- package/dist/impostor/bake/materials.js +51 -13
- package/dist/impostor/bake/materials.js.map +1 -1
- package/dist/impostor/bake/sheet.d.ts +8 -0
- package/dist/impostor/bake/sheet.js +90 -0
- package/dist/impostor/bake/sheet.js.map +1 -0
- package/dist/impostor/bake/source.d.ts +3 -2
- package/dist/impostor/bake/source.js +9 -20
- package/dist/impostor/bake/source.js.map +1 -1
- package/dist/impostor/codec.d.ts +4 -5
- package/dist/impostor/codec.js +36 -109
- package/dist/impostor/codec.js.map +1 -1
- package/dist/impostor/impostor.d.ts +31 -7
- package/dist/impostor/impostor.js +21 -6
- package/dist/impostor/impostor.js.map +1 -1
- package/dist/impostor/ktx2/encode.d.ts +26 -0
- package/dist/impostor/ktx2/encode.js +120 -0
- package/dist/impostor/ktx2/encode.js.map +1 -0
- package/dist/impostor/ktx2/transcode.d.ts +3 -0
- package/dist/impostor/ktx2/transcode.js +99 -0
- package/dist/impostor/ktx2/transcode.js.map +1 -0
- package/dist/impostor/ktx2/uastc.d.ts +7 -0
- package/dist/impostor/ktx2/uastc.js +65 -0
- package/dist/impostor/ktx2/uastc.js.map +1 -0
- package/dist/impostor/ktx2/wasm/encoder.d.ts +4 -0
- package/dist/impostor/ktx2/wasm/encoder.js +10 -0
- package/dist/impostor/ktx2/wasm/encoder.js.map +1 -0
- package/dist/impostor/ktx2/wasm/transcoder.d.ts +3 -0
- package/dist/impostor/ktx2/wasm/transcoder.js +9 -0
- package/dist/impostor/ktx2/wasm/transcoder.js.map +1 -0
- package/dist/impostor/ktx2/worker.d.ts +1 -0
- package/dist/impostor/ktx2/worker.js +10 -0
- package/dist/impostor/ktx2/worker.js.map +1 -0
- package/dist/impostor/mesh/card.d.ts +4 -4
- package/dist/impostor/mesh/card.js +7 -7
- package/dist/impostor/mesh/card.js.map +1 -1
- package/dist/impostor/mesh/index.d.ts +7 -6
- package/dist/impostor/mesh/index.js +10 -11
- package/dist/impostor/mesh/index.js.map +1 -1
- package/dist/impostor/mesh/material.d.ts +18 -9
- package/dist/impostor/mesh/material.js +40 -27
- package/dist/impostor/mesh/material.js.map +1 -1
- package/dist/impostor/mesh/surface.d.ts +1 -1
- package/dist/impostor/mesh/surface.js +13 -9
- package/dist/impostor/mesh/surface.js.map +1 -1
- package/dist/impostor/mesh/textures.d.ts +3 -3
- package/dist/impostor/mesh/textures.js +24 -34
- package/dist/impostor/mesh/textures.js.map +1 -1
- package/dist/index.d.ts +13 -11
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/dist/instanced/camera.d.ts +34 -0
- package/dist/instanced/camera.js +45 -0
- package/dist/instanced/camera.js.map +1 -0
- package/dist/instanced/clusters.d.ts +54 -0
- package/dist/instanced/clusters.js +151 -0
- package/dist/instanced/clusters.js.map +1 -0
- package/dist/instanced/cull.d.ts +28 -0
- package/dist/instanced/cull.js +22 -0
- package/dist/instanced/cull.js.map +1 -0
- package/dist/instanced/instances.d.ts +39 -0
- package/dist/instanced/instances.js +104 -0
- package/dist/instanced/instances.js.map +1 -0
- package/dist/instanced/key.d.ts +19 -0
- package/dist/instanced/key.js +45 -0
- package/dist/instanced/key.js.map +1 -0
- package/dist/instanced/levels.d.ts +60 -0
- package/dist/instanced/levels.js +131 -0
- package/dist/instanced/levels.js.map +1 -0
- package/dist/instanced/lists.d.ts +57 -0
- package/dist/instanced/lists.js +114 -0
- package/dist/instanced/lists.js.map +1 -0
- package/dist/instanced/measure.d.ts +28 -0
- package/dist/instanced/measure.js +203 -0
- package/dist/instanced/measure.js.map +1 -0
- package/dist/instanced/meshes.d.ts +44 -51
- package/dist/instanced/meshes.js +167 -179
- package/dist/instanced/meshes.js.map +1 -1
- package/dist/instanced/mirror.d.ts +24 -0
- package/dist/instanced/mirror.js +76 -0
- package/dist/instanced/mirror.js.map +1 -0
- package/dist/instanced/raycast.d.ts +10 -11
- package/dist/instanced/raycast.js +31 -41
- package/dist/instanced/raycast.js.map +1 -1
- package/dist/instanced/rows.d.ts +50 -0
- package/dist/instanced/rows.js +36 -0
- package/dist/instanced/rows.js.map +1 -0
- package/dist/instanced/shape.d.ts +27 -0
- package/dist/instanced/shape.js +54 -0
- package/dist/instanced/shape.js.map +1 -0
- package/dist/instanced/sort.d.ts +61 -0
- package/dist/instanced/sort.js +192 -0
- package/dist/instanced/sort.js.map +1 -0
- package/dist/instanced/update.d.ts +34 -0
- package/dist/instanced/update.js +180 -0
- package/dist/instanced/update.js.map +1 -0
- package/dist/levels/bounds.d.ts +21 -0
- package/dist/levels/bounds.js +42 -0
- package/dist/levels/bounds.js.map +1 -0
- package/dist/levels/cameras.d.ts +48 -0
- package/dist/levels/cameras.js +122 -0
- package/dist/levels/cameras.js.map +1 -0
- package/dist/levels/compile/contexts.d.ts +30 -0
- package/dist/levels/compile/contexts.js +18 -0
- package/dist/levels/compile/contexts.js.map +1 -0
- package/dist/levels/compile/index.d.ts +41 -0
- package/dist/levels/compile/index.js +193 -0
- package/dist/levels/compile/index.js.map +1 -0
- package/dist/levels/compile/pipelines.d.ts +26 -0
- package/dist/levels/compile/pipelines.js +172 -0
- package/dist/levels/compile/pipelines.js.map +1 -0
- package/dist/levels/compiles.d.ts +29 -0
- package/dist/levels/compiles.js +50 -0
- package/dist/levels/compiles.js.map +1 -0
- package/dist/levels/draw.d.ts +102 -0
- package/dist/levels/draw.js +401 -0
- package/dist/levels/draw.js.map +1 -0
- package/dist/levels/fade.d.ts +60 -0
- package/dist/levels/fade.js +129 -0
- package/dist/levels/fade.js.map +1 -0
- package/dist/levels/index.d.ts +99 -0
- package/dist/levels/index.js +155 -0
- package/dist/levels/index.js.map +1 -0
- package/dist/levels/item.d.ts +38 -0
- package/dist/levels/item.js +89 -0
- package/dist/levels/item.js.map +1 -0
- package/dist/levels/load.d.ts +31 -0
- package/dist/levels/load.js +144 -0
- package/dist/levels/load.js.map +1 -0
- package/dist/levels/manager.d.ts +158 -0
- package/dist/levels/manager.js +352 -0
- package/dist/levels/manager.js.map +1 -0
- package/dist/{material.d.ts → levels/material.d.ts} +2 -2
- package/dist/{material.js → levels/material.js} +6 -5
- package/dist/levels/material.js.map +1 -0
- package/dist/levels/renderer.d.ts +32 -0
- package/dist/levels/renderer.js +57 -0
- package/dist/levels/renderer.js.map +1 -0
- package/dist/levels/requests.d.ts +52 -0
- package/dist/levels/requests.js +97 -0
- package/dist/levels/requests.js.map +1 -0
- package/dist/levels/screen.d.ts +14 -0
- package/dist/levels/screen.js +21 -0
- package/dist/levels/screen.js.map +1 -0
- package/dist/loader/build.d.ts +10 -0
- package/dist/loader/build.js +28 -0
- package/dist/loader/build.js.map +1 -0
- package/dist/loader/context.d.ts +44 -0
- package/dist/loader/context.js +96 -0
- package/dist/loader/context.js.map +1 -0
- package/dist/loader/entry.d.ts +4 -0
- package/dist/loader/entry.js +43 -0
- package/dist/loader/entry.js.map +1 -0
- package/dist/loader/index.d.ts +76 -0
- package/dist/loader/index.js +272 -0
- package/dist/loader/index.js.map +1 -0
- package/dist/loader/level.d.ts +41 -0
- package/dist/loader/level.js +140 -0
- package/dist/loader/level.js.map +1 -0
- package/dist/loader/node.d.ts +26 -0
- package/dist/loader/node.js +199 -0
- package/dist/loader/node.js.map +1 -0
- package/dist/loader/request.d.ts +54 -0
- package/dist/loader/request.js +19 -0
- package/dist/loader/request.js.map +1 -0
- package/dist/loader/url.d.ts +10 -6
- package/dist/loader/url.js +22 -14
- package/dist/loader/url.js.map +1 -1
- package/dist/lod.d.ts +144 -43
- package/dist/lod.js +354 -163
- package/dist/lod.js.map +1 -1
- package/dist/meshopt.d.ts +6 -0
- package/dist/meshopt.js +20 -0
- package/dist/meshopt.js.map +1 -0
- package/dist/node-process.d.ts +5 -0
- package/dist/node-process.js +6 -0
- package/dist/node-process.js.map +1 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.js +5 -0
- package/dist/node.js.map +1 -0
- package/dist/simplify/cards.d.ts +14 -0
- package/dist/simplify/cards.js +128 -0
- package/dist/simplify/cards.js.map +1 -0
- package/dist/{simplify.d.ts → simplify/index.d.ts} +8 -5
- package/dist/{simplify.js → simplify/index.js} +45 -27
- package/dist/simplify/index.js.map +1 -0
- package/dist/{bounds.d.ts → source/detail.d.ts} +9 -23
- package/dist/{bounds.js → source/detail.js} +28 -58
- package/dist/source/detail.js.map +1 -0
- package/dist/source/deviation.js +6 -6
- package/dist/source/deviation.js.map +1 -1
- package/dist/source/{shading.d.ts → evaluator.d.ts} +10 -10
- package/dist/source/{shading.js → evaluator.js} +5 -5
- package/dist/source/evaluator.js.map +1 -0
- package/dist/source/{trace.d.ts → raycaster.d.ts} +6 -6
- package/dist/source/{trace.js → raycaster.js} +8 -8
- package/dist/source/raycaster.js.map +1 -0
- package/dist/source/{texels.d.ts → sampler.d.ts} +1 -1
- package/dist/source/{texels.js → sampler.js} +8 -5
- package/dist/source/sampler.js.map +1 -0
- package/dist/source/source.d.ts +1 -1
- package/dist/source/source.js +1 -1
- package/dist/source/source.js.map +1 -1
- package/dist/source/surface.js +1 -1
- package/dist/source/surface.js.map +1 -1
- package/dist/task.d.ts +6 -0
- package/dist/{pause.js → task.js} +5 -5
- package/dist/task.js.map +1 -0
- package/dist/three.d.ts +19 -30
- package/dist/three.js +30 -57
- package/dist/three.js.map +1 -1
- package/dist/tsl.d.ts +8 -12
- package/dist/tsl.js +11 -39
- package/dist/tsl.js.map +1 -1
- package/dist/typegpu.d.ts +37 -0
- package/dist/typegpu.js +37 -0
- package/dist/typegpu.js.map +1 -0
- package/dist/wind/bounds.js +3 -3
- package/dist/wind/bounds.js.map +1 -1
- package/dist/wind/hooks.d.ts +7 -4
- package/dist/wind/hooks.js +5 -2
- package/dist/wind/hooks.js.map +1 -1
- package/dist/wind/index.d.ts +4 -4
- package/dist/wind/index.js +25 -23
- package/dist/wind/index.js.map +1 -1
- package/dist/wind/sway.d.ts +2 -0
- package/dist/wind/sway.js +4 -1
- package/dist/wind/sway.js.map +1 -1
- package/package.json +24 -10
- package/skills/lod/SKILL.md +120 -32
- package/dist/bounds.js.map +0 -1
- package/dist/compile.d.ts +0 -4
- package/dist/compile.js +0 -100
- package/dist/compile.js.map +0 -1
- package/dist/deferred.d.ts +0 -12
- package/dist/deferred.js +0 -27
- package/dist/deferred.js.map +0 -1
- package/dist/fade.d.ts +0 -36
- package/dist/fade.js +0 -112
- package/dist/fade.js.map +0 -1
- package/dist/instanced/args.d.ts +0 -20
- package/dist/instanced/args.js +0 -77
- package/dist/instanced/args.js.map +0 -1
- package/dist/instanced/blocks.d.ts +0 -66
- package/dist/instanced/blocks.js +0 -294
- package/dist/instanced/blocks.js.map +0 -1
- package/dist/instanced/dirty.d.ts +0 -15
- package/dist/instanced/dirty.js +0 -96
- package/dist/instanced/dirty.js.map +0 -1
- package/dist/instanced/index.d.ts +0 -90
- package/dist/instanced/index.js +0 -349
- package/dist/instanced/index.js.map +0 -1
- package/dist/instanced/parts.d.ts +0 -14
- package/dist/instanced/parts.js +0 -79
- package/dist/instanced/parts.js.map +0 -1
- package/dist/instanced/select.d.ts +0 -92
- package/dist/instanced/select.js +0 -315
- package/dist/instanced/select.js.map +0 -1
- package/dist/instanced/store.d.ts +0 -31
- package/dist/instanced/store.js +0 -96
- package/dist/instanced/store.js.map +0 -1
- package/dist/levels.d.ts +0 -95
- package/dist/levels.js +0 -171
- package/dist/levels.js.map +0 -1
- package/dist/loader/bundle.d.ts +0 -25
- package/dist/loader/bundle.js +0 -241
- package/dist/loader/bundle.js.map +0 -1
- package/dist/loader/cache.d.ts +0 -15
- package/dist/loader/cache.js +0 -75
- package/dist/loader/cache.js.map +0 -1
- package/dist/loader/provenance.d.ts +0 -30
- package/dist/loader/provenance.js +0 -105
- package/dist/loader/provenance.js.map +0 -1
- package/dist/loader.d.ts +0 -55
- package/dist/loader.js +0 -239
- package/dist/loader.js.map +0 -1
- package/dist/material.js.map +0 -1
- package/dist/mesh/codec.d.ts +0 -4
- package/dist/mesh/codec.js.map +0 -1
- package/dist/pause.d.ts +0 -6
- package/dist/pause.js.map +0 -1
- package/dist/queue.d.ts +0 -2
- package/dist/queue.js +0 -33
- package/dist/queue.js.map +0 -1
- package/dist/renderer.d.ts +0 -21
- package/dist/renderer.js +0 -83
- package/dist/renderer.js.map +0 -1
- package/dist/residency.d.ts +0 -44
- package/dist/residency.js +0 -205
- package/dist/residency.js.map +0 -1
- package/dist/simplify.js.map +0 -1
- package/dist/source/shading.js.map +0 -1
- package/dist/source/texels.js.map +0 -1
- package/dist/source/trace.js.map +0 -1
- package/dist/view.d.ts +0 -45
- package/dist/view.js +0 -131
- package/dist/view.js.map +0 -1
|
@@ -1,53 +1,43 @@
|
|
|
1
1
|
import { Matrix4, Ray, Sphere } from "three/webgpu";
|
|
2
|
-
import { stretch } from "
|
|
2
|
+
import { stretch } from "../three.js";
|
|
3
3
|
const inverse = new Matrix4();
|
|
4
4
|
const ray = new Ray();
|
|
5
5
|
const sphere = new Sphere();
|
|
6
6
|
const instance = new Matrix4();
|
|
7
7
|
const world = new Matrix4();
|
|
8
8
|
const hits = [];
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Hits on the first `count` instances of `matrices`, `lod`'s, of `source`'s meshes, each raycast where an instance
|
|
11
|
+
* stands, with `instanceId` set as on an InstancedMesh's hits.
|
|
12
|
+
*/
|
|
13
|
+
export function raycastInstances(lod, source, matrices, count, raycaster, intersects) {
|
|
14
|
+
ray.copy(raycaster.ray).applyMatrix4(inverse.copy(lod.matrixWorld).invert());
|
|
15
|
+
// A mesh of several material groups is a part per group: it is hit once. A mesh's parts share its placement.
|
|
16
|
+
const meshes = new Map();
|
|
17
|
+
for (const { template, placement } of source.parts)
|
|
18
|
+
meshes.set(template, placement);
|
|
19
|
+
for (let index = 0; index < count; index++) {
|
|
20
|
+
instance.fromArray(matrices, index * 16);
|
|
21
|
+
sphere.center.copy(source.rest.center).applyMatrix4(instance);
|
|
22
|
+
sphere.radius = source.rest.radius * stretch(instance);
|
|
23
|
+
if (sphere.radius === 0 || !ray.intersectsSphere(sphere))
|
|
24
|
+
continue;
|
|
25
|
+
for (const [mesh, placement] of meshes)
|
|
26
|
+
for (const hit of hitsAt(mesh, world.multiplyMatrices(lod.matrixWorld, instance).multiply(placement), raycaster))
|
|
27
|
+
intersects.push({ ...hit, object: lod, instanceId: index });
|
|
18
28
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
}
|
|
30
|
+
/** `mesh`'s own raycast, as if it stood at `matrixWorld`. */
|
|
31
|
+
function hitsAt(mesh, matrixWorld, raycaster) {
|
|
32
|
+
const own = mesh.matrixWorld;
|
|
33
|
+
hits.length = 0;
|
|
34
|
+
mesh.matrixWorld = matrixWorld;
|
|
35
|
+
try {
|
|
36
|
+
mesh.raycast(raycaster, hits);
|
|
27
37
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
ray.copy(raycaster.ray).applyMatrix4(inverse.copy(owner.matrixWorld).invert());
|
|
31
|
-
const count = this.matrices.length / 16;
|
|
32
|
-
for (let i = 0; i < count; i++) {
|
|
33
|
-
instance.fromArray(this.matrices, i * 16);
|
|
34
|
-
sphere.center.copy(this.rest.center).applyMatrix4(instance);
|
|
35
|
-
sphere.radius = this.rest.radius * stretch(instance);
|
|
36
|
-
if (!ray.intersectsSphere(sphere))
|
|
37
|
-
continue;
|
|
38
|
-
for (const { mesh, placement } of this.probes) {
|
|
39
|
-
if (!mesh.layers.test(raycaster.layers))
|
|
40
|
-
continue;
|
|
41
|
-
// The template's own raycast, as if it stood where this instance does.
|
|
42
|
-
const own = mesh.matrixWorld;
|
|
43
|
-
mesh.matrixWorld = world.multiplyMatrices(owner.matrixWorld, instance).multiply(placement);
|
|
44
|
-
hits.length = 0;
|
|
45
|
-
mesh.raycast(raycaster, hits);
|
|
46
|
-
mesh.matrixWorld = own;
|
|
47
|
-
for (const hit of hits)
|
|
48
|
-
intersects.push(Object.assign(hit, { object: owner, instanceId: i }));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
38
|
+
finally {
|
|
39
|
+
mesh.matrixWorld = own;
|
|
51
40
|
}
|
|
41
|
+
return hits;
|
|
52
42
|
}
|
|
53
43
|
//# sourceMappingURL=raycast.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raycast.js","sourceRoot":"","sources":["../../src/instanced/raycast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAA+D,MAAM,cAAc,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"raycast.js","sourceRoot":"","sources":["../../src/instanced/raycast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAA+D,MAAM,cAAc,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAStC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;AACtB,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;AAC5B,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAE,CAAC;AAC/B,MAAM,KAAK,GAAG,IAAI,OAAO,EAAE,CAAC;AAC5B,MAAM,IAAI,GAAmB,EAAE,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAa,EAAE,MAAqB,EAAE,QAA2B,EAAE,KAAa,EAAE,SAAoB,EAAE,UAA0B;IACjK,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,6GAA6G;IAC7G,MAAM,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAC;IACxC,KAAK,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,MAAM,CAAC,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACpF,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3C,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC;YAAE,SAAS;QACnE,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM;YACpC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;gBAAE,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IAClL,CAAC;AACH,CAAC;AAED,6DAA6D;AAC7D,SAAS,MAAM,CAAC,IAAU,EAAE,WAAoB,EAAE,SAAoB;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC;IAC7B,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAC/B,IAAI,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;IACzB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { IndirectStorageBufferAttribute, StorageBufferAttribute } from "three/webgpu";
|
|
2
|
+
/** vec4s of the row's u32s and of its f32s. */
|
|
3
|
+
export declare const INT_ROW = 6;
|
|
4
|
+
export declare const FLOAT_ROW = 12;
|
|
5
|
+
/**
|
|
6
|
+
* Where each vec4 of the row lies. Of its u32s (`INTS_AT`): `levels`, the level count, the coarsest level and the forced
|
|
7
|
+
* level as `forcedWord` writes it; `masks`, the levels that draw nothing, whether they fade (1 or 0), those loaded and
|
|
8
|
+
* those loaded before; `flags`, whether the camera is orthographic, cullDistance is set and its survivors scale (1 or
|
|
9
|
+
* 0), and the draw count; `layout`, slots per list; `starts`, per level the first slot of its list, `UNLISTED` for none.
|
|
10
|
+
* Of its f32s (`FLOATS_AT`): maxPixels of levels 0 to 3 and 4 to 7, the camera in the Lod's space (eye and pixels per
|
|
11
|
+
* unit of subtense, or of size, ortho), one instance's source sphere, the arrival's progress, the reach of every level
|
|
12
|
+
* and its sway, cullDistance's near and far, cullDistance's camera, and the frustum's six planes.
|
|
13
|
+
*/
|
|
14
|
+
export declare const INTS_AT: {
|
|
15
|
+
readonly levels: 0;
|
|
16
|
+
readonly masks: 1;
|
|
17
|
+
readonly flags: 2;
|
|
18
|
+
readonly layout: 3;
|
|
19
|
+
readonly starts: 4;
|
|
20
|
+
};
|
|
21
|
+
export declare const FLOATS_AT: {
|
|
22
|
+
readonly low: 0;
|
|
23
|
+
readonly high: 1;
|
|
24
|
+
readonly eye: 2;
|
|
25
|
+
readonly source: 3;
|
|
26
|
+
readonly values: 4;
|
|
27
|
+
readonly cullEye: 5;
|
|
28
|
+
readonly planes: 6;
|
|
29
|
+
};
|
|
30
|
+
/** The forced level as the row holds it: one more, so that 0 is none (-1). */
|
|
31
|
+
export declare const forcedWord: (forced: number) => number;
|
|
32
|
+
/** The start of a level without a list. */
|
|
33
|
+
export declare const UNLISTED = 4294967295;
|
|
34
|
+
/** Bytes per indirect draw, including the unused final word of a non-indexed draw. */
|
|
35
|
+
export declare const DRAW_BYTES = 20;
|
|
36
|
+
/** One indirect draw: a level's mesh, drawing `count` indices (or vertices) from `start`. */
|
|
37
|
+
export interface IndirectDraw {
|
|
38
|
+
level: number;
|
|
39
|
+
count: number;
|
|
40
|
+
start: number;
|
|
41
|
+
indexed: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** The words of `draws` as the indirect pass reads them: level, count, start and whether indexed, per draw. */
|
|
44
|
+
export declare function drawWords(draws: readonly IndirectDraw[]): StorageBufferAttribute;
|
|
45
|
+
export declare const wordsBuffer: () => StorageBufferAttribute;
|
|
46
|
+
export declare const floatsBuffer: () => StorageBufferAttribute;
|
|
47
|
+
/** Per level, how many instances its list holds for the camera sorting: the indirect pass clears them. */
|
|
48
|
+
export declare const countsBuffer: () => StorageBufferAttribute;
|
|
49
|
+
/** Indirect draws only the GPU writes, zero until a sort writes them: nothing draws before a sort. */
|
|
50
|
+
export declare const argsBuffer: (draws: number) => IndirectStorageBufferAttribute;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { IndirectStorageBufferAttribute, StorageBufferAttribute } from "three/webgpu";
|
|
2
|
+
import { MAX_LEVELS } from "../levels/draw.js";
|
|
3
|
+
// What a Lod sorts by for one camera, as the sort passes read it (see update.ts): its row, of u32s and of f32s.
|
|
4
|
+
/** vec4s of the row's u32s and of its f32s. */
|
|
5
|
+
export const INT_ROW = 6;
|
|
6
|
+
export const FLOAT_ROW = 12;
|
|
7
|
+
/**
|
|
8
|
+
* Where each vec4 of the row lies. Of its u32s (`INTS_AT`): `levels`, the level count, the coarsest level and the forced
|
|
9
|
+
* level as `forcedWord` writes it; `masks`, the levels that draw nothing, whether they fade (1 or 0), those loaded and
|
|
10
|
+
* those loaded before; `flags`, whether the camera is orthographic, cullDistance is set and its survivors scale (1 or
|
|
11
|
+
* 0), and the draw count; `layout`, slots per list; `starts`, per level the first slot of its list, `UNLISTED` for none.
|
|
12
|
+
* Of its f32s (`FLOATS_AT`): maxPixels of levels 0 to 3 and 4 to 7, the camera in the Lod's space (eye and pixels per
|
|
13
|
+
* unit of subtense, or of size, ortho), one instance's source sphere, the arrival's progress, the reach of every level
|
|
14
|
+
* and its sway, cullDistance's near and far, cullDistance's camera, and the frustum's six planes.
|
|
15
|
+
*/
|
|
16
|
+
export const INTS_AT = { levels: 0, masks: 1, flags: 2, layout: 3, starts: 4 };
|
|
17
|
+
export const FLOATS_AT = { low: 0, high: 1, eye: 2, source: 3, values: 4, cullEye: 5, planes: 6 };
|
|
18
|
+
/** The forced level as the row holds it: one more, so that 0 is none (-1). */
|
|
19
|
+
export const forcedWord = (forced) => forced + 1;
|
|
20
|
+
/** The start of a level without a list. */
|
|
21
|
+
export const UNLISTED = 0xffffffff;
|
|
22
|
+
/** Bytes per indirect draw, including the unused final word of a non-indexed draw. */
|
|
23
|
+
export const DRAW_BYTES = 20;
|
|
24
|
+
/** The words of `draws` as the indirect pass reads them: level, count, start and whether indexed, per draw. */
|
|
25
|
+
export function drawWords(draws) {
|
|
26
|
+
const values = new Uint32Array(Math.max(draws.length, 1) * 4);
|
|
27
|
+
draws.forEach((draw, i) => values.set([draw.level, draw.count, draw.start, Number(draw.indexed)], i * 4));
|
|
28
|
+
return new StorageBufferAttribute(values, 4);
|
|
29
|
+
}
|
|
30
|
+
export const wordsBuffer = () => new StorageBufferAttribute(new Uint32Array(INT_ROW * 4), 4);
|
|
31
|
+
export const floatsBuffer = () => new StorageBufferAttribute(new Float32Array(FLOAT_ROW * 4), 4);
|
|
32
|
+
/** Per level, how many instances its list holds for the camera sorting: the indirect pass clears them. */
|
|
33
|
+
export const countsBuffer = () => new StorageBufferAttribute(new Uint32Array(MAX_LEVELS), 1);
|
|
34
|
+
/** Indirect draws only the GPU writes, zero until a sort writes them: nothing draws before a sort. */
|
|
35
|
+
export const argsBuffer = (draws) => new IndirectStorageBufferAttribute(new Uint32Array(Math.max(draws, 1) * (DRAW_BYTES / 4)), 1);
|
|
36
|
+
//# sourceMappingURL=rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rows.js","sourceRoot":"","sources":["../../src/instanced/rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,gHAAgH;AAEhH,+CAA+C;AAC/C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AACzB,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAE5B;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAW,CAAC;AACxF,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAW,CAAC;AAE3G,8EAA8E;AAC9E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAEzD,2CAA2C;AAC3C,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;AAEnC,sFAAsF;AACtF,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAU7B,+GAA+G;AAC/G,MAAM,UAAU,SAAS,CAAC,KAA8B;IACtD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1G,OAAO,IAAI,sBAAsB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,sBAAsB,CAAC,IAAI,WAAW,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7F,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,IAAI,sBAAsB,CAAC,IAAI,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACjG,0GAA0G;AAC1G,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,IAAI,sBAAsB,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7F,sGAAsG;AACtG,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,8BAA8B,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Sphere } from "three/webgpu";
|
|
2
|
+
import type { LodLevel } from "../levels/index.js";
|
|
3
|
+
/** One instance of a Lod as its levels measure it, in its own space: what heights, bounds and fades are measured by. */
|
|
4
|
+
export declare class InstanceShape {
|
|
5
|
+
/** The source's sphere, which heights are measured by. */
|
|
6
|
+
readonly source: Sphere;
|
|
7
|
+
/** Around every level, unloaded ones included. */
|
|
8
|
+
readonly rest: Sphere;
|
|
9
|
+
/** The source's radius in its own space, which default thresholds are measured from. */
|
|
10
|
+
readonly ownRadius: number;
|
|
11
|
+
/** The source's radius padded for sway, where fades and shadow casters are cut off (see `wind`). */
|
|
12
|
+
fadeRadius: number;
|
|
13
|
+
/** The diagonal of every level's box: how much a cluster's box shows of its instances' scale. */
|
|
14
|
+
readonly extent: number;
|
|
15
|
+
/** Every level's box. */
|
|
16
|
+
private readonly envelope;
|
|
17
|
+
/** How far levels sway beyond `rest`, relative to it. */
|
|
18
|
+
private sway;
|
|
19
|
+
/** The shape of `inputs`, the levels given; none without levels. */
|
|
20
|
+
constructor(inputs: readonly LodLevel[]);
|
|
21
|
+
/** The radius around the source's centre that every level and its sway stay within. */
|
|
22
|
+
get reach(): number;
|
|
23
|
+
/** How far from the instance's origin every level and its sway reach. */
|
|
24
|
+
get originReach(): number;
|
|
25
|
+
/** Sway as wind of `slope` above `baseY` moves it, the source's fade radius padded by `padding`. */
|
|
26
|
+
wind(padding: number, slope: number, baseY: number): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Box3, Sphere, Vector3 } from "three/webgpu";
|
|
2
|
+
import { levelBox, measureLevels } from "../levels/bounds.js";
|
|
3
|
+
/** One instance of a Lod as its levels measure it, in its own space: what heights, bounds and fades are measured by. */
|
|
4
|
+
export class InstanceShape {
|
|
5
|
+
/** The source's sphere, which heights are measured by. */
|
|
6
|
+
source = new Sphere();
|
|
7
|
+
/** Around every level, unloaded ones included. */
|
|
8
|
+
rest = new Sphere();
|
|
9
|
+
/** The source's radius in its own space, which default thresholds are measured from. */
|
|
10
|
+
ownRadius = 0;
|
|
11
|
+
/** The source's radius padded for sway, where fades and shadow casters are cut off (see `wind`). */
|
|
12
|
+
fadeRadius = 0;
|
|
13
|
+
/** The diagonal of every level's box: how much a cluster's box shows of its instances' scale. */
|
|
14
|
+
extent = 0;
|
|
15
|
+
/** Every level's box. */
|
|
16
|
+
envelope = new Box3();
|
|
17
|
+
/** How far levels sway beyond `rest`, relative to it. */
|
|
18
|
+
sway = 0;
|
|
19
|
+
/** The shape of `inputs`, the levels given; none without levels. */
|
|
20
|
+
constructor(inputs) {
|
|
21
|
+
if (inputs.length === 0)
|
|
22
|
+
return;
|
|
23
|
+
const { own, placed } = measureLevels(inputs, "Lod");
|
|
24
|
+
this.ownRadius = own.radius;
|
|
25
|
+
this.source.copy(placed);
|
|
26
|
+
this.rest.copy(placed);
|
|
27
|
+
this.fadeRadius = placed.radius;
|
|
28
|
+
for (const input of inputs)
|
|
29
|
+
this.envelope.union(levelBox(input));
|
|
30
|
+
// Metadata includes unloaded levels, so later arrivals cannot pass the envelope.
|
|
31
|
+
if (this.envelope.isEmpty())
|
|
32
|
+
return;
|
|
33
|
+
this.extent = this.envelope.getSize(new Vector3()).length();
|
|
34
|
+
const { center } = this.rest;
|
|
35
|
+
const { min, max } = this.envelope;
|
|
36
|
+
this.rest.radius = Math.max(this.rest.radius, Math.hypot(Math.max(Math.abs(min.x - center.x), Math.abs(max.x - center.x)), Math.max(Math.abs(min.y - center.y), Math.abs(max.y - center.y)), Math.max(Math.abs(min.z - center.z), Math.abs(max.z - center.z))));
|
|
37
|
+
}
|
|
38
|
+
/** The radius around the source's centre that every level and its sway stay within. */
|
|
39
|
+
get reach() {
|
|
40
|
+
return this.rest.radius * (1 + this.sway);
|
|
41
|
+
}
|
|
42
|
+
/** How far from the instance's origin every level and its sway reach. */
|
|
43
|
+
get originReach() {
|
|
44
|
+
return this.rest.center.length() + this.reach;
|
|
45
|
+
}
|
|
46
|
+
/** Sway as wind of `slope` above `baseY` moves it, the source's fade radius padded by `padding`. */
|
|
47
|
+
wind(padding, slope, baseY) {
|
|
48
|
+
this.fadeRadius = this.source.radius + padding;
|
|
49
|
+
// The wind's shape comes from the source, but taller or offset levels sway farther.
|
|
50
|
+
const reach = slope * Math.max(Math.abs(this.envelope.min.y - baseY), Math.abs(this.envelope.max.y - baseY));
|
|
51
|
+
this.sway = this.rest.radius > 0 ? reach / this.rest.radius : 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=shape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shape.js","sourceRoot":"","sources":["../../src/instanced/shape.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { StorageInstancedBufferAttribute, type Camera, type Frustum, type Renderer, type Sphere, type Vector3 } from "three/webgpu";
|
|
2
|
+
import type { d } from "typegpu";
|
|
3
|
+
import { type DrawLevels } from "../levels/draw.js";
|
|
4
|
+
import type { InstanceSlots } from "../levels/fade.js";
|
|
5
|
+
import type { Cull } from "./cull.js";
|
|
6
|
+
import { type IndirectDraw } from "./rows.js";
|
|
7
|
+
/** What a Lod sorts by for a camera, everything in its space. */
|
|
8
|
+
export interface RowValues {
|
|
9
|
+
levels: d.Infer<typeof DrawLevels>;
|
|
10
|
+
/** The level loading state levelsToDraw reads (see LodLevelLoadManager). */
|
|
11
|
+
loaded: number;
|
|
12
|
+
before: number;
|
|
13
|
+
progress: number;
|
|
14
|
+
eye: Vector3;
|
|
15
|
+
/** Pixels per unit of subtense (or of size, for an orthographic camera). */
|
|
16
|
+
scale: number;
|
|
17
|
+
ortho: boolean;
|
|
18
|
+
cull: Cull | null;
|
|
19
|
+
/** One instance's source sphere, and how far its levels and their sway reach. */
|
|
20
|
+
source: Sphere;
|
|
21
|
+
reach: number;
|
|
22
|
+
frustum: Frustum;
|
|
23
|
+
}
|
|
24
|
+
/** One Lod's sorts: every camera's buffers, and the passes sorting into them. */
|
|
25
|
+
export declare class Sorter {
|
|
26
|
+
private readonly listed;
|
|
27
|
+
private readonly cameras;
|
|
28
|
+
private readonly draws;
|
|
29
|
+
private drawBuffer;
|
|
30
|
+
private readonly counts;
|
|
31
|
+
/** Survivors' scaled matrices, made once survivors scale; their CPU array is dropped once a pass wrote them. */
|
|
32
|
+
private scaled;
|
|
33
|
+
/** Where survivors' scaled matrices go while none scale: never written, as no survivor scales. */
|
|
34
|
+
private readonly unscaled;
|
|
35
|
+
private passes;
|
|
36
|
+
/** `listed` tells, as a mask, which levels have an instance list: those that draw something. */
|
|
37
|
+
constructor(listed: number);
|
|
38
|
+
/** The meshes draw `draws` too, after those they have; where they start among the draws. */
|
|
39
|
+
appendDraws(draws: readonly IndirectDraw[]): number;
|
|
40
|
+
/** Survivors' scaled matrices for `capacity` instances. */
|
|
41
|
+
scaledMatrices(capacity: number): StorageInstancedBufferAttribute;
|
|
42
|
+
/** Where `camera`'s lists and indirect draws lie; null before a sort was written for it. */
|
|
43
|
+
slotsOf(camera: Camera): InstanceSlots | null;
|
|
44
|
+
/**
|
|
45
|
+
* Write `values` as what `camera` sorts by, over the instances of `ranges` (start and count, flat), `instances` in
|
|
46
|
+
* all, sorted at the camera's next draw. Its lists grow to hold them, within `limit` bytes per buffer.
|
|
47
|
+
*/
|
|
48
|
+
write(camera: Camera, values: RowValues, ranges: readonly number[], instances: number, limit: number): void;
|
|
49
|
+
/** Sort for `camera` on `renderer`, in one compute call, if due: before a level mesh draws for it. */
|
|
50
|
+
run(renderer: Renderer, camera: Camera, matrices: StorageInstancedBufferAttribute): void;
|
|
51
|
+
/** `camera` no longer draws the Lod: its buffers are freed. */
|
|
52
|
+
release(camera: Camera): void;
|
|
53
|
+
dispose(): void;
|
|
54
|
+
private makeBuffers;
|
|
55
|
+
/** Grow `buffers`' lists to hold `instances` per level, by doubling, each buffer within `limit` bytes. */
|
|
56
|
+
private grow;
|
|
57
|
+
/** Write the blocks of `ranges` into `buffers`: one empty block for none, as a dispatch visits one at least. */
|
|
58
|
+
private writeBlocks;
|
|
59
|
+
/** Write the layout of `buffers`' lists and the draw count into its row. */
|
|
60
|
+
private place;
|
|
61
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { StorageBufferAttribute, StorageInstancedBufferAttribute } from "three/webgpu";
|
|
2
|
+
import { MAX_LEVELS } from "../levels/draw.js";
|
|
3
|
+
import { FLOATS_AT, INTS_AT, UNLISTED, argsBuffer, countsBuffer, drawWords, floatsBuffer, forcedWord, wordsBuffer } from "./rows.js";
|
|
4
|
+
import { BLOCK, MAX_BLOCKS, sortPasses } from "./update.js";
|
|
5
|
+
/** One Lod's sorts: every camera's buffers, and the passes sorting into them. */
|
|
6
|
+
export class Sorter {
|
|
7
|
+
listed;
|
|
8
|
+
cameras = new Map();
|
|
9
|
+
draws = [];
|
|
10
|
+
drawBuffer = drawWords([]);
|
|
11
|
+
counts = countsBuffer();
|
|
12
|
+
/** Survivors' scaled matrices, made once survivors scale; their CPU array is dropped once a pass wrote them. */
|
|
13
|
+
scaled = null;
|
|
14
|
+
/** Where survivors' scaled matrices go while none scale: never written, as no survivor scales. */
|
|
15
|
+
unscaled = new StorageInstancedBufferAttribute(new Float32Array(16), 16);
|
|
16
|
+
passes = null;
|
|
17
|
+
/** `listed` tells, as a mask, which levels have an instance list: those that draw something. */
|
|
18
|
+
constructor(listed) {
|
|
19
|
+
this.listed = listed;
|
|
20
|
+
}
|
|
21
|
+
/** The meshes draw `draws` too, after those they have; where they start among the draws. */
|
|
22
|
+
appendDraws(draws) {
|
|
23
|
+
const first = this.draws.length;
|
|
24
|
+
this.draws.push(...draws);
|
|
25
|
+
this.drawBuffer.dispose();
|
|
26
|
+
this.drawBuffer = drawWords(this.draws);
|
|
27
|
+
for (const buffers of this.cameras.values()) {
|
|
28
|
+
buffers.args.dispose();
|
|
29
|
+
buffers.args = argsBuffer(this.draws.length);
|
|
30
|
+
this.place(buffers);
|
|
31
|
+
buffers.due = true;
|
|
32
|
+
}
|
|
33
|
+
return first;
|
|
34
|
+
}
|
|
35
|
+
/** Survivors' scaled matrices for `capacity` instances. */
|
|
36
|
+
scaledMatrices(capacity) {
|
|
37
|
+
if (this.scaled?.capacity !== capacity) {
|
|
38
|
+
this.scaled?.attribute.dispose();
|
|
39
|
+
this.scaled = { attribute: new StorageInstancedBufferAttribute(new Float32Array(capacity * 16), 16), capacity };
|
|
40
|
+
}
|
|
41
|
+
return this.scaled.attribute;
|
|
42
|
+
}
|
|
43
|
+
/** Where `camera`'s lists and indirect draws lie; null before a sort was written for it. */
|
|
44
|
+
slotsOf(camera) {
|
|
45
|
+
const buffers = this.cameras.get(camera);
|
|
46
|
+
return buffers ? { indices: buffers.indices, fades: buffers.fades, args: { attribute: buffers.args, offset: 0 } } : null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Write `values` as what `camera` sorts by, over the instances of `ranges` (start and count, flat), `instances` in
|
|
50
|
+
* all, sorted at the camera's next draw. Its lists grow to hold them, within `limit` bytes per buffer.
|
|
51
|
+
*/
|
|
52
|
+
write(camera, values, ranges, instances, limit) {
|
|
53
|
+
const buffers = this.cameras.get(camera) ?? this.makeBuffers();
|
|
54
|
+
this.cameras.set(camera, buffers);
|
|
55
|
+
if (instances > buffers.listSize)
|
|
56
|
+
this.grow(buffers, instances, limit);
|
|
57
|
+
this.writeBlocks(buffers, ranges);
|
|
58
|
+
const { levels, loaded, before, progress, eye, scale, ortho, cull, source, reach, frustum } = values;
|
|
59
|
+
const words = buffers.words.array;
|
|
60
|
+
words.set([levels.count, levels.coarsest, forcedWord(levels.forced)], INTS_AT.levels * 4);
|
|
61
|
+
words.set([levels.empty, levels.fades, loaded, before], INTS_AT.masks * 4);
|
|
62
|
+
words.set([Number(ortho), Number(cull !== null), Number(cull?.survivors ?? false)], INTS_AT.flags * 4);
|
|
63
|
+
this.place(buffers);
|
|
64
|
+
const floats = buffers.floats.array;
|
|
65
|
+
floats.set(levels.maxPixels, FLOATS_AT.low * 4);
|
|
66
|
+
floats.set([eye.x, eye.y, eye.z, scale], FLOATS_AT.eye * 4);
|
|
67
|
+
floats.set([source.center.x, source.center.y, source.center.z, source.radius], FLOATS_AT.source * 4);
|
|
68
|
+
floats.set([progress, reach, cull?.near ?? 0, cull?.far ?? 1], FLOATS_AT.values * 4);
|
|
69
|
+
if (cull)
|
|
70
|
+
floats.set([cull.eye.x, cull.eye.y, cull.eye.z, 0], FLOATS_AT.cullEye * 4);
|
|
71
|
+
frustum.planes.forEach(({ normal, constant }, i) => floats.set([normal.x, normal.y, normal.z, constant], (FLOATS_AT.planes + i) * 4));
|
|
72
|
+
buffers.floats.needsUpdate = true;
|
|
73
|
+
buffers.due = true;
|
|
74
|
+
}
|
|
75
|
+
/** Sort for `camera` on `renderer`, in one compute call, if due: before a level mesh draws for it. */
|
|
76
|
+
run(renderer, camera, matrices) {
|
|
77
|
+
const buffers = this.cameras.get(camera);
|
|
78
|
+
if (!buffers?.due)
|
|
79
|
+
return;
|
|
80
|
+
const sort = {
|
|
81
|
+
...buffers,
|
|
82
|
+
matrices,
|
|
83
|
+
scaled: this.scaled?.attribute ?? this.unscaled,
|
|
84
|
+
counts: this.counts,
|
|
85
|
+
draws: this.drawBuffer,
|
|
86
|
+
};
|
|
87
|
+
const passes = (this.passes ??= sortPasses(sort));
|
|
88
|
+
passes.point(sort, buffers.blockCount);
|
|
89
|
+
renderer.compute([passes.update, passes.indirect]);
|
|
90
|
+
buffers.due = false;
|
|
91
|
+
// The pass made the scaled matrices' buffer: only the GPU writes them.
|
|
92
|
+
if (this.scaled && this.scaled.attribute.array.length > 0)
|
|
93
|
+
this.scaled.attribute.array = new Float32Array(0);
|
|
94
|
+
}
|
|
95
|
+
/** `camera` no longer draws the Lod: its buffers are freed. */
|
|
96
|
+
release(camera) {
|
|
97
|
+
const buffers = this.cameras.get(camera);
|
|
98
|
+
if (!buffers)
|
|
99
|
+
return;
|
|
100
|
+
this.cameras.delete(camera);
|
|
101
|
+
disposeBuffers(buffers);
|
|
102
|
+
}
|
|
103
|
+
dispose() {
|
|
104
|
+
for (const buffers of this.cameras.values())
|
|
105
|
+
disposeBuffers(buffers);
|
|
106
|
+
this.cameras.clear();
|
|
107
|
+
this.drawBuffer.dispose();
|
|
108
|
+
this.counts.dispose();
|
|
109
|
+
this.scaled?.attribute.dispose();
|
|
110
|
+
this.unscaled.dispose();
|
|
111
|
+
this.passes?.dispose();
|
|
112
|
+
this.passes = null;
|
|
113
|
+
}
|
|
114
|
+
makeBuffers() {
|
|
115
|
+
return {
|
|
116
|
+
words: wordsBuffer(),
|
|
117
|
+
floats: floatsBuffer(),
|
|
118
|
+
blocks: blocksBuffer(1),
|
|
119
|
+
blockCount: 1,
|
|
120
|
+
indices: new StorageBufferAttribute(new Uint32Array(1), 1),
|
|
121
|
+
fades: new StorageBufferAttribute(new Float32Array(1), 1),
|
|
122
|
+
listSize: 0,
|
|
123
|
+
args: argsBuffer(this.draws.length),
|
|
124
|
+
due: false,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/** Grow `buffers`' lists to hold `instances` per level, by doubling, each buffer within `limit` bytes. */
|
|
128
|
+
grow(buffers, instances, limit) {
|
|
129
|
+
let size = Math.max(buffers.listSize, 1);
|
|
130
|
+
while (size < instances)
|
|
131
|
+
size *= 2;
|
|
132
|
+
const slots = countBits(this.listed) * size;
|
|
133
|
+
if (slots * 4 > limit)
|
|
134
|
+
throw new RangeError(`Lod: lists of ${size} instances for each of its ${countBits(this.listed)} levels take ${slots * 4} bytes, more than the device's storage binding of ${limit} bytes: draw fewer instances in view of one camera per Lod, or raise maxStorageBufferBindingSize in the renderer's requiredLimits`);
|
|
135
|
+
buffers.indices.dispose();
|
|
136
|
+
buffers.fades.dispose();
|
|
137
|
+
buffers.indices = new StorageBufferAttribute(new Uint32Array(slots), 1);
|
|
138
|
+
buffers.fades = new StorageBufferAttribute(new Float32Array(slots), 1);
|
|
139
|
+
buffers.listSize = size;
|
|
140
|
+
}
|
|
141
|
+
/** Write the blocks of `ranges` into `buffers`: one empty block for none, as a dispatch visits one at least. */
|
|
142
|
+
writeBlocks(buffers, ranges) {
|
|
143
|
+
let count = 0;
|
|
144
|
+
for (let i = 0; i < ranges.length; i += 2)
|
|
145
|
+
count += Math.ceil((ranges[i + 1] ?? 0) / BLOCK);
|
|
146
|
+
if (count > MAX_BLOCKS)
|
|
147
|
+
throw new RangeError(`Lod: a camera sees ${count} blocks of ${BLOCK} instances, more than one dispatch's ${MAX_BLOCKS}: split the instances across Lods`);
|
|
148
|
+
if (buffers.blocks.count < Math.max(count, 1)) {
|
|
149
|
+
buffers.blocks.dispose();
|
|
150
|
+
buffers.blocks = blocksBuffer(count);
|
|
151
|
+
}
|
|
152
|
+
const words = buffers.blocks.array;
|
|
153
|
+
let at = 0;
|
|
154
|
+
for (let i = 0; i < ranges.length; i += 2) {
|
|
155
|
+
const start = ranges[i] ?? 0;
|
|
156
|
+
const end = start + (ranges[i + 1] ?? 0);
|
|
157
|
+
for (let first = start; first < end; first += BLOCK)
|
|
158
|
+
words.set([first, end], 2 * at++);
|
|
159
|
+
}
|
|
160
|
+
if (count === 0)
|
|
161
|
+
words.set([0, 0], 0);
|
|
162
|
+
buffers.blockCount = Math.max(count, 1);
|
|
163
|
+
buffers.blocks.needsUpdate = true;
|
|
164
|
+
}
|
|
165
|
+
/** Write the layout of `buffers`' lists and the draw count into its row. */
|
|
166
|
+
place(buffers) {
|
|
167
|
+
const words = buffers.words.array;
|
|
168
|
+
words[INTS_AT.flags * 4 + 3] = this.draws.length;
|
|
169
|
+
words[INTS_AT.layout * 4] = buffers.listSize;
|
|
170
|
+
let next = 0;
|
|
171
|
+
for (let level = 0; level < MAX_LEVELS; level++) {
|
|
172
|
+
const on = (this.listed & (1 << level)) !== 0;
|
|
173
|
+
words[INTS_AT.starts * 4 + level] = on ? next : UNLISTED;
|
|
174
|
+
if (on)
|
|
175
|
+
next += buffers.listSize;
|
|
176
|
+
}
|
|
177
|
+
buffers.words.needsUpdate = true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function disposeBuffers({ words, floats, blocks, indices, fades, args }) {
|
|
181
|
+
for (const attribute of [words, floats, blocks, indices, fades, args])
|
|
182
|
+
attribute.dispose();
|
|
183
|
+
}
|
|
184
|
+
const blocksBuffer = (blocks) => new StorageBufferAttribute(new Uint32Array(Math.max(blocks, 1) * 2), 2);
|
|
185
|
+
/** Set bits of `mask`. */
|
|
186
|
+
function countBits(mask) {
|
|
187
|
+
let count = 0;
|
|
188
|
+
for (let bits = mask; bits !== 0; bits &= bits - 1)
|
|
189
|
+
count++;
|
|
190
|
+
return count;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=sort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/instanced/sort.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { IndirectStorageBufferAttribute, StorageBufferAttribute, StorageInstancedBufferAttribute } from "three/webgpu";
|
|
2
|
+
/** Instances per block of a range, one workgroup's lanes. */
|
|
3
|
+
export declare const BLOCK = 64;
|
|
4
|
+
/** WebGPU's guaranteed maxComputeWorkgroupsPerDimension: the most blocks one sort visits. */
|
|
5
|
+
export declare const MAX_BLOCKS = 65535;
|
|
6
|
+
/** The buffers the sort passes read and write: pointed at a camera's (row, blocks, lists, args) as it sorts. */
|
|
7
|
+
export interface SortBuffers {
|
|
8
|
+
/** The camera's row: its u32s and its f32s (see rows.ts). */
|
|
9
|
+
words: StorageBufferAttribute;
|
|
10
|
+
floats: StorageBufferAttribute;
|
|
11
|
+
/** Per block the camera sorts, its first instance and the end of its range. */
|
|
12
|
+
blocks: StorageBufferAttribute;
|
|
13
|
+
/** The instances' matrices, and survivors' scaled ones, which the level meshes draw while survivors scale. */
|
|
14
|
+
matrices: StorageInstancedBufferAttribute;
|
|
15
|
+
scaled: StorageInstancedBufferAttribute;
|
|
16
|
+
/** The camera's slots: per slot, the instance it draws and its signed fade. */
|
|
17
|
+
indices: StorageBufferAttribute;
|
|
18
|
+
fades: StorageBufferAttribute;
|
|
19
|
+
/** Per level, how many instances it holds for the camera: counted by updateInstance, cleared by the indirect pass. */
|
|
20
|
+
counts: StorageBufferAttribute;
|
|
21
|
+
/** The Lod's draws (see `drawWords` in rows.ts). */
|
|
22
|
+
draws: StorageBufferAttribute;
|
|
23
|
+
/** The camera's indirect draws, five words each, in the order of `draws`. */
|
|
24
|
+
args: IndirectStorageBufferAttribute;
|
|
25
|
+
}
|
|
26
|
+
/** The sort passes over `buffers`, their nodes pointed at other buffers by `point`. */
|
|
27
|
+
export declare function sortPasses(buffers: SortBuffers): {
|
|
28
|
+
update: import("three/webgpu").ComputeNode;
|
|
29
|
+
indirect: import("three/webgpu").ComputeNode;
|
|
30
|
+
/** Point the passes at `next`, dispatching the update pass over its `blocks` blocks: before they run. */
|
|
31
|
+
point(next: SortBuffers, blocks: number): void;
|
|
32
|
+
dispose(): void;
|
|
33
|
+
};
|
|
34
|
+
export type SortPasses = ReturnType<typeof sortPasses>;
|