reze-engine 0.50.2 → 0.50.4

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 (42) hide show
  1. package/dist/engine.d.ts +294 -7
  2. package/dist/engine.d.ts.map +1 -1
  3. package/dist/engine.js +900 -109
  4. package/dist/shaders/cast-api.d.ts +1 -1
  5. package/dist/shaders/cast-api.d.ts.map +1 -1
  6. package/dist/shaders/cast-layout.d.ts +44 -1
  7. package/dist/shaders/cast-layout.d.ts.map +1 -1
  8. package/dist/shaders/cast-layout.js +44 -1
  9. package/dist/shaders/materials/common.d.ts.map +1 -1
  10. package/dist/shaders/materials/common.js +7 -1
  11. package/dist/shaders/materials/nodes.d.ts +1 -1
  12. package/dist/shaders/materials/nodes.d.ts.map +1 -1
  13. package/dist/shaders/materials/nodes.js +17 -9
  14. package/dist/shaders/passes/composite.d.ts +1 -1
  15. package/dist/shaders/passes/composite.d.ts.map +1 -1
  16. package/dist/shaders/passes/depth-prepass.d.ts +1 -1
  17. package/dist/shaders/passes/depth-prepass.d.ts.map +1 -1
  18. package/dist/shaders/passes/depth-prepass.js +52 -12
  19. package/dist/shaders/passes/ground.d.ts +16 -0
  20. package/dist/shaders/passes/ground.d.ts.map +1 -1
  21. package/dist/shaders/passes/ground.js +143 -49
  22. package/dist/shaders/passes/outline.d.ts +1 -1
  23. package/dist/shaders/passes/outline.d.ts.map +1 -1
  24. package/dist/shaders/passes/outline.js +12 -3
  25. package/dist/shaders/passes/particles.d.ts.map +1 -1
  26. package/dist/shaders/passes/particles.js +6 -2
  27. package/dist/shaders/passes/scene-contract.d.ts +38 -6
  28. package/dist/shaders/passes/scene-contract.d.ts.map +1 -1
  29. package/dist/shaders/passes/scene-contract.js +53 -16
  30. package/dist/shaders/passes/trails.d.ts.map +1 -1
  31. package/dist/shaders/passes/trails.js +36 -8
  32. package/package.json +2 -2
  33. package/src/engine.ts +952 -100
  34. package/src/shaders/cast-layout.ts +44 -1
  35. package/src/shaders/materials/common.ts +7 -1
  36. package/src/shaders/materials/nodes.ts +17 -9
  37. package/src/shaders/passes/depth-prepass.ts +53 -12
  38. package/src/shaders/passes/ground.ts +145 -49
  39. package/src/shaders/passes/outline.ts +14 -3
  40. package/src/shaders/passes/particles.ts +6 -2
  41. package/src/shaders/passes/scene-contract.ts +55 -16
  42. package/src/shaders/passes/trails.ts +36 -8
@@ -5,6 +5,7 @@ import { anchorAliasWgsl, ribbonSlotWgsl } from "../anchor-table"
5
5
  import { midiApi } from "../midi-api"
6
6
  import { CAST_API } from "../cast-api"
7
7
  import { clockApi, EFFECT_MATH_API, PARTICLE_STRUCT_WGSL, trailSlotsApi, viewportApi } from "./hosted-api"
8
+ import { sceneIdFieldWgsl, sceneIdPadWgsl } from "./scene-contract"
8
9
  // Ribbons along a bone's recorded path, drawn as geometry.
9
10
  //
10
11
  // This is the effect the whole geometry path was built for. As a fullscreen
@@ -123,7 +124,14 @@ struct CameraU {
123
124
  }
124
125
  struct TrailU {
125
126
  time: f32,
126
- _pad0: f32,
127
+ // How many subjects the cast ACTUALLY holds this frame, not the four the
128
+ // layout has room for. The instance count is sized by this on the CPU and
129
+ // decoded by it here, and the two must use the same number or the flattened
130
+ // [ribbon][subject][segment] index lands on the wrong ribbon. It is a uniform
131
+ // rather than the RZ_SUBJECTS constant precisely because it changes when a
132
+ // model is added or removed, and recompiling every trail shader for that
133
+ // would be absurd.
134
+ subjects: f32,
127
135
  _pad1: f32,
128
136
  _pad2: f32,
129
137
  }
