@aethervtt/shard-render 0.0.1
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/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/assets.d.ts +104 -0
- package/dist/assets.js +213 -0
- package/dist/atmosphere-model.d.ts +96 -0
- package/dist/atmosphere-model.js +370 -0
- package/dist/atmosphere-nodes.d.ts +55 -0
- package/dist/atmosphere-nodes.js +780 -0
- package/dist/atmosphere-plugin.d.ts +5 -0
- package/dist/atmosphere-plugin.js +42 -0
- package/dist/atmosphere-shaders.d.ts +7 -0
- package/dist/atmosphere-shaders.js +595 -0
- package/dist/atmosphere-state.d.ts +72 -0
- package/dist/atmosphere-state.js +18 -0
- package/dist/atmosphere.d.ts +191 -0
- package/dist/atmosphere.js +950 -0
- package/dist/camera.d.ts +83 -0
- package/dist/camera.js +163 -0
- package/dist/clusters.d.ts +68 -0
- package/dist/clusters.js +288 -0
- package/dist/culling-shaders.d.ts +2 -0
- package/dist/culling-shaders.js +203 -0
- package/dist/culling.d.ts +84 -0
- package/dist/culling.js +498 -0
- package/dist/debug-shaders.d.ts +3 -0
- package/dist/debug-shaders.js +207 -0
- package/dist/debug-views.d.ts +60 -0
- package/dist/debug-views.js +197 -0
- package/dist/deferred-plugin.d.ts +5 -0
- package/dist/deferred-plugin.js +20 -0
- package/dist/deferred-shaders.d.ts +2 -0
- package/dist/deferred-shaders.js +151 -0
- package/dist/deferred.d.ts +22 -0
- package/dist/deferred.js +296 -0
- package/dist/deform.d.ts +80 -0
- package/dist/deform.js +213 -0
- package/dist/describe-plugin.d.ts +5 -0
- package/dist/describe-plugin.js +19 -0
- package/dist/display-nodes.d.ts +5 -0
- package/dist/display-nodes.js +189 -0
- package/dist/dynamic-resolution.d.ts +47 -0
- package/dist/dynamic-resolution.js +191 -0
- package/dist/environment-plugin.d.ts +6 -0
- package/dist/environment-plugin.js +44 -0
- package/dist/environment-shaders.d.ts +2 -0
- package/dist/environment-shaders.js +260 -0
- package/dist/environment-state.d.ts +71 -0
- package/dist/environment-state.js +144 -0
- package/dist/environment.d.ts +70 -0
- package/dist/environment.js +529 -0
- package/dist/forward.d.ts +123 -0
- package/dist/forward.js +1216 -0
- package/dist/fxaa.d.ts +2 -0
- package/dist/fxaa.js +65 -0
- package/dist/gizmo-font.d.ts +21 -0
- package/dist/gizmo-font.js +132 -0
- package/dist/gizmos-plugin.d.ts +5 -0
- package/dist/gizmos-plugin.js +34 -0
- package/dist/gizmos.d.ts +156 -0
- package/dist/gizmos.js +772 -0
- package/dist/gpu-assets.d.ts +114 -0
- package/dist/gpu-assets.js +494 -0
- package/dist/graph.d.ts +204 -0
- package/dist/graph.js +417 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +540 -0
- package/dist/instances.d.ts +349 -0
- package/dist/instances.js +1335 -0
- package/dist/large-world.d.ts +13 -0
- package/dist/large-world.js +20 -0
- package/dist/lights.d.ts +160 -0
- package/dist/lights.js +468 -0
- package/dist/material-noise.d.ts +19 -0
- package/dist/material-noise.js +7 -0
- package/dist/material-pipelines.d.ts +46 -0
- package/dist/material-pipelines.js +166 -0
- package/dist/materials.d.ts +108 -0
- package/dist/materials.js +219 -0
- package/dist/noise.d.ts +76 -0
- package/dist/noise.js +286 -0
- package/dist/overlay-registry.d.ts +18 -0
- package/dist/overlay-registry.js +30 -0
- package/dist/overlays.d.ts +35 -0
- package/dist/overlays.js +344 -0
- package/dist/paths.d.ts +20 -0
- package/dist/paths.js +46 -0
- package/dist/picking-plugin.d.ts +2 -0
- package/dist/picking-plugin.js +20 -0
- package/dist/picking.d.ts +94 -0
- package/dist/picking.js +456 -0
- package/dist/pixel-perfect-plugin.d.ts +9 -0
- package/dist/pixel-perfect-plugin.js +135 -0
- package/dist/pixel-perfect.d.ts +27 -0
- package/dist/pixel-perfect.js +70 -0
- package/dist/plugin.d.ts +111 -0
- package/dist/plugin.js +182 -0
- package/dist/pool.d.ts +19 -0
- package/dist/pool.js +43 -0
- package/dist/post-common.d.ts +51 -0
- package/dist/post-common.js +148 -0
- package/dist/post-nodes.d.ts +39 -0
- package/dist/post-nodes.js +849 -0
- package/dist/post-plugin.d.ts +5 -0
- package/dist/post-plugin.js +26 -0
- package/dist/post-shaders.d.ts +8 -0
- package/dist/post-shaders.js +698 -0
- package/dist/post.d.ts +175 -0
- package/dist/post.js +453 -0
- package/dist/readback.d.ts +4 -0
- package/dist/readback.js +95 -0
- package/dist/render-scale.d.ts +53 -0
- package/dist/render-scale.js +63 -0
- package/dist/shaders.d.ts +122 -0
- package/dist/shaders.js +1168 -0
- package/dist/shadows.d.ts +119 -0
- package/dist/shadows.js +562 -0
- package/dist/skin-asset.d.ts +26 -0
- package/dist/skin-asset.js +25 -0
- package/dist/skinning-plugin.d.ts +5 -0
- package/dist/skinning-plugin.js +16 -0
- package/dist/skinning.d.ts +19 -0
- package/dist/skinning.js +343 -0
- package/dist/standard-fields.d.ts +67 -0
- package/dist/standard-fields.js +73 -0
- package/dist/standard.d.ts +7 -0
- package/dist/standard.js +37 -0
- package/dist/stats.d.ts +25 -0
- package/dist/stats.js +18 -0
- package/dist/target.d.ts +55 -0
- package/dist/target.js +70 -0
- package/dist/testing.d.ts +34 -0
- package/dist/testing.js +126 -0
- package/dist/timer.d.ts +28 -0
- package/dist/timer.js +136 -0
- package/dist/view.d.ts +117 -0
- package/dist/view.js +389 -0
- package/dist/visibility.d.ts +10 -0
- package/dist/visibility.js +84 -0
- package/package.json +49 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
const CULLING_SHADERS = {
|
|
2
|
+
"shard::cull": `
|
|
3
|
+
struct Instance {
|
|
4
|
+
row0: vec4f,
|
|
5
|
+
row1: vec4f,
|
|
6
|
+
row2: vec4f,
|
|
7
|
+
batch: u32,
|
|
8
|
+
flags: u32,
|
|
9
|
+
range: u32,
|
|
10
|
+
entity: u32,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
struct Batch {
|
|
14
|
+
/** Local bounding sphere: center (xyz), radius (w). */
|
|
15
|
+
sphere: vec4f,
|
|
16
|
+
count: u32,
|
|
17
|
+
indexed: u32,
|
|
18
|
+
/** Where the batch's instances start in a view's visible region. */
|
|
19
|
+
region: u32,
|
|
20
|
+
flags: u32,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
struct LodSet {
|
|
24
|
+
count: u32,
|
|
25
|
+
hysteresis: f32,
|
|
26
|
+
bias: f32,
|
|
27
|
+
_pad: u32,
|
|
28
|
+
thresholds: array<vec4f, 2>,
|
|
29
|
+
batches: array<vec4u, 2>,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
struct CullView {
|
|
33
|
+
planes: array<vec4f, 6>,
|
|
34
|
+
/** xyz: where distances are measured from; w: LOD scale. */
|
|
35
|
+
eye: vec4f,
|
|
36
|
+
flags: u32,
|
|
37
|
+
lod_camera: u32,
|
|
38
|
+
args_base: u32,
|
|
39
|
+
visible_base: u32,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
struct Params {
|
|
43
|
+
slot_count: u32,
|
|
44
|
+
view_offset: u32,
|
|
45
|
+
view_count: u32,
|
|
46
|
+
batch_count: u32,
|
|
47
|
+
slot_capacity: u32,
|
|
48
|
+
_pad0: u32,
|
|
49
|
+
_pad1: u32,
|
|
50
|
+
_pad2: u32,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@group(0) @binding(0) var<storage, read> instances: array<Instance>;
|
|
54
|
+
@group(0) @binding(1) var<storage, read> batches: array<Batch>;
|
|
55
|
+
@group(0) @binding(2) var<storage, read> lod_sets: array<LodSet>;
|
|
56
|
+
@group(0) @binding(3) var<storage, read> views: array<CullView>;
|
|
57
|
+
@group(0) @binding(4) var<storage, read_write> args: array<atomic<u32>>;
|
|
58
|
+
@group(0) @binding(5) var<storage, read_write> visible: array<u32>;
|
|
59
|
+
@group(0) @binding(6) var<storage, read_write> lod_state: array<u32>;
|
|
60
|
+
@group(0) @binding(7) var<uniform> params: Params;
|
|
61
|
+
|
|
62
|
+
/** Skinned slots' world spheres (the rest of the deform record is for the vertex stage). */
|
|
63
|
+
struct Deform {
|
|
64
|
+
sphere: vec4f,
|
|
65
|
+
rest0: vec4u,
|
|
66
|
+
rest1: vec4u,
|
|
67
|
+
}
|
|
68
|
+
@group(0) @binding(8) var<storage, read> deforms: array<Deform>;
|
|
69
|
+
|
|
70
|
+
const NO_BATCH: u32 = 0xffffffffu;
|
|
71
|
+
const LOD_BIT: u32 = 0x80000000u;
|
|
72
|
+
const LOD_UNSET: u32 = 0xffu;
|
|
73
|
+
const FLAG_VISIBLE: u32 = 1u;
|
|
74
|
+
const FLAG_CASTER: u32 = 2u;
|
|
75
|
+
const FLAG_RANGE: u32 = 8u;
|
|
76
|
+
const FLAG_SKINNED: u32 = 32u;
|
|
77
|
+
const VIEW_CASTERS: u32 = 1u;
|
|
78
|
+
const VIEW_UPDATE_LOD: u32 = 2u;
|
|
79
|
+
const VIEW_ORTHO: u32 = 4u;
|
|
80
|
+
const VIEW_NO_PLANES: u32 = 8u;
|
|
81
|
+
const VIEW_NO_EYE: u32 = 16u;
|
|
82
|
+
const BATCH_TRANSPARENT: u32 = 1u;
|
|
83
|
+
const BATCH_NOT_READY: u32 = 2u;
|
|
84
|
+
const ARGS_WORDS: u32 = 5u;
|
|
85
|
+
|
|
86
|
+
/** Writes every (view, batch) indirect draw: counts from the mesh, zero instances, first instance. */
|
|
87
|
+
@compute @workgroup_size(64)
|
|
88
|
+
fn reset(@builtin(global_invocation_id) id: vec3u) {
|
|
89
|
+
let i = id.x;
|
|
90
|
+
if (i >= params.view_count * params.batch_count) { return; }
|
|
91
|
+
let v = i / params.batch_count;
|
|
92
|
+
let b = i % params.batch_count;
|
|
93
|
+
let batch = batches[b];
|
|
94
|
+
let first = views[v].visible_base + batch.region;
|
|
95
|
+
let o = i * ARGS_WORDS;
|
|
96
|
+
atomicStore(&args[o], batch.count);
|
|
97
|
+
atomicStore(&args[o + 1u], 0u);
|
|
98
|
+
atomicStore(&args[o + 2u], 0u);
|
|
99
|
+
// Indexed: (count, instances, first index, base vertex, first instance).
|
|
100
|
+
// Non-indexed: (count, instances, first vertex, first instance).
|
|
101
|
+
atomicStore(&args[o + 3u], select(first, batch.indexed - 1u, batch.indexed != 0u));
|
|
102
|
+
atomicStore(&args[o + 4u], select(0u, first, batch.indexed != 0u));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
fn slot_sphere(inst: Instance, bounds: vec4f) -> vec4f {
|
|
106
|
+
let c = vec4f(bounds.xyz, 1.0);
|
|
107
|
+
let center = vec3f(dot(inst.row0, c), dot(inst.row1, c), dot(inst.row2, c));
|
|
108
|
+
let sx = inst.row0.x * inst.row0.x + inst.row1.x * inst.row1.x + inst.row2.x * inst.row2.x;
|
|
109
|
+
let sy = inst.row0.y * inst.row0.y + inst.row1.y * inst.row1.y + inst.row2.y * inst.row2.y;
|
|
110
|
+
let sz = inst.row0.z * inst.row0.z + inst.row1.z * inst.row1.z + inst.row2.z * inst.row2.z;
|
|
111
|
+
return vec4f(center, bounds.w * sqrt(max(sx, max(sy, sz))));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
fn in_frustum(view: CullView, s: vec4f) -> bool {
|
|
115
|
+
for (var p = 0; p < 6; p++) {
|
|
116
|
+
let plane = view.planes[p];
|
|
117
|
+
if (dot(plane.xyz, s.xyz) + plane.w < -s.w) { return false; }
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Mirrors selectLod: with hysteresis once a level is chosen; count means too small to draw. */
|
|
123
|
+
fn select_lod(size: f32, lod_set: LodSet, previous: u32) -> u32 {
|
|
124
|
+
let count = lod_set.count;
|
|
125
|
+
if (previous == LOD_UNSET || previous > count) {
|
|
126
|
+
for (var k = 0u; k < count; k++) {
|
|
127
|
+
if (size >= lod_set.thresholds[k / 4u][k % 4u]) { return k; }
|
|
128
|
+
}
|
|
129
|
+
return count;
|
|
130
|
+
}
|
|
131
|
+
var level = previous;
|
|
132
|
+
let h = lod_set.hysteresis;
|
|
133
|
+
loop {
|
|
134
|
+
if (level == 0u) { break; }
|
|
135
|
+
let t = lod_set.thresholds[(level - 1u) / 4u][(level - 1u) % 4u];
|
|
136
|
+
if (size <= t * (1.0 + h)) { break; }
|
|
137
|
+
level--;
|
|
138
|
+
}
|
|
139
|
+
loop {
|
|
140
|
+
if (level >= count) { break; }
|
|
141
|
+
let t = lod_set.thresholds[level / 4u][level % 4u];
|
|
142
|
+
if (size >= t * (1.0 - h)) { break; }
|
|
143
|
+
level++;
|
|
144
|
+
}
|
|
145
|
+
return level;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** One thread per (slot, view): test, choose LOD, append to the batch's visible list. */
|
|
149
|
+
@compute @workgroup_size(64)
|
|
150
|
+
fn cull(@builtin(global_invocation_id) id: vec3u) {
|
|
151
|
+
let s = id.x;
|
|
152
|
+
if (s >= params.slot_count) { return; }
|
|
153
|
+
let v = params.view_offset + id.y;
|
|
154
|
+
let view = views[v];
|
|
155
|
+
let inst = instances[s];
|
|
156
|
+
if (inst.batch == NO_BATCH) { return; }
|
|
157
|
+
var mask = FLAG_VISIBLE;
|
|
158
|
+
if ((view.flags & VIEW_CASTERS) != 0u) { mask |= FLAG_CASTER; }
|
|
159
|
+
if ((inst.flags & mask) != mask) { return; }
|
|
160
|
+
var b = inst.batch;
|
|
161
|
+
var lod = false;
|
|
162
|
+
var lod_set: LodSet;
|
|
163
|
+
if ((b & LOD_BIT) != 0u) {
|
|
164
|
+
lod_set = lod_sets[b & ~LOD_BIT];
|
|
165
|
+
b = lod_set.batches[0].x;
|
|
166
|
+
lod = true;
|
|
167
|
+
}
|
|
168
|
+
var batch = batches[b];
|
|
169
|
+
if ((batch.flags & (BATCH_TRANSPARENT | BATCH_NOT_READY)) != 0u) { return; }
|
|
170
|
+
var sphere = slot_sphere(inst, batch.sphere);
|
|
171
|
+
// A skinned pose moves the mesh away from its bounds: the slot's own sphere follows the joints.
|
|
172
|
+
if ((inst.flags & FLAG_SKINNED) != 0u && deforms[s].sphere.w > 0.0) { sphere = deforms[s].sphere; }
|
|
173
|
+
if ((view.flags & VIEW_NO_PLANES) == 0u && !in_frustum(view, sphere)) { return; }
|
|
174
|
+
let has_eye = (view.flags & VIEW_NO_EYE) == 0u;
|
|
175
|
+
let distance = select(0.0, length(sphere.xyz - view.eye.xyz), has_eye);
|
|
176
|
+
if ((inst.flags & FLAG_RANGE) != 0u && has_eye) {
|
|
177
|
+
let range = unpack2x16float(inst.range);
|
|
178
|
+
if (distance < range.x || distance >= range.y) { return; }
|
|
179
|
+
}
|
|
180
|
+
var level = 0u;
|
|
181
|
+
if (lod) {
|
|
182
|
+
let idx = view.lod_camera * params.slot_capacity + s;
|
|
183
|
+
if ((view.flags & VIEW_UPDATE_LOD) != 0u) {
|
|
184
|
+
var size = sphere.w * view.eye.w;
|
|
185
|
+
if ((view.flags & VIEW_ORTHO) == 0u) { size = size / max(distance, 1e-4); }
|
|
186
|
+
size = size * exp2(lod_set.bias);
|
|
187
|
+
level = select_lod(size, lod_set, lod_state[idx]);
|
|
188
|
+
lod_state[idx] = level;
|
|
189
|
+
} else {
|
|
190
|
+
level = lod_state[idx];
|
|
191
|
+
}
|
|
192
|
+
if (level >= lod_set.count) { return; }
|
|
193
|
+
b = lod_set.batches[level / 4u][level % 4u];
|
|
194
|
+
batch = batches[b];
|
|
195
|
+
if ((batch.flags & BATCH_NOT_READY) != 0u) { return; }
|
|
196
|
+
}
|
|
197
|
+
let n = atomicAdd(&args[(view.args_base + b) * ARGS_WORDS + 1u], 1u);
|
|
198
|
+
visible[view.visible_base + batch.region + n] = s | (level << 28u);
|
|
199
|
+
}`
|
|
200
|
+
};
|
|
201
|
+
export {
|
|
202
|
+
CULLING_SHADERS
|
|
203
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { GpuBuffer, type GpuContext } from '@aethervtt/shard-gpu';
|
|
2
|
+
import type { NodeContext } from './graph.js';
|
|
3
|
+
import { type CullParams, type DrawList, type InstanceStore } from './instances.js';
|
|
4
|
+
/**
|
|
5
|
+
* GPU culling: one compute pass per frame culls every instance slot against every draw view
|
|
6
|
+
* (cameras first, which choose LOD levels, then shadow views, which reuse them), writing indirect
|
|
7
|
+
* draw arguments and compacted visible lists. Nothing is read back in the frame; visible counts
|
|
8
|
+
* come back asynchronously for `render.describe`.
|
|
9
|
+
*/
|
|
10
|
+
export declare class GpuCuller {
|
|
11
|
+
readonly supported: boolean;
|
|
12
|
+
/** Turn off to force CPU culling (tests, debugging). */
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
private readonly views;
|
|
15
|
+
private viewCount;
|
|
16
|
+
private cameraViews;
|
|
17
|
+
/** LOD camera index per camera entity, stable while the camera lives. */
|
|
18
|
+
private readonly lodCameras;
|
|
19
|
+
private viewData;
|
|
20
|
+
private viewU32;
|
|
21
|
+
private batchData;
|
|
22
|
+
private batchF32;
|
|
23
|
+
private lodData;
|
|
24
|
+
private lodF32;
|
|
25
|
+
private readonly params;
|
|
26
|
+
readonly viewBuffer: GpuBuffer;
|
|
27
|
+
readonly batchBuffer: GpuBuffer;
|
|
28
|
+
readonly lodBuffer: GpuBuffer;
|
|
29
|
+
readonly args: GpuBuffer;
|
|
30
|
+
readonly visible: GpuBuffer;
|
|
31
|
+
readonly lodState: GpuBuffer;
|
|
32
|
+
readonly paramBuffers: GpuBuffer[];
|
|
33
|
+
/** Instances a view's region can hold: the sum of batch capacities. */
|
|
34
|
+
regionSize: number;
|
|
35
|
+
private batchCount;
|
|
36
|
+
private lodStateCapacity;
|
|
37
|
+
private readonly gpu;
|
|
38
|
+
private bindGroups;
|
|
39
|
+
private readonly readbacks;
|
|
40
|
+
/** Visible instances per DrawList, from the last readback (a frame or two late). */
|
|
41
|
+
readonly counts: WeakMap<DrawList, number>;
|
|
42
|
+
/** Per-LOD-level instance counts per DrawList, from the last readback. */
|
|
43
|
+
readonly lodCounts: WeakMap<DrawList, number[]>;
|
|
44
|
+
/** Batches that drew at least one instance, per DrawList, from the last readback. */
|
|
45
|
+
readonly drawCounts: WeakMap<DrawList, number>;
|
|
46
|
+
/** Instances per batch index, per DrawList, from the last readback. */
|
|
47
|
+
readonly batchCounts: WeakMap<DrawList, Uint32Array<ArrayBufferLike>>;
|
|
48
|
+
private frameViews;
|
|
49
|
+
private readonly pending;
|
|
50
|
+
constructor(gpu: GpuContext);
|
|
51
|
+
get active(): boolean;
|
|
52
|
+
beginFrame(): void;
|
|
53
|
+
/** The LOD state row of a camera (cameras choose; their shadow views reuse the choice). */
|
|
54
|
+
lodCamera(entity: number): number;
|
|
55
|
+
/**
|
|
56
|
+
* Adds a view to this frame's cull. Camera views must come before shadow views (they choose LOD
|
|
57
|
+
* levels). The list gets one indirect draw per live batch; deferred views split non-deferrable
|
|
58
|
+
* batches into `forwardOnly`.
|
|
59
|
+
*/
|
|
60
|
+
add(store: InstanceStore, list: DrawList, params: CullParams, lodCamera: number, forwardOnly?: DrawList): number;
|
|
61
|
+
/** Uploads the frame's view, batch, and LOD tables, and sizes the buffers. */
|
|
62
|
+
prepare(store: InstanceStore): void;
|
|
63
|
+
private slotCount;
|
|
64
|
+
private slotCapacity;
|
|
65
|
+
/** Encodes the cull: reset arguments, cull camera views, then shadow views. */
|
|
66
|
+
encode(ctx: NodeContext, store: InstanceStore): void;
|
|
67
|
+
/** Copies the arguments to a readback buffer; resolves visible counts when it maps. */
|
|
68
|
+
private readback;
|
|
69
|
+
/** Resolves once every readback in flight has landed (tests: stats that match the last frame). */
|
|
70
|
+
whenIdle(): Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
export declare const Culler: import("@aethervtt/shard-core").ResourceDef<GpuCuller>;
|
|
73
|
+
/**
|
|
74
|
+
* Culls transparent instances on the CPU (they need a back-to-front sort), iterating only the
|
|
75
|
+
* members of blended batches, so it costs what's transparent, not what exists.
|
|
76
|
+
*/
|
|
77
|
+
export declare function cullTransparent(store: InstanceStore, list: DrawList, params: CullParams, forward: Float32Array): void;
|
|
78
|
+
/**
|
|
79
|
+
* The CPU-side visible set of a view as slots (tests compare it with the GPU's). Pass
|
|
80
|
+
* `mask = 0xffffffff` to keep the LOD level in the top bits.
|
|
81
|
+
*/
|
|
82
|
+
export declare function visibleSlots(store: InstanceStore, list: DrawList, mask?: number): Set<number>;
|
|
83
|
+
/** Reads back a GPU-culled view's visible set as slots (tests). */
|
|
84
|
+
export declare function readVisibleSlots(gpu: GpuContext, culler: GpuCuller, list: DrawList, mask?: number): Promise<Set<number>>;
|