@plasius/gpu-renderer 0.1.6 → 0.1.8
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/CHANGELOG.md +53 -0
- package/README.md +78 -0
- package/dist/index.cjs +813 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +800 -6
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
- package/src/index.d.ts +239 -1
- package/src/index.js +862 -3
package/dist/index.cjs
CHANGED
|
@@ -21,12 +21,660 @@ var index_exports = {};
|
|
|
21
21
|
__export(index_exports, {
|
|
22
22
|
bindRendererToXrManager: () => bindRendererToXrManager,
|
|
23
23
|
createGpuRenderer: () => createGpuRenderer,
|
|
24
|
+
createRayTracingRenderPlan: () => createRayTracingRenderPlan,
|
|
25
|
+
createRendererDebugHooks: () => createRendererDebugHooks,
|
|
24
26
|
defaultRendererClearColor: () => defaultRendererClearColor,
|
|
27
|
+
defaultRendererWorkerProfile: () => defaultRendererWorkerProfile,
|
|
28
|
+
getRendererWorkerManifest: () => getRendererWorkerManifest,
|
|
29
|
+
getRendererWorkerProfile: () => getRendererWorkerProfile,
|
|
30
|
+
rendererAccelerationStructureUpdateClasses: () => rendererAccelerationStructureUpdateClasses,
|
|
31
|
+
rendererDebugOwner: () => rendererDebugOwner,
|
|
32
|
+
rendererRayTracingStageOrder: () => rendererRayTracingStageOrder,
|
|
33
|
+
rendererRepresentationBands: () => rendererRepresentationBands,
|
|
34
|
+
rendererWorkerManifests: () => rendererWorkerManifests,
|
|
35
|
+
rendererWorkerProfileNames: () => rendererWorkerProfileNames,
|
|
36
|
+
rendererWorkerProfiles: () => rendererWorkerProfiles,
|
|
37
|
+
rendererWorkerQueueClass: () => rendererWorkerQueueClass,
|
|
25
38
|
supportsWebGpu: () => supportsWebGpu
|
|
26
39
|
});
|
|
27
40
|
module.exports = __toCommonJS(index_exports);
|
|
28
41
|
var DEFAULT_CLEAR_COLOR = Object.freeze([0.07, 0.11, 0.18, 1]);
|
|
29
42
|
var DEFAULT_CANVAS_SELECTOR = "canvas[data-plasius-gpu-renderer]";
|
|
43
|
+
var rendererDebugOwner = "renderer";
|
|
44
|
+
var rendererWorkerQueueClass = "render";
|
|
45
|
+
var defaultRendererWorkerProfile = "realtime";
|
|
46
|
+
var rendererRepresentationBands = Object.freeze([
|
|
47
|
+
"near",
|
|
48
|
+
"mid",
|
|
49
|
+
"far",
|
|
50
|
+
"horizon"
|
|
51
|
+
]);
|
|
52
|
+
var rendererAccelerationStructureUpdateClasses = Object.freeze([
|
|
53
|
+
"static",
|
|
54
|
+
"rigid-dynamic",
|
|
55
|
+
"deforming",
|
|
56
|
+
"proxy"
|
|
57
|
+
]);
|
|
58
|
+
var rendererRayTracingStageOrder = Object.freeze([
|
|
59
|
+
"primaryVisibility",
|
|
60
|
+
"shadowAssist",
|
|
61
|
+
"opaqueFoundation",
|
|
62
|
+
"rtDirectLighting",
|
|
63
|
+
"rtReflections",
|
|
64
|
+
"rtGlobalIllumination",
|
|
65
|
+
"denoiseTemporal",
|
|
66
|
+
"transparents",
|
|
67
|
+
"composition",
|
|
68
|
+
"present"
|
|
69
|
+
]);
|
|
70
|
+
var rendererRayTracingStageDefinitions = Object.freeze(
|
|
71
|
+
rendererRayTracingStageOrder.map(
|
|
72
|
+
(key, index) => Object.freeze({
|
|
73
|
+
key,
|
|
74
|
+
order: index + 1,
|
|
75
|
+
required: true,
|
|
76
|
+
description: {
|
|
77
|
+
primaryVisibility: "Primary visibility and depth preparation.",
|
|
78
|
+
shadowAssist: "Shadow assist passes and regional shadow preparation.",
|
|
79
|
+
opaqueFoundation: "Main opaque foundation for shading and tracing inputs.",
|
|
80
|
+
rtDirectLighting: "Ray-traced direct lighting and premium shadows.",
|
|
81
|
+
rtReflections: "Ray-traced reflections for important surfaces.",
|
|
82
|
+
rtGlobalIllumination: "Selective ray-traced indirect lighting and GI.",
|
|
83
|
+
denoiseTemporal: "Required denoise and temporal accumulation stage.",
|
|
84
|
+
transparents: "Transparents, particles, and volumetrics composition.",
|
|
85
|
+
composition: "Final world composition and color resolve.",
|
|
86
|
+
present: "Presentation to the active surface."
|
|
87
|
+
}[key]
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
var rendererRepresentationBandPolicies = Object.freeze({
|
|
92
|
+
near: Object.freeze({
|
|
93
|
+
band: "near",
|
|
94
|
+
rasterMode: "full-live",
|
|
95
|
+
rtParticipation: "premium",
|
|
96
|
+
shadowSource: "ray-traced-primary",
|
|
97
|
+
temporalReuse: "balanced",
|
|
98
|
+
updateCadenceDivisor: 1
|
|
99
|
+
}),
|
|
100
|
+
mid: Object.freeze({
|
|
101
|
+
band: "mid",
|
|
102
|
+
rasterMode: "simplified-live",
|
|
103
|
+
rtParticipation: "selective",
|
|
104
|
+
shadowSource: "regional-raster-and-proxy",
|
|
105
|
+
temporalReuse: "aggressive",
|
|
106
|
+
updateCadenceDivisor: 2
|
|
107
|
+
}),
|
|
108
|
+
far: Object.freeze({
|
|
109
|
+
band: "far",
|
|
110
|
+
rasterMode: "proxy-or-cached",
|
|
111
|
+
rtParticipation: "proxy",
|
|
112
|
+
shadowSource: "merged-proxy-casters",
|
|
113
|
+
temporalReuse: "high",
|
|
114
|
+
updateCadenceDivisor: 8
|
|
115
|
+
}),
|
|
116
|
+
horizon: Object.freeze({
|
|
117
|
+
band: "horizon",
|
|
118
|
+
rasterMode: "horizon-shell",
|
|
119
|
+
rtParticipation: "disabled",
|
|
120
|
+
shadowSource: "baked-impression",
|
|
121
|
+
temporalReuse: "cached",
|
|
122
|
+
updateCadenceDivisor: 60
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
var rendererAccelerationStructurePolicies = Object.freeze(
|
|
126
|
+
rendererAccelerationStructureUpdateClasses.map(
|
|
127
|
+
(updateClass) => Object.freeze({
|
|
128
|
+
updateClass,
|
|
129
|
+
description: {
|
|
130
|
+
static: "Stable static world geometry with infrequent rebuilds.",
|
|
131
|
+
"rigid-dynamic": "Rigid transforms that can be refit or relinked without full deformation updates.",
|
|
132
|
+
deforming: "Skinned or vertex-deforming content treated as a managed RT cost center.",
|
|
133
|
+
proxy: "Low-cost RT proxy or distant representation updates."
|
|
134
|
+
}[updateClass]
|
|
135
|
+
})
|
|
136
|
+
)
|
|
137
|
+
);
|
|
138
|
+
function buildRendererWorkerBudgetLevels(jobType, queueClass, levels) {
|
|
139
|
+
return Object.freeze(
|
|
140
|
+
levels.map(
|
|
141
|
+
(level) => Object.freeze({
|
|
142
|
+
id: level.id,
|
|
143
|
+
estimatedCostMs: level.estimatedCostMs,
|
|
144
|
+
config: Object.freeze({
|
|
145
|
+
maxDispatchesPerFrame: level.config.maxDispatchesPerFrame,
|
|
146
|
+
maxJobsPerDispatch: level.config.maxJobsPerDispatch,
|
|
147
|
+
cadenceDivisor: level.config.cadenceDivisor,
|
|
148
|
+
workgroupScale: level.config.workgroupScale,
|
|
149
|
+
maxQueueDepth: level.config.maxQueueDepth,
|
|
150
|
+
metadata: Object.freeze({
|
|
151
|
+
owner: rendererDebugOwner,
|
|
152
|
+
queueClass,
|
|
153
|
+
jobType,
|
|
154
|
+
quality: level.id
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
)
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
var rendererWorkerProfileSpecs = {
|
|
162
|
+
realtime: {
|
|
163
|
+
description: "Frame-stage DAG for flat rendering with visibility, main encode, post-processing, and submit.",
|
|
164
|
+
suggestedAllocationIds: [
|
|
165
|
+
"renderer.surface.current",
|
|
166
|
+
"renderer.visibility.worklist",
|
|
167
|
+
"renderer.post-process.history"
|
|
168
|
+
],
|
|
169
|
+
jobs: {
|
|
170
|
+
acquire: {
|
|
171
|
+
priority: 5,
|
|
172
|
+
dependencies: [],
|
|
173
|
+
domain: "resolution",
|
|
174
|
+
importance: "critical",
|
|
175
|
+
levels: [
|
|
176
|
+
{
|
|
177
|
+
id: "fixed",
|
|
178
|
+
estimatedCostMs: 0.2,
|
|
179
|
+
config: {
|
|
180
|
+
maxDispatchesPerFrame: 1,
|
|
181
|
+
maxJobsPerDispatch: 1,
|
|
182
|
+
cadenceDivisor: 1,
|
|
183
|
+
workgroupScale: 1,
|
|
184
|
+
maxQueueDepth: 1
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
suggestedAllocationIds: ["renderer.surface.current"]
|
|
189
|
+
},
|
|
190
|
+
visibility: {
|
|
191
|
+
priority: 4,
|
|
192
|
+
dependencies: [],
|
|
193
|
+
domain: "geometry",
|
|
194
|
+
importance: "high",
|
|
195
|
+
levels: [
|
|
196
|
+
{
|
|
197
|
+
id: "low",
|
|
198
|
+
estimatedCostMs: 0.4,
|
|
199
|
+
config: {
|
|
200
|
+
maxDispatchesPerFrame: 1,
|
|
201
|
+
maxJobsPerDispatch: 128,
|
|
202
|
+
cadenceDivisor: 2,
|
|
203
|
+
workgroupScale: 0.5,
|
|
204
|
+
maxQueueDepth: 256
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: "medium",
|
|
209
|
+
estimatedCostMs: 0.8,
|
|
210
|
+
config: {
|
|
211
|
+
maxDispatchesPerFrame: 1,
|
|
212
|
+
maxJobsPerDispatch: 256,
|
|
213
|
+
cadenceDivisor: 1,
|
|
214
|
+
workgroupScale: 0.75,
|
|
215
|
+
maxQueueDepth: 384
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
id: "high",
|
|
220
|
+
estimatedCostMs: 1.2,
|
|
221
|
+
config: {
|
|
222
|
+
maxDispatchesPerFrame: 2,
|
|
223
|
+
maxJobsPerDispatch: 512,
|
|
224
|
+
cadenceDivisor: 1,
|
|
225
|
+
workgroupScale: 1,
|
|
226
|
+
maxQueueDepth: 512
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
],
|
|
230
|
+
suggestedAllocationIds: ["renderer.visibility.worklist"]
|
|
231
|
+
},
|
|
232
|
+
mainEncode: {
|
|
233
|
+
priority: 4,
|
|
234
|
+
dependencies: ["acquire", "visibility"],
|
|
235
|
+
domain: "geometry",
|
|
236
|
+
importance: "critical",
|
|
237
|
+
levels: [
|
|
238
|
+
{
|
|
239
|
+
id: "low",
|
|
240
|
+
estimatedCostMs: 1.2,
|
|
241
|
+
config: {
|
|
242
|
+
maxDispatchesPerFrame: 1,
|
|
243
|
+
maxJobsPerDispatch: 128,
|
|
244
|
+
cadenceDivisor: 1,
|
|
245
|
+
workgroupScale: 0.6,
|
|
246
|
+
maxQueueDepth: 192
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
id: "medium",
|
|
251
|
+
estimatedCostMs: 2.1,
|
|
252
|
+
config: {
|
|
253
|
+
maxDispatchesPerFrame: 1,
|
|
254
|
+
maxJobsPerDispatch: 256,
|
|
255
|
+
cadenceDivisor: 1,
|
|
256
|
+
workgroupScale: 0.8,
|
|
257
|
+
maxQueueDepth: 256
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: "high",
|
|
262
|
+
estimatedCostMs: 3,
|
|
263
|
+
config: {
|
|
264
|
+
maxDispatchesPerFrame: 1,
|
|
265
|
+
maxJobsPerDispatch: 384,
|
|
266
|
+
cadenceDivisor: 1,
|
|
267
|
+
workgroupScale: 1,
|
|
268
|
+
maxQueueDepth: 384
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
],
|
|
272
|
+
suggestedAllocationIds: ["renderer.surface.current"]
|
|
273
|
+
},
|
|
274
|
+
postProcess: {
|
|
275
|
+
priority: 3,
|
|
276
|
+
dependencies: ["mainEncode"],
|
|
277
|
+
domain: "post-processing",
|
|
278
|
+
importance: "high",
|
|
279
|
+
levels: [
|
|
280
|
+
{
|
|
281
|
+
id: "low",
|
|
282
|
+
estimatedCostMs: 0.5,
|
|
283
|
+
config: {
|
|
284
|
+
maxDispatchesPerFrame: 1,
|
|
285
|
+
maxJobsPerDispatch: 64,
|
|
286
|
+
cadenceDivisor: 2,
|
|
287
|
+
workgroupScale: 0.5,
|
|
288
|
+
maxQueueDepth: 96
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
id: "medium",
|
|
293
|
+
estimatedCostMs: 0.9,
|
|
294
|
+
config: {
|
|
295
|
+
maxDispatchesPerFrame: 1,
|
|
296
|
+
maxJobsPerDispatch: 128,
|
|
297
|
+
cadenceDivisor: 1,
|
|
298
|
+
workgroupScale: 0.75,
|
|
299
|
+
maxQueueDepth: 128
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
id: "high",
|
|
304
|
+
estimatedCostMs: 1.4,
|
|
305
|
+
config: {
|
|
306
|
+
maxDispatchesPerFrame: 2,
|
|
307
|
+
maxJobsPerDispatch: 192,
|
|
308
|
+
cadenceDivisor: 1,
|
|
309
|
+
workgroupScale: 1,
|
|
310
|
+
maxQueueDepth: 192
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
],
|
|
314
|
+
suggestedAllocationIds: ["renderer.post-process.history"]
|
|
315
|
+
},
|
|
316
|
+
submit: {
|
|
317
|
+
priority: 2,
|
|
318
|
+
dependencies: ["postProcess"],
|
|
319
|
+
domain: "resolution",
|
|
320
|
+
importance: "critical",
|
|
321
|
+
levels: [
|
|
322
|
+
{
|
|
323
|
+
id: "fixed",
|
|
324
|
+
estimatedCostMs: 0.2,
|
|
325
|
+
config: {
|
|
326
|
+
maxDispatchesPerFrame: 1,
|
|
327
|
+
maxJobsPerDispatch: 1,
|
|
328
|
+
cadenceDivisor: 1,
|
|
329
|
+
workgroupScale: 1,
|
|
330
|
+
maxQueueDepth: 1
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
],
|
|
334
|
+
suggestedAllocationIds: ["renderer.surface.current"]
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
xr: {
|
|
339
|
+
description: "Frame-stage DAG for XR rendering with late-latch coordination before main encode and submit.",
|
|
340
|
+
suggestedAllocationIds: [
|
|
341
|
+
"renderer.xr.surface.current",
|
|
342
|
+
"renderer.xr.visibility.worklist"
|
|
343
|
+
],
|
|
344
|
+
jobs: {
|
|
345
|
+
acquire: {
|
|
346
|
+
priority: 5,
|
|
347
|
+
dependencies: [],
|
|
348
|
+
domain: "xr",
|
|
349
|
+
importance: "critical",
|
|
350
|
+
levels: [
|
|
351
|
+
{
|
|
352
|
+
id: "fixed",
|
|
353
|
+
estimatedCostMs: 0.2,
|
|
354
|
+
config: {
|
|
355
|
+
maxDispatchesPerFrame: 1,
|
|
356
|
+
maxJobsPerDispatch: 1,
|
|
357
|
+
cadenceDivisor: 1,
|
|
358
|
+
workgroupScale: 1,
|
|
359
|
+
maxQueueDepth: 1
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
],
|
|
363
|
+
suggestedAllocationIds: ["renderer.xr.surface.current"]
|
|
364
|
+
},
|
|
365
|
+
visibility: {
|
|
366
|
+
priority: 4,
|
|
367
|
+
dependencies: [],
|
|
368
|
+
domain: "geometry",
|
|
369
|
+
importance: "high",
|
|
370
|
+
levels: [
|
|
371
|
+
{
|
|
372
|
+
id: "low",
|
|
373
|
+
estimatedCostMs: 0.5,
|
|
374
|
+
config: {
|
|
375
|
+
maxDispatchesPerFrame: 1,
|
|
376
|
+
maxJobsPerDispatch: 96,
|
|
377
|
+
cadenceDivisor: 2,
|
|
378
|
+
workgroupScale: 0.5,
|
|
379
|
+
maxQueueDepth: 192
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
id: "medium",
|
|
384
|
+
estimatedCostMs: 0.9,
|
|
385
|
+
config: {
|
|
386
|
+
maxDispatchesPerFrame: 1,
|
|
387
|
+
maxJobsPerDispatch: 192,
|
|
388
|
+
cadenceDivisor: 1,
|
|
389
|
+
workgroupScale: 0.75,
|
|
390
|
+
maxQueueDepth: 256
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
id: "high",
|
|
395
|
+
estimatedCostMs: 1.3,
|
|
396
|
+
config: {
|
|
397
|
+
maxDispatchesPerFrame: 2,
|
|
398
|
+
maxJobsPerDispatch: 320,
|
|
399
|
+
cadenceDivisor: 1,
|
|
400
|
+
workgroupScale: 1,
|
|
401
|
+
maxQueueDepth: 320
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
],
|
|
405
|
+
suggestedAllocationIds: ["renderer.xr.visibility.worklist"]
|
|
406
|
+
},
|
|
407
|
+
lateLatch: {
|
|
408
|
+
priority: 5,
|
|
409
|
+
dependencies: ["acquire"],
|
|
410
|
+
domain: "xr",
|
|
411
|
+
importance: "critical",
|
|
412
|
+
levels: [
|
|
413
|
+
{
|
|
414
|
+
id: "fixed",
|
|
415
|
+
estimatedCostMs: 0.15,
|
|
416
|
+
config: {
|
|
417
|
+
maxDispatchesPerFrame: 1,
|
|
418
|
+
maxJobsPerDispatch: 1,
|
|
419
|
+
cadenceDivisor: 1,
|
|
420
|
+
workgroupScale: 1,
|
|
421
|
+
maxQueueDepth: 1
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
],
|
|
425
|
+
suggestedAllocationIds: ["renderer.xr.surface.current"]
|
|
426
|
+
},
|
|
427
|
+
mainEncode: {
|
|
428
|
+
priority: 4,
|
|
429
|
+
dependencies: ["visibility", "lateLatch"],
|
|
430
|
+
domain: "xr",
|
|
431
|
+
importance: "critical",
|
|
432
|
+
levels: [
|
|
433
|
+
{
|
|
434
|
+
id: "low",
|
|
435
|
+
estimatedCostMs: 1.1,
|
|
436
|
+
config: {
|
|
437
|
+
maxDispatchesPerFrame: 1,
|
|
438
|
+
maxJobsPerDispatch: 96,
|
|
439
|
+
cadenceDivisor: 1,
|
|
440
|
+
workgroupScale: 0.6,
|
|
441
|
+
maxQueueDepth: 128
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
id: "medium",
|
|
446
|
+
estimatedCostMs: 1.8,
|
|
447
|
+
config: {
|
|
448
|
+
maxDispatchesPerFrame: 1,
|
|
449
|
+
maxJobsPerDispatch: 192,
|
|
450
|
+
cadenceDivisor: 1,
|
|
451
|
+
workgroupScale: 0.8,
|
|
452
|
+
maxQueueDepth: 192
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
id: "high",
|
|
457
|
+
estimatedCostMs: 2.6,
|
|
458
|
+
config: {
|
|
459
|
+
maxDispatchesPerFrame: 1,
|
|
460
|
+
maxJobsPerDispatch: 256,
|
|
461
|
+
cadenceDivisor: 1,
|
|
462
|
+
workgroupScale: 1,
|
|
463
|
+
maxQueueDepth: 256
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
],
|
|
467
|
+
suggestedAllocationIds: ["renderer.xr.surface.current"]
|
|
468
|
+
},
|
|
469
|
+
submit: {
|
|
470
|
+
priority: 2,
|
|
471
|
+
dependencies: ["mainEncode"],
|
|
472
|
+
domain: "xr",
|
|
473
|
+
importance: "critical",
|
|
474
|
+
levels: [
|
|
475
|
+
{
|
|
476
|
+
id: "fixed",
|
|
477
|
+
estimatedCostMs: 0.2,
|
|
478
|
+
config: {
|
|
479
|
+
maxDispatchesPerFrame: 1,
|
|
480
|
+
maxJobsPerDispatch: 1,
|
|
481
|
+
cadenceDivisor: 1,
|
|
482
|
+
workgroupScale: 1,
|
|
483
|
+
maxQueueDepth: 1
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
],
|
|
487
|
+
suggestedAllocationIds: ["renderer.xr.surface.current"]
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
function buildRendererInputBoundary(profile) {
|
|
493
|
+
return Object.freeze({
|
|
494
|
+
type: "stable-visual-snapshot",
|
|
495
|
+
owner: rendererDebugOwner,
|
|
496
|
+
profile,
|
|
497
|
+
authority: "visual",
|
|
498
|
+
source: "scene-preparation",
|
|
499
|
+
stable: true
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
function buildRendererRenderStages(profile) {
|
|
503
|
+
return Object.freeze(
|
|
504
|
+
rendererRayTracingStageDefinitions.map(
|
|
505
|
+
(stage) => Object.freeze({
|
|
506
|
+
...stage,
|
|
507
|
+
profile,
|
|
508
|
+
workerJobKeys: profile === "xr" && stage.key === "primaryVisibility" ? Object.freeze(["lateLatch", "visibility"]) : stage.key === "present" ? Object.freeze(["submit"]) : stage.key === "denoiseTemporal" || stage.key === "transparents" || stage.key === "composition" ? Object.freeze(["postProcess"]) : stage.key === "primaryVisibility" ? Object.freeze(["visibility"]) : stage.key === "shadowAssist" || stage.key === "opaqueFoundation" || stage.key === "rtDirectLighting" || stage.key === "rtReflections" || stage.key === "rtGlobalIllumination" ? Object.freeze(["mainEncode"]) : Object.freeze(["mainEncode"])
|
|
509
|
+
})
|
|
510
|
+
)
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
function buildRendererRepresentationBands(profile) {
|
|
514
|
+
return Object.freeze(
|
|
515
|
+
rendererRepresentationBands.map(
|
|
516
|
+
(band) => Object.freeze({
|
|
517
|
+
...rendererRepresentationBandPolicies[band],
|
|
518
|
+
profile
|
|
519
|
+
})
|
|
520
|
+
)
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
function buildRendererAccelerationStructureUpdates(profile) {
|
|
524
|
+
return Object.freeze(
|
|
525
|
+
rendererAccelerationStructurePolicies.map(
|
|
526
|
+
(policy) => Object.freeze({
|
|
527
|
+
...policy,
|
|
528
|
+
profile
|
|
529
|
+
})
|
|
530
|
+
)
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
function assertRendererIdentifier(name, value) {
|
|
534
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
535
|
+
throw new Error(`${name} must be a non-empty string.`);
|
|
536
|
+
}
|
|
537
|
+
return value.trim();
|
|
538
|
+
}
|
|
539
|
+
function buildRendererWorkerProfile(name, spec) {
|
|
540
|
+
return Object.freeze({
|
|
541
|
+
name,
|
|
542
|
+
description: spec.description,
|
|
543
|
+
jobs: Object.freeze(Object.keys(spec.jobs))
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
function buildRendererWorkerManifestJob(profileName, jobName, spec) {
|
|
547
|
+
const label = `renderer.${profileName}.${jobName}`;
|
|
548
|
+
return Object.freeze({
|
|
549
|
+
key: jobName,
|
|
550
|
+
label,
|
|
551
|
+
worker: Object.freeze({
|
|
552
|
+
jobType: label,
|
|
553
|
+
queueClass: rendererWorkerQueueClass,
|
|
554
|
+
priority: spec.priority,
|
|
555
|
+
dependencies: Object.freeze(
|
|
556
|
+
spec.dependencies.map((dependency) => `renderer.${profileName}.${dependency}`)
|
|
557
|
+
),
|
|
558
|
+
schedulerMode: "dag"
|
|
559
|
+
}),
|
|
560
|
+
performance: Object.freeze({
|
|
561
|
+
id: label,
|
|
562
|
+
jobType: label,
|
|
563
|
+
queueClass: rendererWorkerQueueClass,
|
|
564
|
+
domain: spec.domain,
|
|
565
|
+
authority: "visual",
|
|
566
|
+
importance: spec.importance,
|
|
567
|
+
levels: buildRendererWorkerBudgetLevels(
|
|
568
|
+
label,
|
|
569
|
+
rendererWorkerQueueClass,
|
|
570
|
+
spec.levels
|
|
571
|
+
)
|
|
572
|
+
}),
|
|
573
|
+
debug: Object.freeze({
|
|
574
|
+
owner: rendererDebugOwner,
|
|
575
|
+
queueClass: rendererWorkerQueueClass,
|
|
576
|
+
jobType: label,
|
|
577
|
+
tags: Object.freeze(["renderer", profileName, jobName, spec.domain]),
|
|
578
|
+
suggestedAllocationIds: Object.freeze([...spec.suggestedAllocationIds])
|
|
579
|
+
})
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
function buildRendererWorkerManifest(name, spec) {
|
|
583
|
+
return Object.freeze({
|
|
584
|
+
schemaVersion: 1,
|
|
585
|
+
owner: rendererDebugOwner,
|
|
586
|
+
profile: name,
|
|
587
|
+
description: spec.description,
|
|
588
|
+
queueClass: rendererWorkerQueueClass,
|
|
589
|
+
schedulerMode: "dag",
|
|
590
|
+
inputBoundary: buildRendererInputBoundary(name),
|
|
591
|
+
renderStages: buildRendererRenderStages(name),
|
|
592
|
+
representationBands: buildRendererRepresentationBands(name),
|
|
593
|
+
accelerationStructureUpdates: buildRendererAccelerationStructureUpdates(name),
|
|
594
|
+
suggestedAllocationIds: Object.freeze([...spec.suggestedAllocationIds]),
|
|
595
|
+
jobs: Object.freeze(
|
|
596
|
+
Object.entries(spec.jobs).map(
|
|
597
|
+
([jobName, jobSpec]) => buildRendererWorkerManifestJob(name, jobName, jobSpec)
|
|
598
|
+
)
|
|
599
|
+
)
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
var rendererWorkerProfiles = Object.freeze(
|
|
603
|
+
Object.fromEntries(
|
|
604
|
+
Object.entries(rendererWorkerProfileSpecs).map(([name, spec]) => [
|
|
605
|
+
name,
|
|
606
|
+
buildRendererWorkerProfile(name, spec)
|
|
607
|
+
])
|
|
608
|
+
)
|
|
609
|
+
);
|
|
610
|
+
var rendererWorkerProfileNames = Object.freeze(
|
|
611
|
+
Object.keys(rendererWorkerProfiles)
|
|
612
|
+
);
|
|
613
|
+
var rendererWorkerManifests = Object.freeze(
|
|
614
|
+
Object.fromEntries(
|
|
615
|
+
Object.entries(rendererWorkerProfileSpecs).map(([name, spec]) => [
|
|
616
|
+
name,
|
|
617
|
+
buildRendererWorkerManifest(name, spec)
|
|
618
|
+
])
|
|
619
|
+
)
|
|
620
|
+
);
|
|
621
|
+
function getRendererWorkerProfile(name = defaultRendererWorkerProfile) {
|
|
622
|
+
const profile = rendererWorkerProfiles[name];
|
|
623
|
+
if (!profile) {
|
|
624
|
+
const available = rendererWorkerProfileNames.join(", ");
|
|
625
|
+
throw new Error(`Unknown renderer worker profile "${name}". Available: ${available}.`);
|
|
626
|
+
}
|
|
627
|
+
return profile;
|
|
628
|
+
}
|
|
629
|
+
function getRendererWorkerManifest(name = defaultRendererWorkerProfile) {
|
|
630
|
+
const manifest = rendererWorkerManifests[name];
|
|
631
|
+
if (!manifest) {
|
|
632
|
+
const available = rendererWorkerProfileNames.join(", ");
|
|
633
|
+
throw new Error(`Unknown renderer worker profile "${name}". Available: ${available}.`);
|
|
634
|
+
}
|
|
635
|
+
return manifest;
|
|
636
|
+
}
|
|
637
|
+
function createRayTracingRenderPlan(options = {}) {
|
|
638
|
+
const profile = options.profile ?? defaultRendererWorkerProfile;
|
|
639
|
+
const snapshotId = assertRendererIdentifier(
|
|
640
|
+
"snapshotId",
|
|
641
|
+
options.snapshotId
|
|
642
|
+
);
|
|
643
|
+
const workerManifest = getRendererWorkerManifest(profile);
|
|
644
|
+
const representations = Array.isArray(options.representations) ? Object.freeze(
|
|
645
|
+
options.representations.map((representation, index) => {
|
|
646
|
+
if (!representation || typeof representation !== "object") {
|
|
647
|
+
throw new Error(`representations[${index}] must be an object.`);
|
|
648
|
+
}
|
|
649
|
+
const band = assertRendererIdentifier(
|
|
650
|
+
`representations[${index}].band`,
|
|
651
|
+
representation.band
|
|
652
|
+
);
|
|
653
|
+
if (!rendererRepresentationBands.includes(band)) {
|
|
654
|
+
throw new Error(
|
|
655
|
+
`representations[${index}].band must be one of: ${rendererRepresentationBands.join(", ")}.`
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
return Object.freeze({
|
|
659
|
+
...representation,
|
|
660
|
+
band
|
|
661
|
+
});
|
|
662
|
+
})
|
|
663
|
+
) : workerManifest.representationBands;
|
|
664
|
+
return Object.freeze({
|
|
665
|
+
schemaVersion: 1,
|
|
666
|
+
owner: rendererDebugOwner,
|
|
667
|
+
profile,
|
|
668
|
+
inputBoundary: Object.freeze({
|
|
669
|
+
...workerManifest.inputBoundary,
|
|
670
|
+
snapshotId
|
|
671
|
+
}),
|
|
672
|
+
renderStages: workerManifest.renderStages,
|
|
673
|
+
representationBands: representations,
|
|
674
|
+
accelerationStructureUpdates: workerManifest.accelerationStructureUpdates,
|
|
675
|
+
workerManifest
|
|
676
|
+
});
|
|
677
|
+
}
|
|
30
678
|
function clamp01(value) {
|
|
31
679
|
return Math.min(1, Math.max(0, value));
|
|
32
680
|
}
|
|
@@ -62,12 +710,111 @@ function normalizeColor(value) {
|
|
|
62
710
|
}
|
|
63
711
|
return [...DEFAULT_CLEAR_COLOR];
|
|
64
712
|
}
|
|
713
|
+
function readPositiveNumber(name, value) {
|
|
714
|
+
if (value === void 0) {
|
|
715
|
+
return void 0;
|
|
716
|
+
}
|
|
717
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
718
|
+
throw new Error(`${name} must be a finite number greater than zero.`);
|
|
719
|
+
}
|
|
720
|
+
return value;
|
|
721
|
+
}
|
|
65
722
|
function now() {
|
|
66
723
|
if (typeof performance !== "undefined" && typeof performance.now === "function") {
|
|
67
724
|
return performance.now();
|
|
68
725
|
}
|
|
69
726
|
return Date.now();
|
|
70
727
|
}
|
|
728
|
+
function normalizeFrameId(value) {
|
|
729
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
730
|
+
throw new Error("frameIdFactory must return a non-empty string.");
|
|
731
|
+
}
|
|
732
|
+
return value.trim();
|
|
733
|
+
}
|
|
734
|
+
function resolveTargetFrameTimeMs(options, event) {
|
|
735
|
+
const {
|
|
736
|
+
targetFrameTimeMs: fixedTargetFrameTimeMs,
|
|
737
|
+
targetFrameRate,
|
|
738
|
+
getTargetFrameTimeMs
|
|
739
|
+
} = options;
|
|
740
|
+
if (typeof getTargetFrameTimeMs === "function") {
|
|
741
|
+
const resolved = getTargetFrameTimeMs(event);
|
|
742
|
+
return readPositiveNumber("getTargetFrameTimeMs()", resolved);
|
|
743
|
+
}
|
|
744
|
+
if (fixedTargetFrameTimeMs !== void 0) {
|
|
745
|
+
return fixedTargetFrameTimeMs;
|
|
746
|
+
}
|
|
747
|
+
if (targetFrameRate !== void 0) {
|
|
748
|
+
return 1e3 / targetFrameRate;
|
|
749
|
+
}
|
|
750
|
+
return void 0;
|
|
751
|
+
}
|
|
752
|
+
function createRendererDebugHooks(options = {}) {
|
|
753
|
+
const {
|
|
754
|
+
debugSession,
|
|
755
|
+
targetFrameTimeMs,
|
|
756
|
+
targetFrameRate,
|
|
757
|
+
getTargetFrameTimeMs,
|
|
758
|
+
onFrameStart,
|
|
759
|
+
onFrameComplete
|
|
760
|
+
} = options;
|
|
761
|
+
if (!debugSession || typeof debugSession.recordFrame !== "function") {
|
|
762
|
+
throw new Error(
|
|
763
|
+
"debugSession must expose recordFrame(sample). Use @plasius/gpu-debug createGpuDebugSession()."
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
const fixedTargetFrameTimeMs = readPositiveNumber(
|
|
767
|
+
"targetFrameTimeMs",
|
|
768
|
+
targetFrameTimeMs
|
|
769
|
+
);
|
|
770
|
+
const fixedTargetFrameRate = readPositiveNumber(
|
|
771
|
+
"targetFrameRate",
|
|
772
|
+
targetFrameRate
|
|
773
|
+
);
|
|
774
|
+
if (fixedTargetFrameTimeMs !== void 0 && fixedTargetFrameRate !== void 0) {
|
|
775
|
+
throw new Error(
|
|
776
|
+
"Provide either targetFrameTimeMs or targetFrameRate, not both."
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
if (getTargetFrameTimeMs !== void 0 && typeof getTargetFrameTimeMs !== "function") {
|
|
780
|
+
throw new Error("getTargetFrameTimeMs must be a function when provided.");
|
|
781
|
+
}
|
|
782
|
+
const resolvedOptions = {
|
|
783
|
+
targetFrameTimeMs: fixedTargetFrameTimeMs,
|
|
784
|
+
targetFrameRate: fixedTargetFrameRate,
|
|
785
|
+
getTargetFrameTimeMs
|
|
786
|
+
};
|
|
787
|
+
return {
|
|
788
|
+
onFrameStart(event) {
|
|
789
|
+
if (typeof onFrameStart === "function") {
|
|
790
|
+
onFrameStart({
|
|
791
|
+
...event,
|
|
792
|
+
owner: rendererDebugOwner
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
onFrameComplete(event) {
|
|
797
|
+
const resolvedTargetFrameTimeMs = resolveTargetFrameTimeMs(
|
|
798
|
+
resolvedOptions,
|
|
799
|
+
event
|
|
800
|
+
);
|
|
801
|
+
if (typeof event.frameTimeMs === "number" && Number.isFinite(event.frameTimeMs) && event.frameTimeMs > 0) {
|
|
802
|
+
debugSession.recordFrame({
|
|
803
|
+
frameId: event.frameId,
|
|
804
|
+
frameTimeMs: event.frameTimeMs,
|
|
805
|
+
targetFrameTimeMs: resolvedTargetFrameTimeMs
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
if (typeof onFrameComplete === "function") {
|
|
809
|
+
onFrameComplete({
|
|
810
|
+
...event,
|
|
811
|
+
owner: rendererDebugOwner,
|
|
812
|
+
targetFrameTimeMs: resolvedTargetFrameTimeMs
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
}
|
|
71
818
|
function readNavigator(navigatorOverride) {
|
|
72
819
|
const currentNavigator = navigatorOverride ?? globalThis.navigator;
|
|
73
820
|
if (!currentNavigator || typeof currentNavigator !== "object") {
|
|
@@ -148,8 +895,11 @@ async function createGpuRenderer(options = {}) {
|
|
|
148
895
|
clearColor = DEFAULT_CLEAR_COLOR,
|
|
149
896
|
requestAnimationFrame = globalThis.requestAnimationFrame?.bind(globalThis),
|
|
150
897
|
cancelAnimationFrame = globalThis.cancelAnimationFrame?.bind(globalThis),
|
|
898
|
+
frameIdFactory,
|
|
899
|
+
onFrameStart,
|
|
151
900
|
onBeforeEncode,
|
|
152
|
-
onAfterSubmit
|
|
901
|
+
onAfterSubmit,
|
|
902
|
+
onFrameComplete
|
|
153
903
|
} = options;
|
|
154
904
|
const gpu = readGpu(navigatorOverride);
|
|
155
905
|
const adapter = await gpu.requestAdapter({ powerPreference });
|
|
@@ -176,6 +926,28 @@ async function createGpuRenderer(options = {}) {
|
|
|
176
926
|
if (destroyed) {
|
|
177
927
|
throw new Error("Renderer was destroyed.");
|
|
178
928
|
}
|
|
929
|
+
const frameNumber = frame + 1;
|
|
930
|
+
const frameId = normalizeFrameId(
|
|
931
|
+
typeof frameIdFactory === "function" ? frameIdFactory({
|
|
932
|
+
frame: frameNumber,
|
|
933
|
+
timestamp,
|
|
934
|
+
canvas: targetCanvas,
|
|
935
|
+
xrActive
|
|
936
|
+
}) : `renderer.frame.${frameNumber}`
|
|
937
|
+
);
|
|
938
|
+
const frameTimeMs = lastTimestamp > 0 ? Math.max(0, timestamp - lastTimestamp) : void 0;
|
|
939
|
+
if (typeof onFrameStart === "function") {
|
|
940
|
+
onFrameStart({
|
|
941
|
+
frame: frameNumber,
|
|
942
|
+
frameId,
|
|
943
|
+
frameTimeMs,
|
|
944
|
+
timestamp,
|
|
945
|
+
device,
|
|
946
|
+
context,
|
|
947
|
+
canvas: targetCanvas,
|
|
948
|
+
xrActive
|
|
949
|
+
});
|
|
950
|
+
}
|
|
179
951
|
const texture = context.getCurrentTexture?.();
|
|
180
952
|
if (!texture || typeof texture.createView !== "function") {
|
|
181
953
|
throw new Error("WebGPU context returned an invalid current texture.");
|
|
@@ -188,12 +960,16 @@ async function createGpuRenderer(options = {}) {
|
|
|
188
960
|
if (typeof onBeforeEncode === "function") {
|
|
189
961
|
onBeforeEncode({
|
|
190
962
|
frame,
|
|
963
|
+
frameNumber,
|
|
964
|
+
frameId,
|
|
965
|
+
frameTimeMs,
|
|
191
966
|
timestamp,
|
|
192
967
|
device,
|
|
193
968
|
context,
|
|
194
969
|
encoder,
|
|
195
970
|
pass,
|
|
196
|
-
canvas: targetCanvas
|
|
971
|
+
canvas: targetCanvas,
|
|
972
|
+
xrActive
|
|
197
973
|
});
|
|
198
974
|
}
|
|
199
975
|
if (typeof pass.end === "function") {
|
|
@@ -201,19 +977,37 @@ async function createGpuRenderer(options = {}) {
|
|
|
201
977
|
}
|
|
202
978
|
const commandBuffer = encoder.finish();
|
|
203
979
|
device.queue.submit([commandBuffer]);
|
|
204
|
-
frame
|
|
980
|
+
frame = frameNumber;
|
|
205
981
|
lastTimestamp = timestamp;
|
|
206
982
|
if (typeof onAfterSubmit === "function") {
|
|
207
983
|
onAfterSubmit({
|
|
208
|
-
frame,
|
|
984
|
+
frame: frameNumber,
|
|
985
|
+
frameNumber,
|
|
986
|
+
frameId,
|
|
987
|
+
frameTimeMs,
|
|
988
|
+
timestamp,
|
|
989
|
+
device,
|
|
990
|
+
context,
|
|
991
|
+
canvas: targetCanvas,
|
|
992
|
+
xrActive
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
if (typeof onFrameComplete === "function") {
|
|
996
|
+
onFrameComplete({
|
|
997
|
+
frame: frameNumber,
|
|
998
|
+
frameId,
|
|
999
|
+
frameTimeMs,
|
|
209
1000
|
timestamp,
|
|
210
1001
|
device,
|
|
211
1002
|
context,
|
|
212
|
-
canvas: targetCanvas
|
|
1003
|
+
canvas: targetCanvas,
|
|
1004
|
+
xrActive
|
|
213
1005
|
});
|
|
214
1006
|
}
|
|
215
1007
|
return {
|
|
216
|
-
frame,
|
|
1008
|
+
frame: frameNumber,
|
|
1009
|
+
frameId,
|
|
1010
|
+
frameTimeMs,
|
|
217
1011
|
timestamp
|
|
218
1012
|
};
|
|
219
1013
|
};
|
|
@@ -355,7 +1149,20 @@ var defaultRendererClearColor = DEFAULT_CLEAR_COLOR;
|
|
|
355
1149
|
0 && (module.exports = {
|
|
356
1150
|
bindRendererToXrManager,
|
|
357
1151
|
createGpuRenderer,
|
|
1152
|
+
createRayTracingRenderPlan,
|
|
1153
|
+
createRendererDebugHooks,
|
|
358
1154
|
defaultRendererClearColor,
|
|
1155
|
+
defaultRendererWorkerProfile,
|
|
1156
|
+
getRendererWorkerManifest,
|
|
1157
|
+
getRendererWorkerProfile,
|
|
1158
|
+
rendererAccelerationStructureUpdateClasses,
|
|
1159
|
+
rendererDebugOwner,
|
|
1160
|
+
rendererRayTracingStageOrder,
|
|
1161
|
+
rendererRepresentationBands,
|
|
1162
|
+
rendererWorkerManifests,
|
|
1163
|
+
rendererWorkerProfileNames,
|
|
1164
|
+
rendererWorkerProfiles,
|
|
1165
|
+
rendererWorkerQueueClass,
|
|
359
1166
|
supportsWebGpu
|
|
360
1167
|
});
|
|
361
1168
|
//# sourceMappingURL=index.cjs.map
|