@aethervtt/shard-render 0.1.0 → 0.2.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.
Files changed (63) hide show
  1. package/dist/ablation.d.ts +74 -0
  2. package/dist/ablation.js +117 -0
  3. package/dist/atmosphere-nodes.js +100 -12
  4. package/dist/atmosphere-shaders.js +17 -5
  5. package/dist/baseline/exposure.d.ts +1 -1
  6. package/dist/baseline/exposure.js +18 -5
  7. package/dist/crowd.d.ts +21 -0
  8. package/dist/crowd.js +121 -0
  9. package/dist/decals-plugin.d.ts +5 -0
  10. package/dist/decals-plugin.js +54 -0
  11. package/dist/decals.d.ts +69 -0
  12. package/dist/decals.js +326 -0
  13. package/dist/deferred.js +4 -1
  14. package/dist/display-nodes.js +24 -11
  15. package/dist/foliage-budget.d.ts +64 -0
  16. package/dist/foliage-budget.js +108 -0
  17. package/dist/foliage-path.d.ts +19 -0
  18. package/dist/foliage-path.js +7 -0
  19. package/dist/foliage-shaders.d.ts +11 -0
  20. package/dist/foliage-shaders.js +504 -0
  21. package/dist/foliage.d.ts +194 -0
  22. package/dist/foliage.js +1027 -0
  23. package/dist/forward.js +26 -2
  24. package/dist/graph.d.ts +34 -0
  25. package/dist/graph.js +139 -14
  26. package/dist/index.d.ts +11 -1
  27. package/dist/index.js +57 -0
  28. package/dist/overlay-registry.d.ts +3 -1
  29. package/dist/overlay-registry.js +3 -1
  30. package/dist/overlays.js +5 -2
  31. package/dist/perf-overlay.d.ts +9 -0
  32. package/dist/perf-overlay.js +125 -0
  33. package/dist/plugin.d.ts +11 -1
  34. package/dist/plugin.js +33 -2
  35. package/dist/post-common.d.ts +20 -2
  36. package/dist/post-common.js +79 -2
  37. package/dist/post-nodes.d.ts +5 -0
  38. package/dist/post-nodes.js +136 -104
  39. package/dist/post-scene.d.ts +130 -0
  40. package/dist/post-scene.js +164 -0
  41. package/dist/post-shaders.js +41 -63
  42. package/dist/post.js +11 -1
  43. package/dist/ribbons-plugin.d.ts +5 -0
  44. package/dist/ribbons-plugin.js +59 -0
  45. package/dist/ribbons.d.ts +44 -0
  46. package/dist/ribbons.js +288 -0
  47. package/dist/scenario.d.ts +70 -0
  48. package/dist/scenario.js +125 -0
  49. package/dist/shaders.js +58 -5
  50. package/dist/shadows.d.ts +2 -1
  51. package/dist/shadows.js +3 -1
  52. package/dist/standard.js +6 -0
  53. package/dist/testing.d.ts +1 -0
  54. package/dist/testing.js +6 -0
  55. package/dist/timer.d.ts +16 -1
  56. package/dist/timer.js +66 -19
  57. package/dist/vfx-draw.d.ts +37 -0
  58. package/dist/vfx-draw.js +291 -0
  59. package/dist/vfx-state.d.ts +42 -0
  60. package/dist/vfx-state.js +81 -0
  61. package/dist/vfx.d.ts +69 -0
  62. package/dist/vfx.js +103 -0
  63. package/package.json +19 -11
package/dist/forward.js CHANGED
@@ -36,6 +36,7 @@ import { DataStore, dataEntry } from "./data-store.js";
36
36
  import { addDisplayNodes } from "./display-nodes.js";
37
37
  import { Environments, environmentParams } from "./environment-state.js";
38
38
  import { addRenderFeatures } from "./features.js";
39
+ import { FoliagePath } from "./foliage-path.js";
39
40
  import { GpuAssets, GpuAssetsResource } from "./gpu-assets.js";
40
41
  import { RenderPhase } from "./graph.js";
41
42
  import { clearHealthIssue, MaterialFallbacks, raiseHealthIssue } from "./health.js";
@@ -127,6 +128,15 @@ import { SkinAssetType, Skins } from "./skin-asset.js";
127
128
  import { GpuMemory, RenderCounters, RenderStats } from "./stats.js";
128
129
  import { bindingDimension } from "./tier.js";
129
130
  import { addShaderVariantSource, materialVariants, ShaderVariantSources } from "./variants.js";