@@ -244,11 +252,14 @@ fn vs(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VSOut
244
252
  let rest = ii / subs;
245
253
  let seg = k / SUB;
246
254
  let sub = k % SUB;
247
- let subject = i32(rest % u32(RZ_SUBJECTS));
255
+ // The LIVE subject count, floored at one so a cast that is momentarily empty
256
+ // divides by something. See TrailU.subjects.
257
+ let live = max(1u, u32(tu.subjects));
258
+ let subject = i32(rest % live);
248
259
  // Instance index counts RIBBONS; the cast buffer is addressed by anchor slot.
249
260
  // One ribbon per trailed anchor, so these are the same number only when every
250
261
  // anchor is trailed — _rzRibbonSlot is what bridges them.
251
- let ribbon = i32(rest / u32(RZ_SUBJECTS));
262
+ let ribbon = i32(rest / live);
252
263
  let slot = _rzRibbonSlot(ribbon);
253
264
 
254
265
  let n = rzTrailCount(subject, slot);
@@ -342,9 +353,23 @@ fn vs(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VSOut
342
353
  if (dot(perpA, perpB) < 0.0) { perpB = -perpB; }
343
354
  let clipP = select(clipA, clipB, atEnd);
344
355
  let perp = select(perpA, perpB, atEnd);
345
- // trailWidth speaks PIXELS, like the original's constants; rzViewportHeight()
346
- // lets the effect scale them to the frame.
347
- let wPx = max(0.0, trailWidth(u, age));
356
+ // trailWidth speaks WORLD UNITS the model's units, not the screen's.
357
+ //
358
+ // It spoke pixels, like the fullscreen original's constants, and that made
359
+ // the ribbon a screen ornament: zoom out and it grew relative to the hand
360
+ // that drew it, zoom in and it thinned to a thread. A ribbon is a thing in
361
+ // the scene, so its width belongs in the scene's units and should foreshorten
362
+ // like everything else.
363
+ //
364
+ // The EXTRUSION stays in 2D pixel space untouched — every 3D-extrusion
365
+ // artefact this ribbon ever had (fold-over wedges, bowties, twisted quads) is
366
+ // recorded above, and none of it comes back. Only the width's SOURCE changes:
367
+ // a world length L perpendicular to view at depth w projects to
368
+ // L * proj[1][1] / w in NDC y, so half the frame height converts it to the
369
+ // pixels the 2D offset wants. Per vertex, so a ribbon receding along its own
370
+ // length tapers with distance exactly as geometry would.
371
+ let wWorld = max(0.0, trailWidth(u, age));
372
+ let wPx = wWorld * cam.proj[1][1] * (H * 0.5) / max(clipP.w, 0.01);
348
373
  let ndc = clipP.xy / clipP.w + perp * (c.y * wPx) / toPx;
349
374
  out.clip = vec4f(ndc * clipP.w, clipP.z, clipP.w);
350
375
  out.slot = u32(slot);
@@ -364,7 +389,10 @@ struct TrailFSOut {
364
389
  // The scene's aux target: (bloom mask, coverage). Writing mask 1 is what
365
390
  // makes a ribbon BLOOM — it is light, and the gate is what says so.
366
391
  @location(1) aux: vec4f,
367
- }
392
+ // Declared whenever the pass carries the attachment, and padded rather than
393
+ // written: a ribbon is not a thing you would address by id, so its pipeline
394
+ // takes this target at writeMask 0. Declared anyway — see sceneFsOutWgsl.
395
+ ${sceneIdFieldWgsl()}}
368
396
 
369
397
  @fragment
370
398
  fn fs(in: VSOut) -> TrailFSOut {
@@ -383,7 +411,7 @@ fn fs(in: VSOut) -> TrailFSOut {
383
411
  // mapper is what keeps the sum from clipping.
384
412
  o.color = vec4f(c.rgb, c.a);
385
413
  o.aux = vec4f(${src.bloom ? "1.0" : "0.0"}, 1.0, 0.0, c.a);
386
- return o;
414
+ ${sceneIdPadWgsl("o")} return o;
387
415
  }
388
416
  `
389
417
  )