@zephyr3d/scene 0.9.19 → 0.9.21

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 (95) hide show
  1. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  2. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  3. package/dist/asset/assetmanager.js +1 -0
  4. package/dist/asset/assetmanager.js.map +1 -1
  5. package/dist/camera/camera.js +39 -0
  6. package/dist/camera/camera.js.map +1 -1
  7. package/dist/index.d.ts +190 -4
  8. package/dist/index.js +2 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/material/meshmaterial.js +2 -2
  11. package/dist/material/meshmaterial.js.map +1 -1
  12. package/dist/material/mixins/lit.js +10 -0
  13. package/dist/material/mixins/lit.js.map +1 -1
  14. package/dist/material/shader/helper.js +117 -2
  15. package/dist/material/shader/helper.js.map +1 -1
  16. package/dist/posteffect/skinsss.js +10 -10
  17. package/dist/posteffect/skinsss.js.map +1 -1
  18. package/dist/posteffect/ssr.js +13 -13
  19. package/dist/posteffect/ssr.js.map +1 -1
  20. package/dist/posteffect/sss.js +8 -7
  21. package/dist/posteffect/sss.js.map +1 -1
  22. package/dist/posteffect/tonemap.js +5 -5
  23. package/dist/posteffect/tonemap.js.map +1 -1
  24. package/dist/render/abuffer_oit.js +5 -0
  25. package/dist/render/abuffer_oit.js.map +1 -1
  26. package/dist/render/cluster_light.js +52 -8
  27. package/dist/render/cluster_light.js.map +1 -1
  28. package/dist/render/dualdepthpeeling_oit.js +331 -0
  29. package/dist/render/dualdepthpeeling_oit.js.map +1 -0
  30. package/dist/render/lightpass.js +29 -8
  31. package/dist/render/lightpass.js.map +1 -1
  32. package/dist/render/renderer.js +3 -0
  33. package/dist/render/renderer.js.map +1 -1
  34. package/dist/render/rendergraph/blackboard.js +40 -39
  35. package/dist/render/rendergraph/blackboard.js.map +1 -1
  36. package/dist/render/rendergraph/device_pool_allocator.js +10 -1
  37. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  38. package/dist/render/rendergraph/forward_plus_builder.js +75 -4
  39. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  40. package/dist/render/rendergraph/types.js.map +1 -1
  41. package/dist/render/renderpass.js +12 -2
  42. package/dist/render/renderpass.js.map +1 -1
  43. package/dist/render/shadow_mask_pass.js +297 -0
  44. package/dist/render/shadow_mask_pass.js.map +1 -0
  45. package/dist/render/weightedblended_oit.js +5 -0
  46. package/dist/render/weightedblended_oit.js.map +1 -1
  47. package/dist/scene/basesprite.js +1 -0
  48. package/dist/scene/basesprite.js.map +1 -1
  49. package/dist/scene/batchgroup.js +1 -0
  50. package/dist/scene/batchgroup.js.map +1 -1
  51. package/dist/scene/environment.js +1 -0
  52. package/dist/scene/environment.js.map +1 -1
  53. package/dist/scene/msdftext.js +1 -0
  54. package/dist/scene/msdftext.js.map +1 -1
  55. package/dist/scene/msdftextsprite.js +1 -0
  56. package/dist/scene/msdftextsprite.js.map +1 -1
  57. package/dist/scene/particlesys.js +1 -0
  58. package/dist/scene/particlesys.js.map +1 -1
  59. package/dist/scene/scene.js +1 -0
  60. package/dist/scene/scene.js.map +1 -1
  61. package/dist/scene/terrain-cm/grass.js +1 -0
  62. package/dist/scene/terrain-cm/grass.js.map +1 -1
  63. package/dist/scene/terrain-cm/terrain-cm.js +1 -0
  64. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  65. package/dist/scene/water.js +1 -0
  66. package/dist/scene/water.js.map +1 -1
  67. package/dist/utility/serialization/manager.js +1 -0
  68. package/dist/utility/serialization/manager.js.map +1 -1
  69. package/dist/utility/serialization/scene/animation.js +1 -0
  70. package/dist/utility/serialization/scene/animation.js.map +1 -1
  71. package/dist/utility/serialization/scene/batch.js +1 -0
  72. package/dist/utility/serialization/scene/batch.js.map +1 -1
  73. package/dist/utility/serialization/scene/camera.js +35 -2
  74. package/dist/utility/serialization/scene/camera.js.map +1 -1
  75. package/dist/utility/serialization/scene/light.js +1 -0
  76. package/dist/utility/serialization/scene/light.js.map +1 -1
  77. package/dist/utility/serialization/scene/mesh.js +1 -0
  78. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  79. package/dist/utility/serialization/scene/node.js +1 -0
  80. package/dist/utility/serialization/scene/node.js.map +1 -1
  81. package/dist/utility/serialization/scene/particle.js +1 -0
  82. package/dist/utility/serialization/scene/particle.js.map +1 -1
  83. package/dist/utility/serialization/scene/primitive.js +1 -0
  84. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  85. package/dist/utility/serialization/scene/sprite.js +1 -0
  86. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  87. package/dist/utility/serialization/scene/terrain.js +1 -0
  88. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  89. package/dist/utility/serialization/scene/text.js +1 -0
  90. package/dist/utility/serialization/scene/text.js.map +1 -1
  91. package/dist/utility/serialization/scene/water.js +1 -0
  92. package/dist/utility/serialization/scene/water.js.map +1 -1
  93. package/dist/values.js +11 -1
  94. package/dist/values.js.map +1 -1
  95. package/package.json +2 -2
