@drawcall/lod 0.5.3 → 0.5.5
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/dist/loader/node.d.ts
CHANGED
|
@@ -9,7 +9,8 @@ import type { LodRequest } from "./request.js";
|
|
|
9
9
|
* a .glts source imports from a CDN, fails, since no stored level could be checked against it. Served paths such as
|
|
10
10
|
* `/trees/oak.glts`, and `file:` URLs in the public directory, as a headless .glts script's manager resolves them to,
|
|
11
11
|
* load from vitecache's public directory (see `publicURL`), and `.glts` sources through a GLTSLoader of the load's own;
|
|
12
|
-
* bakes draw on a
|
|
12
|
+
* bakes draw on a canvas of the process's document, as a glts host has one, or else on a WebGPU device of
|
|
13
|
+
* @drawcall/webgpu. The manager only resolves the request's URL.
|
|
13
14
|
*
|
|
14
15
|
* Each `loadAsync` loads and bakes with what it makes for itself, which it frees before resolving, so loads may run
|
|
15
16
|
* concurrently. The levels it returns load their stored bytes as in browsers, and none holds the source: the source
|
package/dist/loader/node.js
CHANGED
|
@@ -5,7 +5,7 @@ import { createCanvas } from "@drawcall/webgpu";
|
|
|
5
5
|
import { resolve as resolveImport } from "import-meta-resolve";
|
|
6
6
|
import { Loader, LoadingManager, WebGPURenderer } from "three/webgpu";
|
|
7
7
|
import { publicURL } from "vitecache";
|
|
8
|
-
import { setUpBakeRenderer } from "../bake.js";
|
|
8
|
+
import { createBakeRenderer, setUpBakeRenderer } from "../bake.js";
|
|
9
9
|
import { CachedLodLoader as BrowserCachedLodLoader } from "./index.js";
|
|
10
10
|
import { loaderPathURL, placeholderOrigin } from "./url.js";
|
|
11
11
|
/** The session of each load, by its async context: the served fetch is global. */
|
|
@@ -17,7 +17,8 @@ const sessions = new AsyncLocalStorage();
|
|
|
17
17
|
* a .glts source imports from a CDN, fails, since no stored level could be checked against it. Served paths such as
|
|
18
18
|
* `/trees/oak.glts`, and `file:` URLs in the public directory, as a headless .glts script's manager resolves them to,
|
|
19
19
|
* load from vitecache's public directory (see `publicURL`), and `.glts` sources through a GLTSLoader of the load's own;
|
|
20
|
-
* bakes draw on a
|
|
20
|
+
* bakes draw on a canvas of the process's document, as a glts host has one, or else on a WebGPU device of
|
|
21
|
+
* @drawcall/webgpu. The manager only resolves the request's URL.
|
|
21
22
|
*
|
|
22
23
|
* Each `loadAsync` loads and bakes with what it makes for itself, which it frees before resolving, so loads may run
|
|
23
24
|
* concurrently. The levels it returns load their stored bytes as in browsers, and none holds the source: the source
|
|
@@ -75,13 +76,23 @@ class SessionLoader extends BrowserCachedLodLoader {
|
|
|
75
76
|
publicPath(url) {
|
|
76
77
|
return url.startsWith(`${placeholderOrigin}/`) ? url.slice(placeholderOrigin.length) : super.publicPath(url);
|
|
77
78
|
}
|
|
78
|
-
/**
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Load `url` in the load's session, or, once `loadAsync` has resolved, in a session of its own. In a process without a
|
|
81
|
+
* document, on the canvas's platform: three's loaders report progress with ProgressEvent and decode images, which Node
|
|
82
|
+
* has not.
|
|
83
|
+
*/
|
|
84
|
+
async loadAsset(url) {
|
|
85
|
+
if (!sessions.getStore())
|
|
86
|
+
return session({ read: new Set(), packages: new Set() }, () => this.loadAsset(url));
|
|
87
|
+
if (typeof document === "undefined")
|
|
88
|
+
await canvas();
|
|
89
|
+
return super.loadAsset(url);
|
|
83
90
|
}
|
|
84
91
|
async newBakeRenderer() {
|
|
92
|
+
// A process with a document, such as a glts host's, has WebGPU of its own: bake on a canvas of that document, as a
|
|
93
|
+
// .glts script does. A second WebGPU runtime beside the host's would take over globals the host's images upload with.
|
|
94
|
+
if (typeof document !== "undefined")
|
|
95
|
+
return createBakeRenderer();
|
|
85
96
|
// Three's DOM canvas types exclude native canvases; its constructor checks the actual API.
|
|
86
97
|
const renderer = Reflect.construct(WebGPURenderer, [{ canvas: await canvas(), antialias: false }]);
|
|
87
98
|
if (!(renderer instanceof WebGPURenderer))
|
|
@@ -175,8 +186,8 @@ async function session(state, run) {
|
|
|
175
186
|
}
|
|
176
187
|
}
|
|
177
188
|
/**
|
|
178
|
-
* The served fetch, and a canvas of @drawcall/webgpu once a session bakes, which installs WebGPU,
|
|
179
|
-
* workers while it lives.
|
|
189
|
+
* The served fetch, and a canvas of @drawcall/webgpu once a session loads a source or bakes, which installs WebGPU,
|
|
190
|
+
* image decoding and workers while it lives.
|
|
180
191
|
*/
|
|
181
192
|
function install() {
|
|
182
193
|
const { fetch } = globalThis;
|
package/dist/loader/node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/loader/node.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { readFile } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\nimport { createCanvas, type Canvas } from \"@drawcall/webgpu\";\nimport type { GLTSLoader } from \"@drawcall/glts\";\nimport { resolve as resolveImport } from \"import-meta-resolve\";\nimport { Loader, LoadingManager, WebGPURenderer, type Object3D } from \"three/webgpu\";\nimport { publicURL, type Input } from \"vitecache\";\nimport { setUpBakeRenderer } from \"../bake.js\";\nimport type { LodLevel } from \"../levels/index.js\";\nimport { CachedLodLoader as BrowserCachedLodLoader, type CachedLodLoaderOptions } from \"./index.js\";\nimport type { LodRequest } from \"./request.js\";\nimport { loaderPathURL, placeholderOrigin } from \"./url.js\";\n\ninterface Session {\n /** The `file:` URLs of the public files the session's loads read. */\n read: Set<string>;\n /** The installed packages the session's .glts sources import. */\n packages: Set<string>;\n}\n\n/** The session of each load, by its async context: the served fetch is global. */\nconst sessions = new AsyncLocalStorage<Session>();\n\n/**\n * CachedLodLoader in Node, as the vitecache plugin and the glts CLI run it: `loadAsync` builds and saves every level of\n * the ladder, each with the public files the ladder's loads read and the installed versions of three and of the\n * packages its .glts sources import. A load that reads anything else, such as a URL off the public directory or a module\n * a .glts source imports from a CDN, fails, since no stored level could be checked against it. Served paths such as\n * `/trees/oak.glts`, and `file:` URLs in the public directory, as a headless .glts script's manager resolves them to,\n * load from vitecache's public directory (see `publicURL`), and `.glts` sources through a GLTSLoader of the load's own;\n * bakes draw on a WebGPU device of @drawcall/webgpu. The manager only resolves the request's URL.\n *\n * Each `loadAsync` loads and bakes with what it makes for itself, which it frees before resolving, so loads may run\n * concurrently. The levels it returns load their stored bytes as in browsers, and none holds the source: the source\n * level, and a simplified level, which draws with the source's materials, load the source again when a camera needs\n * them, as the glts CLI's renders of a .glts script that draws a Lod do.\n */\nexport class CachedLodLoader extends BrowserCachedLodLoader {\n constructor(manager?: LoadingManager, options: CachedLodLoaderOptions = {}) {\n super(manager, options);\n }\n\n override loadAsync(request: LodRequest): Promise<LodLevel[]> {\n const input = typeof request === \"string\" ? { url: request } : request;\n const url = this.publicPath(this.manager.resolveURL(loaderPathURL(input.url, this.path)));\n return session({ read: new Set(), packages: new Set() }, async () => {\n const loader = new SessionLoader(this.options);\n try {\n return await loader.loadAsync({ ...input, url });\n } finally {\n await loader.dispose();\n }\n });\n }\n\n /** Nothing to free: each load frees what it made. */\n override async dispose(): Promise<void> {}\n\n /** A `file:` URL in the public directory as its served path; others as in browsers. */\n protected override publicPath(url: string): string {\n if (!url.startsWith(\"file:\")) return super.publicPath(url);\n const base = publicURL(\"/\");\n if (!url.startsWith(base)) throw new Error(`CachedLodLoader: cannot precompute \"${url}\", which lies outside the public directory ${base}`);\n return `/${url.slice(base.length)}`;\n }\n}\n\n/** One `loadAsync` of the Node loader: builds every level, with a GLTSLoader and bake renderer of its own. */\nclass SessionLoader extends BrowserCachedLodLoader {\n protected override readonly buildsAll = true;\n private readonly scripts: ScriptLoader;\n\n constructor(options: CachedLodLoaderOptions) {\n super(servingManager(), options);\n // Packages resolve as the app's do.\n this.scripts = new ScriptLoader(this.manager, publicURL(\"/\"));\n this.manager.addHandler(/\\.glts$/i, this.scripts);\n }\n\n override async dispose(): Promise<void> {\n await super.dispose();\n await this.scripts.dispose();\n }\n\n /**\n * A path its manager served at the placeholder origin as that path, which `CachedLodLoader.loadAsync` gave below the\n * app's base: keyed as in browsers whatever document the process has, such as the one a headless GLTS renderer\n * installs, against which the placeholder origin would be foreign.\n */\n protected override publicPath(url: string): string {\n return url.startsWith(`${placeholderOrigin}/`) ? url.slice(placeholderOrigin.length) : super.publicPath(url);\n }\n\n /** Load `url` in the load's session, or, once `loadAsync` has resolved, in a session of its own. */\n protected override loadAsset(url: string): Promise<Object3D> {\n if (sessions.getStore()) return super.loadAsset(url);\n return session({ read: new Set(), packages: new Set() }, () => super.loadAsset(url));\n }\n\n protected override async newBakeRenderer(): Promise<WebGPURenderer> {\n // Three's DOM canvas types exclude native canvases; its constructor checks the actual API.\n const renderer: unknown = Reflect.construct(WebGPURenderer, [{ canvas: await canvas(), antialias: false }]);\n if (!(renderer instanceof WebGPURenderer)) throw new Error(\"CachedLodLoader: three did not make a WebGPURenderer\");\n return setUpBakeRenderer(renderer);\n }\n\n protected override inputs(): Input[] {\n const state = sessions.getStore();\n if (!state) throw new Error(\"CachedLodLoader: a level was built outside loadAsync\");\n // three builds every level, whatever its source imports.\n const packages = [...new Set([\"three\", ...state.packages])].sort();\n return [...[...state.read].sort().map((path) => ({ path })), ...packages.map((name) => ({ package: name }))];\n }\n}\n\n/** A manager that serves root-relative paths from the public directory while a load runs. */\nfunction servingManager(): LoadingManager {\n const manager = new LoadingManager();\n manager.setURLModifier((url) => {\n if (!url.startsWith(\"/\") || url.startsWith(\"//\")) return url;\n if (!sessions.getStore()) throw new Error(`CachedLodLoader: cannot load \"${url}\" once the load that asked for it has ended`);\n return placeholderOrigin + url;\n });\n return manager;\n}\n\n/**\n * Loads `.glts` sources with a GLTSLoader made at the first load, resolving their packages as the app at `root` does,\n * and records the packages each imports.\n */\nclass ScriptLoader extends Loader<Object3D> {\n private loader: Promise<GLTSLoader> | undefined;\n\n constructor(\n manager: LoadingManager,\n private readonly root: string,\n ) {\n super(manager);\n }\n\n override async loadAsync(url: string): Promise<Object3D> {\n this.loader ??= import(\"@drawcall/glts\").then(\n ({ GLTSLoader }) => new GLTSLoader(this.manager, { resolve: (specifier) => resolveImport(specifier, this.root) }),\n );\n const scene = await (await this.loader).loadAsync(url);\n const { packages, runtimeModules } = scene.source;\n if (runtimeModules.length > 0)\n throw new Error(\n `CachedLodLoader: cannot precompute \"${url}\": it imports ${runtimeModules.join(\", \")} from a CDN at runtime, which a stored level cannot be checked against`,\n );\n const state = sessions.getStore();\n if (!state) throw new Error(`CachedLodLoader: \"${url}\" loaded outside loadAsync`);\n for (const name of packages) state.packages.add(name);\n return scene;\n }\n\n /** Free the GLTSLoader and the scenes it loaded, resolving once freed; the next load makes another. */\n async dispose(): Promise<void> {\n const loader = this.loader;\n this.loader = undefined;\n // A GLTSLoader that failed to load failed the load that made it.\n const made = await loader?.catch(() => undefined);\n made?.dispose();\n }\n}\n\nlet users = 0;\n/** What sessions install while any runs: the served fetch, and the canvas once one bakes. */\nlet installed: Promise<Install> | undefined;\n/**\n * The restore of the last sessions to finish, which the next install waits for: @drawcall/webgpu saves and restores\n * the globals it installs per canvas, so two canvases' lives must not overlap.\n */\nlet restored: Promise<void> = Promise.resolve();\nlet current: Install | undefined;\n\ninterface Install {\n /**\n * The canvas bakes draw on, made by the first bake, so loads that only read stored levels or load sources leave the\n * process's globals alone, such as those of a glts host whose @drawcall/webgpu is another copy.\n */\n canvas?: Promise<Canvas>;\n restore: () => Promise<void>;\n}\n\n/** The canvas of the sessions running. */\nfunction canvas(): Promise<Canvas> {\n if (!current) throw new Error(\"CachedLodLoader: baking outside loadAsync\");\n return (current.canvas ??= createCanvas(1, 1));\n}\n\nasync function session<T>(state: Session, run: () => Promise<T>): Promise<T> {\n users++;\n // A failed restore failed the session that ran it. Sessions running together share one install.\n const shared = (installed ??= restored.catch(() => {}).then(install));\n try {\n current = await shared;\n return await sessions.run(state, run);\n } finally {\n if (--users === 0) {\n installed = current = undefined;\n // A failed install failed the run above.\n restored = shared.then(\n ({ restore }) => restore(),\n () => {},\n );\n await restored;\n }\n }\n}\n\n/**\n * The served fetch, and a canvas of @drawcall/webgpu once a session bakes, which installs WebGPU, image decoding and\n * workers while it lives.\n */\nfunction install(): Install {\n const { fetch } = globalThis;\n globalThis.fetch = (input, init) => serve(fetch, input, init);\n const made: Install = {\n restore: async () => {\n globalThis.fetch = fetch;\n // A canvas that failed to make failed the bake that made it.\n const canvas = await made.canvas?.catch(() => undefined);\n await canvas?.dispose();\n },\n };\n return made;\n}\n\nasync function serve(fetch: typeof globalThis.fetch, input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n const url = new URL(input instanceof Request ? input.url : input);\n const state = sessions.getStore();\n if (!state || url.protocol === \"data:\" || url.protocol === \"blob:\") return fetch(input, init);\n if (url.origin !== placeholderOrigin)\n throw new Error(`CachedLodLoader: cannot precompute a load that fetches ${url.href}, which a stored level cannot be checked against`);\n const file = publicURL(url.pathname);\n try {\n const bytes = await readFile(fileURLToPath(file));\n state.read.add(file);\n return new Response(bytes);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return new Response(null, { status: 404 });\n throw error;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/loader/node.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { readFile } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\nimport { createCanvas, type Canvas } from \"@drawcall/webgpu\";\nimport type { GLTSLoader } from \"@drawcall/glts\";\nimport { resolve as resolveImport } from \"import-meta-resolve\";\nimport { Loader, LoadingManager, WebGPURenderer, type Object3D } from \"three/webgpu\";\nimport { publicURL, type Input } from \"vitecache\";\nimport { createBakeRenderer, setUpBakeRenderer } from \"../bake.js\";\nimport type { LodLevel } from \"../levels/index.js\";\nimport { CachedLodLoader as BrowserCachedLodLoader, type CachedLodLoaderOptions } from \"./index.js\";\nimport type { LodRequest } from \"./request.js\";\nimport { loaderPathURL, placeholderOrigin } from \"./url.js\";\n\ninterface Session {\n /** The `file:` URLs of the public files the session's loads read. */\n read: Set<string>;\n /** The installed packages the session's .glts sources import. */\n packages: Set<string>;\n}\n\n/** The session of each load, by its async context: the served fetch is global. */\nconst sessions = new AsyncLocalStorage<Session>();\n\n/**\n * CachedLodLoader in Node, as the vitecache plugin and the glts CLI run it: `loadAsync` builds and saves every level of\n * the ladder, each with the public files the ladder's loads read and the installed versions of three and of the\n * packages its .glts sources import. A load that reads anything else, such as a URL off the public directory or a module\n * a .glts source imports from a CDN, fails, since no stored level could be checked against it. Served paths such as\n * `/trees/oak.glts`, and `file:` URLs in the public directory, as a headless .glts script's manager resolves them to,\n * load from vitecache's public directory (see `publicURL`), and `.glts` sources through a GLTSLoader of the load's own;\n * bakes draw on a canvas of the process's document, as a glts host has one, or else on a WebGPU device of\n * @drawcall/webgpu. The manager only resolves the request's URL.\n *\n * Each `loadAsync` loads and bakes with what it makes for itself, which it frees before resolving, so loads may run\n * concurrently. The levels it returns load their stored bytes as in browsers, and none holds the source: the source\n * level, and a simplified level, which draws with the source's materials, load the source again when a camera needs\n * them, as the glts CLI's renders of a .glts script that draws a Lod do.\n */\nexport class CachedLodLoader extends BrowserCachedLodLoader {\n constructor(manager?: LoadingManager, options: CachedLodLoaderOptions = {}) {\n super(manager, options);\n }\n\n override loadAsync(request: LodRequest): Promise<LodLevel[]> {\n const input = typeof request === \"string\" ? { url: request } : request;\n const url = this.publicPath(this.manager.resolveURL(loaderPathURL(input.url, this.path)));\n return session({ read: new Set(), packages: new Set() }, async () => {\n const loader = new SessionLoader(this.options);\n try {\n return await loader.loadAsync({ ...input, url });\n } finally {\n await loader.dispose();\n }\n });\n }\n\n /** Nothing to free: each load frees what it made. */\n override async dispose(): Promise<void> {}\n\n /** A `file:` URL in the public directory as its served path; others as in browsers. */\n protected override publicPath(url: string): string {\n if (!url.startsWith(\"file:\")) return super.publicPath(url);\n const base = publicURL(\"/\");\n if (!url.startsWith(base)) throw new Error(`CachedLodLoader: cannot precompute \"${url}\", which lies outside the public directory ${base}`);\n return `/${url.slice(base.length)}`;\n }\n}\n\n/** One `loadAsync` of the Node loader: builds every level, with a GLTSLoader and bake renderer of its own. */\nclass SessionLoader extends BrowserCachedLodLoader {\n protected override readonly buildsAll = true;\n private readonly scripts: ScriptLoader;\n\n constructor(options: CachedLodLoaderOptions) {\n super(servingManager(), options);\n // Packages resolve as the app's do.\n this.scripts = new ScriptLoader(this.manager, publicURL(\"/\"));\n this.manager.addHandler(/\\.glts$/i, this.scripts);\n }\n\n override async dispose(): Promise<void> {\n await super.dispose();\n await this.scripts.dispose();\n }\n\n /**\n * A path its manager served at the placeholder origin as that path, which `CachedLodLoader.loadAsync` gave below the\n * app's base: keyed as in browsers whatever document the process has, such as the one a headless GLTS renderer\n * installs, against which the placeholder origin would be foreign.\n */\n protected override publicPath(url: string): string {\n return url.startsWith(`${placeholderOrigin}/`) ? url.slice(placeholderOrigin.length) : super.publicPath(url);\n }\n\n /**\n * Load `url` in the load's session, or, once `loadAsync` has resolved, in a session of its own. In a process without a\n * document, on the canvas's platform: three's loaders report progress with ProgressEvent and decode images, which Node\n * has not.\n */\n protected override async loadAsset(url: string): Promise<Object3D> {\n if (!sessions.getStore()) return session({ read: new Set(), packages: new Set() }, () => this.loadAsset(url));\n if (typeof document === \"undefined\") await canvas();\n return super.loadAsset(url);\n }\n\n protected override async newBakeRenderer(): Promise<WebGPURenderer> {\n // A process with a document, such as a glts host's, has WebGPU of its own: bake on a canvas of that document, as a\n // .glts script does. A second WebGPU runtime beside the host's would take over globals the host's images upload with.\n if (typeof document !== \"undefined\") return createBakeRenderer();\n // Three's DOM canvas types exclude native canvases; its constructor checks the actual API.\n const renderer: unknown = Reflect.construct(WebGPURenderer, [{ canvas: await canvas(), antialias: false }]);\n if (!(renderer instanceof WebGPURenderer)) throw new Error(\"CachedLodLoader: three did not make a WebGPURenderer\");\n return setUpBakeRenderer(renderer);\n }\n\n protected override inputs(): Input[] {\n const state = sessions.getStore();\n if (!state) throw new Error(\"CachedLodLoader: a level was built outside loadAsync\");\n // three builds every level, whatever its source imports.\n const packages = [...new Set([\"three\", ...state.packages])].sort();\n return [...[...state.read].sort().map((path) => ({ path })), ...packages.map((name) => ({ package: name }))];\n }\n}\n\n/** A manager that serves root-relative paths from the public directory while a load runs. */\nfunction servingManager(): LoadingManager {\n const manager = new LoadingManager();\n manager.setURLModifier((url) => {\n if (!url.startsWith(\"/\") || url.startsWith(\"//\")) return url;\n if (!sessions.getStore()) throw new Error(`CachedLodLoader: cannot load \"${url}\" once the load that asked for it has ended`);\n return placeholderOrigin + url;\n });\n return manager;\n}\n\n/**\n * Loads `.glts` sources with a GLTSLoader made at the first load, resolving their packages as the app at `root` does,\n * and records the packages each imports.\n */\nclass ScriptLoader extends Loader<Object3D> {\n private loader: Promise<GLTSLoader> | undefined;\n\n constructor(\n manager: LoadingManager,\n private readonly root: string,\n ) {\n super(manager);\n }\n\n override async loadAsync(url: string): Promise<Object3D> {\n this.loader ??= import(\"@drawcall/glts\").then(\n ({ GLTSLoader }) => new GLTSLoader(this.manager, { resolve: (specifier) => resolveImport(specifier, this.root) }),\n );\n const scene = await (await this.loader).loadAsync(url);\n const { packages, runtimeModules } = scene.source;\n if (runtimeModules.length > 0)\n throw new Error(\n `CachedLodLoader: cannot precompute \"${url}\": it imports ${runtimeModules.join(\", \")} from a CDN at runtime, which a stored level cannot be checked against`,\n );\n const state = sessions.getStore();\n if (!state) throw new Error(`CachedLodLoader: \"${url}\" loaded outside loadAsync`);\n for (const name of packages) state.packages.add(name);\n return scene;\n }\n\n /** Free the GLTSLoader and the scenes it loaded, resolving once freed; the next load makes another. */\n async dispose(): Promise<void> {\n const loader = this.loader;\n this.loader = undefined;\n // A GLTSLoader that failed to load failed the load that made it.\n const made = await loader?.catch(() => undefined);\n made?.dispose();\n }\n}\n\nlet users = 0;\n/** What sessions install while any runs: the served fetch, and the canvas once one bakes. */\nlet installed: Promise<Install> | undefined;\n/**\n * The restore of the last sessions to finish, which the next install waits for: @drawcall/webgpu saves and restores\n * the globals it installs per canvas, so two canvases' lives must not overlap.\n */\nlet restored: Promise<void> = Promise.resolve();\nlet current: Install | undefined;\n\ninterface Install {\n /**\n * The canvas bakes draw on in a process without a document, made by the first source load or bake, so loads that only\n * read stored levels install no WebGPU runtime.\n */\n canvas?: Promise<Canvas>;\n restore: () => Promise<void>;\n}\n\n/** The canvas of the sessions running. */\nfunction canvas(): Promise<Canvas> {\n if (!current) throw new Error(\"CachedLodLoader: baking outside loadAsync\");\n return (current.canvas ??= createCanvas(1, 1));\n}\n\nasync function session<T>(state: Session, run: () => Promise<T>): Promise<T> {\n users++;\n // A failed restore failed the session that ran it. Sessions running together share one install.\n const shared = (installed ??= restored.catch(() => {}).then(install));\n try {\n current = await shared;\n return await sessions.run(state, run);\n } finally {\n if (--users === 0) {\n installed = current = undefined;\n // A failed install failed the run above.\n restored = shared.then(\n ({ restore }) => restore(),\n () => {},\n );\n await restored;\n }\n }\n}\n\n/**\n * The served fetch, and a canvas of @drawcall/webgpu once a session loads a source or bakes, which installs WebGPU,\n * image decoding and workers while it lives.\n */\nfunction install(): Install {\n const { fetch } = globalThis;\n globalThis.fetch = (input, init) => serve(fetch, input, init);\n const made: Install = {\n restore: async () => {\n globalThis.fetch = fetch;\n // A canvas that failed to make failed the bake that made it.\n const canvas = await made.canvas?.catch(() => undefined);\n await canvas?.dispose();\n },\n };\n return made;\n}\n\nasync function serve(fetch: typeof globalThis.fetch, input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n const url = new URL(input instanceof Request ? input.url : input);\n const state = sessions.getStore();\n if (!state || url.protocol === \"data:\" || url.protocol === \"blob:\") return fetch(input, init);\n if (url.origin !== placeholderOrigin)\n throw new Error(`CachedLodLoader: cannot precompute a load that fetches ${url.href}, which a stored level cannot be checked against`);\n const file = publicURL(url.pathname);\n try {\n const bytes = await readFile(fileURLToPath(file));\n state.read.add(file);\n return new Response(bytes);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return new Response(null, { status: 404 });\n throw error;\n }\n}\n"]}
|
package/dist/source/sampler.js
CHANGED
|
@@ -128,15 +128,17 @@ function pixels(texture) {
|
|
|
128
128
|
if (!source)
|
|
129
129
|
throw new Error(`cannot read the image of texture "${texture.name}" on the CPU`);
|
|
130
130
|
const { width, height } = source;
|
|
131
|
-
// ImageBitmaps
|
|
132
|
-
|
|
131
|
+
// ImageBitmaps ignore flipY on upload.
|
|
132
|
+
const bitmap = typeof ImageBitmap !== "undefined" && source instanceof ImageBitmap;
|
|
133
|
+
// Node without a 2D canvas, unlike a glts host's, reads them with @drawcall/webgpu.
|
|
134
|
+
if (bitmap && typeof OffscreenCanvas === "undefined")
|
|
133
135
|
return { data: readImageBitmap(source).data, width, height, rowsUp: true };
|
|
134
136
|
const context = new OffscreenCanvas(width, height).getContext("2d", { willReadFrequently: true });
|
|
135
137
|
if (!context)
|
|
136
138
|
throw new Error("no 2D canvas to read textures with");
|
|
137
139
|
context.drawImage(source, 0, 0);
|
|
138
140
|
const { data } = context.getImageData(0, 0, width, height, { colorSpace: "srgb" });
|
|
139
|
-
return { data, width, height, rowsUp:
|
|
141
|
+
return { data, width, height, rowsUp: bitmap };
|
|
140
142
|
}
|
|
141
143
|
function isData(image) {
|
|
142
144
|
if (typeof image !== "object" || image === null || !("data" in image))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sampler.js","sourceRoot":"","sources":["../../src/source/sampler.ts"],"names":[],"mappings":"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","sourcesContent":["import { ClampToEdgeWrapping, MirroredRepeatWrapping, RGBAFormat, SRGBColorSpace, UnsignedByteType, type Texture, type Wrapping } from \"three/webgpu\";\nimport { readImageBitmap } from \"@drawcall/webgpu\";\n\n// Reading textures on the CPU, as the GPU samples them.\n\n/** One mip of an RGBA8 image, row 0 first. */\nexport interface Mip {\n data: Uint8ClampedArray;\n width: number;\n height: number;\n}\n\n/**\n * A texture's texels on the CPU, with a box-filtered mip chain like the GPU's, sampled\n * trilinearly in its UV space (its matrix, wrapping and flipY applied). An sRGB texture is\n * filtered and returned in linear values, as the GPU decodes before filtering. Every\n * texture is read through the `uv` attribute: `texture.channel` is ignored. The pixels\n * are read at the first sample: a texture nothing samples is never read.\n */\nexport class CpuTextureSampler {\n /** |det| of the texture matrix: how much it scales UV area */\n readonly uvScale: number;\n /** 8-bit value to 0..1, per channel: colour channels decode sRGB if the texture is sRGB */\n private readonly decode: Float32Array[];\n /** the texture's UV transform (Matrix3 elements, column-major) */\n readonly matrix: number[];\n private readonly wrapS: Wrapping;\n private readonly wrapT: Wrapping;\n private readonly lower = new Float32Array(4);\n private readonly upper = new Float32Array(4);\n private read: { mips: Mip[]; flipY: boolean } | null = null;\n\n constructor(private readonly texture: Texture) {\n this.decode = decoders(texture.colorSpace === SRGBColorSpace);\n if (texture.matrixAutoUpdate) texture.updateMatrix();\n this.matrix = texture.matrix.elements.slice();\n const [a = 1, b = 0, , c = 0, d = 1] = this.matrix;\n this.uvScale = Math.abs(a * d - b * c);\n this.wrapS = texture.wrapS;\n this.wrapT = texture.wrapT;\n }\n\n get width(): number {\n return this.base().width;\n }\n\n get height(): number {\n return this.base().height;\n }\n\n private base(): Mip {\n return this.pixels().mips[0] ?? missing();\n }\n\n private pixels(): { mips: Mip[]; flipY: boolean } {\n if (this.read) return this.read;\n const { texture } = this;\n const { data, width, height, rowsUp } = pixels(texture);\n // Row 0 of the pixels is v = 1 when they were uploaded flipped.\n this.read = { mips: mipmaps({ data, width, height }, texture.colorSpace === SRGBColorSpace), flipY: texture.flipY && !rowsUp };\n return this.read;\n }\n\n /** The texel at (u, v) from mip `mip` (fractional: trilinear) into `out`, channels 0..1. */\n sample(u: number, v: number, mip: number, out: Float32Array): void {\n const [m0 = 1, m1 = 0, , m3 = 0, m4 = 1, , m6 = 0, m7 = 0] = this.matrix;\n const su = wrap(m0 * u + m3 * v + m6, this.wrapS);\n const tv = wrap(m1 * u + m4 * v + m7, this.wrapT);\n const { mips, flipY } = this.pixels();\n const sv = flipY ? 1 - tv : tv;\n const top = mips.length - 1;\n const l = Math.min(Math.max(mip, 0), top);\n const l0 = Math.floor(l);\n const f = l - l0;\n this.bilinear(l0, su, sv, f > 0 ? this.lower : out);\n if (f === 0) return;\n this.bilinear(Math.min(l0 + 1, top), su, sv, this.upper);\n for (let k = 0; k < 4; k++) out[k] = (this.lower[k] ?? 0) * (1 - f) + (this.upper[k] ?? 0) * f;\n }\n\n private bilinear(mip: number, su: number, sv: number, out: Float32Array): void {\n const { data, width, height } = this.pixels().mips[mip] ?? missing();\n const x = su * width - 0.5;\n const y = sv * height - 0.5;\n const x0 = Math.floor(x);\n const y0 = Math.floor(y);\n const fx = x - x0;\n const fy = y - y0;\n const cx = (i: number) => (this.wrapS === ClampToEdgeWrapping ? Math.min(Math.max(i, 0), width - 1) : ((i % width) + width) % width);\n const cy = (i: number) => (this.wrapT === ClampToEdgeWrapping ? Math.min(Math.max(i, 0), height - 1) : ((i % height) + height) % height);\n const a = (cy(y0) * width + cx(x0)) * 4;\n const b = (cy(y0) * width + cx(x0 + 1)) * 4;\n const c = (cy(y0 + 1) * width + cx(x0)) * 4;\n const d = (cy(y0 + 1) * width + cx(x0 + 1)) * 4;\n for (let k = 0; k < 4; k++) {\n const decode = this.decode[k] ?? missing();\n const top = (decode[data[a + k] ?? 0] ?? 0) * (1 - fx) + (decode[data[b + k] ?? 0] ?? 0) * fx;\n const bottom = (decode[data[c + k] ?? 0] ?? 0) * (1 - fx) + (decode[data[d + k] ?? 0] ?? 0) * fx;\n out[k] = top * (1 - fy) + bottom * fy;\n }\n }\n}\n\nconst missing = (): never => {\n throw new Error(\"CpuTextureSampler: lookup out of range\");\n};\n\nexport const srgbToLinear = (c: number) => (c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));\nexport const linearToSrgb = (c: number) => (c <= 0.0031308 ? c * 12.92 : 1.055 * Math.pow(Math.min(c, 1), 1 / 2.4) - 0.055);\n\nfunction wrap(x: number, mode: Wrapping): number {\n if (mode === ClampToEdgeWrapping) return Math.min(Math.max(x, 0), 1);\n if (mode === MirroredRepeatWrapping) {\n const f = ((x % 2) + 2) % 2;\n return f > 1 ? 2 - f : f;\n }\n return x - Math.floor(x);\n}\n\n/** Whether `pixels` can read `texture` on the CPU. */\nexport function readable(texture: Texture): boolean {\n if (\"isCompressedTexture\" in texture) return false;\n const image: unknown = texture.image;\n if (isData(image)) return texture.format === RGBAFormat && texture.type === UnsignedByteType;\n return drawable(image) !== null;\n}\n\n/** The texture's 8-bit RGBA pixels; `rowsUp` when row 0 is v = 0 whatever flipY says. */\nfunction pixels(texture: Texture): Mip & { rowsUp: boolean } {\n const image = texture.image;\n if (\"isCompressedTexture\" in texture) throw new Error(`cannot read compressed texture \"${texture.name}\" on the CPU`);\n if (isData(image)) {\n if (texture.format !== RGBAFormat || texture.type !== UnsignedByteType)\n throw new Error(`cannot read data texture \"${texture.name}\" on the CPU: it is not 8-bit RGBA`);\n const data = new Uint8ClampedArray(image.data.buffer, image.data.byteOffset, image.width * image.height * 4);\n // Data textures are uploaded as they are.\n return { data, width: image.width, height: image.height, rowsUp: true };\n }\n const source = drawable(image);\n if (!source) throw new Error(`cannot read the image of texture \"${texture.name}\" on the CPU`);\n const { width, height } = source;\n // ImageBitmaps are read with @drawcall/webgpu, in browsers as in Node, which has no 2D canvas; they ignore flipY on upload.\n if (typeof ImageBitmap !== \"undefined\" && source instanceof ImageBitmap) return { data: readImageBitmap(source).data, width, height, rowsUp: true };\n const context = new OffscreenCanvas(width, height).getContext(\"2d\", { willReadFrequently: true });\n if (!context) throw new Error(\"no 2D canvas to read textures with\");\n context.drawImage(source, 0, 0);\n const { data } = context.getImageData(0, 0, width, height, { colorSpace: \"srgb\" });\n return { data, width, height, rowsUp: false };\n}\n\nfunction isData(image: unknown): image is { data: Uint8Array | Uint8ClampedArray; width: number; height: number } {\n if (typeof image !== \"object\" || image === null || !(\"data\" in image)) return false;\n return image.data instanceof Uint8Array || image.data instanceof Uint8ClampedArray;\n}\n\n/** `image` as something a 2D canvas draws, if it is one. */\nfunction drawable(image: unknown): (CanvasImageSource & { width: number; height: number }) | null {\n const kinds = [globalThis.ImageBitmap, globalThis.HTMLImageElement, globalThis.HTMLCanvasElement, globalThis.OffscreenCanvas];\n for (const kind of kinds) if (kind && image instanceof kind) return image;\n return null;\n}\n\n/** Per channel, 8-bit value to 0..1: the colour channels of an sRGB image decode to linear. */\nfunction decoders(srgb: boolean): Float32Array[] {\n const linear = Float32Array.from({ length: 256 }, (_, i) => i / 255);\n const color = srgb ? linear.map(srgbToLinear) : linear;\n return [color, color, color, linear];\n}\n\n/**\n * `base` and its box-filtered halvings down to 1×1, as generateMipmap makes them: an sRGB\n * image is averaged in linear values.\n */\nexport function mipmaps(base: Mip, srgb: boolean): Mip[] {\n const decode = decoders(srgb);\n const encode = (value: number, channel: number) => (srgb && channel < 3 ? linearToSrgb(value) : value);\n const mips = [base];\n let mip = base;\n while (mip.width > 1 || mip.height > 1) {\n const { data: from, width: w, height: h } = mip;\n const width = Math.max(1, w >> 1);\n const height = Math.max(1, h >> 1);\n const data = new Uint8ClampedArray(width * height * 4);\n for (let k = 0; k < 4; k++) {\n const d = decode[k] ?? missing();\n for (let y = 0; y < height; y++) {\n const row0 = Math.min(y * 2, h - 1) * w;\n const row1 = Math.min(y * 2 + 1, h - 1) * w;\n for (let x = 0; x < width; x++) {\n const x0 = Math.min(x * 2, w - 1);\n const x1 = Math.min(x * 2 + 1, w - 1);\n const sum =\n (d[from[(row0 + x0) * 4 + k] ?? 0] ?? 0) +\n (d[from[(row0 + x1) * 4 + k] ?? 0] ?? 0) +\n (d[from[(row1 + x0) * 4 + k] ?? 0] ?? 0) +\n (d[from[(row1 + x1) * 4 + k] ?? 0] ?? 0);\n data[(y * width + x) * 4 + k] = encode(sum / 4, k) * 255;\n }\n }\n }\n mips.push((mip = { data, width, height }));\n }\n return mips;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sampler.js","sourceRoot":"","sources":["../../src/source/sampler.ts"],"names":[],"mappings":"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","sourcesContent":["import { ClampToEdgeWrapping, MirroredRepeatWrapping, RGBAFormat, SRGBColorSpace, UnsignedByteType, type Texture, type Wrapping } from \"three/webgpu\";\nimport { readImageBitmap } from \"@drawcall/webgpu\";\n\n// Reading textures on the CPU, as the GPU samples them.\n\n/** One mip of an RGBA8 image, row 0 first. */\nexport interface Mip {\n data: Uint8ClampedArray;\n width: number;\n height: number;\n}\n\n/**\n * A texture's texels on the CPU, with a box-filtered mip chain like the GPU's, sampled\n * trilinearly in its UV space (its matrix, wrapping and flipY applied). An sRGB texture is\n * filtered and returned in linear values, as the GPU decodes before filtering. Every\n * texture is read through the `uv` attribute: `texture.channel` is ignored. The pixels\n * are read at the first sample: a texture nothing samples is never read.\n */\nexport class CpuTextureSampler {\n /** |det| of the texture matrix: how much it scales UV area */\n readonly uvScale: number;\n /** 8-bit value to 0..1, per channel: colour channels decode sRGB if the texture is sRGB */\n private readonly decode: Float32Array[];\n /** the texture's UV transform (Matrix3 elements, column-major) */\n readonly matrix: number[];\n private readonly wrapS: Wrapping;\n private readonly wrapT: Wrapping;\n private readonly lower = new Float32Array(4);\n private readonly upper = new Float32Array(4);\n private read: { mips: Mip[]; flipY: boolean } | null = null;\n\n constructor(private readonly texture: Texture) {\n this.decode = decoders(texture.colorSpace === SRGBColorSpace);\n if (texture.matrixAutoUpdate) texture.updateMatrix();\n this.matrix = texture.matrix.elements.slice();\n const [a = 1, b = 0, , c = 0, d = 1] = this.matrix;\n this.uvScale = Math.abs(a * d - b * c);\n this.wrapS = texture.wrapS;\n this.wrapT = texture.wrapT;\n }\n\n get width(): number {\n return this.base().width;\n }\n\n get height(): number {\n return this.base().height;\n }\n\n private base(): Mip {\n return this.pixels().mips[0] ?? missing();\n }\n\n private pixels(): { mips: Mip[]; flipY: boolean } {\n if (this.read) return this.read;\n const { texture } = this;\n const { data, width, height, rowsUp } = pixels(texture);\n // Row 0 of the pixels is v = 1 when they were uploaded flipped.\n this.read = { mips: mipmaps({ data, width, height }, texture.colorSpace === SRGBColorSpace), flipY: texture.flipY && !rowsUp };\n return this.read;\n }\n\n /** The texel at (u, v) from mip `mip` (fractional: trilinear) into `out`, channels 0..1. */\n sample(u: number, v: number, mip: number, out: Float32Array): void {\n const [m0 = 1, m1 = 0, , m3 = 0, m4 = 1, , m6 = 0, m7 = 0] = this.matrix;\n const su = wrap(m0 * u + m3 * v + m6, this.wrapS);\n const tv = wrap(m1 * u + m4 * v + m7, this.wrapT);\n const { mips, flipY } = this.pixels();\n const sv = flipY ? 1 - tv : tv;\n const top = mips.length - 1;\n const l = Math.min(Math.max(mip, 0), top);\n const l0 = Math.floor(l);\n const f = l - l0;\n this.bilinear(l0, su, sv, f > 0 ? this.lower : out);\n if (f === 0) return;\n this.bilinear(Math.min(l0 + 1, top), su, sv, this.upper);\n for (let k = 0; k < 4; k++) out[k] = (this.lower[k] ?? 0) * (1 - f) + (this.upper[k] ?? 0) * f;\n }\n\n private bilinear(mip: number, su: number, sv: number, out: Float32Array): void {\n const { data, width, height } = this.pixels().mips[mip] ?? missing();\n const x = su * width - 0.5;\n const y = sv * height - 0.5;\n const x0 = Math.floor(x);\n const y0 = Math.floor(y);\n const fx = x - x0;\n const fy = y - y0;\n const cx = (i: number) => (this.wrapS === ClampToEdgeWrapping ? Math.min(Math.max(i, 0), width - 1) : ((i % width) + width) % width);\n const cy = (i: number) => (this.wrapT === ClampToEdgeWrapping ? Math.min(Math.max(i, 0), height - 1) : ((i % height) + height) % height);\n const a = (cy(y0) * width + cx(x0)) * 4;\n const b = (cy(y0) * width + cx(x0 + 1)) * 4;\n const c = (cy(y0 + 1) * width + cx(x0)) * 4;\n const d = (cy(y0 + 1) * width + cx(x0 + 1)) * 4;\n for (let k = 0; k < 4; k++) {\n const decode = this.decode[k] ?? missing();\n const top = (decode[data[a + k] ?? 0] ?? 0) * (1 - fx) + (decode[data[b + k] ?? 0] ?? 0) * fx;\n const bottom = (decode[data[c + k] ?? 0] ?? 0) * (1 - fx) + (decode[data[d + k] ?? 0] ?? 0) * fx;\n out[k] = top * (1 - fy) + bottom * fy;\n }\n }\n}\n\nconst missing = (): never => {\n throw new Error(\"CpuTextureSampler: lookup out of range\");\n};\n\nexport const srgbToLinear = (c: number) => (c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));\nexport const linearToSrgb = (c: number) => (c <= 0.0031308 ? c * 12.92 : 1.055 * Math.pow(Math.min(c, 1), 1 / 2.4) - 0.055);\n\nfunction wrap(x: number, mode: Wrapping): number {\n if (mode === ClampToEdgeWrapping) return Math.min(Math.max(x, 0), 1);\n if (mode === MirroredRepeatWrapping) {\n const f = ((x % 2) + 2) % 2;\n return f > 1 ? 2 - f : f;\n }\n return x - Math.floor(x);\n}\n\n/** Whether `pixels` can read `texture` on the CPU. */\nexport function readable(texture: Texture): boolean {\n if (\"isCompressedTexture\" in texture) return false;\n const image: unknown = texture.image;\n if (isData(image)) return texture.format === RGBAFormat && texture.type === UnsignedByteType;\n return drawable(image) !== null;\n}\n\n/** The texture's 8-bit RGBA pixels; `rowsUp` when row 0 is v = 0 whatever flipY says. */\nfunction pixels(texture: Texture): Mip & { rowsUp: boolean } {\n const image = texture.image;\n if (\"isCompressedTexture\" in texture) throw new Error(`cannot read compressed texture \"${texture.name}\" on the CPU`);\n if (isData(image)) {\n if (texture.format !== RGBAFormat || texture.type !== UnsignedByteType)\n throw new Error(`cannot read data texture \"${texture.name}\" on the CPU: it is not 8-bit RGBA`);\n const data = new Uint8ClampedArray(image.data.buffer, image.data.byteOffset, image.width * image.height * 4);\n // Data textures are uploaded as they are.\n return { data, width: image.width, height: image.height, rowsUp: true };\n }\n const source = drawable(image);\n if (!source) throw new Error(`cannot read the image of texture \"${texture.name}\" on the CPU`);\n const { width, height } = source;\n // ImageBitmaps ignore flipY on upload.\n const bitmap = typeof ImageBitmap !== \"undefined\" && source instanceof ImageBitmap;\n // Node without a 2D canvas, unlike a glts host's, reads them with @drawcall/webgpu.\n if (bitmap && typeof OffscreenCanvas === \"undefined\") return { data: readImageBitmap(source).data, width, height, rowsUp: true };\n const context = new OffscreenCanvas(width, height).getContext(\"2d\", { willReadFrequently: true });\n if (!context) throw new Error(\"no 2D canvas to read textures with\");\n context.drawImage(source, 0, 0);\n const { data } = context.getImageData(0, 0, width, height, { colorSpace: \"srgb\" });\n return { data, width, height, rowsUp: bitmap };\n}\n\nfunction isData(image: unknown): image is { data: Uint8Array | Uint8ClampedArray; width: number; height: number } {\n if (typeof image !== \"object\" || image === null || !(\"data\" in image)) return false;\n return image.data instanceof Uint8Array || image.data instanceof Uint8ClampedArray;\n}\n\n/** `image` as something a 2D canvas draws, if it is one. */\nfunction drawable(image: unknown): (CanvasImageSource & { width: number; height: number }) | null {\n const kinds = [globalThis.ImageBitmap, globalThis.HTMLImageElement, globalThis.HTMLCanvasElement, globalThis.OffscreenCanvas];\n for (const kind of kinds) if (kind && image instanceof kind) return image;\n return null;\n}\n\n/** Per channel, 8-bit value to 0..1: the colour channels of an sRGB image decode to linear. */\nfunction decoders(srgb: boolean): Float32Array[] {\n const linear = Float32Array.from({ length: 256 }, (_, i) => i / 255);\n const color = srgb ? linear.map(srgbToLinear) : linear;\n return [color, color, color, linear];\n}\n\n/**\n * `base` and its box-filtered halvings down to 1×1, as generateMipmap makes them: an sRGB\n * image is averaged in linear values.\n */\nexport function mipmaps(base: Mip, srgb: boolean): Mip[] {\n const decode = decoders(srgb);\n const encode = (value: number, channel: number) => (srgb && channel < 3 ? linearToSrgb(value) : value);\n const mips = [base];\n let mip = base;\n while (mip.width > 1 || mip.height > 1) {\n const { data: from, width: w, height: h } = mip;\n const width = Math.max(1, w >> 1);\n const height = Math.max(1, h >> 1);\n const data = new Uint8ClampedArray(width * height * 4);\n for (let k = 0; k < 4; k++) {\n const d = decode[k] ?? missing();\n for (let y = 0; y < height; y++) {\n const row0 = Math.min(y * 2, h - 1) * w;\n const row1 = Math.min(y * 2 + 1, h - 1) * w;\n for (let x = 0; x < width; x++) {\n const x0 = Math.min(x * 2, w - 1);\n const x1 = Math.min(x * 2 + 1, w - 1);\n const sum =\n (d[from[(row0 + x0) * 4 + k] ?? 0] ?? 0) +\n (d[from[(row0 + x1) * 4 + k] ?? 0] ?? 0) +\n (d[from[(row1 + x0) * 4 + k] ?? 0] ?? 0) +\n (d[from[(row1 + x1) * 4 + k] ?? 0] ?? 0);\n data[(y * width + x) * 4 + k] = encode(sum / 4, k) * 255;\n }\n }\n }\n mips.push((mip = { data, width, height }));\n }\n return mips;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drawcall/lod",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Level of detail for three.js: octahedral impostors, simplified and baked meshes, with dithered switching by on-screen size. WebGPURenderer only.",
|
|
6
6
|
"keywords": [
|