@drawcall/lod 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/README.md +5 -8
  2. package/dist/bake.d.ts +16 -2
  3. package/dist/bake.js +92 -4
  4. package/dist/bake.js.map +1 -1
  5. package/dist/baked/index.d.ts +2 -2
  6. package/dist/baked/index.js +2 -2
  7. package/dist/baked/interior/faces.js +4 -2
  8. package/dist/baked/interior/faces.js.map +1 -1
  9. package/dist/baked/interior/material.js +1 -1
  10. package/dist/baked/interior/material.js.map +1 -1
  11. package/dist/baked/interior/rooms.d.ts +1 -1
  12. package/dist/baked/interior/rooms.js +1 -1
  13. package/dist/dispose.d.ts +3 -3
  14. package/dist/dispose.js +6 -6
  15. package/dist/dispose.js.map +1 -1
  16. package/dist/foliage.d.ts +32 -0
  17. package/dist/foliage.js +137 -0
  18. package/dist/foliage.js.map +1 -0
  19. package/dist/impostor/bake/index.d.ts +3 -3
  20. package/dist/impostor/bake/index.js +12 -3
  21. package/dist/impostor/bake/index.js.map +1 -1
  22. package/dist/impostor/bake/source.d.ts +2 -1
  23. package/dist/impostor/bake/source.js +2 -2
  24. package/dist/impostor/bake/source.js.map +1 -1
  25. package/dist/impostor/impostor.d.ts +1 -1
  26. package/dist/impostor/impostor.js +1 -1
  27. package/dist/impostor/ktx2/encode.js +5 -2
  28. package/dist/impostor/ktx2/encode.js.map +1 -1
  29. package/dist/impostor/ktx2/uastc.js +3 -2
  30. package/dist/impostor/ktx2/uastc.js.map +1 -1
  31. package/dist/impostor/ktx2/worker.js +0 -2
  32. package/dist/impostor/ktx2/worker.js.map +1 -1
  33. package/dist/impostor/mesh/card.d.ts +1 -1
  34. package/dist/impostor/mesh/index.d.ts +2 -2
  35. package/dist/impostor/mesh/index.js +3 -3
  36. package/dist/impostor/mesh/index.js.map +1 -1
  37. package/dist/index.d.ts +3 -6
  38. package/dist/index.js +3 -6
  39. package/dist/index.js.map +1 -1
  40. package/dist/instanced/camera.d.ts +13 -25
  41. package/dist/instanced/camera.js +17 -42
  42. package/dist/instanced/camera.js.map +1 -1
  43. package/dist/instanced/clusters.d.ts +54 -0
  44. package/dist/instanced/clusters.js +151 -0
  45. package/dist/instanced/clusters.js.map +1 -0
  46. package/dist/instanced/cull.d.ts +3 -3
  47. package/dist/instanced/cull.js +2 -2
  48. package/dist/instanced/cull.js.map +1 -1
  49. package/dist/instanced/instances.d.ts +39 -0
  50. package/dist/instanced/instances.js +104 -0
  51. package/dist/instanced/instances.js.map +1 -0
  52. package/dist/instanced/key.d.ts +1 -1
  53. package/dist/instanced/key.js +1 -1
  54. package/dist/instanced/key.js.map +1 -1
  55. package/dist/instanced/levels.d.ts +9 -9
  56. package/dist/instanced/levels.js +7 -6
  57. package/dist/instanced/levels.js.map +1 -1
  58. package/dist/instanced/lists.d.ts +26 -39
  59. package/dist/instanced/lists.js +42 -61
  60. package/dist/instanced/lists.js.map +1 -1
  61. package/dist/instanced/measure.d.ts +2 -2
  62. package/dist/instanced/measure.js +2 -2
  63. package/dist/instanced/meshes.d.ts +11 -9
  64. package/dist/instanced/meshes.js +26 -16
  65. package/dist/instanced/meshes.js.map +1 -1
  66. package/dist/instanced/mirror.d.ts +16 -12
  67. package/dist/instanced/mirror.js +51 -12
  68. package/dist/instanced/mirror.js.map +1 -1
  69. package/dist/instanced/raycast.d.ts +6 -9
  70. package/dist/instanced/raycast.js +15 -18
  71. package/dist/instanced/raycast.js.map +1 -1
  72. package/dist/instanced/rows.d.ts +15 -73
  73. package/dist/instanced/rows.js +16 -189
  74. package/dist/instanced/rows.js.map +1 -1
  75. package/dist/instanced/shape.d.ts +3 -1
  76. package/dist/instanced/shape.js +6 -3
  77. package/dist/instanced/shape.js.map +1 -1
  78. package/dist/instanced/sort.d.ts +32 -34
  79. package/dist/instanced/sort.js +162 -132
  80. package/dist/instanced/sort.js.map +1 -1
  81. package/dist/instanced/update.d.ts +16 -12
  82. package/dist/instanced/update.js +57 -84
  83. package/dist/instanced/update.js.map +1 -1
  84. package/dist/levels/compile/index.d.ts +4 -2
  85. package/dist/levels/compile/index.js +10 -2
  86. package/dist/levels/compile/index.js.map +1 -1
  87. package/dist/levels/compile/pipelines.d.ts +1 -1
  88. package/dist/levels/compile/pipelines.js +1 -6
  89. package/dist/levels/compile/pipelines.js.map +1 -1
  90. package/dist/levels/draw.d.ts +1 -1
  91. package/dist/levels/draw.js +3 -3
  92. package/dist/levels/fade.d.ts +13 -22
  93. package/dist/levels/fade.js +17 -38
  94. package/dist/levels/fade.js.map +1 -1
  95. package/dist/levels/index.d.ts +7 -7
  96. package/dist/levels/index.js +1 -1
  97. package/dist/levels/item.d.ts +10 -10
  98. package/dist/levels/item.js +15 -23
  99. package/dist/levels/item.js.map +1 -1
  100. package/dist/levels/load.d.ts +1 -1
  101. package/dist/levels/load.js +5 -3
  102. package/dist/levels/load.js.map +1 -1
  103. package/dist/levels/manager.d.ts +30 -31
  104. package/dist/levels/manager.js +75 -62
  105. package/dist/levels/manager.js.map +1 -1
  106. package/dist/levels/material.d.ts +2 -2
  107. package/dist/levels/material.js +2 -2
  108. package/dist/levels/renderer.d.ts +8 -5
  109. package/dist/levels/renderer.js +20 -4
  110. package/dist/levels/renderer.js.map +1 -1
  111. package/dist/levels/requests.d.ts +4 -1
  112. package/dist/levels/requests.js +3 -1
  113. package/dist/levels/requests.js.map +1 -1
  114. package/dist/loader/context.d.ts +9 -11
  115. package/dist/loader/context.js +12 -7
  116. package/dist/loader/context.js.map +1 -1
  117. package/dist/loader/entry.d.ts +4 -0
  118. package/dist/loader/entry.js +43 -0
  119. package/dist/loader/entry.js.map +1 -0
  120. package/dist/loader/index.d.ts +49 -35
  121. package/dist/loader/index.js +123 -135
  122. package/dist/loader/index.js.map +1 -1
  123. package/dist/loader/level.js +5 -5
  124. package/dist/loader/level.js.map +1 -1
  125. package/dist/loader/node.d.ts +26 -0
  126. package/dist/loader/node.js +199 -0
  127. package/dist/loader/node.js.map +1 -0
  128. package/dist/loader/request.d.ts +11 -44
  129. package/dist/loader/request.js +7 -47
  130. package/dist/loader/request.js.map +1 -1
  131. package/dist/loader/url.d.ts +10 -9
  132. package/dist/loader/url.js +21 -17
  133. package/dist/loader/url.js.map +1 -1
  134. package/dist/lod.d.ts +122 -62
  135. package/dist/lod.js +331 -187
  136. package/dist/lod.js.map +1 -1
  137. package/dist/meshopt.d.ts +1 -1
  138. package/dist/meshopt.js +3 -2
  139. package/dist/meshopt.js.map +1 -1
  140. package/dist/node-process.d.ts +5 -0
  141. package/dist/node-process.js +6 -0
  142. package/dist/node-process.js.map +1 -0
  143. package/dist/node.d.ts +2 -0
  144. package/dist/node.js +5 -0
  145. package/dist/node.js.map +1 -0
  146. package/dist/simplify/index.d.ts +2 -2
  147. package/dist/simplify/index.js +7 -7
  148. package/dist/simplify/index.js.map +1 -1
  149. package/dist/source/detail.d.ts +7 -2
  150. package/dist/source/detail.js +24 -22
  151. package/dist/source/detail.js.map +1 -1
  152. package/dist/source/sampler.js +5 -2
  153. package/dist/source/sampler.js.map +1 -1
  154. package/dist/three.d.ts +7 -7
  155. package/dist/three.js +4 -4
  156. package/dist/three.js.map +1 -1
  157. package/dist/wind/bounds.js +1 -1
  158. package/dist/wind/bounds.js.map +1 -1
  159. package/dist/wind/hooks.d.ts +1 -1
  160. package/dist/wind/hooks.js +1 -1
  161. package/dist/wind/index.d.ts +3 -3
  162. package/dist/wind/index.js +11 -9
  163. package/dist/wind/index.js.map +1 -1
  164. package/package.json +10 -6
  165. package/skills/lod/SKILL.md +65 -54
  166. package/dist/gpu.d.ts +0 -39
  167. package/dist/gpu.js +0 -41
  168. package/dist/gpu.js.map +0 -1
  169. package/dist/instanced/chunk.d.ts +0 -97
  170. package/dist/instanced/chunk.js +0 -156
  171. package/dist/instanced/chunk.js.map +0 -1
  172. package/dist/instanced/chunks.d.ts +0 -60
  173. package/dist/instanced/chunks.js +0 -208
  174. package/dist/instanced/chunks.js.map +0 -1
  175. package/dist/instanced/index.d.ts +0 -120
  176. package/dist/instanced/index.js +0 -290
  177. package/dist/instanced/index.js.map +0 -1
  178. package/dist/instanced/pages/buffers.d.ts +0 -37
  179. package/dist/instanced/pages/buffers.js +0 -15
  180. package/dist/instanced/pages/buffers.js.map +0 -1
  181. package/dist/instanced/pages/chunk.d.ts +0 -51
  182. package/dist/instanced/pages/chunk.js +0 -81
  183. package/dist/instanced/pages/chunk.js.map +0 -1
  184. package/dist/instanced/pages/index.d.ts +0 -74
  185. package/dist/instanced/pages/index.js +0 -269
  186. package/dist/instanced/pages/index.js.map +0 -1
  187. package/dist/instanced/pages/passes.d.ts +0 -21
  188. package/dist/instanced/pages/passes.js +0 -52
  189. package/dist/instanced/pages/passes.js.map +0 -1
  190. package/dist/instanced/pages/slots.d.ts +0 -11
  191. package/dist/instanced/pages/slots.js +0 -90
  192. package/dist/instanced/pages/slots.js.map +0 -1
  193. package/dist/instanced/pages/workgroup.d.ts +0 -14
  194. package/dist/instanced/pages/workgroup.js +0 -38
  195. package/dist/instanced/pages/workgroup.js.map +0 -1
  196. package/dist/levels/wait.d.ts +0 -27
  197. package/dist/levels/wait.js +0 -61
  198. package/dist/levels/wait.js.map +0 -1
  199. package/dist/loader/cache.d.ts +0 -12
  200. package/dist/loader/cache.js +0 -68
  201. package/dist/loader/cache.js.map +0 -1
  202. package/dist/loader/dependencies.d.ts +0 -32
  203. package/dist/loader/dependencies.js +0 -113
  204. package/dist/loader/dependencies.js.map +0 -1