@@ -4,6 +4,7 @@ import { LightPass } from '../lightpass.js';
4
4
  import { ShadowMapPass } from '../shadowmap_pass.js';
5
5
  import { DepthPass } from '../depthpass.js';
6
6
  import { ClusteredLight } from '../cluster_light.js';
7
+ import { ShadowMaskRenderer } from '../shadow_mask_pass.js';
7
8
  import { buildHiZ } from '../hzb.js';
8
9
  import '../primitive.js';
9
10
  import '@zephyr3d/device';
@@ -31,6 +32,7 @@ const _scenePass = new LightPass();
31
32
  const _depthPass = new DepthPass();
32
33
  const _shadowMapPass = new ShadowMapPass();
33
34
  const _clusters = [];
35
+ const _shadowMaskRenderer = new ShadowMaskRenderer();
34
36
  const _devicePoolAllocator = new DevicePoolAllocator();
35
37
  let _backDepthColorState = null;
36
38
  let _frontDepthColorState = null;
@@ -385,6 +387,64 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
385
387
  if (depthPassResult.graphDepthAttachmentHandle) {
386
388
  blackboard.set(FrameResources.SceneDepthAttachment, depthPassResult.graphDepthAttachmentHandle);
387
389
  }
390
+ // ── Screen-space shadow mask ────────────────────────────────────────────
391
+ // When active, render each shadow-casting light's visibility into an RGBA8
392
+ // texture array (4 lights per layer). The clustered LightPass samples this
393
+ // mask instead of each shadowed light running its own additive pass. The
394
+ // layer/channel order is locked to ClusteredLight.getVisibleLights: shadow
395
+ // lights fill clustered buffer indices 1..N in renderQueue.shadowedLights
396
+ // order, and ordinal s = index-1 maps to layer s>>2, channel s&3.
397
+ let shadowMaskHandle = null;
398
+ // Reset any mask carried over from a previous frame; the pass below re-sets it
399
+ // during execution only when the mask is actually produced.
400
+ ctx.shadowMaskTexture = null;
401
+ // Gate on build-time state only: renderQueue.shadowedLights is available now,
402
+ // whereas ctx.shadowMapInfo is populated later by the ShadowMaps pass execute
403
+ // (which runs before this pass thanks to the orderToken chain), so it must not
404
+ // be part of the pass-creation condition.
405
+ const useShadowMask = ctx.screenSpaceShadowMask && renderQueue.shadowedLights.length > 0;
406
+ if (useShadowMask) {
407
+ const numShadowLights = renderQueue.shadowedLights.length;
408
+ const numLayers = ShadowMaskRenderer.getLayerCount(numShadowLights);
409
+ const maskPassResult = graph.addPass('ShadowMaskPass', (builder)=>{
410
+ // Freeze the current linear-depth handle at build time. `depthHandle` is a
411
+ // mutable `let` that a later TransmissionDepth pass reassigns to a new
412
+ // version ('linearDepth@TransmissionDepth'); if the execute closure below
413
+ // captured it by reference it would read a handle this pass never declared,
414
+ // tripping RenderGraphExecutor's access assertion. The shadow mask is built
415
+ // from the opaque prepass depth, so the pre-transmission version is correct.
416
+ const maskDepthHandle = depthHandle;
417
+ builder.read(maskDepthHandle);
418
+ builder.read(depthPassResult.depthFramebufferHandle);
419
+ // createTexture already registers this pass as the resource producer, so
420
+ // downstream passes read this handle directly (same pattern as HiZ). The
421
+ // per-layer framebuffers are created inside execute (rgCtx.createFramebuffer),
422
+ // which the graph cannot see; the createTexture producer edge is what keeps
423
+ // the resource alive and ordered before the LightPass reader.
424
+ const maskHandle = builder.createTexture({
425
+ format: 'rgba8unorm',
426
+ label: 'shadowMask',
427
+ arrayLayers: numLayers
428
+ });
429
+ builder.setExecute((rgCtx)=>{
430
+ const depthTex = rgCtx.getTexture(maskDepthHandle);
431
+ const maskTex = rgCtx.getTexture(maskHandle);
432
+ _shadowMaskRenderer.render(ctx, depthTex, renderQueue.shadowedLights, (layer)=>rgCtx.createFramebuffer({
433
+ width: maskTex.width,
434
+ height: maskTex.height,
435
+ colorAttachments: maskTex,
436
+ depthAttachment: null,
437
+ attachmentLayer: layer
438
+ }));
439
+ ctx.shadowMaskTexture = maskTex;
440
+ });
441
+ return {
442
+ maskHandle
443
+ };
444
+ });
445
+ shadowMaskHandle = maskPassResult.maskHandle;
446
+ blackboard.set(FrameResources.ShadowMask, shadowMaskHandle);
447
+ }
388
448
  const renderDepthAttachment = depthPassResult.graphDepthAttachmentHandle ?? depthPassResult.externalDepthAttachment ?? null;