131
+ import {
132
+ Beam,
133
+ Decal,
134
+ DecalReceiver,
135
+ DecalsPath,
136
+ observeVfxWithoutPlugin,
137
+ RibbonsPath,
138
+ Trail
139
+ } from "./vfx.js";
130
140
  import {
131
141
  CameraMoved,
132
142
  Cameras,
@@ -533,7 +543,7 @@ const PICK_TARGETS = [
533
543
  { format: "r32uint" },
534
544
  { format: "rgba32float" }
535
545
  ];
536
- const PREPASS_TARGETS = [{ format: "rgba16float" }, { format: "rg16float" }];
546
+ const PREPASS_TARGETS = [{ format: "rg16float" }, { format: "rg16float" }];
537
547
  function drawMaterials(ctx, state, pv, cam, draws, pass) {
538
548
  const store = ctx.world.resource(Instances);
539
549
  const assets = ctx.world.resource(GpuAssetsResource);
@@ -982,8 +992,12 @@ function cascadeNode(state) {
982
992
  const shadows = ctx.world.resource(ShadowsResource);
983
993
  const size = ctx.world.resource(LightingSettings).cascadeMapSize;
984
994
  const texture = pv.cascades.ensureTexture(ctx.gpu, size, ctx.view.name);
995
+ const foliage = ctx.world.tryResource(FoliagePath);
996
+ const cam = cameraOf(ctx.view);
997
+ const animated = foliage?.animatedShadows(cam) ?? false;
985
998
  for (let i = 0; i < pv.cascades.count; i++) {
986
999
  const view = pv.cascades.views[i];
1000
+ if (animated && i === 0) view.redraw = true;
987
1001
  if (!beginShadowView(ctx, view)) continue;
988
1002
  drawShadowCasters(
989
1003
  ctx,
@@ -993,7 +1007,10 @@ function cascadeNode(state) {
993
1007
  shadows.uniforms,
994
1008
  state.pipelines,
995
1009
  state.layouts.shadowView,
996
- `shadows/cascade${i}`
1010
+ `shadows/cascade${i}`,
1011
+ foliage,
1012
+ cam,
1013
+ i
997
1014
  );
998
1015
  endShadowView(ctx, view);
999
1016
  }
@@ -1387,6 +1404,12 @@ function forwardCorePlugin(options = {}) {
1387
1404
  RenderLayers,
1388
1405
  Outline,
1389
1406
  OutlinePath,
1407
+ Trail,
1408
+ Beam,
1409
+ Decal,
1410
+ DecalReceiver,
1411
+ RibbonsPath,
1412
+ DecalsPath,
1390
1413
  CameraMoved,
1391
1414
  // shadows
1392
1415
  ShadowsResource,
@@ -1436,6 +1459,7 @@ function forwardCorePlugin(options = {}) {
1436
1459
  w.initResource(RenderDescribers).set("screenEffects", describeScreenEffects);
1437
1460
  observeInstanceRemovals(w);
1438
1461
  observeOutlinesWithoutPass(w);
1462
+ observeVfxWithoutPlugin(w);
1439
1463
  observeViewVisibilityWithoutPlugin(w);
1440
1464
  observeLightRemovals(w);
1441
1465
  observeOriginShifts(w);
package/dist/graph.d.ts CHANGED
@@ -67,6 +67,11 @@ export interface NodeContext {
67
67
  /** Set for compute nodes. */
68
68
  readonly computePass: GPUComputePassEncoder | undefined;
69
69
  texture(name: string): GPUTexture;
70
+ /**
71
+ * Hands later nodes `texture` as resource `name` for the rest of this view's frame, instead of a
72
+ * pooled one: a node that keeps its output across frames (TAA's history) writes it once.
73
+ */
74
+ provide(name: string, texture: GPUTexture): void;
70
75
  /** Timestamp writes for a pass the node begins itself (raw nodes), labeled `name`. */
71
76
  timestamps(name: string): GPURenderPassTimestampWrites | undefined;
72
77
  /** Runs after the frame's commands are submitted (e.g. to map a readback buffer). */
@@ -85,6 +90,11 @@ export interface NodeDescriptor {
85
90
  phase?: number;
86
91
  /** Runs even if nothing reads its outputs. */
87
92
  sideEffects?: boolean;
93
+ /**
94
+ * Render nodes: always a render pass of its own, never shared with the nodes around it (see
95
+ * `continues`), so its GPU time is its own: what reads it (FoliageBudget's `gpu:foliage/*`) needs it.
96
+ */
97
+ ownPass?: boolean;
88
98
  /**
89
99
  * Whether the node runs for a view (e.g. only when the camera has the effect's component).
90
100
  * Disabled nodes are removed before resolving, so what they fed is culled too.
@@ -169,6 +179,13 @@ export declare class RenderGraph {
169
179
  /** Views rendered in the last frame, in order. */
170
180
  private lastViews;
171
181
  private readonly viewData;
182
+ /** Each node's `render/<node>` span and its CPU time this frame, summed over views (0074). */
183
+ private readonly nodeSlots;
184
+ private readonly nodeSpans;
185
+ private nodeMs;
186
+ private nodeRan;
187
+ /** Nodes disabled for measurement (0075): see `ablate`. */
188
+ private readonly ablatedNodes;
172
189
  constructor(gpu: GpuContext);
173
190
  /** Rejects pending captures and destroys the timer's query set (the app is being disposed). */
174
191
  dispose(): void;
@@ -177,6 +194,17 @@ export declare class RenderGraph {
177
194
  hasNode(name: string): boolean;
178
195
  /** Every node's name, in the order they were added. */
179
196
  nodeNames(): string[];
197
+ /**
198
+ * Disables nodes for measurement (0075's ablation), replacing the previous set; `[]` restores
199
+ * them. A disabled render or compute node still begins and ends its pass, with its attachments'
200
+ * clears, so the textures it writes stay valid for what reads them; only its `run` (its draws and
201
+ * dispatches) is skipped. A raw node, which begins its own passes, is skipped whole. The graph
202
+ * resolves as before: what the node fed still runs, on whatever its textures hold. The image is
203
+ * wrong while nodes are disabled. Throws `render/unknown-node` for a name the graph lacks.
204
+ */
205
+ ablate(names: Iterable<string>): void;
206
+ /** The nodes `ablate` disabled. */
207
+ ablated(): string[];
180
208
  /** The data of a view rendered in the last frame. */
181
209
  lastViewData(view: string): Record<string, unknown> | undefined;
182
210
  /** Declares a transient texture any node can write, read, or attach by name. */
@@ -185,6 +213,12 @@ export declare class RenderGraph {
185
213
  resolve(): ResolvedGraph;
186
214
  /** `off`: nodes that don't run on this device (features the baseline tier doesn't support). */
187
215
  private resolveFor;
216
+ /**
217
+ * Whether render node `order[k]` can draw in the pass `order[from]` began: the same color
218
+ * attachments, loaded rather than cleared, the same depth (written only if the pass writes it),
219
+ * and nothing it samples bound as an attachment.
220
+ */
221
+ private continues;
188
222
  /** Whether a node after `k` loads or reads `resource` (so its contents must be stored). */
189
223
  private loadedLater;
190
224
  /**
package/dist/graph.js CHANGED
@@ -1,4 +1,9 @@
1
- import { ShardError } from "@aethervtt/shard-core";
1
+ import {
2
+ defineSpan,
3
+ ProfilerResource,
4
+ ShardError,
5
+ TRACK
6
+ } from "@aethervtt/shard-core";
2
7
  import { flushDataStores } from "./data-store.js";
3
8
  import { unsupportedNodes } from "./features.js";
4
9
  import { TexturePool } from "./pool.js";
@@ -130,6 +135,13 @@ class RenderGraph {
130
135
  /** Views rendered in the last frame, in order. */
131
136
  lastViews = [];
132
137
  viewData = /* @__PURE__ */ new Map();
138
+ /** Each node's `render/<node>` span and its CPU time this frame, summed over views (0074). */
139
+ nodeSlots = /* @__PURE__ */ new Map();
140
+ nodeSpans = [];
141
+ nodeMs = new Float64Array(16);
142
+ nodeRan = new Uint8Array(16);
143
+ /** Nodes disabled for measurement (0075): see `ablate`. */
144
+ ablatedNodes = /* @__PURE__ */ new Set();
133
145
  constructor(gpu) {
134
146
  this.gpu = gpu;
135
147
  this.pool = new TexturePool(gpu);
@@ -147,6 +159,19 @@ class RenderGraph {
147
159
  }
148
160
  this.nodes.set(name, node);
149
161
  this.resolutions.clear();
162
+ if (!this.nodeSlots.has(name)) {
163
+ const slot = this.nodeSpans.length;
164
+ this.nodeSlots.set(name, slot);
165
+ this.nodeSpans.push(defineSpan(`render/${name}`));
166
+ if (slot >= this.nodeMs.length) {
167
+ const ms = new Float64Array(this.nodeMs.length * 2);
168
+ ms.set(this.nodeMs);
169
+ this.nodeMs = ms;
170
+ const ran = new Uint8Array(this.nodeRan.length * 2);
171
+ ran.set(this.nodeRan);
172
+ this.nodeRan = ran;
173
+ }
174
+ }
150
175
  }
151
176
  removeNode(name) {
152
177
  this.nodes.delete(name);
@@ -159,6 +184,30 @@ class RenderGraph {
159
184
  nodeNames() {
160
185
  return [...this.nodes.keys()];
161
186
  }
187
+ /**
188
+ * Disables nodes for measurement (0075's ablation), replacing the previous set; `[]` restores
189
+ * them. A disabled render or compute node still begins and ends its pass, with its attachments'
190
+ * clears, so the textures it writes stay valid for what reads them; only its `run` (its draws and
191
+ * dispatches) is skipped. A raw node, which begins its own passes, is skipped whole. The graph
192
+ * resolves as before: what the node fed still runs, on whatever its textures hold. The image is
193
+ * wrong while nodes are disabled. Throws `render/unknown-node` for a name the graph lacks.
194
+ */
195
+ ablate(names) {
196
+ const next = [...names];
197
+ for (const name of next) {
198
+ if (!this.nodes.has(name)) {
199
+ throw new ShardError("render/unknown-node", `No render graph node "${name}"`, {
200
+ hint: `Nodes: ${this.nodeNames().join(", ")}.`
201
+ });
202
+ }
203
+ }
204
+ this.ablatedNodes.clear();
205
+ for (const name of next) this.ablatedNodes.add(name);
206
+ }
207
+ /** The nodes `ablate` disabled. */
208
+ ablated() {
209
+ return [...this.ablatedNodes];
210
+ }
162
211
  /** The data of a view rendered in the last frame. */
163
212
  lastViewData(view) {
164
213
  return this.viewData.get(view);
@@ -200,6 +249,47 @@ class RenderGraph {
200
249
  }
201
250
  return resolved;
202
251
  }
252
+ /**
253
+ * Whether render node `order[k]` can draw in the pass `order[from]` began: the same color
254
+ * attachments, loaded rather than cleared, the same depth (written only if the pass writes it),
255
+ * and nothing it samples bound as an attachment.
256
+ */
257
+ continues(order, from, k, view) {
258
+ const a = this.nodes.get(order[from]);
259
+ const b = this.nodes.get(order[k]);
260
+ if (a.ownPass || b.ownPass) return false;
261
+ const aliases = view.aliases;
262
+ const ca = colorOf(a, view);
263
+ const cb = colorOf(b, view);
264
+ if (ca.length !== cb.length) return false;
265
+ for (let i = 0; i < ca.length; i++) {
266
+ const x = ca[i];
267
+ const y = cb[i];
268
+ if (y.clear !== void 0 || (x.mip ?? 0) !== (y.mip ?? 0)) return false;
269
+ if (canonicalOf(aliases, x.resource) !== canonicalOf(aliases, y.resource)) return false;
270
+ if (x.resolve === void 0 !== (y.resolve === void 0)) return false;
271
+ if (x.resolve && canonicalOf(aliases, x.resolve) !== canonicalOf(aliases, y.resolve))
272
+ return false;
273
+ }
274
+ const da = a.depth;
275
+ const db = b.depth;
276
+ if (!da !== !db) return false;
277
+ if (da && db) {
278
+ if (canonicalOf(aliases, da.resource) !== canonicalOf(aliases, db.resource)) return false;
279
+ if (db.clear !== void 0 || da.readOnly && !db.readOnly) return false;
280
+ }
281
+ const reads = b.reads ?? [];
282
+ for (let r = 0; r < reads.length; r++) {
283
+ const c = canonicalOf(aliases, reads[r]);
284
+ if (da && c === canonicalOf(aliases, da.resource)) return false;
285
+ for (let i = 0; i < ca.length; i++) {
286
+ const x = ca[i];
287
+ if (c === canonicalOf(aliases, x.resource)) return false;
288
+ if (x.resolve && c === canonicalOf(aliases, x.resolve)) return false;
289
+ }
290
+ }
291
+ return true;
292
+ }
203
293
  /** Whether a node after `k` loads or reads `resource` (so its contents must be stored). */
204
294
  loadedLater(order, k, resource, view) {
205
295
  const canonical = canonicalOf(view.aliases, resource);
@@ -253,6 +343,7 @@ class RenderGraph {
253
343
  this.viewData.clear();
254
344
  for (const v of sorted) this.viewData.set(v.name, v.data);
255
345
  const off = this.gpu.tier === "baseline" ? unsupportedNodes(world) : void 0;
346
+ const profiler = world.tryResource(ProfilerResource);
256
347
  for (const view of sorted) {
257
348
  const resolved = this.resolveFor(view, off);
258
349
  const order = resolved.order;
@@ -299,14 +390,28 @@ class RenderGraph {
299
390
  textures.set(canonical, t);
300
391
  return t;
301
392
  };
393
+ const provide = (name, t) => {
394
+ textures.set(canonicalOf(view.aliases, name), t);
395
+ };
302
396
  const timestamps = (name) => this.timer.allocate(name);
303
397
  const afterSubmit = (fn) => void submitted.push(fn);
398
+ let open;
399
+ let openFrom = -1;
304
400
  for (let k = 0; k < order.length; k++) {
305
401
  const name = order[k];
306
402
  const node = this.nodes.get(name);
403
+ const ablated = this.ablatedNodes.size > 0 && this.ablatedNodes.has(name);
404
+ if (ablated && node.kind === "raw") continue;
405
+ const t0 = profiler !== void 0 ? profiler.now() : 0;
307
406
  let renderPass;
308
407
  let computePass;
309
- if (node.kind === "render") {
408
+ if (node.kind === "render" && open && this.continues(order, openFrom, k, view)) {
409
+ renderPass = open;
410
+ } else {
411
+ open?.end();
412
+ open = void 0;
413
+ }
414
+ if (node.kind === "render" && !renderPass) {
310
415
  const colors = colorOf(node, view);
311
416
  renderPass = encoder.beginRenderPass({
312
417
  label: `${view.name}/${name}`,
@@ -326,26 +431,38 @@ class RenderGraph {
326
431
  } : void 0,
327
432
  timestampWrites: this.timer.allocate(name)
328
433
  });
434
+ open = renderPass;
435
+ openFrom = k;
329
436
  } else if (node.kind === "compute") {
330
437
  computePass = encoder.beginComputePass({
331
438
  label: `${view.name}/${name}`,
332
439
  timestampWrites: this.timer.allocate(name)
333
440
  });
334
441
  }
335
- node.run({
336
- gpu: this.gpu,
337
- world,
338
- view,
339
- encoder,
340
- renderPass,
341
- computePass,
342
- texture,
343
- timestamps,
344
- afterSubmit
345
- });
346
- renderPass?.end();
442
+ if (!ablated) {
443
+ node.run({
444
+ gpu: this.gpu,
445
+ world,
446
+ view,
447
+ encoder,
448
+ renderPass,
449
+ computePass,
450
+ texture,
451
+ provide,
452
+ timestamps,
453
+ afterSubmit
454
+ });
455
+ }
347
456
  computePass?.end();
457
+ if (profiler !== void 0) {
458
+ const ms = profiler.now() - t0;
459
+ const slot = this.nodeSlots.get(name);
460
+ this.nodeMs[slot] = this.nodeMs[slot] + ms;
461
+ this.nodeRan[slot] = 1;
462
+ profiler.event(this.nodeSpans[slot], TRACK.main, t0, ms);
463
+ }
348
464
  }
465
+ open?.end();
349
466
  for (const capture of this.captures) {
350
467
  if (capture.view !== view.name) continue;
351
468
  let source;
@@ -380,6 +497,14 @@ class RenderGraph {
380
497
  readbacks.push({ capture, buffer, width, height, format, bytesPerRow });
381
498
  }
382
499
  }
500
+ if (profiler !== void 0) {
501
+ for (let slot = 0; slot < this.nodeSpans.length; slot++) {
502
+ if (!this.nodeRan[slot]) continue;
503
+ profiler.sample(this.nodeSpans[slot], this.nodeMs[slot]);
504
+ this.nodeMs[slot] = 0;
505
+ this.nodeRan[slot] = 0;
506
+ }
507
+ }
383
508
  this.captures = this.captures.filter((c) => !readbacks.some((r) => r.capture === c));
384
509
  this.timer.resolve(encoder);
385
510
  flushDataStores(this.gpu);
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { type AblationDriver, type AblationOptions, type AblationResult, ablatePasses, type PassCost, PassCosts, type PassCostsData, runAblation, } from './ablation.js';
1
2
  export { AssetStore, MaterialAsset, MaterialAssetType, MaterialImporter, Materials, type MaterialValue, MeshAsset, Meshes, materialFields, materialFromJson, materialTypeOf, missingMesh, RenderTargets, STANDARD_TYPE, StandardMaterial, type StandardMaterialValue, validateMaterial, } from './assets.js';
2
3
  export { Atmosphere, type AtmospherePreset, AtmospherePresets, type AtmosphereRecord, type AtmosphereSampleResult, AtmosphereSettings, AtmosphereStore, Atmospheres, type AtmosphereValue, atmosphereMethods, atmosphereModel, type CameraAtmosphere, describeAtmospheres, sampleAtmosphere, selectAtmospheres, sunTransmittanceAt, } from './atmosphere.js';
3
4
  export { type AtmosphereModel, createSkySample, integrateSky, multiscatterLut, transmittanceLut, transmittanceToTop, } from './atmosphere-model.js';
@@ -10,6 +11,8 @@ export { Cutaway, CutawayPath, type CutawaySupport, CutawayView, MAX_REVEAL_POIN
10
11
  export { CUTAWAY_SHADERS, CutawayCameras, type CutawayState, cutawayPlugin, describeCutaways, extractCutaways, } from './cutaway-plugin.js';
11
12
  export { DATA_WIDTH, DataStore, type DataStoreOptions, dataEntry, flushDataStores, loadDataTextures, } from './data-store.js';
12
13
  export { captureShadowMap, DEBUG_VIEWS, type DebugView, describeCulling, describeLighting, readBuffer, readTextureLayer, setDebugView, } from './debug-views.js';
14
+ export { Decals, describeDecals, updateDecals } from './decals.js';
15
+ export { DecalGpu, decalsPlugin } from './decals-plugin.js';
13
16
  export { captureGBuffer, describeDeferred, GBUFFER_CHANNELS, type GBufferChannel, } from './deferred.js';
14
17
  export { deferredPlugin } from './deferred-plugin.js';
15
18
  export { DEFORM_WORDS, DeformStore, type MeshDeform } from './deform.js';
@@ -19,6 +22,10 @@ export { dynamicResolutionPlugin, type FrameTimings, RenderScaleController, upda
19
22
  export { type CameraEnvironment, DefaultEnvironment, type DefaultEnvironmentValue, describeEnvironment, Environment, type EnvironmentBaker, EnvironmentMap, type EnvironmentMapValue, EnvironmentPresets, EnvironmentStore, Environments, environmentBakers, ProceduralSky, type ProceduralSkyValue, Skybox, } from './environment.js';
20
23
  export { environmentPlugin } from './environment-plugin.js';
21
24
  export { addRenderFeatures, type BaselineStrategy, clearUnsupported, describeFeatures, featureOfNode, type RenderFeature, RenderFeatures, reportUnsupported, unsupportedNodes, } from './features.js';
25
+ export { type FoliageChunk, FoliageLayer, type FoliageLayerOptions, FoliageLayerSet, FoliageLayers, foliagePlugin, } from './foliage.js';
26
+ export { CoveredGpuTime, FOLIAGE_SPAN_KEY, FoliageBudget, type FoliageBudgetValue, FoliageController, } from './foliage-budget.js';
27
+ export { FoliagePath, type FoliageSupport } from './foliage-path.js';
28
+ export { FOLIAGE_SHADERS, MAX_FOLIAGE_MESHES } from './foliage-shaders.js';
22
29
  export { type ForwardPluginOptions, type ForwardState, ForwardStateResource, forwardCorePlugin, forwardQueue, PASS_GROUND, PICK_TARGETS, sceneColor, VERTEX_BUFFERS, type ViewGpu, viewBindGroup, viewPixelScale, } from './forward.js';
23
30
  export { fxaaPlugin } from './fxaa.js';
24
31
  export { LABEL_FONT, labelAtlas, labelWidth } from './gizmo-font.js';
@@ -46,13 +53,15 @@ export { type PickBlocker, type PickDetail, type PickDetailer, type PickDrawer,
46
53
  export { pickingPlugin } from './picking-plugin.js';
47
54
  export { PixelPerfect, type PixelPerfectLayout, PixelPerfectPath, PixelTargets, pixelPerfectLayout, } from './pixel-perfect.js';
48
55
  export { pixelPerfectPlugin } from './pixel-perfect-plugin.js';
49
- export { captureBuffer, captureView, describeRender, Gpu, GpuDeviceLost, Graph, RenderDescribers, RenderOptions, type RenderOptionsValue, type RenderPluginOptions, RenderSet, renderOwner, renderPlugin, Shaders, Views, Window, } from './plugin.js';
56
+ export { captureBuffer, captureView, describeRender, Gpu, GpuDeviceLost, Graph, gpuMemory, RenderDescribers, RenderOptions, type RenderOptionsValue, type RenderPluginOptions, RenderSet, renderOwner, renderPlugin, Shaders, Views, Window, } from './plugin.js';
50
57
  export { TexturePool } from './pool.js';
51
58
  export { ANTIALIASING_MODES, Antialiasing, AutoExposure, Bloom, ColorGrading, cocRadiusPixels, DepthOfField, Fog, METERING_MODES, MotionBlur, PostEffect, type PostSettings, SSAO_QUALITIES, Ssao, Vignette, } from './post.js';
52
59
  export { bloomLevels, describePost, ExposureMeters, type ExposureState, histogramEv, METER_READBACKS, POST_NODES, } from './post-nodes.js';
53
60
  export { postPlugin } from './post-plugin.js';
54
61
  export { screenToPlane, screenToRay, worldToScreen } from './projection.js';
55
62
  export { describeRenderScale, RenderScale, type RenderScaleValue, SCALE_STEP, scaledSize, } from './render-scale.js';
63
+ export { describeRibbons, Ribbons, shiftRibbons, updateRibbons } from './ribbons.js';
64
+ export { RibbonGpu, ribbonsPlugin } from './ribbons-plugin.js';
56
65
  export { clearScreenEffects, describeScreenEffects, expireScreenEffects, forwardScreenEffects, MAX_SCREEN_EFFECT_PARAMS, MAX_SCREEN_EFFECTS, onScreenEffect, publishScreenEffect, runScreenEffects, SCREEN_EFFECTS_DEMAND, type ScreenEffect, type ScreenEffectHandler, ScreenEffectHandlers, type ScreenEffectParams, ScreenEffects, } from './screen-effects.js';
57
66
  export { ENGINE_SHADERS, materialLayout, registerEngineShaders, registerShaders, ViewUniform, viewLayout, } from './shaders.js';
58
67
  export { SHADOW_CATCHER_SHADERS, ShadowCatcher, shadowCatcherPlugin } from './shadow-catcher.js';
@@ -66,6 +75,7 @@ export { OffscreenTarget, type OffscreenTargetOptions, type RenderTarget, } from
66
75
  export { bindingDimension, depthReadEntry } from './tier.js';
67
76
  export { GpuTimer } from './timer.js';
68
77
  export { addShaderVariantSource, type MaterialVariantEntry, materialVariants, type ShaderVariantManifest, type ShaderVariantSource, ShaderVariantSources, showToCamera, showVariants, } from './variants.js';
78
+ export { Beam, Decal, DecalReceiver, DecalsPath, RibbonsPath, Trail } from './vfx.js';
69
79
  export { type CameraData, CameraMoved, Cameras, cameraOf, DEFAULT_CURVE, isScaled, RenderPath, shiftCameraHistory, TONEMAP_CURVES, type TonemapCurve, Tonemapping, ViewSettings, type ViewSettingsValue, viewAliases, } from './view.js';
70
80
  export { type HiddenSet, HiddenSetsResource, NO_HIDDEN, observeViewVisibilityWithoutPlugin, VIEW_SHADOWS, ViewVisibility, } from './view-visibility.js';
71
81
  export { describeViewVisibility, HiddenSets, resolveViewVisibility, viewVisibilityPlugin, } from './view-visibility-plugin.js';
package/dist/index.js CHANGED
@@ -1,3 +1,8 @@
1
+ import {
2
+ ablatePasses,
3
+ PassCosts,
4
+ runAblation
5
+ } from "./ablation.js";
1
6
  import {
2
7
  AssetStore,
3
8
  MaterialAsset,
@@ -94,6 +99,8 @@ import {
94
99
  readTextureLayer,
95
100
  setDebugView
96
101
  } from "./debug-views.js";
102
+ import { Decals, describeDecals, updateDecals } from "./decals.js";
103
+ import { DecalGpu, decalsPlugin } from "./decals-plugin.js";
97
104
  import {
98
105
  captureGBuffer,
99
106
  describeDeferred,
@@ -130,6 +137,20 @@ import {
130
137
  reportUnsupported,
131
138
  unsupportedNodes
132
139
  } from "./features.js";
140
+ import {
141
+ FoliageLayer,
142
+ FoliageLayerSet,
143
+ FoliageLayers,
144
+ foliagePlugin
145
+ } from "./foliage.js";
146
+ import {
147
+ CoveredGpuTime,
148
+ FOLIAGE_SPAN_KEY,
149
+ FoliageBudget,
150
+ FoliageController
151
+ } from "./foliage-budget.js";
152
+ import { FoliagePath } from "./foliage-path.js";
153
+ import { FOLIAGE_SHADERS, MAX_FOLIAGE_MESHES } from "./foliage-shaders.js";
133
154
  import {
134
155
  ForwardStateResource,
135
156
  forwardCorePlugin,
@@ -314,6 +335,7 @@ import {
314
335
  Gpu,
315
336
  GpuDeviceLost,
316
337
  Graph,
338
+ gpuMemory,
317
339
  RenderDescribers,
318
340
  RenderOptions,
319
341
  RenderSet,
@@ -356,6 +378,8 @@ import {
356
378
  SCALE_STEP,
357
379
  scaledSize
358
380
  } from "./render-scale.js";
381
+ import { describeRibbons, Ribbons, shiftRibbons, updateRibbons } from "./ribbons.js";
382
+ import { RibbonGpu, ribbonsPlugin } from "./ribbons-plugin.js";
359
383
  import {
360
384
  clearScreenEffects,
361
385
  describeScreenEffects,
@@ -409,6 +433,7 @@ import {
409
433
  showToCamera,
410
434
  showVariants
411
435
  } from "./variants.js";
436
+ import { Beam, Decal, DecalReceiver, DecalsPath, RibbonsPath, Trail } from "./vfx.js";
412
437
  import {
413
438
  CameraMoved,
414
439
  Cameras,
@@ -450,6 +475,7 @@ export {
450
475
  Atmospheres,
451
476
  AutoExposure,
452
477
  BLEND_MODES,
478
+ Beam,
453
479
  Bloom,
454
480
  CLUSTER_COUNT,
455
481
  CLUSTER_X,
@@ -467,6 +493,7 @@ export {
467
493
  ClusterBuffers,
468
494
  ColorGrading,
469
495
  ComputedVisibility,
496
+ CoveredGpuTime,
470
497
  Culler,
471
498
  Cutaway,
472
499
  CutawayCameras,
@@ -478,6 +505,11 @@ export {
478
505
  DEFORM_WORDS,
479
506
  DataStore,
480
507
  DebugOverlays,
508
+ Decal,
509
+ DecalGpu,
510
+ DecalReceiver,
511
+ Decals,
512
+ DecalsPath,
481
513
  DefaultEnvironment,
482
514
  DeformPath,
483
515
  DeformStore,
@@ -493,7 +525,15 @@ export {
493
525
  ExposureMeters,
494
526
  ExposurePresets,
495
527
  FALLOFFS,
528
+ FOLIAGE_SHADERS,
529
+ FOLIAGE_SPAN_KEY,
496
530
  Fog,
531
+ FoliageBudget,
532
+ FoliageController,
533
+ FoliageLayer,
534
+ FoliageLayerSet,
535
+ FoliageLayers,
536
+ FoliagePath,
497
537
  ForwardStateResource,
498
538
  GBUFFER_CHANNELS,
499
539
  GIZMO_LINE_FLOATS,
@@ -547,6 +587,7 @@ export {
547
587
  LocalShadows,
548
588
  Lod,
549
589
  LuminousPowerPresets,
590
+ MAX_FOLIAGE_MESHES,
550
591
  MAX_JOINTS,
551
592
  MAX_LENS_FIELDS,
552
593
  MAX_LENS_PIXELS,
@@ -583,6 +624,7 @@ export {
583
624
  PASS_GROUND,
584
625
  PICK_TARGETS,
585
626
  POST_NODES,
627
+ PassCosts,
586
628
  PhysicalCamera,
587
629
  Picking,
588
630
  PixelPerfect,
@@ -612,6 +654,9 @@ export {
612
654
  RenderStats,
613
655
  RenderStatsMap,
614
656
  RenderTargets,
657
+ RibbonGpu,
658
+ Ribbons,
659
+ RibbonsPath,
615
660
  SCALE_STEP,
616
661
  SCREEN_EFFECTS_DEMAND,
617
662
  SHADOW_CATCHER_SHADERS,
@@ -635,6 +680,7 @@ export {
635
680
  TONEMAP_CURVES,
636
681
  TexturePool,
637
682
  Tonemapping,
683
+ Trail,
638
684
  VERTEX_BUFFERS,
639
685
  VIEW_SHADOWS,
640
686
  VIEW_TARGET,
@@ -648,6 +694,7 @@ export {
648
694
  Visibility,
649
695
  VisibilityRange,
650
696
  Window,
697
+ ablatePasses,
651
698
  addRenderFeatures,
652
699
  addShaderVariantSource,
653
700
  allMaterialTypes,
@@ -680,6 +727,7 @@ export {
680
727
  cullGround,
681
728
  cutawayPlugin,
682
729
  dataEntry,
730
+ decalsPlugin,
683
731
  deferredPlugin,
684
732
  defineMaterial,
685
733
  defineOverlay,
@@ -688,6 +736,7 @@ export {
688
736
  describeAtmospheres,
689
737
  describeCulling,
690
738
  describeCutaways,
739
+ describeDecals,
691
740
  describeDeferred,
692
741
  describeEnvironment,
693
742
  describeFeatures,
@@ -698,6 +747,7 @@ export {
698
747
  describePost,
699
748
  describeRender,
700
749
  describeRenderScale,
750
+ describeRibbons,
701
751
  describeScreenEffects,
702
752
  describeViewVisibility,
703
753
  dynamicResolutionPlugin,
@@ -717,6 +767,7 @@ export {
717
767
  findMaterialType,
718
768
  findModelRoot,
719
769
  flushDataStores,
770
+ foliagePlugin,
720
771
  forwardCorePlugin,
721
772
  forwardLensFields,
722
773
  forwardPlugin,
@@ -724,6 +775,7 @@ export {
724
775
  forwardScreenEffects,
725
776
  fxaaPlugin,
726
777
  gizmosPlugin,
778
+ gpuMemory,
727
779
  gridsOverlay,
728
780
  groundKey,
729
781
  histogramEv,
@@ -779,6 +831,8 @@ export {
779
831
  reportUnsupported,
780
832
  resolveGraph,
781
833
  resolveViewVisibility,
834
+ ribbonsPlugin,
835
+ runAblation,
782
836
  runScreenEffects,
783
837
  sampleAtmosphere,
784
838
  scaledSize,
@@ -793,6 +847,7 @@ export {
793
847
  shadowCatcherPlugin,
794
848
  shiftCameraHistory,
795
849
  shiftRenderHistory,
850
+ shiftRibbons,
796
851
  showToCamera,
797
852
  showVariants,
798
853
  skinArtifact,
@@ -804,7 +859,9 @@ export {
804
859
  transmittanceToTop,
805
860
  typeOrdinal,
806
861
  unsupportedNodes,
862
+ updateDecals,
807
863
  updateRenderScale,
864
+ updateRibbons,
808
865
  validateMaterial,
809
866
  viewAliases,
810
867
  viewBindGroup,
@@ -1,6 +1,8 @@
1
1
  import type { Entity, World } from '@aethervtt/shard-core';
2
2
  import type { GizmoStore } from './gizmos.js';
3
- export declare const OVERLAYS: readonly ['bounds', 'lights', 'cameras', 'cascades', 'normals', 'axes', 'labels'];
3
+ export declare const OVERLAYS: readonly ['bounds', 'lights', 'cameras', 'cascades', 'normals', 'axes', 'labels',
4
+ /** Frame time, the top 8 spans, and the GPU frame (0074). */
5
+ 'perf'];
4
6
  export type Overlay = (typeof OVERLAYS)[number];
5
7
  /** An overlay another package draws (physics colliders, the navmesh, UI rects). */
6
8
  export interface OverlayDef {
@@ -5,7 +5,9 @@ const OVERLAYS = [
5
5
  "cascades",
6
6
  "normals",
7
7
  "axes",
8
- "labels"
8
+ "labels",
9
+ /** Frame time, the top 8 spans, and the GPU frame (0074). */
10
+ "perf"
9
11
  ];
10
12
  const extraOverlays = /* @__PURE__ */ new Map();
11
13
  function defineOverlay(def) {