@@ -1,74 +0,0 @@
1
- import { type Renderer, StorageBufferAttribute, StorageInstancedBufferAttribute } from "three/webgpu";
2
- import type { Attributes, ChunkRange } from "./chunk.js";
3
- /** A chunk to take in: its attributes and its range of them, where its instance count lies, and its InstancedLod's row. */
4
- export interface PoolChunk extends Pick<ChunkRange, "start" | "count" | "countIndex"> {
5
- readonly attributes: Attributes;
6
- readonly row: number;
7
- }
8
- /** The page pool of a LodGpu, and the passes that fill and free it. */
9
- export declare class InstancePagePool {
10
- /** Room for instances, in pages of `PAGE`. */
11
- readonly capacity: number;
12
- readonly pages: number;
13
- /** How many pages chunks hold, then per page held its id and its InstancedLod's row (see `PAGE_BITS`). */
14
- readonly occupied: StorageBufferAttribute;
15
- /** Bumped whenever the passes ran: what the pages hold changed. */
16
- version: number;
17
- private readonly pool;
18
- private passes;
19
- /** Per slot, its chunk and windows, and the generation of the chunk it last took: a slot reused in one frame still frees its pages. */
20
- private readonly held;
21
- private readonly generations;
22
- private readonly free;
23
- /** The windows no chunk counts in, and those of chunks removed, free once the passes freed their pages. */
24
- private windows;
25
- private releasing;
26
- /** The slots whose chunks are taken in at the next run, and whether a chunk was removed since the last. */
27
- private readonly due;
28
- private removed;
29
- /** The last read of the chunks' states, and the run it followed. */
30
- private read;
31
- /** Whether the pool's CPU arrays were dropped (see `releaseArrays`). */
32
- private released;
33
- constructor(
34
- /** The most instances held at once. */
35
- maxInstanceCount: number,
36
- /** The most chunks held at once. */
37
- maxChunkCount: number);
38
- /** Every pool index's instance matrix, as the level meshes draw them. */
39
- get matrices(): StorageInstancedBufferAttribute;
40
- /** Every pool index's colour, RGB and a pad. */
41
- get colors(): StorageInstancedBufferAttribute;
42
- /** Whether the next run takes chunks in or frees them. */
43
- get pending(): boolean;
44
- /** Take `chunk` into a free slot at the next run; its slot. */
45
- add(chunk: PoolChunk): number;
46
- /** Take slot `slot`'s chunk in again at the next run: its attributes changed. */
47
- change(slot: number): void;
48
- /** Free slot `slot`; its chunk's pages go back to the pool at the next run, its windows after it. */
49
- remove(slot: number): void;
50
- private heldAt;
51
- private write;
52
- /** The first of `count` free windows, taken; null if no run of them is free. */
53
- private take;
54
- /** Free the windows of `freed`, merging runs that meet. */
55
- private giveBack;
56
- /** Take the chunks' changes in on `renderer`, if they changed since the last run. */
57
- prepare(renderer: Renderer): void;
58
- /** Run slot `slot`'s chunk's `pass`, one workgroup per window of its range. */
59
- private run;
60
- /**
61
- * The instances the chunks of `slots` hold, once every one has been taken in; null while changes wait for the passes
62
- * or chunks changed meanwhile. Throws if a chunk lacks pages. Reads the GPU's progress back.
63
- */
64
- status(renderer: Renderer, slots: readonly number[]): Promise<number | null>;
65
- /** The chunks' states as the GPU holds them after run `version`: one read back for every InstancedLod asking. */
66
- private statesAt;
67
- dispose(): void;
68
- }
69
- /**
70
- * Drop the CPU arrays of `attributes`, buffers only the GPU writes, once a pass has run with them: they are never read
71
- * again, and they are most of what they cost on the CPU. This relies on three never uploading them again (as of three
72
- * r186): nothing marks them for an update, and a LodGpu's renderer, initialised, made each buffer as the pass ran.
73
- */
74
- export declare function releaseArrays(attributes: readonly StorageInstancedBufferAttribute[]): void;
@@ -1,269 +0,0 @@
1
- import { StorageBufferAttribute, StorageInstancedBufferAttribute } from "three/webgpu";
2
- import { at } from "../../at.js";
3
- import { PAGE_BITS } from "./buffers.js";
4
- import { PoolPasses } from "./passes.js";
5
- import { PAGE } from "./workgroup.js";
6
- // Every instance of every InstancedLod of a LodGpu lives in its page pool: fixed pages of `PAGE` instances, which chunks,
7
- // from the CPU or the GPU, are copied into, and which updateInstance visits one workgroup per page (see update.ts).
8
- //
9
- // In the first render after chunks were added, changed or removed, these passes run: one workgroup
10
- // walks the chunk slots and pushes every removed or changed chunk's pages back on the free stack; per chunk taken in, a
11
- // pass with one workgroup per window of `PAGE` of its range counts the window's instances, those at a scale above 0 (an
12
- // app's pass marks "no instance" with scale 0); one workgroup then gives every such chunk the pages its instances need,
13
- // turning its windows' counts into where their instances start; per chunk again, a pass writes each instance into its
14
- // page, so a chunk's instances fill its pages in order, a spot without an instance costs no room, and the room past its
15
- // last instance draws nothing; last, one workgroup lists every page chunks hold, with its InstancedLod's row. That
16
- // render is the only time a chunk's attributes are read. A chunk that finds the stack short holds the pages it got, its
17
- // instances clamped to them, until it is removed; `status` reports it. The CPU never learns a count: it knows only
18
- // which slots hold chunks and which windows they count in, and the GPU knows what each got.
19
- /** Windows of `PAGE` spots per page of instances that chunks may span: chunks hold far more spots than instances. */
20
- const WINDOWS_PER_PAGE = 16;
21
- /** WebGPU's guaranteed maxStorageBufferBindingSize: the pool's matrices are one binding. */
22
- const MAX_BINDING = 128 * 2 ** 20;
23
- /** The page pool of a LodGpu, and the passes that fill and free it. */
24
- export class InstancePagePool {
25
- /** Room for instances, in pages of `PAGE`. */
26
- capacity;
27
- pages;
28
- /** How many pages chunks hold, then per page held its id and its InstancedLod's row (see `PAGE_BITS`). */
29
- occupied;
30
- /** Bumped whenever the passes ran: what the pages hold changed. */
31
- version = 0;
32
- pool;
33
- passes = null;
34
- /** Per slot, its chunk and windows, and the generation of the chunk it last took: a slot reused in one frame still frees its pages. */
35
- held;
36
- generations;
37
- free = [];
38
- /** The windows no chunk counts in, and those of chunks removed, free once the passes freed their pages. */
39
- windows;
40
- releasing = [];
41
- /** The slots whose chunks are taken in at the next run, and whether a chunk was removed since the last. */
42
- due = new Set();
43
- removed = false;
44
- /** The last read of the chunks' states, and the run it followed. */
45
- read = null;
46
- /** Whether the pool's CPU arrays were dropped (see `releaseArrays`). */
47
- released = false;
48
- constructor(
49
- /** The most instances held at once. */
50
- maxInstanceCount,
51
- /** The most chunks held at once. */
52
- maxChunkCount) {
53
- for (const [name, value] of [
54
- ["maxInstanceCount", maxInstanceCount],
55
- ["maxChunkCount", maxChunkCount],
56
- ]) {
57
- if (!Number.isInteger(value) || value < 1)
58
- throw new RangeError(`LodGpu: ${name} must be a positive integer, got ${value}`);
59
- }
60
- // A part-filled page per chunk besides the pages that fill.
61
- const pages = maxChunkCount + Math.ceil(maxInstanceCount / PAGE);
62
- if (pages >= 2 ** PAGE_BITS)
63
- throw new RangeError(`LodGpu: ${pages} pages of ${PAGE} instances outgrow the ${2 ** PAGE_BITS} a pool lists: lower maxInstanceCount or maxChunkCount`);
64
- if (pages * PAGE * 64 > MAX_BINDING)
65
- throw new RangeError(`LodGpu: the matrices of ${pages} pages of ${PAGE} instances outgrow a storage binding of ${MAX_BINDING} bytes: lower maxInstanceCount or maxChunkCount`);
66
- const windows = WINDOWS_PER_PAGE * pages;
67
- this.pages = pages;
68
- this.capacity = pages * PAGE;
69
- // Popped from the end: page 0 first.
70
- const stack = new Uint32Array(pages + 1);
71
- stack[0] = pages;
72
- for (let i = 0; i < pages; i++)
73
- stack[i + 1] = pages - 1 - i;
74
- const words = (length, itemSize = 1) => new StorageBufferAttribute(new Uint32Array(length * itemSize), itemSize);
75
- this.pool = {
76
- pages,
77
- slots: maxChunkCount,
78
- stack: new StorageBufferAttribute(stack, 1),
79
- table: words(windows),
80
- windows: words(windows),
81
- sources: words(maxChunkCount, 4),
82
- states: words(2 * maxChunkCount, 4),
83
- occupied: words(pages + 1),
84
- matrices: new StorageInstancedBufferAttribute(new Float32Array(this.capacity * 16), 16),
85
- colors: new StorageInstancedBufferAttribute(new Float32Array(this.capacity * 4), 4),
86
- };
87
- this.occupied = this.pool.occupied;
88
- this.windows = [{ first: 0, count: windows }];
89
- this.held = Array.from({ length: maxChunkCount }, () => null);
90
- this.generations = new Uint32Array(maxChunkCount);
91
- for (let slot = maxChunkCount - 1; slot >= 0; slot--)
92
- this.free.push(slot);
93
- }
94
- /** Every pool index's instance matrix, as the level meshes draw them. */
95
- get matrices() {
96
- return this.pool.matrices;
97
- }
98
- /** Every pool index's colour, RGB and a pad. */
99
- get colors() {
100
- return this.pool.colors;
101
- }
102
- /** Whether the next run takes chunks in or frees them. */
103
- get pending() {
104
- return this.due.size > 0 || this.removed;
105
- }
106
- /** Take `chunk` into a free slot at the next run; its slot. */
107
- add(chunk) {
108
- const slot = this.free.pop();
109
- if (slot === undefined)
110
- throw new Error(`InstancedLod: all ${this.pool.slots} chunk slots are taken: raise LodGpu's maxChunkCount`);
111
- const windows = Math.ceil(chunk.count / PAGE);
112
- const base = this.take(windows);
113
- if (base === null) {
114
- this.free.push(slot);
115
- throw new Error(`InstancedLod: chunks span more than the pool's ${this.pool.table.count} windows of ${PAGE} spots: raise LodGpu's maxInstanceCount`);
116
- }
117
- this.held[slot] = { chunk, base, windows };
118
- this.change(slot);
119
- return slot;
120
- }
121
- /** Take slot `slot`'s chunk in again at the next run: its attributes changed. */
122
- change(slot) {
123
- const { base, windows, chunk } = this.heldAt(slot);
124
- const generation = at(this.generations, slot) + 1;
125
- this.generations[slot] = generation;
126
- this.write(slot, [base, windows, generation, chunk.row + 1]);
127
- this.due.add(slot);
128
- }
129
- /** Free slot `slot`; its chunk's pages go back to the pool at the next run, its windows after it. */
130
- remove(slot) {
131
- const { base, windows } = this.heldAt(slot);
132
- this.held[slot] = null;
133
- this.releasing.push({ first: base, count: windows });
134
- this.write(slot, [0, 0, at(this.generations, slot), 0]);
135
- this.due.delete(slot);
136
- this.free.push(slot);
137
- this.removed = true;
138
- }
139
- heldAt(slot) {
140
- const held = this.held[slot];
141
- if (!held)
142
- throw new Error(`InstancedLod: chunk slot ${slot} holds no chunk`);
143
- return held;
144
- }
145
- write(slot, values) {
146
- const { sources } = this.pool;
147
- sources.array.set(values, slot * 4);
148
- sources.addUpdateRange(slot * 4, 4);
149
- sources.needsUpdate = true;
150
- }
151
- /** The first of `count` free windows, taken; null if no run of them is free. */
152
- take(count) {
153
- if (count === 0)
154
- return 0;
155
- const run = this.windows.find((each) => each.count >= count);
156
- if (!run)
157
- return null;
158
- const first = run.first;
159
- run.first += count;
160
- run.count -= count;
161
- if (run.count === 0)
162
- this.windows.splice(this.windows.indexOf(run), 1);
163
- return first;
164
- }
165
- /** Free the windows of `freed`, merging runs that meet. */
166
- giveBack(freed) {
167
- if (freed.length === 0)
168
- return;
169
- const runs = [...this.windows, ...freed.filter((run) => run.count > 0)].sort((a, b) => a.first - b.first);
170
- const merged = [];
171
- for (const run of runs) {
172
- const last = merged.at(-1);
173
- if (last && last.first + last.count === run.first)
174
- last.count += run.count;
175
- else
176
- merged.push({ ...run });
177
- }
178
- this.windows = merged;
179
- }
180
- /** Take the chunks' changes in on `renderer`, if they changed since the last run. */
181
- prepare(renderer) {
182
- if (!this.pending)
183
- return;
184
- const passes = (this.passes ??= new PoolPasses(this.pool));
185
- // The free pass reads the windows of chunks removed since the last run: they serve chunks taken in after it.
186
- const freed = this.releasing;
187
- this.releasing = [];
188
- renderer.compute(passes.free);
189
- for (const slot of this.due)
190
- this.run(renderer, passes, slot, "count");
191
- renderer.compute(passes.allocate);
192
- for (const slot of this.due)
193
- this.run(renderer, passes, slot, "write");
194
- renderer.compute(passes.occupy);
195
- this.due.clear();
196
- this.removed = false;
197
- this.version++;
198
- this.giveBack(freed);
199
- if (!this.released)
200
- releaseArrays([this.pool.matrices, this.pool.colors]);
201
- this.released = true;
202
- }
203
- /** Run slot `slot`'s chunk's `pass`, one workgroup per window of its range. */
204
- run(renderer, passes, slot, pass) {
205
- const { chunk, base, windows } = this.heldAt(slot);
206
- if (windows === 0)
207
- return;
208
- const { attributes, start, count, countIndex } = chunk;
209
- renderer.compute(passes.chunkPass(pass, attributes, { slot, base, start, count, countIndex }), [windows, 1, 1]);
210
- }
211
- /**
212
- * The instances the chunks of `slots` hold, once every one has been taken in; null while changes wait for the passes
213
- * or chunks changed meanwhile. Throws if a chunk lacks pages. Reads the GPU's progress back.
214
- */
215
- async status(renderer, slots) {
216
- if (this.pending)
217
- return null;
218
- if (slots.length === 0)
219
- return 0;
220
- const version = this.version;
221
- const states = await this.statesAt(renderer, version);
222
- if (version !== this.version || this.pending)
223
- return null;
224
- let instances = 0;
225
- let short = 0;
226
- let got = 0;
227
- let needed = 0;
228
- for (const slot of slots) {
229
- const base = slot * 8;
230
- if (states[base] !== this.generations[slot])
231
- return null;
232
- instances += at(states, base + 2);
233
- if (at(states, base + 1) === at(states, base + 3))
234
- continue;
235
- short++;
236
- got += at(states, base + 1);
237
- needed += at(states, base + 3);
238
- }
239
- if (short > 0) {
240
- throw new Error(`InstancedLod: ${short} chunk${short === 1 ? "" : "s"} lack pages, holding ${got} of the ${needed} pages they need: raise LodGpu's maxInstanceCount (its pool has ${this.pool.pages} pages of ${PAGE})`);
241
- }
242
- return instances;
243
- }
244
- /** The chunks' states as the GPU holds them after run `version`: one read back for every InstancedLod asking. */
245
- statesAt(renderer, version) {
246
- if (this.read?.version !== version) {
247
- const promise = renderer.getArrayBufferAsync(this.pool.states).then((buffer) => new Uint32Array(buffer));
248
- this.read = { version, promise };
249
- }
250
- return this.read.promise;
251
- }
252
- dispose() {
253
- const { pool } = this;
254
- for (const attribute of [pool.stack, pool.table, pool.windows, pool.sources, pool.states, pool.occupied, pool.matrices, pool.colors])
255
- attribute.dispose();
256
- this.passes?.dispose();
257
- this.passes = null;
258
- }
259
- }
260
- /**
261
- * Drop the CPU arrays of `attributes`, buffers only the GPU writes, once a pass has run with them: they are never read
262
- * again, and they are most of what they cost on the CPU. This relies on three never uploading them again (as of three
263
- * r186): nothing marks them for an update, and a LodGpu's renderer, initialised, made each buffer as the pass ran.
264
- */
265
- export function releaseArrays(attributes) {
266
- for (const attribute of attributes)
267
- attribute.array = new Float32Array(0);
268
- }
269
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/instanced/pages/index.ts"],"names":[],"mappings":"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"}
@@ -1,21 +0,0 @@
1
- import type { ComputeNode } from "three/webgpu";
2
- import type { PoolBuffers } from "./buffers.js";
3
- import { type Attributes, type ChunkRange } from "./chunk.js";
4
- /**
5
- * A pool's passes: built once, the count and write passes once per layout of the attributes they read (colours of a
6
- * stride or none, counts or none: six at most), and pointed at a chunk's attributes and range as it is about to run
7
- * (see `chunkPass`). They run at once as the pool prepares, never queued, so no pass still waits to run when the next
8
- * chunk is set.
9
- */
10
- export declare class PoolPasses {
11
- private readonly pool;
12
- readonly free: ComputeNode;
13
- readonly allocate: ComputeNode;
14
- readonly occupy: ComputeNode;
15
- private readonly uniforms;
16
- private readonly byLayout;
17
- constructor(pool: PoolBuffers);
18
- /** `pass` for the chunk of `attributes` and `range`, pointed at them: run it before pointing it at another. */
19
- chunkPass(pass: "count" | "write", attributes: Attributes, range: ChunkRange): ComputeNode;
20
- dispose(): void;
21
- }
@@ -1,52 +0,0 @@
1
- import { chunkReads, chunkUniforms, countPass, writePass } from "./chunk.js";
2
- import { allocatePass, freePass, occupyPass } from "./slots.js";
3
- /**
4
- * A pool's passes: built once, the count and write passes once per layout of the attributes they read (colours of a
5
- * stride or none, counts or none: six at most), and pointed at a chunk's attributes and range as it is about to run
6
- * (see `chunkPass`). They run at once as the pool prepares, never queued, so no pass still waits to run when the next
7
- * chunk is set.
8
- */
9
- export class PoolPasses {
10
- pool;
11
- free;
12
- allocate;
13
- occupy;
14
- uniforms = chunkUniforms();
15
- byLayout = new Map();
16
- constructor(pool) {
17
- this.pool = pool;
18
- this.free = freePass(pool);
19
- this.allocate = allocatePass(pool);
20
- this.occupy = occupyPass(pool);
21
- }
22
- /** `pass` for the chunk of `attributes` and `range`, pointed at them: run it before pointing it at another. */
23
- chunkPass(pass, attributes, range) {
24
- const layout = `${attributes.colors?.stride ?? 0}/${attributes.counts ? 1 : 0}`;
25
- let passes = this.byLayout.get(layout);
26
- if (!passes) {
27
- const reads = chunkReads(attributes);
28
- passes = { reads, count: countPass(this.pool, this.uniforms, reads), write: writePass(this.pool, this.uniforms, reads) };
29
- this.byLayout.set(layout, passes);
30
- }
31
- const { reads } = passes;
32
- reads.matrices.value = attributes.matrices;
33
- if (reads.colors && attributes.colors)
34
- reads.colors.floats.value = attributes.colors.attribute;
35
- if (reads.counts && attributes.counts)
36
- reads.counts.value = attributes.counts;
37
- const { uniforms } = this;
38
- uniforms.slot.value = range.slot;
39
- uniforms.base.value = range.base;
40
- uniforms.start.value = range.start;
41
- uniforms.count.value = range.count;
42
- uniforms.countIndex.value = range.countIndex;
43
- return passes[pass];
44
- }
45
- dispose() {
46
- const chunkNodes = [...this.byLayout.values()].flatMap(({ count, write }) => [count, write]);
47
- for (const node of [this.free, this.allocate, this.occupy, ...chunkNodes])
48
- node.dispose();
49
- this.byLayout.clear();
50
- }
51
- }
52
- //# sourceMappingURL=passes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"passes.js","sourceRoot":"","sources":["../../../src/instanced/pages/passes.ts"],"names":[],"mappings":"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"}
@@ -1,11 +0,0 @@
1
- import type { ComputeNode } from "three/webgpu";
2
- import { type PoolBuffers } from "./buffers.js";
3
- /** Frees the pages of every chunk removed or changed since the last run: one workgroup. */
4
- export declare function freePass(pool: PoolBuffers): ComputeNode;
5
- /**
6
- * Gives new chunks the pages their instances need, turning their window counts into where their instances start: one
7
- * workgroup. Under a short stack, which chunks get its last pages is a race.
8
- */
9
- export declare function allocatePass(pool: PoolBuffers): ComputeNode;
10
- /** Lists every page chunks hold, with its InstancedLod's row, for updateInstance to visit: one workgroup. */
11
- export declare function occupyPass(pool: PoolBuffers): ComputeNode;
@@ -1,90 +0,0 @@
1
- import { Break, If, Loop, atomicAdd, atomicLoad, atomicStore, atomicSub, localId, storage, storageBarrier, uint, uvec4 } from "three/tsl";
2
- import { PAGE_BITS, nodes } from "./buffers.js";
3
- import { PAGE, least, workgroups } from "./workgroup.js";
4
- /** `body` for every chunk slot of `pool`, in a pass of one workgroup, its lanes taking every `PAGE`th slot. */
5
- function eachSlot(pool, body) {
6
- Loop({ start: uint(0), end: uint(Math.ceil(pool.slots / PAGE)), type: "uint", condition: "<" }, ({ i }) => {
7
- const slot = i.mul(PAGE).add(localId.x).toVar();
8
- If(slot.lessThan(pool.slots), () => body(slot));
9
- });
10
- }
11
- /** Slot `slot`'s state, the generation, pages, instances and needed pages, and the first window its pages are listed from. */
12
- function stateOf(n, slot) {
13
- return { state: n.states.element(slot.mul(2)).toVar(), first: n.states.element(slot.mul(2).add(1)).x.toVar() };
14
- }
15
- /** Frees the pages of every chunk removed or changed since the last run: one workgroup. */
16
- export function freePass(pool) {
17
- const n = nodes(pool);
18
- const top = n.stack.element(0);
19
- return workgroups(() => {
20
- eachSlot(pool, (slot) => {
21
- const source = n.sources.element(slot).toVar();
22
- const { state, first } = stateOf(n, slot);
23
- If(source.w.equal(0).or(state.x.notEqual(source.z)), () => {
24
- Loop({ start: uint(0), end: state.y, type: "uint", condition: "<" }, ({ i }) => {
25
- atomicStore(n.stack.element(atomicAdd(top, uint(1)).add(1)), n.table.element(first.add(i)));
26
- });
27
- n.states.element(slot.mul(2)).assign(uvec4(0));
28
- });
29
- });
30
- });
31
- }
32
- /**
33
- * Gives new chunks the pages their instances need, turning their window counts into where their instances start: one
34
- * workgroup. Under a short stack, which chunks get its last pages is a race.
35
- */
36
- export function allocatePass(pool) {
37
- const n = nodes(pool);
38
- const top = n.stack.element(0);
39
- return workgroups(() => {
40
- eachSlot(pool, (slot) => {
41
- const source = n.sources.element(slot).toVar();
42
- const state = n.states.element(slot.mul(2)).toVar();
43
- If(source.w.notEqual(0).and(state.x.notEqual(source.z)), () => {
44
- const first = source.x;
45
- const instances = uint(0).toVar();
46
- Loop({ start: uint(0), end: source.y, type: "uint", condition: "<" }, ({ i }) => {
47
- const window = n.windows.element(first.add(i));
48
- const counted = window.toVar();
49
- window.assign(instances);
50
- instances.addAssign(counted);
51
- });
52
- const need = instances
53
- .add(PAGE - 1)
54
- .div(PAGE)
55
- .toVar();
56
- const held = uint(0).toVar();
57
- Loop({ start: uint(0), end: need, type: "uint", condition: "<" }, ({ i }) => {
58
- // The page under the top before taking it; none when the stack ran dry, its count wrapped past 0.
59
- const before = atomicSub(top, uint(1)).toVar();
60
- If(before.sub(1).greaterThanEqual(pool.pages), () => {
61
- atomicAdd(top, uint(1));
62
- Break();
63
- });
64
- n.table.element(first.add(i)).assign(atomicLoad(n.stack.element(before)));
65
- held.addAssign(1);
66
- });
67
- n.states.element(slot.mul(2)).assign(uvec4(source.z, held, least(instances, held.mul(PAGE)), need));
68
- n.states.element(slot.mul(2).add(1)).assign(uvec4(first, 0, 0, 0));
69
- });
70
- });
71
- });
72
- }
73
- /** Lists every page chunks hold, with its InstancedLod's row, for updateInstance to visit: one workgroup. */
74
- export function occupyPass(pool) {
75
- const n = nodes(pool);
76
- const occupied = storage(pool.occupied, "uint", 0).toAtomic();
77
- return workgroups(() => {
78
- If(localId.x.equal(0), () => void atomicStore(occupied.element(0), uint(0)));
79
- storageBarrier();
80
- eachSlot(pool, (slot) => {
81
- const row = n.sources.element(slot).w.sub(1).toVar();
82
- const { state, first } = stateOf(n, slot);
83
- Loop({ start: uint(0), end: state.y, type: "uint", condition: "<" }, ({ i }) => {
84
- const entry = n.table.element(first.add(i)).bitOr(row.shiftLeft(PAGE_BITS));
85
- atomicStore(occupied.element(atomicAdd(occupied.element(0), uint(1)).add(1)), entry);
86
- });
87
- });
88
- });
89
- }
90
- //# sourceMappingURL=slots.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slots.js","sourceRoot":"","sources":["../../../src/instanced/pages/slots.ts"],"names":[],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- import type { ComputeNode, Node } from "three/webgpu";
2
- /** Instances per page, and lanes per workgroup of the passes over pages: updateInstance runs one workgroup per page. */
3
- export declare const PAGE = 256;
4
- /**
5
- * A pass of workgroups of `PAGE` lanes: one, unless dispatched indirectly. A dispatch size rather than a count: a count
6
- * adds an early return, which a barrier may not follow.
7
- */
8
- export declare function workgroups(body: () => void): ComputeNode;
9
- /** The lesser of two uints. */
10
- export declare const least: (a: Node<"uint">, b: Node<"uint">) => Node<"uint">;
11
- export declare function rank(chosen: Node<"bool">): {
12
- before: Node<"uint">;
13
- total: Node<"uint">;
14
- };
@@ -1,38 +0,0 @@
1
- import { Fn, code, computeKernel, localId, uint, uvec2, wgslFn } from "three/tsl";
2
- // What the page passes share: workgroups of `PAGE` lanes, and ranking lanes within one.
3
- /** Instances per page, and lanes per workgroup of the passes over pages: updateInstance runs one workgroup per page. */
4
- export const PAGE = 256;
5
- /**
6
- * A pass of workgroups of `PAGE` lanes: one, unless dispatched indirectly. A dispatch size rather than a count: a count
7
- * adds an early return, which a barrier may not follow.
8
- */
9
- export function workgroups(body) {
10
- const node = computeKernel(Fn(body)(), [PAGE]);
11
- node.dispatchSize = [1, 1, 1];
12
- return node;
13
- }
14
- /** The lesser of two uints. */
15
- export const least = (a, b) => a.lessThan(b).select(a, b);
16
- /**
17
- * Across a workgroup of `PAGE` lanes: how many lanes before this one are `chosen`, and how many are in all. Every lane
18
- * calls it, outside any branch: it waits for the others. Hillis–Steele: after the step of width w, each lane holds the
19
- * sum of the 2w lanes up to it.
20
- */
21
- const rankOf = wgslFn(`fn lodRank(lane: u32, chosen: u32) -> vec2u {
22
- lodRankSums[lane] = chosen;
23
- for (var width = 1u; width < ${PAGE}u; width *= 2u) {
24
- workgroupBarrier();
25
- var sum = lodRankSums[lane];
26
- if (lane >= width) { sum += lodRankSums[lane - width]; }
27
- workgroupBarrier();
28
- lodRankSums[lane] = sum;
29
- }
30
- workgroupBarrier();
31
- return vec2u(lodRankSums[lane] - chosen, lodRankSums[${PAGE - 1}]);
32
- }`, [code(`var<workgroup> lodRankSums: array<u32, ${PAGE}>;`)]);
33
- export function rank(chosen) {
34
- const ranked = uvec2(0).toVar();
35
- ranked.assign(rankOf({ lane: localId.x, chosen: chosen.select(uint(1), uint(0)) }));
36
- return { before: ranked.x, total: ranked.y };
37
- }
38
- //# sourceMappingURL=workgroup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workgroup.js","sourceRoot":"","sources":["../../../src/instanced/pages/workgroup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAElF,wFAAwF;AAExF,wHAAwH;AACxH,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,IAAgB;IACzC,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+BAA+B;AAC/B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAe,EAAE,CAAe,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEtF;;;;GAIG;AACH,MAAM,MAAM,GAAG,MAAM,CACnB;;iCAE+B,IAAI;;;;;;;;yDAQoB,IAAI,GAAG,CAAC;EAC/D,EACA,CAAC,IAAI,CAAC,0CAA0C,IAAI,IAAI,CAAC,CAAC,CAC3D,CAAC;AAEF,MAAM,UAAU,IAAI,CAAC,MAAoB;IACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;IAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpF,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;AAC/C,CAAC"}
@@ -1,27 +0,0 @@
1
- /**
2
- * Whether an InstancedLod's chunks wait to be shown taken in on the GPU: from a change until, a few renders later, a
3
- * read of their status shows each taken in, so that its manager holds its item until a host sees them drawn.
4
- */
5
- export declare class ChunkWait {
6
- /** Whether the GPU shows every chunk taken in, read back; it throws if a chunk lacks room. */
7
- private readonly read;
8
- /** Called once a read shows every chunk taken in. */
9
- private readonly taken;
10
- /** Called with what a read throws. */
11
- private readonly failed;
12
- /** While chunks wait, the renders left before their status is read, and whether a read is under way. */
13
- private rest;
14
- constructor(
15
- /** Whether the GPU shows every chunk taken in, read back; it throws if a chunk lacks room. */
16
- read: () => Promise<boolean>,
17
- /** Called once a read shows every chunk taken in. */
18
- taken: () => void,
19
- /** Called with what a read throws. */
20
- failed: (error: unknown) => void);
21
- /** Whether chunks wait to be shown taken in. */
22
- get waiting(): boolean;
23
- /** The chunks were added or removed: wait for them again. */
24
- changed(): void;
25
- /** A render updated the InstancedLod: read the chunks' status once their change has rested. */
26
- render(): void;
27
- }