@drawcall/lod 0.1.2 → 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 +13 -70
- package/dist/at.d.ts +2 -0
- package/dist/at.js +8 -0
- package/dist/at.js.map +1 -0
- 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 +5 -5
- package/dist/baked/codec.js +58 -158
- 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 +16 -6
- package/dist/baked/index.js +23 -21
- 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.d.ts +2 -2
- package/dist/baked/low.js +9 -8
- 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/codec/mesh.js +220 -0
- package/dist/codec/mesh.js.map +1 -0
- package/dist/dispose.d.ts +11 -4
- package/dist/dispose.js +39 -12
- 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 +23 -14
- package/dist/impostor/bake/index.js +42 -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 +60 -12
- 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 +5 -11
- package/dist/impostor/codec.js +37 -121
- 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 +11 -8
- package/dist/impostor/mesh/card.js.map +1 -1
- package/dist/impostor/mesh/index.d.ts +10 -7
- package/dist/impostor/mesh/index.js +15 -18
- package/dist/impostor/mesh/index.js.map +1 -1
- package/dist/impostor/mesh/material.d.ts +24 -13
- package/dist/impostor/mesh/material.js +67 -51
- package/dist/impostor/mesh/material.js.map +1 -1
- package/dist/impostor/mesh/surface.d.ts +20 -16
- package/dist/impostor/mesh/surface.js +81 -58
- 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/impostor/octahedral.d.ts +1 -8
- package/dist/impostor/octahedral.js +3 -18
- package/dist/impostor/octahedral.js.map +1 -1
- package/dist/index.d.ts +16 -10
- package/dist/index.js +14 -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 -92
- package/dist/instanced/index.js +229 -512
- 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 +46 -14
- package/dist/instanced/meshes.js +137 -22
- 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 +15 -0
- package/dist/instanced/raycast.js +46 -0
- package/dist/instanced/raycast.js.map +1 -0
- 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} +13 -7
- 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 +12 -15
- package/dist/loader/cache.js +64 -33
- 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/dependencies.d.ts +32 -0
- package/dist/loader/dependencies.js +113 -0
- 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 +16 -0
- package/dist/loader/url.js +35 -0
- package/dist/loader/url.js.map +1 -0
- package/dist/lod.d.ts +79 -49
- package/dist/lod.js +209 -153
- 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} +42 -22
- package/dist/simplify/index.js.map +1 -0
- package/dist/{bounds.d.ts → source/detail.d.ts} +4 -13
- package/dist/{bounds.js → source/detail.js} +62 -32
- package/dist/source/detail.js.map +1 -0
- package/dist/source/{error.d.ts → deviation.d.ts} +3 -3
- package/dist/source/{error.js → deviation.js} +12 -12
- package/dist/source/deviation.js.map +1 -0
- 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 +2 -2
- package/dist/source/source.js +2 -2
- 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 +20 -19
- package/dist/three.js +29 -35
- package/dist/three.js.map +1 -1
- package/dist/tsl.d.ts +10 -14
- package/dist/tsl.js +12 -47
- 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 +4 -4
- package/dist/wind/index.js +43 -40
- package/dist/wind/index.js.map +1 -1
- package/dist/wind/sway.d.ts +4 -1
- package/dist/wind/sway.js +4 -1
- package/dist/wind/sway.js.map +1 -1
- package/package.json +24 -8
- package/skills/lod/SKILL.md +147 -108
- package/dist/bounds.js.map +0 -1
- package/dist/fade.d.ts +0 -44
- package/dist/fade.js +0 -78
- package/dist/fade.js.map +0 -1
- package/dist/impostor/cache.d.ts +0 -15
- package/dist/impostor/cache.js +0 -44
- package/dist/impostor/cache.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/bounds.d.ts +0 -50
- package/dist/instanced/bounds.js +0 -271
- package/dist/instanced/bounds.js.map +0 -1
- package/dist/instanced/dirty.d.ts +0 -12
- package/dist/instanced/dirty.js +0 -61
- package/dist/instanced/dirty.js.map +0 -1
- package/dist/instanced/select.d.ts +0 -84
- package/dist/instanced/select.js +0 -264
- package/dist/instanced/select.js.map +0 -1
- package/dist/lazy.d.ts +0 -64
- package/dist/lazy.js +0 -187
- package/dist/lazy.js.map +0 -1
- package/dist/levels.d.ts +0 -72
- package/dist/levels.js +0 -146
- package/dist/levels.js.map +0 -1
- package/dist/loader/dispose.d.ts +0 -3
- package/dist/loader/dispose.js +0 -25
- package/dist/loader/dispose.js.map +0 -1
- package/dist/loader.d.ts +0 -99
- package/dist/loader.js +0 -234
- package/dist/loader.js.map +0 -1
- package/dist/material.js.map +0 -1
- package/dist/pause.d.ts +0 -6
- package/dist/pause.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/simplify.js.map +0 -1
- package/dist/source/error.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 -30
- package/dist/view.js +0 -75
- package/dist/view.js.map +0 -1
- /package/dist/{material.d.ts → levels/material.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcoder.js","sourceRoot":"","sources":["../../../../src/impostor/ktx2/wasm/transcoder.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,kEAAkE;AAClE,+EAA+E;AAC/E,mGAAmG;AAEnG,mHAAmH;AACnH,MAAM,CAAC,MAAM,aAAa,GACxB,0woBAA0woB,CAAC;AAC7woB,MAAM,CAAC,MAAM,eAAe,GAC1B,8u4UAA8u4U,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const url: string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { encode } from "./uastc.js";
|
|
2
|
+
export const url = import.meta.url;
|
|
3
|
+
const scope = Reflect.get(globalThis, "WorkerGlobalScope");
|
|
4
|
+
if (typeof scope === "function" && globalThis instanceof scope) {
|
|
5
|
+
// The encoder reports every image's progress on stdout, which Emscripten writes to console.log; nothing else here logs.
|
|
6
|
+
console.log = () => { };
|
|
7
|
+
addEventListener("message", (event) => {
|
|
8
|
+
encode(event.data).then((file) => reply({ file }, [file.buffer]), (error) => reply({ error: error instanceof Error ? error.message : String(error) }));
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
const reply = (message, transfer = []) => postMessage(message, { transfer });
|
|
12
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/impostor/ktx2/worker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;AAEnC,MAAM,KAAK,GAAY,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;AACpE,IAAI,OAAO,KAAK,KAAK,UAAU,IAAI,UAAU,YAAY,KAAK,EAAE,CAAC;IAC/D,wHAAwH;IACxH,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IACvB,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAwB,EAAE,EAAE;QACvD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CACrB,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EACxC,CAAC,KAAc,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAC7F,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,OAAc,EAAE,WAA2B,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC"}
|
|
@@ -8,7 +8,7 @@ export interface CardInputs {
|
|
|
8
8
|
extent: Node<"vec3">;
|
|
9
9
|
/** bounding sphere radius: the depth channel's unit */
|
|
10
10
|
radius: Node<"float">;
|
|
11
|
-
/** half the edge of every frame
|
|
11
|
+
/** half the edge of every frame */
|
|
12
12
|
halfSize: Node<"float">;
|
|
13
13
|
/** frames per atlas side */
|
|
14
14
|
frames: Node<"float">;
|
|
@@ -17,10 +17,10 @@ export interface CardInputs {
|
|
|
17
17
|
}
|
|
18
18
|
/** The card as the surface reads it. */
|
|
19
19
|
export declare const card: {
|
|
20
|
-
/** the three frames around the
|
|
20
|
+
/** the three frames around the direction to the camera and their barycentric weights */
|
|
21
21
|
readonly frames: readonly [Node<"vec2">, Node<"vec2">, Node<"vec2">];
|
|
22
22
|
readonly weights: import("three/webgpu").PropertyNode<"vec3">;
|
|
23
|
-
/** the
|
|
23
|
+
/** the camera's ray through the fragment, in the object's space: from `point`, along `ray` */
|
|
24
24
|
readonly point: import("three/webgpu").PropertyNode<"vec3">;
|
|
25
25
|
readonly ray: import("three/webgpu").PropertyNode<"vec3">;
|
|
26
26
|
/** the same ray in world space: `ray` × s in object space is `worldRay` × s in the world */
|
|
@@ -18,10 +18,10 @@ const first = written.frames.xy;
|
|
|
18
18
|
const neighbour = written.frames.z;
|
|
19
19
|
/** The card as the surface reads it. */
|
|
20
20
|
export const card = {
|
|
21
|
-
/** the three frames around the
|
|
21
|
+
/** the three frames around the direction to the camera and their barycentric weights */
|
|
22
22
|
frames: [first, first.add(vec2(neighbour, neighbour.oneMinus())), first.add(1)],
|
|
23
23
|
weights: written.weights,
|
|
24
|
-
/** the
|
|
24
|
+
/** the camera's ray through the fragment, in the object's space: from `point`, along `ray` */
|
|
25
25
|
point: written.point,
|
|
26
26
|
ray: written.ray,
|
|
27
27
|
/** the same ray in world space: `ray` × s in object space is `worldRay` × s in the world */
|
|
@@ -50,22 +50,25 @@ export function buildCard(inputs, instance, deform) {
|
|
|
50
50
|
const back = column(cameraWorldMatrix, 2).xyz;
|
|
51
51
|
const toEye = eye.sub(centre);
|
|
52
52
|
const distance = length(toEye);
|
|
53
|
-
const
|
|
53
|
+
const toCamera = select(ortho, normalize(toWorld.solve(back)), toEye.div(distance)).toVar();
|
|
54
54
|
// Up close, perspective spreads the near side of the object past the ortho frame.
|
|
55
55
|
const grow = select(ortho, float(1), min(distance.div(max(distance.sub(radius), 1e-4)), 4));
|
|
56
|
-
const { tangent, bitangent } = basisNode(
|
|
56
|
+
const { tangent, bitangent } = basisNode(toCamera);
|
|
57
57
|
// The card covers the box as seen from here, plus the frame's empty border (the bake's
|
|
58
58
|
// PAD) for the filtered edge, and no more than the frame: every pixel of it runs the
|
|
59
59
|
// whole surface, and a square frame is mostly empty for a tall plant.
|
|
60
60
|
const box = vec2(dot(tangent.abs(), extent), dot(bitangent.abs(), extent)).add(halfSize.mul(0.06));
|
|
61
61
|
const size = min(box, vec2(halfSize, halfSize)).mul(grow.mul(2));
|
|
62
|
-
const point = centre
|
|
62
|
+
const point = centre
|
|
63
|
+
.add(tangent.mul(positionGeometry.x.mul(size.x)))
|
|
64
|
+
.add(bitangent.mul(positionGeometry.y.mul(size.y)))
|
|
65
|
+
.toVar();
|
|
63
66
|
const last = frames.sub(1);
|
|
64
|
-
// Clamped: rounding can put a horizon
|
|
65
|
-
const grid = clamp(encodeNode(layout,
|
|
67
|
+
// Clamped: rounding can put a horizon direction a hair outside the grid.
|
|
68
|
+
const grid = clamp(encodeNode(layout, toCamera).mul(last), vec2(0, 0), vec2(last, last));
|
|
66
69
|
const cell = min(floor(grid), vec2(last.sub(1), last.sub(1)));
|
|
67
70
|
const f = grid.sub(cell);
|
|
68
|
-
const ray = select(ortho,
|
|
71
|
+
const ray = select(ortho, toCamera.negate(), point.sub(eye));
|
|
69
72
|
// Every vertex of a card holds the same frames and weights, so they interpolate to themselves.
|
|
70
73
|
written.frames.assign(vec3(cell, select(f.x.greaterThan(f.y), float(1), float(0))));
|
|
71
74
|
written.weights.assign(vec3(min(f.x.oneMinus(), f.y.oneMinus()), f.x.sub(f.y).abs(), min(f.x, f.y)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../../src/impostor/mesh/card.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,EACL,GAAG,EACH,KAAK,EACL,KAAK,EACL,MAAM,EACN,GAAG,EACH,GAAG,EACH,gBAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,MAAM,EACN,eAAe,EACf,IAAI,EACJ,IAAI,EACJ,IAAI,GACL,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAwBzD,wFAAwF;AACxF,uFAAuF;AACvF,wDAAwD;AACxD,MAAM,OAAO,GAAG;IACd,sEAAsE;IACtE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAClD,OAAO,EAAE,eAAe,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpD,KAAK,EAAE,eAAe,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAChD,GAAG,EAAE,eAAe,CAAC,MAAM,EAAE,cAAc,CAAC;IAC5C,UAAU,EAAE,eAAe,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAC1D,QAAQ,EAAE,eAAe,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACtD,OAAO,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE,eAAe,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE,eAAe,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAU;CAC1J,CAAC;AAEF,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;AAChC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAEnC,wCAAwC;AACxC,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB
|
|
1
|
+
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../../src/impostor/mesh/card.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,13 +21,15 @@ export interface ImpostorMeshOptions {
|
|
|
21
21
|
* Draws an impostor once per instance, as an InstancedMesh draws a mesh: instance
|
|
22
22
|
* matrices are ordinary model transforms of the source object (identity = where the
|
|
23
23
|
* source was baked), set with `setMatrixAt`, and instance colours with `setColorAt`.
|
|
24
|
-
* Lighting, fog, shadows and colour go through three's MeshStandardNodeMaterial;
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* Lighting, fog, shadows and colour go through three's MeshStandardNodeMaterial; a clone
|
|
25
|
+
* shares its material, and with it its textures and its shader. Clone one mesh rather
|
|
26
|
+
* than make another of the same impostor, which uploads the impostor's textures again.
|
|
27
27
|
*
|
|
28
28
|
* It draws nothing of an instance into a directional light's shadow map whose texels are
|
|
29
29
|
* wider than the instance. Like an InstancedMesh, it is culled by `boundingSphere`,
|
|
30
30
|
* which `computeBoundingSphere` makes from the instances.
|
|
31
|
+
* On multisampled targets, edges use alpha-to-coverage and leave fractional canvas
|
|
32
|
+
* alpha; use a renderer with `alpha: false` when the page must not show through them.
|
|
31
33
|
*/
|
|
32
34
|
export declare class ImpostorMesh extends Mesh<PlaneGeometry, ImpostorMaterial> {
|
|
33
35
|
readonly isImpostorMesh = true;
|
|
@@ -36,15 +38,15 @@ export declare class ImpostorMesh extends Mesh<PlaneGeometry, ImpostorMaterial>
|
|
|
36
38
|
options: ImpostorMeshOptions;
|
|
37
39
|
/** Instances drawn. */
|
|
38
40
|
count: number;
|
|
39
|
-
/** 16 floats per instance
|
|
41
|
+
/** 16 floats per instance, read from its storage buffer for every draw. */
|
|
40
42
|
instanceMatrix: StorageInstancedBufferAttribute;
|
|
41
43
|
/** RGB (and a pad) per instance, once `setColorAt` was called. */
|
|
42
44
|
instanceColor: StorageInstancedBufferAttribute | null;
|
|
43
45
|
boundingSphere: Sphere | null;
|
|
46
|
+
/** Where the card sits within an instance's space (InstancedLod places it). */
|
|
47
|
+
readonly placement: Matrix4;
|
|
44
48
|
private disposed;
|
|
45
49
|
constructor(impostor: Impostor, count?: number, options?: ImpostorMeshOptions, material?: ImpostorMaterial);
|
|
46
|
-
/** Where the card sits within an instance's space (InstancedLod places it). */
|
|
47
|
-
get placement(): Matrix4;
|
|
48
50
|
setMatrixAt(index: number, matrix: Matrix4): void;
|
|
49
51
|
getMatrixAt(index: number, matrix: Matrix4): Matrix4;
|
|
50
52
|
setColorAt(index: number, color: Color): void;
|
|
@@ -61,6 +63,7 @@ export declare class ImpostorMesh extends Mesh<PlaneGeometry, ImpostorMaterial>
|
|
|
61
63
|
/**
|
|
62
64
|
* An ImpostorMesh like `template` for `count` instances, its card placed by `placement`
|
|
63
65
|
* within each instance's space (instance matrix × placement), as InstancedLod draws it.
|
|
64
|
-
* It
|
|
66
|
+
* It draws with the template's material, its tint and mip bias included; placement is
|
|
67
|
+
* per draw.
|
|
65
68
|
*/
|
|
66
69
|
export declare function impostorInstances(template: ImpostorMesh, count: number, placement: Matrix4): ImpostorMesh;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Box3, Color, Matrix4, Mesh, PlaneGeometry, Ray, Sphere, StorageInstancedBufferAttribute, Vector3, } from "three/webgpu";
|
|
2
|
-
import {
|
|
2
|
+
import { setFadeSource } from "../../levels/fade.js";
|
|
3
3
|
import { sameClass } from "../../three.js";
|
|
4
4
|
import { copyWind } from "../../wind/index.js";
|
|
5
5
|
import { boundingRadius, validateImpostor } from "../impostor.js";
|
|
@@ -24,13 +24,15 @@ const sphere = new Sphere();
|
|
|
24
24
|
* Draws an impostor once per instance, as an InstancedMesh draws a mesh: instance
|
|
25
25
|
* matrices are ordinary model transforms of the source object (identity = where the
|
|
26
26
|
* source was baked), set with `setMatrixAt`, and instance colours with `setColorAt`.
|
|
27
|
-
* Lighting, fog, shadows and colour go through three's MeshStandardNodeMaterial;
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* Lighting, fog, shadows and colour go through three's MeshStandardNodeMaterial; a clone
|
|
28
|
+
* shares its material, and with it its textures and its shader. Clone one mesh rather
|
|
29
|
+
* than make another of the same impostor, which uploads the impostor's textures again.
|
|
30
30
|
*
|
|
31
31
|
* It draws nothing of an instance into a directional light's shadow map whose texels are
|
|
32
32
|
* wider than the instance. Like an InstancedMesh, it is culled by `boundingSphere`,
|
|
33
33
|
* which `computeBoundingSphere` makes from the instances.
|
|
34
|
+
* On multisampled targets, edges use alpha-to-coverage and leave fractional canvas
|
|
35
|
+
* alpha; use a renderer with `alpha: false` when the page must not show through them.
|
|
34
36
|
*/
|
|
35
37
|
export class ImpostorMesh extends Mesh {
|
|
36
38
|
isImpostorMesh = true;
|
|
@@ -39,11 +41,13 @@ export class ImpostorMesh extends Mesh {
|
|
|
39
41
|
options;
|
|
40
42
|
/** Instances drawn. */
|
|
41
43
|
count;
|
|
42
|
-
/** 16 floats per instance
|
|
44
|
+
/** 16 floats per instance, read from its storage buffer for every draw. */
|
|
43
45
|
instanceMatrix;
|
|
44
46
|
/** RGB (and a pad) per instance, once `setColorAt` was called. */
|
|
45
47
|
instanceColor = null;
|
|
46
48
|
boundingSphere = null;
|
|
49
|
+
/** Where the card sits within an instance's space (InstancedLod places it). */
|
|
50
|
+
placement = new Matrix4();
|
|
47
51
|
disposed = false;
|
|
48
52
|
constructor(impostor, count = 1, options = {}, material) {
|
|
49
53
|
validateImpostor(impostor);
|
|
@@ -61,11 +65,7 @@ export class ImpostorMesh extends Mesh {
|
|
|
61
65
|
this.instanceMatrix = new StorageInstancedBufferAttribute(count, 16);
|
|
62
66
|
for (let i = 0; i < count; i++)
|
|
63
67
|
scratch.identity().toArray(this.instanceMatrix.array, i * 16);
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
/** Where the card sits within an instance's space (InstancedLod places it). */
|
|
67
|
-
get placement() {
|
|
68
|
-
return this.material.placement;
|
|
68
|
+
setFadeSource(this, { kind: "instances", slots: null, radius: boundingRadius(impostor.box), tint: new Color(1, 1, 1) });
|
|
69
69
|
}
|
|
70
70
|
setMatrixAt(index, matrix) {
|
|
71
71
|
matrix.toArray(this.instanceMatrix.array, index * 16);
|
|
@@ -77,8 +77,6 @@ export class ImpostorMesh extends Mesh {
|
|
|
77
77
|
setColorAt(index, color) {
|
|
78
78
|
if (!this.instanceColor) {
|
|
79
79
|
this.instanceColor = new StorageInstancedBufferAttribute(new Float32Array(this.count * 4).fill(1), 4);
|
|
80
|
-
// Instance colours change the shader.
|
|
81
|
-
this.material.needsUpdate = true;
|
|
82
80
|
}
|
|
83
81
|
color.toArray(this.instanceColor.array, index * 4);
|
|
84
82
|
this.instanceColor.needsUpdate = true;
|
|
@@ -109,11 +107,11 @@ export class ImpostorMesh extends Mesh {
|
|
|
109
107
|
}
|
|
110
108
|
this.count = source.count;
|
|
111
109
|
this.options = source.options;
|
|
110
|
+
this.placement.copy(source.placement);
|
|
112
111
|
this.instanceMatrix.dispose();
|
|
113
112
|
this.instanceColor?.dispose();
|
|
114
113
|
this.instanceMatrix = new StorageInstancedBufferAttribute(source.instanceMatrix.array.slice(), 16);
|
|
115
114
|
this.instanceColor = source.instanceColor ? new StorageInstancedBufferAttribute(source.instanceColor.array.slice(), 4) : null;
|
|
116
|
-
this.material.needsUpdate = true;
|
|
117
115
|
this.boundingSphere = source.boundingSphere?.clone() ?? null;
|
|
118
116
|
copyWind(source, this);
|
|
119
117
|
return this;
|
|
@@ -146,6 +144,7 @@ export class ImpostorMesh extends Mesh {
|
|
|
146
144
|
if (this.disposed)
|
|
147
145
|
return this;
|
|
148
146
|
this.disposed = true;
|
|
147
|
+
super.dispose();
|
|
149
148
|
this.geometry.dispose();
|
|
150
149
|
this.instanceMatrix.dispose();
|
|
151
150
|
this.instanceColor?.dispose();
|
|
@@ -161,14 +160,12 @@ const point = new Vector3();
|
|
|
161
160
|
/**
|
|
162
161
|
* An ImpostorMesh like `template` for `count` instances, its card placed by `placement`
|
|
163
162
|
* within each instance's space (instance matrix × placement), as InstancedLod draws it.
|
|
164
|
-
* It
|
|
163
|
+
* It draws with the template's material, its tint and mip bias included; placement is
|
|
164
|
+
* per draw.
|
|
165
165
|
*/
|
|
166
166
|
export function impostorInstances(template, count, placement) {
|
|
167
|
-
const mesh = new ImpostorMesh(template.impostor, count, template.options);
|
|
167
|
+
const mesh = new ImpostorMesh(template.impostor, count, template.options, template.material);
|
|
168
168
|
mesh.placement.copy(placement);
|
|
169
|
-
// A tint and mip bias set on the template, as for a level drawn by a Lod.
|
|
170
|
-
mesh.material.color.copy(template.material.color);
|
|
171
|
-
mesh.material.mipBias.value = template.material.mipBias.value;
|
|
172
169
|
return mesh;
|
|
173
170
|
}
|
|
174
171
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/impostor/mesh/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,KAAK,EACL,OAAO,EACP,IAAI,EACJ,aAAa,EACb,GAAG,EACH,MAAM,EACN,+BAA+B,EAC/B,OAAO,GAGR,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/impostor/mesh/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MeshStandardNodeMaterial, PhysicalLightingModel, type Node, type NodeBuilder, type Texture } from "three/webgpu";
|
|
2
2
|
import { type Impostor } from "../impostor.js";
|
|
3
3
|
/** How an ImpostorMesh draws: see `ImpostorMeshOptions`. */
|
|
4
|
-
|
|
4
|
+
interface ImpostorShading {
|
|
5
5
|
cutoff: number;
|
|
6
6
|
parallax: number;
|
|
7
7
|
tolerance: number;
|
|
@@ -18,46 +18,57 @@ export declare class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
18
18
|
readonly impostor: Impostor;
|
|
19
19
|
readonly shading: ImpostorShading;
|
|
20
20
|
readonly isImpostorMaterial = true;
|
|
21
|
-
/** Where the card sits within an instance's space; identity except under InstancedLod. */
|
|
22
|
-
readonly placement: Matrix4;
|
|
23
21
|
/** An object-space deformation of every instance (wind), applied before `placement`; null for none. */
|
|
24
22
|
deformNode: Node<"mat4"> | null;
|
|
25
23
|
/** Mip bias of every atlas read: see `ImpostorMeshOptions.mipBias`, which it starts at. */
|
|
26
24
|
readonly mipBias: Node<"float"> & {
|
|
27
25
|
value: number;
|
|
28
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* The view-space mean of the normals a texel averages, its length how far they agree. A lighting term of its own reads this with
|
|
29
|
+
* `cosine` rather than `normalView`, a single unit normal that would light every averaged leaf one way.
|
|
30
|
+
*/
|
|
31
|
+
readonly spread: Node<"vec3">;
|
|
32
|
+
/**
|
|
33
|
+
* Diffuse light of the app's own, which the bake cannot hold as it depends on the light (leaves passing it through):
|
|
34
|
+
* given the direction to a direct light, the share of the light's colour × the surface's colour to add. Null for none.
|
|
35
|
+
* Only its source text enters the material's cache key, not what it captures: what tells two materials' shaders
|
|
36
|
+
* apart here is the ids of the nodes each makes for itself, so a value it captures needs no key of its own.
|
|
37
|
+
*/
|
|
38
|
+
directTerm: ((direction: Node<"vec3">) => Node<"vec3">) | null;
|
|
39
|
+
/** The impostor's atlases, one per map: the material's own, freed with it. */
|
|
40
|
+
readonly textures: readonly Texture[];
|
|
29
41
|
private readonly inputs;
|
|
42
|
+
private readonly specular;
|
|
30
43
|
/**
|
|
31
44
|
* Per build, one surface for every slot that reads it, made when the fragment stage
|
|
32
45
|
* first reads it: TSL adds a node's variables to the stage being built when the node
|
|
33
|
-
* is made. Keyed by what the build
|
|
46
|
+
* is made. Keyed by what the build holds for `anchor`: each slot gets its own proxy of
|
|
34
47
|
* the builder.
|
|
35
48
|
*/
|
|
36
49
|
private readonly surfaces;
|
|
50
|
+
private readonly multisampled;
|
|
37
51
|
private readonly anchor;
|
|
38
52
|
private users;
|
|
39
53
|
private disposed;
|
|
40
54
|
constructor(impostor: Impostor, shading: ImpostorShading);
|
|
55
|
+
setup(builder: NodeBuilder): void;
|
|
41
56
|
/** One mesh starts or stops sharing this material, including when `copy` replaces it. */
|
|
42
57
|
acquire(): this;
|
|
43
58
|
release(): void;
|
|
44
|
-
/** Explicit disposal, including by a caller:
|
|
59
|
+
/** Explicit disposal, including by a caller: frees its textures once. */
|
|
45
60
|
dispose(): void;
|
|
46
61
|
/** The card's vertex as `builder` draws it, in the vertex stage. */
|
|
47
62
|
private card;
|
|
48
63
|
/**
|
|
49
64
|
* The surface `builder` draws, as its pass needs it. No parallax walk in shadow passes:
|
|
50
|
-
* shadow maps cover far more impostor pixels than the
|
|
65
|
+
* shadow maps cover far more impostor pixels than the camera does, and shadows are too soft to
|
|
51
66
|
* show it.
|
|
52
67
|
*/
|
|
53
68
|
private surface;
|
|
54
69
|
private lit;
|
|
55
70
|
setupLightingModel(): PhysicalLightingModel;
|
|
56
|
-
/**
|
|
71
|
+
/** Baked F0 (RGB) and F90 (A) are uniforms so different asset averages share a shader. */
|
|
57
72
|
setupSpecular(): void;
|
|
58
|
-
/**
|
|
59
|
-
* The view keeps the card's depth, so early depth testing keeps rejecting hidden pixels
|
|
60
|
-
* (several times faster in crowds); shadow maps get the surface's (`depthNode`).
|
|
61
|
-
*/
|
|
62
|
-
setupDepth(builder: NodeBuilder): void;
|
|
63
73
|
}
|
|
74
|
+
export {};
|
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
import { DoubleSide, Matrix4, MeshStandardNodeMaterial, PhysicalLightingModel, TSL, Vector3 } from "three/webgpu";
|
|
2
|
-
import { Fn, diffuseColor, float,
|
|
3
|
-
import { castPosition,
|
|
1
|
+
import { ConvertNode, DoubleSide, Matrix4, MeshStandardNodeMaterial, PhysicalLightingModel, TSL, Vector3, Vector4, } from "three/webgpu";
|
|
2
|
+
import { Fn, diffuseColor, float, materialColor, metalness, mix, specularColor, specularF90, uniform, varyingProperty, vec3, vec4 } from "three/tsl";
|
|
3
|
+
import { castPosition, instanceColor, instanceMatrixOf, tint } from "../../levels/fade.js";
|
|
4
4
|
import { isImpostorMesh, isShadowPass } from "../../three.js";
|
|
5
|
-
import { buildKey,
|
|
5
|
+
import { buildKey, isNodeOf } from "../../tsl.js";
|
|
6
6
|
import { boundingRadius, boxCentre, boxExtent } from "../impostor.js";
|
|
7
7
|
import { buildCard, card } from "./card.js";
|
|
8
8
|
import { buildSurface, cosine } from "./surface.js";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
const singleColor = uniform(new Vector3(1, 1, 1)).onObjectUpdate(({ object }, self) => object && isImpostorMesh(object) && object.instanceColor ? self.value.fromArray(object.instanceColor.array) : self.value.set(1, 1, 1));
|
|
9
|
+
import { impostorTextures } from "./textures.js";
|
|
10
|
+
const placement = uniform(new Matrix4()).onObjectUpdate(({ object }, self) => object && isImpostorMesh(object) ? self.value.copy(object.placement) : self.value.identity());
|
|
12
11
|
/** How `object`, an ImpostorMesh, places and colours its instances. */
|
|
13
12
|
function instancesOf(object) {
|
|
14
13
|
const matrix = instanceMatrixOf(object);
|
|
15
14
|
if (!matrix || !isImpostorMesh(object))
|
|
16
15
|
throw new Error(`ImpostorMesh: "${object.name}" is drawn with an impostor's material but is no ImpostorMesh`);
|
|
17
|
-
|
|
18
|
-
return { matrix, color: singleColor };
|
|
19
|
-
const { instanceColor } = object;
|
|
20
|
-
return { matrix, color: instanceColor && varying(instanceColors(instanceColor).element(instanceIndex).xyz).setInterpolation("flat") };
|
|
16
|
+
return { matrix, color: instanceColor };
|
|
21
17
|
}
|
|
22
18
|
/**
|
|
23
19
|
* Draws an impostor: the card (see card.ts) in the vertex stage and the surface (see
|
|
@@ -30,20 +26,34 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
30
26
|
impostor;
|
|
31
27
|
shading;
|
|
32
28
|
isImpostorMaterial = true;
|
|
33
|
-
/** Where the card sits within an instance's space; identity except under InstancedLod. */
|
|
34
|
-
placement = new Matrix4();
|
|
35
29
|
/** An object-space deformation of every instance (wind), applied before `placement`; null for none. */
|
|
36
30
|
deformNode = null;
|
|
37
31
|
/** Mip bias of every atlas read: see `ImpostorMeshOptions.mipBias`, which it starts at. */
|
|
38
32
|
mipBias;
|
|
33
|
+
/**
|
|
34
|
+
* The view-space mean of the normals a texel averages, its length how far they agree. A lighting term of its own reads this with
|
|
35
|
+
* `cosine` rather than `normalView`, a single unit normal that would light every averaged leaf one way.
|
|
36
|
+
*/
|
|
37
|
+
spread = Fn((builder) => this.lit(builder).spread)();
|
|
38
|
+
/**
|
|
39
|
+
* Diffuse light of the app's own, which the bake cannot hold as it depends on the light (leaves passing it through):
|
|
40
|
+
* given the direction to a direct light, the share of the light's colour × the surface's colour to add. Null for none.
|
|
41
|
+
* Only its source text enters the material's cache key, not what it captures: what tells two materials' shaders
|
|
42
|
+
* apart here is the ids of the nodes each makes for itself, so a value it captures needs no key of its own.
|
|
43
|
+
*/
|
|
44
|
+
directTerm = null;
|
|
45
|
+
/** The impostor's atlases, one per map: the material's own, freed with it. */
|
|
46
|
+
textures;
|
|
39
47
|
inputs;
|
|
48
|
+
specular;
|
|
40
49
|
/**
|
|
41
50
|
* Per build, one surface for every slot that reads it, made when the fragment stage
|
|
42
51
|
* first reads it: TSL adds a node's variables to the stage being built when the node
|
|
43
|
-
* is made. Keyed by what the build
|
|
52
|
+
* is made. Keyed by what the build holds for `anchor`: each slot gets its own proxy of
|
|
44
53
|
* the builder.
|
|
45
54
|
*/
|
|
46
55
|
surfaces = new WeakMap();
|
|
56
|
+
multisampled = new WeakMap();
|
|
47
57
|
anchor = float(0);
|
|
48
58
|
users = 0;
|
|
49
59
|
disposed = false;
|
|
@@ -52,8 +62,10 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
52
62
|
this.impostor = impostor;
|
|
53
63
|
this.shading = shading;
|
|
54
64
|
this.name = "impostor";
|
|
55
|
-
const textures =
|
|
65
|
+
const textures = impostorTextures(impostor);
|
|
66
|
+
this.textures = textures;
|
|
56
67
|
this.mipBias = uniform(shading.mipBias);
|
|
68
|
+
this.specular = uniform(new Vector4().fromArray(impostor.specular ?? [0.04, 0.04, 0.04, 1]));
|
|
57
69
|
const layer = (map) => textures[impostor.maps.indexOf(map)] ?? null;
|
|
58
70
|
const base = layer("base");
|
|
59
71
|
const normalDepth = layer("normalDepth");
|
|
@@ -67,7 +79,7 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
67
79
|
radius: uniform(boundingRadius(impostor.box)),
|
|
68
80
|
halfSize: uniform(impostor.halfSize),
|
|
69
81
|
frames: uniform(impostor.frames),
|
|
70
|
-
placement
|
|
82
|
+
placement,
|
|
71
83
|
cell: impostor.size / impostor.frames,
|
|
72
84
|
maps: { base, normalDepth, orm, emissive: layer("emissive") },
|
|
73
85
|
cutoff: shading.cutoff,
|
|
@@ -83,13 +95,12 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
83
95
|
return color;
|
|
84
96
|
const rgb = color.rgb.mul(materialColor.rgb).mul(tint);
|
|
85
97
|
const instance = instancesOf(builder.object).color;
|
|
86
|
-
return vec4(
|
|
98
|
+
return vec4(rgb.mul(instance), color.a);
|
|
87
99
|
})();
|
|
88
100
|
this.maskNode = Fn((builder) => this.surface(builder).drawn)();
|
|
89
101
|
this.maskShadowNode = this.maskNode;
|
|
90
|
-
|
|
91
|
-
this.
|
|
92
|
-
this.receivedShadowPositionNode = Fn((builder) => this.surface(builder).shadowPosition)();
|
|
102
|
+
this.depthNode = Fn((builder) => this.surface(builder).resolve().depth)();
|
|
103
|
+
this.receivedShadowPositionNode = Fn((builder) => this.surface(builder).resolve().shadowPosition)();
|
|
93
104
|
this.normalNode = Fn((builder) => this.lit(builder).normal)();
|
|
94
105
|
this.roughnessNode = Fn((builder) => this.lit(builder).roughness)();
|
|
95
106
|
this.metalnessNode = Fn((builder) => this.lit(builder).metalness)();
|
|
@@ -97,6 +108,12 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
97
108
|
if (layer("emissive"))
|
|
98
109
|
this.emissiveNode = Fn((builder) => this.lit(builder).emissive ?? vec3(0))();
|
|
99
110
|
}
|
|
111
|
+
setup(builder) {
|
|
112
|
+
// Async shader builds yield between stages; snapshot this pass before the
|
|
113
|
+
// renderer returns to a different target while the fragment stage is pending.
|
|
114
|
+
this.multisampled.set(buildKey(builder, this.anchor), builder.renderer.currentSamples > 1);
|
|
115
|
+
super.setup(builder);
|
|
116
|
+
}
|
|
100
117
|
/** One mesh starts or stops sharing this material, including when `copy` replaces it. */
|
|
101
118
|
acquire() {
|
|
102
119
|
this.users++;
|
|
@@ -106,13 +123,14 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
106
123
|
if (--this.users === 0)
|
|
107
124
|
this.dispose();
|
|
108
125
|
}
|
|
109
|
-
/** Explicit disposal, including by a caller:
|
|
126
|
+
/** Explicit disposal, including by a caller: frees its textures once. */
|
|
110
127
|
dispose() {
|
|
111
128
|
if (this.disposed)
|
|
112
129
|
return;
|
|
113
130
|
this.disposed = true;
|
|
114
131
|
super.dispose();
|
|
115
|
-
|
|
132
|
+
for (const texture of this.textures)
|
|
133
|
+
texture.dispose();
|
|
116
134
|
}
|
|
117
135
|
/** The card's vertex as `builder` draws it, in the vertex stage. */
|
|
118
136
|
card(builder) {
|
|
@@ -125,7 +143,7 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
125
143
|
}
|
|
126
144
|
/**
|
|
127
145
|
* The surface `builder` draws, as its pass needs it. No parallax walk in shadow passes:
|
|
128
|
-
* shadow maps cover far more impostor pixels than the
|
|
146
|
+
* shadow maps cover far more impostor pixels than the camera does, and shadows are too soft to
|
|
129
147
|
* show it.
|
|
130
148
|
*/
|
|
131
149
|
surface(builder) {
|
|
@@ -133,9 +151,12 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
133
151
|
let surface = this.surfaces.get(build);
|
|
134
152
|
if (!surface) {
|
|
135
153
|
const shadow = isShadowPass(builder.material);
|
|
154
|
+
const multisampled = shadow ? false : this.multisampled.get(build);
|
|
155
|
+
if (multisampled === undefined)
|
|
156
|
+
throw new Error("ImpostorMaterial: surface built before pass setup");
|
|
136
157
|
surface = buildSurface(this.inputs, card, {
|
|
137
158
|
parallax: shadow ? 0 : this.shading.parallax,
|
|
138
|
-
multisampled
|
|
159
|
+
multisampled,
|
|
139
160
|
lit: !shadow,
|
|
140
161
|
});
|
|
141
162
|
this.surfaces.set(build, surface);
|
|
@@ -143,57 +164,52 @@ export class ImpostorMaterial extends MeshStandardNodeMaterial {
|
|
|
143
164
|
return surface;
|
|
144
165
|
}
|
|
145
166
|
lit(builder) {
|
|
146
|
-
const
|
|
147
|
-
if (!
|
|
167
|
+
const light = this.surface(builder).light;
|
|
168
|
+
if (!light)
|
|
148
169
|
throw new Error("ImpostorMesh: lighting read in a shadow pass");
|
|
149
|
-
return
|
|
170
|
+
return light();
|
|
150
171
|
}
|
|
151
172
|
setupLightingModel() {
|
|
152
|
-
return new
|
|
173
|
+
return new ImpostorLightingModel(this.spread, this.directTerm);
|
|
153
174
|
}
|
|
154
|
-
/**
|
|
175
|
+
/** Baked F0 (RGB) and F90 (A) are uniforms so different asset averages share a shader. */
|
|
155
176
|
setupSpecular() {
|
|
156
|
-
const
|
|
157
|
-
if (!specular)
|
|
158
|
-
return super.setupSpecular();
|
|
159
|
-
const f0 = vec3(specular[0], specular[1], specular[2]);
|
|
177
|
+
const f0 = this.specular.rgb;
|
|
160
178
|
specularColor.assign(f0);
|
|
161
179
|
TSL.specularColorBlended.assign(mix(f0, diffuseColor.rgb, metalness));
|
|
162
|
-
specularF90.assign(specular
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* The view keeps the card's depth, so early depth testing keeps rejecting hidden pixels
|
|
166
|
-
* (several times faster in crowds); shadow maps get the surface's (`depthNode`).
|
|
167
|
-
*/
|
|
168
|
-
setupDepth(builder) {
|
|
169
|
-
const surface = this.depthNode;
|
|
170
|
-
this.depthNode = null;
|
|
171
|
-
super.setupDepth(builder);
|
|
172
|
-
this.depthNode = surface;
|
|
180
|
+
specularF90.assign(this.specular.a);
|
|
173
181
|
}
|
|
174
182
|
}
|
|
175
183
|
/**
|
|
176
184
|
* Direct diffuse light by `cosine` instead of the clamped cosine of the mean normal. That
|
|
177
185
|
* one leaves a canopy unlit wherever its mean normal is side-on to the sun, where the real
|
|
178
186
|
* leaves, tilted every which way, catch a good part of it; renormalised, the mean lights
|
|
179
|
-
* the canopy as one smooth surface. Specular keeps three's terms: its roughness widens
|
|
187
|
+
* the canopy as one smooth surface. Specular keeps three's terms, on the leaned normal (see surface.ts): its roughness widens
|
|
180
188
|
* with the spread instead.
|
|
181
189
|
*/
|
|
182
|
-
class
|
|
190
|
+
class ImpostorLightingModel extends PhysicalLightingModel {
|
|
183
191
|
spread;
|
|
184
|
-
|
|
192
|
+
term;
|
|
193
|
+
constructor(spread, term) {
|
|
185
194
|
super();
|
|
186
195
|
this.spread = spread;
|
|
196
|
+
this.term = term;
|
|
187
197
|
}
|
|
188
198
|
direct(input, builder) {
|
|
189
|
-
const { lightDirection,
|
|
199
|
+
const { lightDirection, reflectedLight } = input;
|
|
190
200
|
const { directDiffuse } = reflectedLight;
|
|
191
|
-
if (!isNodeOf(lightDirection, "vec3", builder) || !isNodeOf(
|
|
192
|
-
throw new Error("ImpostorMesh: three's direct light is not a direction
|
|
201
|
+
if (!isNodeOf(lightDirection, "vec3", builder) || !isNodeOf(directDiffuse, "vec3", builder))
|
|
202
|
+
throw new Error("ImpostorMesh: three's direct light is not a direction and a sum");
|
|
203
|
+
// Converted rather than asked its type: asking makes three keep a type the shadow it multiplies in may not have (a
|
|
204
|
+
// cascaded shadow's is vec4), and the shader then multiplies a vec3 by a vec4.
|
|
205
|
+
const lightColor = new ConvertNode(input.lightColor, "vec3");
|
|
193
206
|
// three's terms, its diffuse into a throwaway.
|
|
194
207
|
super.direct({ ...input, reflectedLight: { ...reflectedLight, directDiffuse: vec3(0).toVar() } }, builder);
|
|
195
208
|
// Lambert: the diffuse colour over π.
|
|
196
|
-
|
|
209
|
+
const reflected = lightColor.mul(TSL.diffuseContribution);
|
|
210
|
+
directDiffuse.addAssign(cosine(this.spread, lightDirection).mul(reflected).div(Math.PI));
|
|
211
|
+
if (this.term)
|
|
212
|
+
directDiffuse.addAssign(this.term(lightDirection).mul(reflected));
|
|
197
213
|
}
|
|
198
214
|
}
|
|
199
215
|
//# sourceMappingURL=material.js.map
|