@drawcall/lod 0.2.0 → 0.3.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 +8 -6
- package/dist/bake.d.ts +22 -0
- package/dist/bake.js +88 -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 +12 -6
- package/dist/baked/index.js +22 -20
- package/dist/baked/index.js.map +1 -1
- package/dist/baked/interior/faces.d.ts +4 -3
- package/dist/baked/interior/faces.js +13 -10
- 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.js +1 -1
- 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 +7 -4
- package/dist/dispose.js +20 -22
- package/dist/dispose.js.map +1 -1
- package/dist/gpu.d.ts +39 -0
- package/dist/gpu.js +41 -0
- package/dist/gpu.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 +41 -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 +2 -2
- package/dist/impostor/bake/source.js +8 -19
- 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 +117 -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 +64 -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 +12 -0
- package/dist/impostor/ktx2/worker.js.map +1 -0
- package/dist/impostor/mesh/card.d.ts +3 -3
- package/dist/impostor/mesh/card.js +7 -7
- package/dist/impostor/mesh/card.js.map +1 -1
- package/dist/impostor/mesh/index.d.ts +5 -4
- package/dist/impostor/mesh/index.js +8 -9
- 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 +15 -10
- package/dist/index.js +13 -8
- package/dist/index.js.map +1 -1
- package/dist/instanced/camera.d.ts +46 -0
- package/dist/instanced/camera.js +70 -0
- package/dist/instanced/camera.js.map +1 -0
- package/dist/instanced/chunk.d.ts +97 -0
- package/dist/instanced/chunk.js +156 -0
- package/dist/instanced/chunk.js.map +1 -0
- package/dist/instanced/chunks.d.ts +60 -0
- package/dist/instanced/chunks.js +208 -0
- package/dist/instanced/chunks.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/index.d.ts +96 -66
- package/dist/instanced/index.js +229 -288
- package/dist/instanced/index.js.map +1 -1
- 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 +130 -0
- package/dist/instanced/levels.js.map +1 -0
- package/dist/instanced/lists.d.ts +70 -0
- package/dist/instanced/lists.js +133 -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 +42 -51
- package/dist/instanced/meshes.js +158 -180
- package/dist/instanced/meshes.js.map +1 -1
- package/dist/instanced/mirror.d.ts +20 -0
- package/dist/instanced/mirror.js +37 -0
- package/dist/instanced/mirror.js.map +1 -0
- package/dist/instanced/pages/buffers.d.ts +37 -0
- package/dist/instanced/pages/buffers.js +15 -0
- package/dist/instanced/pages/buffers.js.map +1 -0
- package/dist/instanced/pages/chunk.d.ts +51 -0
- package/dist/instanced/pages/chunk.js +81 -0
- package/dist/instanced/pages/chunk.js.map +1 -0
- package/dist/instanced/pages/index.d.ts +74 -0
- package/dist/instanced/pages/index.js +269 -0
- package/dist/instanced/pages/index.js.map +1 -0
- package/dist/instanced/pages/passes.d.ts +21 -0
- package/dist/instanced/pages/passes.js +52 -0
- package/dist/instanced/pages/passes.js.map +1 -0
- package/dist/instanced/pages/slots.d.ts +11 -0
- package/dist/instanced/pages/slots.js +90 -0
- package/dist/instanced/pages/slots.js.map +1 -0
- package/dist/instanced/pages/workgroup.d.ts +14 -0
- package/dist/instanced/pages/workgroup.js +38 -0
- package/dist/instanced/pages/workgroup.js.map +1 -0
- package/dist/instanced/raycast.d.ts +13 -11
- package/dist/instanced/raycast.js +33 -40
- package/dist/instanced/raycast.js.map +1 -1
- package/dist/instanced/rows.d.ts +108 -0
- package/dist/instanced/rows.js +209 -0
- package/dist/instanced/rows.js.map +1 -0
- package/dist/instanced/shape.d.ts +25 -0
- package/dist/instanced/shape.js +51 -0
- package/dist/instanced/shape.js.map +1 -0
- package/dist/instanced/sort.d.ts +63 -0
- package/dist/instanced/sort.js +162 -0
- package/dist/instanced/sort.js.map +1 -0
- package/dist/instanced/update.d.ts +30 -0
- package/dist/instanced/update.js +207 -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 +39 -0
- package/dist/levels/compile/index.js +185 -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 +177 -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 +69 -0
- package/dist/levels/fade.js +150 -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 +97 -0
- package/dist/levels/item.js.map +1 -0
- package/dist/levels/load.d.ts +31 -0
- package/dist/levels/load.js +142 -0
- package/dist/levels/load.js.map +1 -0
- package/dist/levels/manager.d.ts +159 -0
- package/dist/levels/manager.js +339 -0
- package/dist/levels/manager.js.map +1 -0
- package/dist/{material.js → levels/material.js} +4 -3
- package/dist/levels/material.js.map +1 -0
- package/dist/levels/renderer.d.ts +29 -0
- package/dist/levels/renderer.js +41 -0
- package/dist/levels/renderer.js.map +1 -0
- package/dist/levels/requests.d.ts +49 -0
- package/dist/levels/requests.js +95 -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/levels/wait.d.ts +27 -0
- package/dist/levels/wait.js +61 -0
- package/dist/levels/wait.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/cache.d.ts +6 -9
- package/dist/loader/cache.js +17 -24
- package/dist/loader/cache.js.map +1 -1
- package/dist/loader/context.d.ts +46 -0
- package/dist/loader/context.js +91 -0
- package/dist/loader/context.js.map +1 -0
- package/dist/loader/{provenance.d.ts → dependencies.d.ts} +5 -3
- package/dist/loader/{provenance.js → dependencies.js} +12 -4
- package/dist/loader/dependencies.js.map +1 -0
- package/dist/loader/index.d.ts +62 -0
- package/dist/loader/index.js +284 -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/request.d.ts +87 -0
- package/dist/loader/request.js +59 -0
- package/dist/loader/request.js.map +1 -0
- package/dist/loader/url.d.ts +5 -2
- package/dist/loader/url.js +10 -6
- package/dist/loader/url.js.map +1 -1
- package/dist/lod.d.ts +81 -40
- package/dist/lod.js +196 -149
- package/dist/lod.js.map +1 -1
- package/dist/meshopt.d.ts +6 -0
- package/dist/meshopt.js +19 -0
- package/dist/meshopt.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} +7 -4
- package/dist/{simplify.js → simplify/index.js} +41 -23
- package/dist/simplify/index.js.map +1 -0
- package/dist/{bounds.d.ts → source/detail.d.ts} +4 -23
- package/dist/{bounds.js → source/detail.js} +19 -51
- 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} +3 -3
- 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 +13 -24
- package/dist/three.js +26 -53
- 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 +2 -2
- 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 +2 -2
- package/dist/wind/index.js +15 -15
- 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 +18 -8
- package/skills/lod/SKILL.md +108 -31
- 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/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/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
- /package/dist/{material.d.ts → levels/material.d.ts} +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Box3, Vector3 } from "three/webgpu";
|
|
2
|
+
import { MeshoptSimplifier } from "meshoptimizer";
|
|
3
|
+
import { at } from "../at.js";
|
|
4
|
+
import { triangleArea } from "../source/surface.js";
|
|
5
|
+
import { isTexture } from "../three.js";
|
|
6
|
+
// Simplifying cards: the alpha-tested quads foliage draws (needles, leaves), which simplify decimates card by card rather
|
|
7
|
+
// than collapsing their edges.
|
|
8
|
+
/** Per material of `mesh`, whether it alpha-tests a texture, so draws cards. */
|
|
9
|
+
export function cardMaterials(mesh) {
|
|
10
|
+
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
11
|
+
return materials.map((m) => m.alphaTest > 0 && ["map" in m && m.map, "alphaMap" in m && m.alphaMap].some(isTexture));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* About `ratio` of the cards (connected parts, touching where vertices share a position)
|
|
15
|
+
* of the triangles `indices`, spread evenly over them by meshopt's point simplifier on the
|
|
16
|
+
* cards' centres. Each picked card is enlarged about its centre, in `positions`, so the picked
|
|
17
|
+
* cards cover as much area as all did; a card larger than most grows only as far as a
|
|
18
|
+
* card of the median size does, or a long spray would reach far out of the crown, and no
|
|
19
|
+
* card grows past the bounds of all, which a level must stay inside.
|
|
20
|
+
* Edge collapse would instead shrink and warp each card, and so cut most of an
|
|
21
|
+
* alpha-tested texture (needles, leaves) away.
|
|
22
|
+
*/
|
|
23
|
+
export function decimateCards(indices, positions, ratio) {
|
|
24
|
+
const { card, count } = cards(indices, positions);
|
|
25
|
+
const corner = (t, k) => indices[t * 3 + k] ?? 0;
|
|
26
|
+
const point = new Vector3();
|
|
27
|
+
const area = new Float64Array(count);
|
|
28
|
+
const centre = Array.from({ length: count }, () => new Vector3());
|
|
29
|
+
const corners = new Uint32Array(count);
|
|
30
|
+
card.forEach((c, t) => {
|
|
31
|
+
area[c] = (area[c] ?? 0) + triangleArea(positions, 3, indices, t * 3);
|
|
32
|
+
for (let k = 0; k < 3; k++)
|
|
33
|
+
at(centre, c).add(point.fromArray(positions, corner(t, k) * 3));
|
|
34
|
+
corners[c] = (corners[c] ?? 0) + 3;
|
|
35
|
+
});
|
|
36
|
+
centre.forEach((p, c) => p.divideScalar(corners[c] ?? 1));
|
|
37
|
+
const radius = new Float64Array(count);
|
|
38
|
+
const box = Array.from({ length: count }, () => new Box3());
|
|
39
|
+
const bounds = new Box3();
|
|
40
|
+
card.forEach((c, t) => {
|
|
41
|
+
for (let k = 0; k < 3; k++) {
|
|
42
|
+
point.fromArray(positions, corner(t, k) * 3);
|
|
43
|
+
radius[c] = Math.max(radius[c] ?? 0, point.distanceTo(at(centre, c)));
|
|
44
|
+
at(box, c).expandByPoint(point);
|
|
45
|
+
bounds.expandByPoint(point);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const median = Float64Array.from(radius).sort()[count >> 1] ?? 0;
|
|
49
|
+
// The most each card can grow about its centre and stay inside `bounds`.
|
|
50
|
+
const fit = centre.map((p, c) => {
|
|
51
|
+
const { min, max } = at(box, c);
|
|
52
|
+
let most = Infinity;
|
|
53
|
+
for (const axis of ["x", "y", "z"]) {
|
|
54
|
+
if (max[axis] > p[axis])
|
|
55
|
+
most = Math.min(most, (bounds.max[axis] - p[axis]) / (max[axis] - p[axis]));
|
|
56
|
+
if (min[axis] < p[axis])
|
|
57
|
+
most = Math.min(most, (p[axis] - bounds.min[axis]) / (p[axis] - min[axis]));
|
|
58
|
+
}
|
|
59
|
+
return Math.max(1, most);
|
|
60
|
+
});
|
|
61
|
+
const picked = new Uint8Array(count);
|
|
62
|
+
const target = Math.max(1, Math.round(count * ratio));
|
|
63
|
+
const points = Float32Array.from(centre.flatMap((p) => p.toArray()));
|
|
64
|
+
for (const c of target < count ? MeshoptSimplifier.simplifyPoints(points, 3, target) : picked.keys())
|
|
65
|
+
picked[c] = 1;
|
|
66
|
+
// `scale` enlarges a median card; bisect for the one at which the picked cards cover what all did.
|
|
67
|
+
const grow = (c, scale) => Math.min(scale, fit[c] ?? 1, Math.max(1, (scale * median) / Math.max(radius[c] ?? 0, 1e-30)));
|
|
68
|
+
const covered = (scale) => area.reduce((sum, a, c) => sum + (picked[c] ? a * grow(c, scale) ** 2 : 0), 0);
|
|
69
|
+
const total = area.reduce((sum, a) => sum + a, 0);
|
|
70
|
+
let [low, high] = [1, 1];
|
|
71
|
+
while (covered(high) < total && high < 1e6)
|
|
72
|
+
high *= 2;
|
|
73
|
+
for (let i = 0; i < 40; i++) {
|
|
74
|
+
const mid = (low + high) / 2;
|
|
75
|
+
if (covered(mid) < total)
|
|
76
|
+
low = mid;
|
|
77
|
+
else
|
|
78
|
+
high = mid;
|
|
79
|
+
}
|
|
80
|
+
const out = [];
|
|
81
|
+
const moved = new Uint8Array(positions.length / 3);
|
|
82
|
+
card.forEach((c, t) => {
|
|
83
|
+
if (!picked[c])
|
|
84
|
+
return;
|
|
85
|
+
const p = at(centre, c);
|
|
86
|
+
for (let k = 0; k < 3; k++) {
|
|
87
|
+
const v = corner(t, k);
|
|
88
|
+
out.push(v);
|
|
89
|
+
if (moved[v])
|
|
90
|
+
continue;
|
|
91
|
+
moved[v] = 1;
|
|
92
|
+
point
|
|
93
|
+
.fromArray(positions, v * 3)
|
|
94
|
+
.sub(p)
|
|
95
|
+
.multiplyScalar(grow(c, high))
|
|
96
|
+
.add(p)
|
|
97
|
+
.toArray(positions, v * 3);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return Uint32Array.from(out);
|
|
101
|
+
}
|
|
102
|
+
/** The card of each triangle, numbered 0..count-1. */
|
|
103
|
+
function cards(indices, positions) {
|
|
104
|
+
const remap = MeshoptSimplifier.generatePositionRemap(positions, 3);
|
|
105
|
+
const parent = Uint32Array.from(remap.keys());
|
|
106
|
+
const root = (vertex) => {
|
|
107
|
+
let v = remap[vertex] ?? vertex;
|
|
108
|
+
while (parent[v] !== v)
|
|
109
|
+
v = parent[v] = parent[parent[v] ?? v] ?? v;
|
|
110
|
+
return v;
|
|
111
|
+
};
|
|
112
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
113
|
+
const a = root(indices[i] ?? 0);
|
|
114
|
+
parent[root(indices[i + 1] ?? 0)] = a;
|
|
115
|
+
parent[root(indices[i + 2] ?? 0)] = a;
|
|
116
|
+
}
|
|
117
|
+
const number = new Map();
|
|
118
|
+
const card = new Uint32Array(indices.length / 3);
|
|
119
|
+
for (let t = 0; t < card.length; t++) {
|
|
120
|
+
const r = root(indices[t * 3] ?? 0);
|
|
121
|
+
let c = number.get(r);
|
|
122
|
+
if (c === undefined)
|
|
123
|
+
number.set(r, (c = number.size));
|
|
124
|
+
card[t] = c;
|
|
125
|
+
}
|
|
126
|
+
return { card, count: number.size };
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=cards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cards.js","sourceRoot":"","sources":["../../src/simplify/cards.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { type Object3D } from "three/webgpu";
|
|
2
2
|
export interface SimplifyOptions {
|
|
3
|
-
/** share of each mesh's triangles
|
|
3
|
+
/** share of each mesh's triangles that remains, in (0, 1]; default 0.5 */
|
|
4
4
|
ratio?: number;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* A copy of `object` with the geometry of every mesh drawn at full detail decimated by
|
|
8
8
|
* meshoptimizer to about `ratio` of its triangles: of a nested LOD only level 0 (its other
|
|
9
|
-
* levels are
|
|
9
|
+
* levels stay as they are), of an InstancedMesh the geometry its instances share. Materials (and
|
|
10
10
|
* so textures) are the originals, shared with `object`. Meshes that share a geometry
|
|
11
11
|
* share the simplified one. Morph targets are dropped. ImpostorMeshes and hidden meshes
|
|
12
|
-
*
|
|
12
|
+
* stay as they are. Skinned meshes and InstancedLods are refused: simplify an
|
|
13
13
|
* InstancedLod's source and build a new InstancedLod of it.
|
|
14
14
|
*
|
|
15
|
-
* Per material group it
|
|
15
|
+
* Per material group it preserves UV and normal seams; if that cannot reach the target it
|
|
16
16
|
* lets seams collapse, and as a last resort ignores topology (meshopt's sloppy mode).
|
|
17
|
+
* A group drawn with an alpha-tested texture (foliage cards) is decimated card by card
|
|
18
|
+
* instead: about `ratio` of its cards remain, whole, spread evenly and enlarged to cover
|
|
19
|
+
* what all covered (see `decimateCards`).
|
|
17
20
|
*
|
|
18
21
|
* How far the copy's surface is from `object`'s (the 99.9th percentile of the distance
|
|
19
22
|
* between the two, by area, over the parts seen from outside; ImpostorMeshes left out)
|
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
import { BufferAttribute, BufferGeometry } from "three/webgpu";
|
|
2
2
|
import { mergeVertices } from "three/addons/utils/BufferGeometryUtils.js";
|
|
3
3
|
import { MeshoptSimplifier } from "meshoptimizer";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
4
|
+
import { recordDeviation } from "../levels/index.js";
|
|
5
|
+
import { detailed } from "../source/detail.js";
|
|
6
|
+
import { measureDeviation } from "../source/deviation.js";
|
|
7
|
+
import { readSource } from "../source/source.js";
|
|
8
|
+
import { merge } from "../source/surface.js";
|
|
9
|
+
import { isImpostorMesh, isInstancedLod, isMesh, isSkinnedMesh } from "../three.js";
|
|
10
|
+
import { cardMaterials, decimateCards } from "./cards.js";
|
|
11
11
|
/**
|
|
12
12
|
* A copy of `object` with the geometry of every mesh drawn at full detail decimated by
|
|
13
13
|
* meshoptimizer to about `ratio` of its triangles: of a nested LOD only level 0 (its other
|
|
14
|
-
* levels are
|
|
14
|
+
* levels stay as they are), of an InstancedMesh the geometry its instances share. Materials (and
|
|
15
15
|
* so textures) are the originals, shared with `object`. Meshes that share a geometry
|
|
16
16
|
* share the simplified one. Morph targets are dropped. ImpostorMeshes and hidden meshes
|
|
17
|
-
*
|
|
17
|
+
* stay as they are. Skinned meshes and InstancedLods are refused: simplify an
|
|
18
18
|
* InstancedLod's source and build a new InstancedLod of it.
|
|
19
19
|
*
|
|
20
|
-
* Per material group it
|
|
20
|
+
* Per material group it preserves UV and normal seams; if that cannot reach the target it
|
|
21
21
|
* lets seams collapse, and as a last resort ignores topology (meshopt's sloppy mode).
|
|
22
|
+
* A group drawn with an alpha-tested texture (foliage cards) is decimated card by card
|
|
23
|
+
* instead: about `ratio` of its cards remain, whole, spread evenly and enlarged to cover
|
|
24
|
+
* what all covered (see `decimateCards`).
|
|
22
25
|
*
|
|
23
26
|
* How far the copy's surface is from `object`'s (the 99.9th percentile of the distance
|
|
24
27
|
* between the two, by area, over the parts seen from outside; ImpostorMeshes left out)
|
|
@@ -34,7 +37,7 @@ export async function decimate(object, ratio) {
|
|
|
34
37
|
if (!(ratio > 0 && ratio <= 1))
|
|
35
38
|
throw new Error(`simplify: ratio must be in (0, 1], got ${ratio}`);
|
|
36
39
|
await MeshoptSimplifier.ready;
|
|
37
|
-
// clone() also visits hidden children, whose
|
|
40
|
+
// clone() also visits hidden children, whose InstancedLod allocations must never be
|
|
38
41
|
// created just to reject them (or skipped by the visible-detail walk below).
|
|
39
42
|
object.traverse((node) => {
|
|
40
43
|
if (isInstancedLod(node))
|
|
@@ -44,21 +47,25 @@ export async function decimate(object, ratio) {
|
|
|
44
47
|
});
|
|
45
48
|
const copy = object.clone(true);
|
|
46
49
|
decimateTree(copy, ratio, new Map());
|
|
47
|
-
borrowMaterials(copy);
|
|
48
50
|
return copy;
|
|
49
51
|
}
|
|
50
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Decimate the meshes of `node` drawn at full detail; `done` maps each geometry, with
|
|
54
|
+
* which of its material indices are cards, to its simplified one.
|
|
55
|
+
*/
|
|
51
56
|
function decimateTree(node, ratio, done) {
|
|
52
57
|
if (isMesh(node) && !isImpostorMesh(node)) {
|
|
53
|
-
|
|
58
|
+
const cards = cardMaterials(node);
|
|
59
|
+
const key = `${node.geometry.uuid} ${cards.join()}`;
|
|
60
|
+
let geometry = done.get(key);
|
|
54
61
|
if (!geometry)
|
|
55
|
-
done.set(
|
|
62
|
+
done.set(key, (geometry = simplifyGeometry(node.geometry, ratio, cards)));
|
|
56
63
|
node.geometry = geometry;
|
|
57
64
|
}
|
|
58
65
|
for (const child of detailed(node))
|
|
59
66
|
decimateTree(child, ratio, done);
|
|
60
67
|
}
|
|
61
|
-
function simplifyGeometry(source, ratio) {
|
|
68
|
+
function simplifyGeometry(source, ratio, cards) {
|
|
62
69
|
const geometry = source.index ? source : mergeVertices(source);
|
|
63
70
|
const index = geometry.index;
|
|
64
71
|
if (!index)
|
|
@@ -67,12 +74,20 @@ function simplifyGeometry(source, ratio) {
|
|
|
67
74
|
const { attributes, stride, weights } = simplifierAttributes(geometry);
|
|
68
75
|
const groups = geometry.groups.length > 0 ? geometry.groups : [{ start: 0, count: index.count, materialIndex: 0 }];
|
|
69
76
|
const parts = [];
|
|
77
|
+
let decimatedCards = false;
|
|
70
78
|
for (const group of groups) {
|
|
71
79
|
const indices = new Uint32Array(Math.min(group.count, index.count - group.start));
|
|
72
80
|
for (let i = 0; i < indices.length; i++)
|
|
73
81
|
indices[i] = index.getX(group.start + i);
|
|
74
|
-
const
|
|
75
|
-
|
|
82
|
+
const materialIndex = group.materialIndex ?? 0;
|
|
83
|
+
// A single material draws every group.
|
|
84
|
+
const card = (cards.length === 1 ? cards[0] : cards[materialIndex]) ?? false;
|
|
85
|
+
if (card)
|
|
86
|
+
decimatedCards = true;
|
|
87
|
+
const simplified = card
|
|
88
|
+
? decimateCards(indices, positions, ratio)
|
|
89
|
+
: simplifyIndices(indices, positions, attributes, stride, weights, Math.floor((indices.length / 3) * ratio) * 3)[0];
|
|
90
|
+
parts.push({ indices: simplified, materialIndex });
|
|
76
91
|
}
|
|
77
92
|
const all = new Uint32Array(parts.reduce((n, p) => n + p.indices.length, 0));
|
|
78
93
|
const out = new BufferGeometry();
|
|
@@ -84,8 +99,11 @@ function simplifyGeometry(source, ratio) {
|
|
|
84
99
|
offset += part.indices.length;
|
|
85
100
|
}
|
|
86
101
|
const [remap, unique] = MeshoptSimplifier.compactMesh(all); // rewrites `all` in place
|
|
87
|
-
for (const [name, attribute] of Object.entries(geometry.attributes))
|
|
88
|
-
|
|
102
|
+
for (const [name, attribute] of Object.entries(geometry.attributes)) {
|
|
103
|
+
// decimateCards moved the remaining cards' vertices, past the range a quantized position may hold.
|
|
104
|
+
const from = name === "position" && decimatedCards ? new BufferAttribute(positions, 3) : attribute;
|
|
105
|
+
out.setAttribute(name, compactAttribute(from, remap, unique));
|
|
106
|
+
}
|
|
89
107
|
out.setIndex(new BufferAttribute(all, 1));
|
|
90
108
|
out.computeBoundingBox();
|
|
91
109
|
out.computeBoundingSphere();
|
|
@@ -100,7 +118,7 @@ function simplifyIndices(indices, positions, attributes, stride, weights, target
|
|
|
100
118
|
if (reached(permissive[0]))
|
|
101
119
|
return permissive;
|
|
102
120
|
const sloppy = MeshoptSimplifier.simplifySloppy(indices, positions, 3, null, target, 1);
|
|
103
|
-
// Sloppy can collapse a tiny target to nothing; then
|
|
121
|
+
// Sloppy can collapse a tiny target to nothing; then use the permissive result.
|
|
104
122
|
return sloppy[0].length > 0 ? sloppy : permissive;
|
|
105
123
|
}
|
|
106
124
|
/** Normal (weight 0.5) and UV (weight 1) packed per vertex for simplifyWithAttributes. */
|
|
@@ -126,7 +144,7 @@ function simplifierAttributes(geometry) {
|
|
|
126
144
|
}
|
|
127
145
|
function compactAttribute(attribute, remap, unique) {
|
|
128
146
|
const size = attribute.itemSize;
|
|
129
|
-
// A slice
|
|
147
|
+
// A slice has the array's type, so normalized and integer attributes hold their encoding;
|
|
130
148
|
// every element is written below (unique <= count, so it is long enough).
|
|
131
149
|
const out = new BufferAttribute(attribute.array.slice(0, unique * size), size, attribute.normalized);
|
|
132
150
|
for (let i = 0; i < remap.length; i++) {
|
|
@@ -147,4 +165,4 @@ function toFloat32(attribute) {
|
|
|
147
165
|
}
|
|
148
166
|
return out;
|
|
149
167
|
}
|
|
150
|
-
//# sourceMappingURL=
|
|
168
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/simplify/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Box3, Matrix4,
|
|
1
|
+
import { Box3, Matrix4, Vector3, type Mesh, type Object3D } from "three/webgpu";
|
|
2
2
|
/**
|
|
3
3
|
* Call `visit` with every mesh of `root` drawn at full detail, and the matrix that places
|
|
4
4
|
* it in `root`'s own space (`root`'s own transform not applied): `root` itself and its
|
|
@@ -10,6 +10,8 @@ import { Box3, Matrix4, Sphere, Vector3, type Mesh, type Object3D } from "three/
|
|
|
10
10
|
export declare function forEachMesh(root: Object3D, visit: (mesh: Mesh, placement: Matrix4) => void): void;
|
|
11
11
|
/** The children of `node` drawn at full detail: of a LOD its level 0, whatever it shows, else the visible ones. */
|
|
12
12
|
export declare function detailed(node: Object3D): Object3D[];
|
|
13
|
+
/** `node`'s matrix in its parent's space, up to date. */
|
|
14
|
+
export declare function local(node: Object3D): Matrix4;
|
|
13
15
|
/** Show level 0 of every LOD under `root` and stop them switching: a bake sees full detail. */
|
|
14
16
|
export declare function showDetail(root: Object3D): void;
|
|
15
17
|
/**
|
|
@@ -18,26 +20,5 @@ export declare function showDetail(root: Object3D): void;
|
|
|
18
20
|
* an ImpostorMesh. `visit` gets one reused vector.
|
|
19
21
|
*/
|
|
20
22
|
export declare function forEachVertex(root: Object3D, visit: (p: Vector3) => void): void;
|
|
21
|
-
/** Conservative full-detail bounds from cached geometry boxes and deferred metadata, in the root's space. */
|
|
23
|
+
/** Conservative full-detail bounds from cached geometry boxes and deferred metadata, in the root's space: what a bake measures. */
|
|
22
24
|
export declare function boundingBox(root: Object3D): Box3;
|
|
23
|
-
/** The centre and half diagonal of `boundingBox(root)`: an impostor baked from `root` has the same box. */
|
|
24
|
-
export declare function boundingSphere(root: Object3D): Sphere;
|
|
25
|
-
/**
|
|
26
|
-
* The sphere fades measure for a Lod's levels (see `boundingSphere`): level 0's, or the
|
|
27
|
-
* first level's that draws anything when level 0 draws nothing; `own` in that level's
|
|
28
|
-
* own space, `placed` in its parent's (the Lod's). `who` names the caller in the error.
|
|
29
|
-
*/
|
|
30
|
-
export declare function measureLevels(levels: readonly {
|
|
31
|
-
object?: Object3D;
|
|
32
|
-
box?: Box3;
|
|
33
|
-
}[], who: string): {
|
|
34
|
-
own: Sphere;
|
|
35
|
-
placed: Sphere;
|
|
36
|
-
};
|
|
37
|
-
/** A level's bounds in its owner's space, including an eager object's transform. */
|
|
38
|
-
export declare function levelBox(level: {
|
|
39
|
-
object?: Object3D;
|
|
40
|
-
box?: Box3;
|
|
41
|
-
}): Box3;
|
|
42
|
-
/** Fill absent mesh bounds conservatively from a deferred level's declared box, without reading vertices. */
|
|
43
|
-
export declare function prepareBounds(root: Object3D, box: Box3): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Box3, Matrix4,
|
|
2
|
-
import { isBatchedMesh, isImpostorMesh, isInstancedLod, isInstancedMesh, isLOD, isMesh } from "
|
|
1
|
+
import { Box3, Matrix4, Vector3 } from "three/webgpu";
|
|
2
|
+
import { isBatchedMesh, isImpostorMesh, isInstancedLod, isInstancedMesh, isLOD, isMesh, isStorageInstanced } from "../three.js";
|
|
3
3
|
// What an object is at full detail: its meshes, where they sit and the vertices they draw.
|
|
4
4
|
/**
|
|
5
5
|
* Call `visit` with every mesh of `root` drawn at full detail, and the matrix that places
|
|
@@ -20,8 +20,8 @@ function walk(node, placement, visit) {
|
|
|
20
20
|
if (!source)
|
|
21
21
|
return;
|
|
22
22
|
const instance = new Matrix4();
|
|
23
|
-
for (
|
|
24
|
-
walk(source, local(source).premultiply(
|
|
23
|
+
for (const { chunk, index } of instancesOf(node))
|
|
24
|
+
walk(source, local(source).premultiply(chunk.getMatrixAt(index, instance)).premultiply(placement), visit);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
if (isInstancedMesh(node) || isImpostorMesh(node)) {
|
|
@@ -42,7 +42,7 @@ export function detailed(node) {
|
|
|
42
42
|
return source ? [source] : [];
|
|
43
43
|
}
|
|
44
44
|
/** `node`'s matrix in its parent's space, up to date. */
|
|
45
|
-
function local(node) {
|
|
45
|
+
export function local(node) {
|
|
46
46
|
if (node.matrixAutoUpdate)
|
|
47
47
|
node.updateMatrix();
|
|
48
48
|
return node.matrix.clone();
|
|
@@ -97,7 +97,7 @@ export function forEachVertex(root, visit) {
|
|
|
97
97
|
visit(mesh.getVertexPosition(i, point).applyMatrix4(placement));
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
|
-
/** Conservative full-detail bounds from cached geometry boxes and deferred metadata, in the root's space. */
|
|
100
|
+
/** Conservative full-detail bounds from cached geometry boxes and deferred metadata, in the root's space: what a bake measures. */
|
|
101
101
|
export function boundingBox(root) {
|
|
102
102
|
const box = new Box3();
|
|
103
103
|
boxes(root, new Matrix4(), box);
|
|
@@ -108,10 +108,12 @@ function boxes(node, placement, box) {
|
|
|
108
108
|
const source = node.levels[0];
|
|
109
109
|
if (!source)
|
|
110
110
|
return;
|
|
111
|
-
|
|
111
|
+
// Its level 0 at every instance, as forEachMesh visits them: tighter than its level meshes' box (see InstancedLod).
|
|
112
|
+
// The box it declares, else the one it draws.
|
|
113
|
+
const own = source.box?.clone() ?? (source.object ? boundingBox(source.object).applyMatrix4(local(source.object)) : new Box3());
|
|
112
114
|
const instance = new Matrix4();
|
|
113
|
-
for (
|
|
114
|
-
box.union(own.clone().applyMatrix4(
|
|
115
|
+
for (const { chunk, index } of instancesOf(node))
|
|
116
|
+
box.union(own.clone().applyMatrix4(chunk.getMatrixAt(index, instance).premultiply(placement)));
|
|
115
117
|
return;
|
|
116
118
|
}
|
|
117
119
|
if (isLOD(node) && !node.levels[0]?.object) {
|
|
@@ -143,47 +145,13 @@ function boxes(node, placement, box) {
|
|
|
143
145
|
for (const child of detailed(node))
|
|
144
146
|
boxes(child, local(child).premultiply(placement), box);
|
|
145
147
|
}
|
|
146
|
-
/**
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
const sphereOf = (box) => (box.isEmpty() ? null : new Sphere(box.getCenter(new Vector3()), box.getSize(new Vector3()).length() / 2));
|
|
154
|
-
/**
|
|
155
|
-
* The sphere fades measure for a Lod's levels (see `boundingSphere`): level 0's, or the
|
|
156
|
-
* first level's that draws anything when level 0 draws nothing; `own` in that level's
|
|
157
|
-
* own space, `placed` in its parent's (the Lod's). `who` names the caller in the error.
|
|
158
|
-
*/
|
|
159
|
-
export function measureLevels(levels, who) {
|
|
160
|
-
for (const { object, box } of levels) {
|
|
161
|
-
const own = sphereOf(object ? boundingBox(object) : (box ?? new Box3()));
|
|
162
|
-
if (!own)
|
|
163
|
-
continue;
|
|
164
|
-
return { own, placed: object ? own.clone().applyMatrix4(local(object)) : own.clone() };
|
|
148
|
+
/** Every instance of `lod`'s chunks; a GPU chunk's live on the GPU, where the CPU cannot visit them. */
|
|
149
|
+
function* instancesOf(lod) {
|
|
150
|
+
for (const chunk of lod.chunks) {
|
|
151
|
+
if (isStorageInstanced(chunk.instanceMatrix))
|
|
152
|
+
throw new Error("@drawcall/lod: a GPU chunk's instances live on the GPU: the CPU cannot visit its meshes");
|
|
153
|
+
for (let index = 0; index < chunk.count; index++)
|
|
154
|
+
yield { chunk, index };
|
|
165
155
|
}
|
|
166
|
-
throw new Error(`${who}: no level has visible geometry to measure`);
|
|
167
|
-
}
|
|
168
|
-
/** A level's bounds in its owner's space, including an eager object's transform. */
|
|
169
|
-
export function levelBox(level) {
|
|
170
|
-
if (level.box)
|
|
171
|
-
return level.box.clone();
|
|
172
|
-
return level.object ? boundingBox(level.object).applyMatrix4(local(level.object)) : new Box3();
|
|
173
|
-
}
|
|
174
|
-
/** Fill absent mesh bounds conservatively from a deferred level's declared box, without reading vertices. */
|
|
175
|
-
export function prepareBounds(root, box) {
|
|
176
|
-
const visit = (node, placement) => {
|
|
177
|
-
if (isMesh(node)) {
|
|
178
|
-
if (placement.determinant() === 0)
|
|
179
|
-
throw new Error("Lod: mesh placement must be invertible");
|
|
180
|
-
const geometry = node.geometry;
|
|
181
|
-
geometry.boundingBox ??= box.clone().applyMatrix4(placement.clone().invert());
|
|
182
|
-
geometry.boundingSphere ??= geometry.boundingBox.getBoundingSphere(new Sphere());
|
|
183
|
-
}
|
|
184
|
-
for (const child of node.children)
|
|
185
|
-
visit(child, local(child).premultiply(placement));
|
|
186
|
-
};
|
|
187
|
-
visit(root, local(root));
|
|
188
156
|
}
|
|
189
|
-
//# sourceMappingURL=
|
|
157
|
+
//# sourceMappingURL=detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detail.js","sourceRoot":"","sources":["../../src/source/detail.ts"],"names":[],"mappings":"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"}
|
package/dist/source/deviation.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BufferAttribute, BufferGeometry, Vector3 } from "three/webgpu";
|
|
2
2
|
import { MeshBVH } from "three-mesh-bvh";
|
|
3
|
-
import {
|
|
3
|
+
import { MaterialEvaluator } from "./evaluator.js";
|
|
4
4
|
import { triangleArea } from "./surface.js";
|
|
5
|
-
import {
|
|
5
|
+
import { SourceRaycaster } from "./raycaster.js";
|
|
6
6
|
/** Points sampled per surface to measure the deviation. */
|
|
7
7
|
const SAMPLES = 20000;
|
|
8
8
|
/**
|
|
@@ -46,14 +46,14 @@ function visibility(source) {
|
|
|
46
46
|
const bounds = geometry.boundingSphere;
|
|
47
47
|
if (!bounds)
|
|
48
48
|
throw new Error("@drawcall/lod: the source has no bounds");
|
|
49
|
-
const
|
|
50
|
-
const
|
|
49
|
+
const evaluator = new MaterialEvaluator(source, 0);
|
|
50
|
+
const raycaster = new SourceRaycaster(source, evaluator);
|
|
51
51
|
const normal = new Vector3();
|
|
52
52
|
const corner = new Vector3();
|
|
53
53
|
const origin = new Vector3();
|
|
54
54
|
const epsilon = bounds.radius * 1e-4;
|
|
55
55
|
const far = bounds.radius * 4;
|
|
56
|
-
const escapes = (point, direction) =>
|
|
56
|
+
const escapes = (point, direction) => raycaster.cast(origin.copy(point).addScaledVector(direction, epsilon), direction, far, null) !== "opaque";
|
|
57
57
|
return (point, triangle) => {
|
|
58
58
|
const { positions, index } = source;
|
|
59
59
|
const a = (index[triangle * 3] ?? 0) * 3;
|
|
@@ -62,7 +62,7 @@ function visibility(source) {
|
|
|
62
62
|
normal.cross(corner).normalize();
|
|
63
63
|
if (escapes(point, normal))
|
|
64
64
|
return true;
|
|
65
|
-
return
|
|
65
|
+
return evaluator.material(triangle).doubleSided && escapes(point, normal.negate());
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
/** Call `visit` with points spread evenly by area over `from`, and the triangle of each. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviation.js","sourceRoot":"","sources":["../../src/source/deviation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"deviation.js","sourceRoot":"","sources":["../../src/source/deviation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Color, Vector2, Vector3, type Material, type Texture } from "three/webgpu";
|
|
2
2
|
import type { Source } from "./source.js";
|
|
3
|
-
import {
|
|
3
|
+
import { CpuTextureSampler } from "./sampler.js";
|
|
4
4
|
/**
|
|
5
5
|
* What the bake reads of a material, read as a MeshStandardMaterial: color, map, opacity,
|
|
6
6
|
* alphaMap, alphaTest, vertexColors, roughness (+ map G), metalness (+ map B), normalMap
|
|
@@ -9,8 +9,8 @@ import { Texels } from "./texels.js";
|
|
|
9
9
|
*/
|
|
10
10
|
export interface MaterialInputs {
|
|
11
11
|
color: Color;
|
|
12
|
-
map:
|
|
13
|
-
alphaMap:
|
|
12
|
+
map: CpuTextureSampler | null;
|
|
13
|
+
alphaMap: CpuTextureSampler | null;
|
|
14
14
|
opacity: number;
|
|
15
15
|
/**
|
|
16
16
|
* Whether alpha cuts holes: an alphaTest, or alpha to coverage without blending.
|
|
@@ -20,12 +20,12 @@ export interface MaterialInputs {
|
|
|
20
20
|
alphaTest: number;
|
|
21
21
|
vertexColors: boolean;
|
|
22
22
|
roughness: number;
|
|
23
|
-
roughnessMap:
|
|
23
|
+
roughnessMap: CpuTextureSampler | null;
|
|
24
24
|
metalness: number;
|
|
25
|
-
metalnessMap:
|
|
26
|
-
normalMap:
|
|
25
|
+
metalnessMap: CpuTextureSampler | null;
|
|
26
|
+
normalMap: CpuTextureSampler | null;
|
|
27
27
|
normalScale: Vector2;
|
|
28
|
-
aoMap:
|
|
28
|
+
aoMap: CpuTextureSampler | null;
|
|
29
29
|
aoMapIntensity: number;
|
|
30
30
|
doubleSided: boolean;
|
|
31
31
|
/**
|
|
@@ -36,14 +36,14 @@ export interface MaterialInputs {
|
|
|
36
36
|
transmittance: number;
|
|
37
37
|
}
|
|
38
38
|
/** `material` as the CPU reads it, to `bake` or to `measure` (see `readSource`). */
|
|
39
|
-
export declare function readMaterial(material: Material, cache: Map<Texture,
|
|
39
|
+
export declare function readMaterial(material: Material, cache: Map<Texture, CpuTextureSampler>, purpose: "bake" | "measure"): MaterialInputs;
|
|
40
40
|
/**
|
|
41
41
|
* What a ray met: the back of a single-sided surface (which three does not draw), a
|
|
42
42
|
* surface cut out at that point, or an opaque one.
|
|
43
43
|
*/
|
|
44
44
|
export type Hit = "back" | "cutout" | "opaque";
|
|
45
|
-
/** The source's material values at surface points: `test` where a ray meets one, `shade` the one it
|
|
46
|
-
export declare class
|
|
45
|
+
/** The source's material values at surface points: `test` where a ray meets one, `shade` the one it stops at. */
|
|
46
|
+
export declare class MaterialEvaluator {
|
|
47
47
|
private readonly source;
|
|
48
48
|
/** size of one baked texel in the source's units: mip levels are picked to match it */
|
|
49
49
|
private readonly texelSize;
|