389
449
  // Rendering the scene directly into the final framebuffer is only possible
390
450
  // when no opaque-layer effect is enabled: those effects must sample the
@@ -573,6 +633,9 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
573
633
  const lightPassResult = graph.addPass('LightPass', (builder)=>{
574
634
  builder.read(depthHandle);
575
635
  builder.read(depthPassResult.depthFramebufferHandle);
636
+ if (shadowMaskHandle) {
637
+ builder.read(shadowMaskHandle);
638
+ }
576
639
  if (preLightTransmissionDepthToken) {
577
640
  builder.read(preLightTransmissionDepthToken);
578
641
  }
@@ -1320,8 +1383,12 @@ function blitToCurrentColorAttachment(ctx, source) {
1320
1383
  _scenePass.renderOpaque = true;
1321
1384
  _scenePass.renderTransparent = false;
1322
1385
  _scenePass.render(ctx, null, null, renderQueue);
1323
- _scenePass.renderTransparent = true;
1324
1386
  } finally{
1387
+ // Restore the shared _scenePass flags so no state leaks to the next pass:
1388
+ // the transparent pass sets transmission/renderOpaque/renderTransparent
1389
+ // itself rather than inheriting whatever this pass happened to leave.
1390
+ _scenePass.renderTransparent = true;
1391
+ _scenePass.transmission = false;
1325
1392
  ctx.device.popDeviceStates();
1326
1393
  }
1327
1394
  }
@@ -1364,9 +1431,13 @@ function blitToCurrentColorAttachment(ctx, source) {
1364
1431
  device.setFramebuffer(framebuffer);
1365
1432
  device.setViewport(null);
1366
1433
  device.setScissor(null);
1367
- // _scenePass.transmission carries over from the opaque phase (true when the
1368
- // scene color copy seeded the background, false otherwise). Never clear:
1369
- // the opaque result is already in the target.
1434
+ // Derive transmission mode from the same single source of truth the opaque
1435
+ // pass used (renderQueue.needSceneColor()) instead of inheriting leftover
1436
+ // _scenePass state. When scene color is needed the opaque pass seeded the
1437
+ // refraction background and drew the transmission-opaque list, so here we
1438
+ // draw transmission_trans + transparent; otherwise just the transparent
1439
+ // list. Never clear: the opaque result is already in the target.
1440
+ _scenePass.transmission = renderQueue.needSceneColor();
1370
1441
  _scenePass.clearColor = null;
1371
1442
  _scenePass.clearDepth = null;
1372
1443
  _scenePass.clearStencil = null;