@yali-engine/render 0.0.0-stage → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bvh.d.ts +66 -0
- package/dist/bvh.js +493 -0
- package/dist/bvh.js.map +1 -0
- package/dist/camera.d.ts +34 -0
- package/dist/camera.js +66 -0
- package/dist/camera.js.map +1 -0
- package/dist/cluster-build.d.ts +46 -0
- package/dist/cluster-build.js +179 -0
- package/dist/cluster-build.js.map +1 -0
- package/dist/cluster-pages.d.ts +70 -0
- package/dist/cluster-pages.js +203 -0
- package/dist/cluster-pages.js.map +1 -0
- package/dist/cluster-stream.d.ts +83 -0
- package/dist/cluster-stream.js +226 -0
- package/dist/cluster-stream.js.map +1 -0
- package/dist/culled-draws.d.ts +30 -0
- package/dist/culled-draws.js +103 -0
- package/dist/culled-draws.js.map +1 -0
- package/dist/debug-lines.d.ts +51 -0
- package/dist/debug-lines.js +158 -0
- package/dist/debug-lines.js.map +1 -0
- package/dist/device-profile.d.ts +100 -0
- package/dist/device-profile.js +131 -0
- package/dist/device-profile.js.map +1 -0
- package/dist/device.d.ts +39 -0
- package/dist/device.js +79 -0
- package/dist/device.js.map +1 -0
- package/dist/environment.d.ts +60 -0
- package/dist/environment.js +204 -0
- package/dist/environment.js.map +1 -0
- package/dist/extract.d.ts +74 -0
- package/dist/extract.js +194 -0
- package/dist/extract.js.map +1 -0
- package/dist/frame-graph.d.ts +112 -0
- package/dist/frame-graph.js +226 -0
- package/dist/frame-graph.js.map +1 -0
- package/dist/gpu-health.d.ts +74 -0
- package/dist/gpu-health.js +106 -0
- package/dist/gpu-health.js.map +1 -0
- package/dist/gpu-timer.d.ts +26 -0
- package/dist/gpu-timer.js +93 -0
- package/dist/gpu-timer.js.map +1 -0
- package/dist/headless.d.ts +28 -0
- package/dist/headless.js +91 -0
- package/dist/headless.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/lights.d.ts +81 -0
- package/dist/lights.js +247 -0
- package/dist/lights.js.map +1 -0
- package/dist/matrix.d.ts +6 -0
- package/dist/matrix.js +59 -0
- package/dist/matrix.js.map +1 -0
- package/dist/meshes.d.ts +411 -0
- package/dist/meshes.js +545 -0
- package/dist/meshes.js.map +1 -0
- package/dist/meshlets-decoder.d.ts +20 -0
- package/dist/meshlets-decoder.js +47 -0
- package/dist/meshlets-decoder.js.map +1 -0
- package/dist/meshlets.d.ts +186 -0
- package/dist/meshlets.js +1040 -0
- package/dist/meshlets.js.map +1 -0
- package/dist/occlusion.d.ts +51 -0
- package/dist/occlusion.js +188 -0
- package/dist/occlusion.js.map +1 -0
- package/dist/pick-decoder.d.ts +19 -0
- package/dist/pick-decoder.js +45 -0
- package/dist/pick-decoder.js.map +1 -0
- package/dist/pick.d.ts +86 -0
- package/dist/pick.js +452 -0
- package/dist/pick.js.map +1 -0
- package/dist/pipeline-cache.d.ts +53 -0
- package/dist/pipeline-cache.js +96 -0
- package/dist/pipeline-cache.js.map +1 -0
- package/dist/post-options.d.ts +109 -0
- package/dist/post-options.js +23 -0
- package/dist/post-options.js.map +1 -0
- package/dist/post-shaders.gen.d.ts +40 -0
- package/dist/post-shaders.gen.js +43 -0
- package/dist/post-shaders.gen.js.map +1 -0
- package/dist/post.d.ts +101 -0
- package/dist/post.js +555 -0
- package/dist/post.js.map +1 -0
- package/dist/render-plugin.d.ts +239 -0
- package/dist/render-plugin.js +633 -0
- package/dist/render-plugin.js.map +1 -0
- package/dist/scene.d.ts +406 -0
- package/dist/scene.js +2005 -0
- package/dist/scene.js.map +1 -0
- package/dist/shaders.gen.d.ts +40 -0
- package/dist/shaders.gen.js +43 -0
- package/dist/shaders.gen.js.map +1 -0
- package/dist/shadows.d.ts +104 -0
- package/dist/shadows.js +227 -0
- package/dist/shadows.js.map +1 -0
- package/dist/staging-ring.d.ts +41 -0
- package/dist/staging-ring.js +125 -0
- package/dist/staging-ring.js.map +1 -0
- package/dist/textures.d.ts +165 -0
- package/dist/textures.js +361 -0
- package/dist/textures.js.map +1 -0
- package/dist/tonemap.d.ts +45 -0
- package/dist/tonemap.js +141 -0
- package/dist/tonemap.js.map +1 -0
- package/dist/viewport.d.ts +78 -0
- package/dist/viewport.js +130 -0
- package/dist/viewport.js.map +1 -0
- package/dist/webgl2/plugin.d.ts +40 -0
- package/dist/webgl2/plugin.js +190 -0
- package/dist/webgl2/plugin.js.map +1 -0
- package/dist/webgl2/program.d.ts +27 -0
- package/dist/webgl2/program.js +74 -0
- package/dist/webgl2/program.js.map +1 -0
- package/dist/webgl2/renderer.d.ts +128 -0
- package/dist/webgl2/renderer.js +976 -0
- package/dist/webgl2/renderer.js.map +1 -0
- package/dist/webgl2/shaders.glsl.gen.d.ts +27 -0
- package/dist/webgl2/shaders.glsl.gen.js +20 -0
- package/dist/webgl2/shaders.glsl.gen.js.map +1 -0
- package/dist/webgl2/textures.d.ts +11 -0
- package/dist/webgl2/textures.js +82 -0
- package/dist/webgl2/textures.js.map +1 -0
- package/dist/webgl2/webgl2.d.ts +1 -0
- package/dist/webgl2/webgl2.js +4 -0
- package/dist/webgl2/webgl2.js.map +1 -0
- package/dist/worker-mode.d.ts +85 -0
- package/dist/worker-mode.js +204 -0
- package/dist/worker-mode.js.map +1 -0
- package/package.json +47 -3
- package/README.md +0 -3
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { type DecodedPage } from './cluster-pages.ts';
|
|
2
|
+
/** What the residency needs of the cluster arrays (`ClusterData`). */
|
|
3
|
+
export interface ClusterArrays {
|
|
4
|
+
words: Uint32Array;
|
|
5
|
+
vertices: Uint32Array;
|
|
6
|
+
triangles: Uint8Array;
|
|
7
|
+
}
|
|
8
|
+
/** One streamed mesh as `addMesh` takes it: the file's page table and where its clusters and vertices landed. */
|
|
9
|
+
export interface StreamedMeshLayout {
|
|
10
|
+
/** The mesh's first cluster record (`Clustered.first`). */
|
|
11
|
+
readonly first: number;
|
|
12
|
+
/** `PAGE_WORDS` a page; the clusters in page order (`ClusterPages.pages`). */
|
|
13
|
+
readonly table: Uint32Array;
|
|
14
|
+
readonly roots: number;
|
|
15
|
+
readonly slotVertices: number;
|
|
16
|
+
/** The mesh's first vertex in the pool (its root pages' vertices from there, then the slots). */
|
|
17
|
+
readonly baseVertex: number;
|
|
18
|
+
/** Vertices before the slots (its root pages'). */
|
|
19
|
+
readonly rootVertices: number;
|
|
20
|
+
/** Page slots after the roots. */
|
|
21
|
+
readonly slots: number;
|
|
22
|
+
}
|
|
23
|
+
/** A vertex block to write into the pool: the mesh-relative first vertex and the data. */
|
|
24
|
+
export interface VertexWrite {
|
|
25
|
+
readonly mesh: number;
|
|
26
|
+
readonly first: number;
|
|
27
|
+
readonly data: Float32Array;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The residency of every streamed mesh's pages (ADR-0134). Root pages are resident from the start and
|
|
31
|
+
* never leave; another page arrives only after the page holding its parents (requests come from drawn
|
|
32
|
+
* leaves), and leaves only after its own children (children first), so the cut never has a hole:
|
|
33
|
+
* a cluster whose page is missing is never drawn, and one whose children's page is missing is drawn as
|
|
34
|
+
* a leaf (`STREAM_LEAF`: its own error counted as 0).
|
|
35
|
+
*/
|
|
36
|
+
export declare class ClusterResidency {
|
|
37
|
+
#private;
|
|
38
|
+
/** Pages evicted, loaded, and requests dropped for want of a slot. */
|
|
39
|
+
readonly stats: {
|
|
40
|
+
loaded: number;
|
|
41
|
+
evicted: number;
|
|
42
|
+
starved: number;
|
|
43
|
+
};
|
|
44
|
+
/** Pages over every mesh (the cull's page bits cover this many). */
|
|
45
|
+
get pageCount(): number;
|
|
46
|
+
/** Pages on the GPU now. */
|
|
47
|
+
get resident(): number;
|
|
48
|
+
/** Pages being fetched. */
|
|
49
|
+
get inFlight(): number;
|
|
50
|
+
/**
|
|
51
|
+
* Registers a mesh whose records were appended (vertex and triangle offsets already moved, base
|
|
52
|
+
* vertex the mesh's): numbers its pages globally, sets every record's flags, and applies its root
|
|
53
|
+
* pages (`roots`, decoded, in page order). Returns the mesh's index.
|
|
54
|
+
*/
|
|
55
|
+
addMesh(d: ClusterArrays, layout: StreamedMeshLayout, roots: readonly DecodedPage[]): number;
|
|
56
|
+
/**
|
|
57
|
+
* One read of the cull's page bits (`needed`, `used`: a bit per global page, a frame or so old):
|
|
58
|
+
* marks what was seen, and returns the pages to fetch now (not resident, not in flight, their parents
|
|
59
|
+
* resident), at most `room`, coarse (lower page ids) first.
|
|
60
|
+
*/
|
|
61
|
+
requests(d: ClusterArrays, needed: Uint32Array, used: Uint32Array, room: number): number[];
|
|
62
|
+
/** Where page `g` is in its mesh's page data: the table's byte offset and length, and the mesh. */
|
|
63
|
+
locate(g: number): {
|
|
64
|
+
mesh: number;
|
|
65
|
+
offset: number;
|
|
66
|
+
length: number;
|
|
67
|
+
};
|
|
68
|
+
/** A fetch that failed or was abandoned: the page may be asked for again. */
|
|
69
|
+
cancel(g: number): void;
|
|
70
|
+
/**
|
|
71
|
+
* A fetched page arrived: takes a free slot of its mesh or evicts the least recently seen page that
|
|
72
|
+
* has no resident children (and was not seen in the last read), then applies it. False when no slot
|
|
73
|
+
* could be had (the request is dropped; its parents stay leaves).
|
|
74
|
+
*/
|
|
75
|
+
load(d: ClusterArrays, g: number, page: DecodedPage): boolean;
|
|
76
|
+
/** What changed since the last call: records to re-upload, local-id and triangle-byte ranges, vertex blocks. */
|
|
77
|
+
takeDirty(): {
|
|
78
|
+
records: number[];
|
|
79
|
+
ids: [number, number][];
|
|
80
|
+
triangles: [number, number][];
|
|
81
|
+
vertices: VertexWrite[];
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// Page residency for streamed cluster hierarchies (ADR-0134): which pages are on the GPU, where their
|
|
2
|
+
// vertices live, and the residency flags in each cluster record that keep the cut whole. Pure: it
|
|
3
|
+
// edits `ClusterData`'s CPU arrays and reports what changed; `@yali-engine/render/meshlets` fetches, uploads
|
|
4
|
+
// and reads the cull's page bits. Tested in Node.
|
|
5
|
+
import { YaliError } from '@yali-engine/core';
|
|
6
|
+
import { CLUSTER_WORDS } from "./cluster-build.js";
|
|
7
|
+
import { KIDS_WORD, PAGE_WORDS, STREAM_LEAF, STREAM_MISSING, STREAM_WORD } from "./cluster-pages.js";
|
|
8
|
+
/**
|
|
9
|
+
* The residency of every streamed mesh's pages (ADR-0134). Root pages are resident from the start and
|
|
10
|
+
* never leave; another page arrives only after the page holding its parents (requests come from drawn
|
|
11
|
+
* leaves), and leaves only after its own children (children first), so the cut never has a hole:
|
|
12
|
+
* a cluster whose page is missing is never drawn, and one whose children's page is missing is drawn as
|
|
13
|
+
* a leaf (`STREAM_LEAF`: its own error counted as 0).
|
|
14
|
+
*/
|
|
15
|
+
export class ClusterResidency {
|
|
16
|
+
#pages = [];
|
|
17
|
+
#meshes = [];
|
|
18
|
+
#reads = 0;
|
|
19
|
+
/** Cluster records, local-id words and triangle bytes changed since `takeDirty` (record indices; [start, end) ranges). */
|
|
20
|
+
#dirtyRecords = new Set();
|
|
21
|
+
#dirtyIds = [];
|
|
22
|
+
#dirtyTris = [];
|
|
23
|
+
#writes = [];
|
|
24
|
+
/** Pages evicted, loaded, and requests dropped for want of a slot. */
|
|
25
|
+
stats = { loaded: 0, evicted: 0, starved: 0 };
|
|
26
|
+
/** Pages over every mesh (the cull's page bits cover this many). */
|
|
27
|
+
get pageCount() {
|
|
28
|
+
return this.#pages.length;
|
|
29
|
+
}
|
|
30
|
+
/** Pages on the GPU now. */
|
|
31
|
+
get resident() {
|
|
32
|
+
let n = 0;
|
|
33
|
+
for (const p of this.#pages)
|
|
34
|
+
if (p.resident)
|
|
35
|
+
n++;
|
|
36
|
+
return n;
|
|
37
|
+
}
|
|
38
|
+
/** Pages being fetched. */
|
|
39
|
+
get inFlight() {
|
|
40
|
+
let n = 0;
|
|
41
|
+
for (const p of this.#pages)
|
|
42
|
+
if (p.inFlight)
|
|
43
|
+
n++;
|
|
44
|
+
return n;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Registers a mesh whose records were appended (vertex and triangle offsets already moved, base
|
|
48
|
+
* vertex the mesh's): numbers its pages globally, sets every record's flags, and applies its root
|
|
49
|
+
* pages (`roots`, decoded, in page order). Returns the mesh's index.
|
|
50
|
+
*/
|
|
51
|
+
addMesh(d, layout, roots) {
|
|
52
|
+
const mesh = this.#meshes.length;
|
|
53
|
+
const pageBase = this.#pages.length;
|
|
54
|
+
const np = layout.table.length / PAGE_WORDS;
|
|
55
|
+
for (let p = 0; p < np; p++)
|
|
56
|
+
this.#pages.push({ mesh, local: p, resident: false, inFlight: false, slot: -1, seen: 0, children: [], parents: [], residentChildren: 0 });
|
|
57
|
+
this.#meshes.push({ layout, pageBase, free: Array.from({ length: layout.slots }, (_, k) => layout.slots - 1 - k) });
|
|
58
|
+
for (let p = 0; p < np; p++) {
|
|
59
|
+
const page = this.#pages[pageBase + p];
|
|
60
|
+
const [first, count] = layout.table.subarray(p * PAGE_WORDS, p * PAGE_WORDS + 2);
|
|
61
|
+
const kids = new Set();
|
|
62
|
+
for (let c = layout.first + first; c < layout.first + first + count; c++) {
|
|
63
|
+
const o = c * CLUSTER_WORDS;
|
|
64
|
+
const k = d.words[o + KIDS_WORD];
|
|
65
|
+
d.words[o + STREAM_WORD] = ((pageBase + p) << 2) | STREAM_MISSING;
|
|
66
|
+
if (k > 0) {
|
|
67
|
+
const g = pageBase + k - 1;
|
|
68
|
+
d.words[o + KIDS_WORD] = g + 1;
|
|
69
|
+
d.words[o + STREAM_WORD] |= STREAM_LEAF;
|
|
70
|
+
kids.add(g);
|
|
71
|
+
this.#pages[g].parents.push(c);
|
|
72
|
+
}
|
|
73
|
+
this.#dirtyRecords.add(c);
|
|
74
|
+
}
|
|
75
|
+
page.children.push(...kids);
|
|
76
|
+
}
|
|
77
|
+
// The roots: their vertices at the start of the mesh's block, one page after another.
|
|
78
|
+
let at = 0;
|
|
79
|
+
for (let p = 0; p < layout.roots; p++) {
|
|
80
|
+
this.#apply(d, pageBase + p, roots[p], at);
|
|
81
|
+
at += roots[p].vertices.length / 8;
|
|
82
|
+
}
|
|
83
|
+
return mesh;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* One read of the cull's page bits (`needed`, `used`: a bit per global page, a frame or so old):
|
|
87
|
+
* marks what was seen, and returns the pages to fetch now (not resident, not in flight, their parents
|
|
88
|
+
* resident), at most `room`, coarse (lower page ids) first.
|
|
89
|
+
*/
|
|
90
|
+
requests(d, needed, used, room) {
|
|
91
|
+
const r = ++this.#reads;
|
|
92
|
+
const out = [];
|
|
93
|
+
for (let w = 0; w < needed.length; w++) {
|
|
94
|
+
let bits = needed[w] | used[w];
|
|
95
|
+
while (bits) {
|
|
96
|
+
const b = 31 - Math.clz32(bits & -bits);
|
|
97
|
+
bits &= bits - 1;
|
|
98
|
+
const g = w * 32 + b;
|
|
99
|
+
const p = this.#pages[g];
|
|
100
|
+
if (!p)
|
|
101
|
+
continue;
|
|
102
|
+
p.seen = r;
|
|
103
|
+
if ((needed[w] >>> b) & 1 && !p.resident && !p.inFlight && out.length < room && this.#parentsResident(d, g))
|
|
104
|
+
out.push(g);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (const g of out)
|
|
108
|
+
this.#pages[g].inFlight = true;
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
/** Where page `g` is in its mesh's page data: the table's byte offset and length, and the mesh. */
|
|
112
|
+
locate(g) {
|
|
113
|
+
const p = this.#pages[g];
|
|
114
|
+
const t = this.#meshes[p.mesh].layout.table;
|
|
115
|
+
return { mesh: p.mesh, offset: t[p.local * PAGE_WORDS + 3], length: t[p.local * PAGE_WORDS + 4] };
|
|
116
|
+
}
|
|
117
|
+
/** A fetch that failed or was abandoned: the page may be asked for again. */
|
|
118
|
+
cancel(g) {
|
|
119
|
+
this.#pages[g].inFlight = false;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* A fetched page arrived: takes a free slot of its mesh or evicts the least recently seen page that
|
|
123
|
+
* has no resident children (and was not seen in the last read), then applies it. False when no slot
|
|
124
|
+
* could be had (the request is dropped; its parents stay leaves).
|
|
125
|
+
*/
|
|
126
|
+
load(d, g, page) {
|
|
127
|
+
const p = this.#pages[g];
|
|
128
|
+
p.inFlight = false;
|
|
129
|
+
if (p.resident || !this.#parentsResident(d, g))
|
|
130
|
+
return false;
|
|
131
|
+
const m = this.#meshes[p.mesh];
|
|
132
|
+
let slot = m.free.pop();
|
|
133
|
+
if (slot === undefined) {
|
|
134
|
+
let victim = -1;
|
|
135
|
+
const keep = this.#parentPages(d, g);
|
|
136
|
+
for (let q = m.pageBase + m.layout.roots; q < m.pageBase + m.layout.table.length / PAGE_WORDS; q++) {
|
|
137
|
+
const v = this.#pages[q];
|
|
138
|
+
if (!v.resident || v.residentChildren > 0 || v.seen >= this.#reads || keep.has(q))
|
|
139
|
+
continue;
|
|
140
|
+
if (victim < 0 || v.seen < this.#pages[victim].seen)
|
|
141
|
+
victim = q;
|
|
142
|
+
}
|
|
143
|
+
if (victim < 0) {
|
|
144
|
+
this.stats.starved++;
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
this.#evict(d, victim);
|
|
148
|
+
slot = m.free.pop();
|
|
149
|
+
}
|
|
150
|
+
this.#apply(d, g, page, m.layout.rootVertices + slot * m.layout.slotVertices, slot);
|
|
151
|
+
this.stats.loaded++;
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
#parentsResident(d, g) {
|
|
155
|
+
for (const c of this.#pages[g].parents)
|
|
156
|
+
if ((d.words[c * CLUSTER_WORDS + STREAM_WORD] & STREAM_MISSING) !== 0)
|
|
157
|
+
return false;
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
/** The pages holding page `g`'s parents. */
|
|
161
|
+
#parentPages(d, g) {
|
|
162
|
+
const out = new Set();
|
|
163
|
+
for (const c of this.#pages[g].parents)
|
|
164
|
+
out.add(d.words[c * CLUSTER_WORDS + STREAM_WORD] >>> 2);
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
#apply(d, g, page, at, slot = -1) {
|
|
168
|
+
const p = this.#pages[g];
|
|
169
|
+
const m = this.#meshes[p.mesh];
|
|
170
|
+
const [first, count, vcount] = m.layout.table.subarray(p.local * PAGE_WORDS, p.local * PAGE_WORDS + 3);
|
|
171
|
+
if (page.vertices.length !== vcount * 8)
|
|
172
|
+
throw new YaliError('PAGE_MISMATCH', `Cluster page ${p.local} has ${page.vertices.length / 8} vertices; the file's table says ${vcount}.`, 'The .pages.bin does not belong to this GLB: convert again and serve both files together.');
|
|
173
|
+
const c0 = m.layout.first + first;
|
|
174
|
+
const ids = d.words[c0 * CLUSTER_WORDS + 12];
|
|
175
|
+
const tris = d.words[c0 * CLUSTER_WORDS + 13];
|
|
176
|
+
d.vertices.set(page.ids, ids);
|
|
177
|
+
d.triangles.set(page.triangles, tris);
|
|
178
|
+
this.#dirtyIds.push([ids, ids + page.ids.length]);
|
|
179
|
+
this.#dirtyTris.push([tris, tris + page.triangles.length]);
|
|
180
|
+
for (let c = c0; c < c0 + count; c++) {
|
|
181
|
+
const o = c * CLUSTER_WORDS;
|
|
182
|
+
d.words[o + 11] = m.layout.baseVertex + at;
|
|
183
|
+
d.words[o + STREAM_WORD] &= ~STREAM_MISSING;
|
|
184
|
+
this.#dirtyRecords.add(c);
|
|
185
|
+
}
|
|
186
|
+
for (const c of p.parents) {
|
|
187
|
+
d.words[c * CLUSTER_WORDS + STREAM_WORD] &= ~STREAM_LEAF;
|
|
188
|
+
this.#dirtyRecords.add(c);
|
|
189
|
+
}
|
|
190
|
+
this.#parentPage(d, g, +1);
|
|
191
|
+
p.resident = true;
|
|
192
|
+
p.slot = slot;
|
|
193
|
+
p.seen = this.#reads;
|
|
194
|
+
this.#writes.push({ mesh: p.mesh, first: at, data: page.vertices });
|
|
195
|
+
}
|
|
196
|
+
#evict(d, g) {
|
|
197
|
+
const p = this.#pages[g];
|
|
198
|
+
const m = this.#meshes[p.mesh];
|
|
199
|
+
const [first, count] = m.layout.table.subarray(p.local * PAGE_WORDS, p.local * PAGE_WORDS + 2);
|
|
200
|
+
for (let c = m.layout.first + first; c < m.layout.first + first + count; c++) {
|
|
201
|
+
d.words[c * CLUSTER_WORDS + STREAM_WORD] |= STREAM_MISSING;
|
|
202
|
+
this.#dirtyRecords.add(c);
|
|
203
|
+
}
|
|
204
|
+
for (const c of p.parents) {
|
|
205
|
+
d.words[c * CLUSTER_WORDS + STREAM_WORD] |= STREAM_LEAF;
|
|
206
|
+
this.#dirtyRecords.add(c);
|
|
207
|
+
}
|
|
208
|
+
this.#parentPage(d, g, -1);
|
|
209
|
+
p.resident = false;
|
|
210
|
+
m.free.push(p.slot);
|
|
211
|
+
p.slot = -1;
|
|
212
|
+
this.stats.evicted++;
|
|
213
|
+
}
|
|
214
|
+
/** The pages holding page `g`'s parents gain or lose a resident child. */
|
|
215
|
+
#parentPage(d, g, by) {
|
|
216
|
+
for (const q of this.#parentPages(d, g))
|
|
217
|
+
this.#pages[q].residentChildren += by;
|
|
218
|
+
}
|
|
219
|
+
/** What changed since the last call: records to re-upload, local-id and triangle-byte ranges, vertex blocks. */
|
|
220
|
+
takeDirty() {
|
|
221
|
+
const out = { records: [...this.#dirtyRecords].sort((a, b) => a - b), ids: this.#dirtyIds.splice(0), triangles: this.#dirtyTris.splice(0), vertices: this.#writes.splice(0) };
|
|
222
|
+
this.#dirtyRecords.clear();
|
|
223
|
+
return out;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=cluster-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster-stream.js","sourceRoot":"","sources":["../src/cluster-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type MeshEntry } from './meshes.ts';
|
|
2
|
+
/** Most cascades the CPU cull partitions by (`CULL_CASCADES` in the core). */
|
|
3
|
+
export declare const CULL_CASCADES = 3;
|
|
4
|
+
/**
|
|
5
|
+
* The draws of a CPU-culled frame (ADR-0057, ADR-0073), built from the core's per-bin counts:
|
|
6
|
+
* the main pass draws each (mesh, LOD) slot whole, and shadow cascade c draws only the runs of
|
|
7
|
+
* the slot's groups whose instances reach it. Draws are 5 words: index count, first index,
|
|
8
|
+
* base vertex, first instance, instance count. Reused frame to frame; it allocates only to grow.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CulledDraws {
|
|
11
|
+
main: Uint32Array<ArrayBuffer>;
|
|
12
|
+
/** Each main draw's draw class (ADR-0081). */
|
|
13
|
+
mainClass: Uint8Array<ArrayBuffer>;
|
|
14
|
+
mainCount: number;
|
|
15
|
+
/** Per cascade: its draws, and how many. */
|
|
16
|
+
readonly cascade: Uint32Array<ArrayBuffer>[];
|
|
17
|
+
readonly cascadeCount: number[];
|
|
18
|
+
/** Each cascade draw's draw class (blend classes cast no shadow, so never appear). */
|
|
19
|
+
readonly cascadeClass: Uint8Array<ArrayBuffer>[];
|
|
20
|
+
/** Instances drawn at each LOD (index 0 = full detail). */
|
|
21
|
+
readonly byLod: Uint32Array<ArrayBuffer>;
|
|
22
|
+
/** Instances each cascade draws (its casters), and the main pass (`mainInstances`). */
|
|
23
|
+
readonly casters: number[];
|
|
24
|
+
mainInstances: number;
|
|
25
|
+
/**
|
|
26
|
+
* Reads `meshes × 8 × 2^cascades` counts from `u32[at…]` (bins mesh-major, then LOD, then
|
|
27
|
+
* group) and lays the slots out back to back from instance 0, as the core wrote them.
|
|
28
|
+
*/
|
|
29
|
+
build(u32: Uint32Array, at: number, meshes: number, entries: readonly MeshEntry[], cascades: number): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { isBlendClass } from "./meshes.js";
|
|
2
|
+
/** Most cascades the CPU cull partitions by (`CULL_CASCADES` in the core). */
|
|
3
|
+
export const CULL_CASCADES = 3;
|
|
4
|
+
/** Each cascade count's group order (`CASCADE_ORDER` in the core): group g holds cascade mask `order[g]`. */
|
|
5
|
+
const CASCADE_ORDER = [[0], [1, 0], [1, 3, 2, 0], [1, 3, 7, 5, 6, 2, 4, 0]];
|
|
6
|
+
/**
|
|
7
|
+
* The draws of a CPU-culled frame (ADR-0057, ADR-0073), built from the core's per-bin counts:
|
|
8
|
+
* the main pass draws each (mesh, LOD) slot whole, and shadow cascade c draws only the runs of
|
|
9
|
+
* the slot's groups whose instances reach it. Draws are 5 words: index count, first index,
|
|
10
|
+
* base vertex, first instance, instance count. Reused frame to frame; it allocates only to grow.
|
|
11
|
+
*/
|
|
12
|
+
export class CulledDraws {
|
|
13
|
+
main = new Uint32Array(0);
|
|
14
|
+
/** Each main draw's draw class (ADR-0081). */
|
|
15
|
+
mainClass = new Uint8Array(0);
|
|
16
|
+
mainCount = 0;
|
|
17
|
+
/** Per cascade: its draws, and how many. */
|
|
18
|
+
cascade = [new Uint32Array(0), new Uint32Array(0), new Uint32Array(0)];
|
|
19
|
+
cascadeCount = [0, 0, 0];
|
|
20
|
+
/** Each cascade draw's draw class (blend classes cast no shadow, so never appear). */
|
|
21
|
+
cascadeClass = [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)];
|
|
22
|
+
/** Instances drawn at each LOD (index 0 = full detail). */
|
|
23
|
+
byLod = new Uint32Array(8);
|
|
24
|
+
/** Instances each cascade draws (its casters), and the main pass (`mainInstances`). */
|
|
25
|
+
casters = [0, 0, 0];
|
|
26
|
+
mainInstances = 0;
|
|
27
|
+
/**
|
|
28
|
+
* Reads `meshes × 8 × 2^cascades` counts from `u32[at…]` (bins mesh-major, then LOD, then
|
|
29
|
+
* group) and lays the slots out back to back from instance 0, as the core wrote them.
|
|
30
|
+
*/
|
|
31
|
+
build(u32, at, meshes, entries, cascades) {
|
|
32
|
+
const groups = 1 << cascades;
|
|
33
|
+
const order = CASCADE_ORDER[cascades];
|
|
34
|
+
const grow = (a, n) => (a.length >= n ? a : new Uint32Array(2 ** Math.ceil(Math.log2(Math.max(1, n)))));
|
|
35
|
+
this.main = grow(this.main, meshes * 8 * 5);
|
|
36
|
+
if (this.mainClass.length < meshes * 8)
|
|
37
|
+
this.mainClass = new Uint8Array(this.main.length / 5);
|
|
38
|
+
// A cascade has at most two runs per slot.
|
|
39
|
+
for (let c = 0; c < cascades; c++) {
|
|
40
|
+
this.cascade[c] = grow(this.cascade[c], meshes * 8 * 2 * 5);
|
|
41
|
+
if (this.cascadeClass[c].length < meshes * 8 * 2)
|
|
42
|
+
this.cascadeClass[c] = new Uint8Array(this.cascade[c].length / 5);
|
|
43
|
+
}
|
|
44
|
+
this.byLod.fill(0);
|
|
45
|
+
this.cascadeCount.fill(0);
|
|
46
|
+
this.casters.fill(0);
|
|
47
|
+
let n = 0;
|
|
48
|
+
let start = 0;
|
|
49
|
+
for (let m = 0; m < meshes; m++) {
|
|
50
|
+
const e = entries[m];
|
|
51
|
+
for (let l = 0; l < 8; l++) {
|
|
52
|
+
const bin = (m * 8 + l) * groups;
|
|
53
|
+
let total = 0;
|
|
54
|
+
for (let g = 0; g < groups; g++)
|
|
55
|
+
total += u32[at + bin + g];
|
|
56
|
+
if (total === 0)
|
|
57
|
+
continue;
|
|
58
|
+
const lod = e.lods[l] ?? e.lods[0];
|
|
59
|
+
const d = this.main;
|
|
60
|
+
d[n * 5] = lod.count;
|
|
61
|
+
d[n * 5 + 1] = lod.firstIndex;
|
|
62
|
+
d[n * 5 + 2] = e.baseVertex;
|
|
63
|
+
d[n * 5 + 3] = start;
|
|
64
|
+
d[n * 5 + 4] = total;
|
|
65
|
+
this.mainClass[n] = e.drawClass;
|
|
66
|
+
n++;
|
|
67
|
+
this.byLod[l] += total;
|
|
68
|
+
// A blended mesh casts no shadow (ADR-0081).
|
|
69
|
+
for (let c = 0; c < (isBlendClass(e.drawClass) ? 0 : cascades); c++) {
|
|
70
|
+
const out = this.cascade[c];
|
|
71
|
+
let first = start;
|
|
72
|
+
let runStart = -1;
|
|
73
|
+
let k = this.cascadeCount[c];
|
|
74
|
+
for (let g = 0; g <= groups; g++) {
|
|
75
|
+
const inside = g < groups && (order[g] & (1 << c)) !== 0;
|
|
76
|
+
const size = g < groups ? u32[at + bin + g] : 0;
|
|
77
|
+
if (inside && runStart < 0)
|
|
78
|
+
runStart = first;
|
|
79
|
+
if (!inside && runStart >= 0) {
|
|
80
|
+
if (first > runStart) {
|
|
81
|
+
out[k * 5] = lod.count;
|
|
82
|
+
out[k * 5 + 1] = lod.firstIndex;
|
|
83
|
+
out[k * 5 + 2] = e.baseVertex;
|
|
84
|
+
out[k * 5 + 3] = runStart;
|
|
85
|
+
out[k * 5 + 4] = first - runStart;
|
|
86
|
+
this.cascadeClass[c][k] = e.drawClass;
|
|
87
|
+
this.casters[c] += first - runStart;
|
|
88
|
+
k++;
|
|
89
|
+
}
|
|
90
|
+
runStart = -1;
|
|
91
|
+
}
|
|
92
|
+
first += size;
|
|
93
|
+
}
|
|
94
|
+
this.cascadeCount[c] = k;
|
|
95
|
+
}
|
|
96
|
+
start += total;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
this.mainCount = n;
|
|
100
|
+
this.mainInstances = start;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=culled-draws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"culled-draws.js","sourceRoot":"","sources":["../src/culled-draws.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { OrbitCamera } from './camera.ts';
|
|
2
|
+
import type { PipelineCache } from './pipeline-cache.ts';
|
|
3
|
+
/** Bytes per debug vertex: x, y, z (f32, camera-relative once queued) and an RGBA8 colour. */
|
|
4
|
+
export declare const DEBUG_VERTEX_BYTES = 16;
|
|
5
|
+
/**
|
|
6
|
+
* Debug line segments for this frame (`render.debug`, ADR-0087): plugins queue them after the
|
|
7
|
+
* camera has moved (Extract or later), the renderer draws them at the end of the scene pass,
|
|
8
|
+
* depth-tested against it, and the queue empties every frame. Positions are converted to
|
|
9
|
+
* camera-relative f32 as they are queued, from f64 origins, so lines far from the world origin
|
|
10
|
+
* stay exact. Allocation-free once the buffer has grown.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const render = app.resource<RenderContext>('render');
|
|
14
|
+
* render.debug.line([0, 0, 0], [0, 2, 0], 0xff0000ff); // a red post, 2 m tall
|
|
15
|
+
*/
|
|
16
|
+
export declare class DebugLines {
|
|
17
|
+
#private;
|
|
18
|
+
/** Vertices queued this frame (two per segment). */
|
|
19
|
+
count: number;
|
|
20
|
+
/** At most this many vertices per frame; more are dropped (and counted). */
|
|
21
|
+
capacity: number;
|
|
22
|
+
/** Vertices dropped this frame over `capacity`. */
|
|
23
|
+
dropped: number;
|
|
24
|
+
/** Vertices the last drawn frame had (what `clear` emptied; the `render.debugLines` counter). */
|
|
25
|
+
drawn: number;
|
|
26
|
+
constructor(camera: OrbitCamera, capacity?: number);
|
|
27
|
+
/** The queued vertices (`count × 16` bytes from offset 0). */
|
|
28
|
+
get data(): Float32Array;
|
|
29
|
+
/**
|
|
30
|
+
* Queues `count` vertices from a packed buffer: 16 bytes each (x, y, z as f32 relative to
|
|
31
|
+
* `origin`, then RGBA8), starting at vertex `first` of the views `f32` / `u32` (one buffer,
|
|
32
|
+
* e.g. WASM memory). `origin` is f64 world coordinates.
|
|
33
|
+
*/
|
|
34
|
+
add(f32: Float32Array, u32: Uint32Array, first: number, count: number, origin: ArrayLike<number>): void;
|
|
35
|
+
/** Queues one segment between world points `a` and `b`, colour `rgba` (red in the low byte). */
|
|
36
|
+
line(a: ArrayLike<number>, b: ArrayLike<number>, rgba: number): void;
|
|
37
|
+
/** Empties the queue (the renderer calls it after each frame). */
|
|
38
|
+
clear(): void;
|
|
39
|
+
}
|
|
40
|
+
/** Draws a `DebugLines` queue in the scene pass (WebGPU). */
|
|
41
|
+
export declare class DebugLinesPass {
|
|
42
|
+
#private;
|
|
43
|
+
readonly device: GPUDevice;
|
|
44
|
+
constructor(device: GPUDevice, format: GPUTextureFormat, camera: GPUBuffer);
|
|
45
|
+
init(cache: PipelineCache): Promise<void>;
|
|
46
|
+
/** Uploads and draws `lines` into `pass` (inside the scene pass, after its draws). */
|
|
47
|
+
encode(pass: GPURenderPassEncoder, lines: DebugLines): void;
|
|
48
|
+
/** GPU buffers held (the leak check). */
|
|
49
|
+
get liveBuffers(): number;
|
|
50
|
+
destroy(): void;
|
|
51
|
+
}
|