@forgeax/engine-render 0.1.24 → 0.1.25

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 (135) hide show
  1. package/README.md +100 -1
  2. package/dist/assembly/factory.d.ts +1 -1
  3. package/dist/assembly/factory.d.ts.map +1 -1
  4. package/dist/assembly/material/surface-projection.d.ts +24 -0
  5. package/dist/assembly/material/surface-projection.d.ts.map +1 -0
  6. package/dist/assembly/material-shader-policy.d.ts +20 -0
  7. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  8. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  9. package/dist/assembly/webgpu-renderer.d.ts +1 -1
  10. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  11. package/dist/assembly/webgpu-vertex-layouts.d.ts +89 -0
  12. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -0
  13. package/dist/assets/asset-decoders.d.ts.map +1 -1
  14. package/dist/authoring.mjs +1 -1
  15. package/dist/{chunk-Q752SHI5.mjs → chunk-ADHHVYLW.mjs} +3 -3
  16. package/dist/chunk-ADHHVYLW.mjs.map +1 -0
  17. package/dist/{chunk-TFH5I7JJ.mjs → chunk-E34VL5VI.mjs} +3 -3
  18. package/dist/{chunk-TFH5I7JJ.mjs.map → chunk-E34VL5VI.mjs.map} +1 -1
  19. package/dist/{chunk-KZFTK6DO.mjs → chunk-HKXTW355.mjs} +7 -4
  20. package/dist/chunk-HKXTW355.mjs.map +1 -0
  21. package/dist/{chunk-YKB5DQV7.mjs → chunk-JSEDTZYS.mjs} +87 -19
  22. package/dist/chunk-JSEDTZYS.mjs.map +1 -0
  23. package/dist/{chunk-UQYS7FRM.mjs → chunk-KM2NOX2I.mjs} +4 -4
  24. package/dist/{chunk-UQYS7FRM.mjs.map → chunk-KM2NOX2I.mjs.map} +1 -1
  25. package/dist/{chunk-Z3YYH2MB.mjs → chunk-N3RT2EUR.mjs} +94 -41
  26. package/dist/chunk-N3RT2EUR.mjs.map +1 -0
  27. package/dist/{chunk-YRUYGA4A.mjs → chunk-TCLDX7SZ.mjs} +559 -138
  28. package/dist/chunk-TCLDX7SZ.mjs.map +1 -0
  29. package/dist/{chunk-RR5L4SRS.mjs → chunk-ZZ4YQ474.mjs} +2 -2
  30. package/dist/{chunk-RR5L4SRS.mjs.map → chunk-ZZ4YQ474.mjs.map} +1 -1
  31. package/dist/components/instances.d.ts +13 -31
  32. package/dist/components/instances.d.ts.map +1 -1
  33. package/dist/construct-renderer.mjs +865 -142
  34. package/dist/construct-renderer.mjs.map +1 -1
  35. package/dist/gpu-driven/production-raster.d.ts +6 -1
  36. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  37. package/dist/gpu-scene.d.ts +4 -0
  38. package/dist/gpu-scene.d.ts.map +1 -1
  39. package/dist/index.d.ts +1 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.mjs +27 -9
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/instance-buffer-cache.d.ts +7 -1
  44. package/dist/instance-buffer-cache.d.ts.map +1 -1
  45. package/dist/instances.d.ts +101 -0
  46. package/dist/instances.d.ts.map +1 -0
  47. package/dist/internal.mjs +5 -5
  48. package/dist/materials.d.ts +63 -2
  49. package/dist/materials.d.ts.map +1 -1
  50. package/dist/pipeline-builder.d.ts.map +1 -1
  51. package/dist/pipeline-spec.d.ts.map +1 -1
  52. package/dist/record/frame-snapshot.d.ts +13 -2
  53. package/dist/record/frame-snapshot.d.ts.map +1 -1
  54. package/dist/record/frame.d.ts.map +1 -1
  55. package/dist/record/main-pass-geometry.d.ts +22 -3
  56. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  57. package/dist/record/render-context.d.ts +2 -1
  58. package/dist/record/render-context.d.ts.map +1 -1
  59. package/dist/record/shadow-pass.d.ts +11 -1
  60. package/dist/record/shadow-pass.d.ts.map +1 -1
  61. package/dist/recovery/render-system-candidate.d.ts +1 -1
  62. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  63. package/dist/render-contract.d.ts +4 -0
  64. package/dist/render-contract.d.ts.map +1 -1
  65. package/dist/render-system-extract-tail.d.ts +4 -0
  66. package/dist/render-system-extract-tail.d.ts.map +1 -1
  67. package/dist/render-system-extract.d.ts +25 -1
  68. package/dist/render-system-extract.d.ts.map +1 -1
  69. package/dist/render-system.d.ts +4 -1
  70. package/dist/render-system.d.ts.map +1 -1
  71. package/dist/scene/render-scene-types.d.ts +2 -0
  72. package/dist/scene/render-scene-types.d.ts.map +1 -1
  73. package/dist/scene/render-scene.d.ts +12 -1
  74. package/dist/scene/render-scene.d.ts.map +1 -1
  75. package/dist/systems/skin-palette-allocator.d.ts +6 -0
  76. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  77. package/dist/temporal/index.mjs +5 -5
  78. package/package.json +20 -20
  79. package/src/__tests__/gpu-scene.unit.test.ts +38 -2
  80. package/src/__tests__/instances-store.unit.test.ts +46 -0
  81. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  82. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -13
  83. package/src/__tests__/material-pass-policy.unit.test.ts +69 -0
  84. package/src/__tests__/material-snapshot-mutation.integration.test.ts +69 -0
  85. package/src/__tests__/material-surface-authoring.test-d.ts +62 -0
  86. package/src/__tests__/materials-transmission-validation.unit.test.ts +24 -0
  87. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +0 -4
  88. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +42 -0
  89. package/src/__tests__/skin-motion-regression.unit.test.ts +33 -0
  90. package/src/__tests__/skinned-shadow-caster.test.ts +30 -2
  91. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +60 -0
  92. package/src/__tests__/surface-standard-pipeline.browser.test.ts +20 -0
  93. package/src/__tests__/surface-standard-pipeline.dawn.test.ts +20 -0
  94. package/src/__tests__/surface-standard-pipeline.fixture.ts +132 -0
  95. package/src/__tests__/surface-variant-provenance.integration.test.ts +33 -0
  96. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +1 -1
  97. package/src/assembly/factory.ts +2 -0
  98. package/src/assembly/material/__tests__/standard-layer-plan-projection.integration.test.ts +18 -0
  99. package/src/assembly/material/__tests__/surface-pass-projection.integration.test.ts +62 -0
  100. package/src/assembly/material/surface-projection.ts +90 -0
  101. package/src/assembly/material-shader-policy.ts +88 -10
  102. package/src/assembly/recovery/renderer-recover.ts +1 -1
  103. package/src/assembly/webgpu-ready.ts +3 -16
  104. package/src/assembly/webgpu-renderer.ts +90 -158
  105. package/src/assembly/webgpu-vertex-layouts.ts +132 -0
  106. package/src/assets/asset-decoders.ts +27 -4
  107. package/src/components/instances.ts +14 -197
  108. package/src/gpu-driven/production-raster.ts +34 -1
  109. package/src/gpu-scene.ts +84 -29
  110. package/src/index.ts +1 -0
  111. package/src/instance-buffer-cache.ts +14 -1
  112. package/src/instances.ts +288 -0
  113. package/src/materials.ts +107 -12
  114. package/src/pipeline-builder.ts +14 -10
  115. package/src/pipeline-spec.ts +6 -14
  116. package/src/record/frame-snapshot.ts +19 -2
  117. package/src/record/frame.ts +31 -2
  118. package/src/record/main-pass-geometry.ts +498 -59
  119. package/src/record/main-pass-sprite-draws.ts +1 -1
  120. package/src/record/render-context.ts +4 -0
  121. package/src/record/shadow-pass.ts +46 -99
  122. package/src/recovery/render-system-candidate.ts +41 -4
  123. package/src/render-contract.ts +4 -0
  124. package/src/render-system-extract-tail.ts +107 -51
  125. package/src/render-system-extract.ts +53 -26
  126. package/src/render-system.ts +40 -5
  127. package/src/scene/render-scene-types.ts +2 -0
  128. package/src/scene/render-scene.ts +579 -36
  129. package/src/systems/skin-palette-allocator.ts +129 -7
  130. package/src/transmission/__tests__/surface-compatibility.integration.test.ts +32 -0
  131. package/dist/chunk-KZFTK6DO.mjs.map +0 -1
  132. package/dist/chunk-Q752SHI5.mjs.map +0 -1
  133. package/dist/chunk-YKB5DQV7.mjs.map +0 -1
  134. package/dist/chunk-YRUYGA4A.mjs.map +0 -1
  135. package/dist/chunk-Z3YYH2MB.mjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { GlyphText, selectActiveCameraIndex, getActiveCamera } from './chunk-FJ6P52EE.mjs';
2
- import { MeshRenderer, MeshFilter, DirectionalLight, validateDirectionalLightData, PointLight, computeInvRangeSquared, SpotLight, degToCos, RectAreaLight, validateRectAreaLightData, directionalShadowQualityFromF32, PointLightShadow, Skylight, LightProbe, validateLightProbeData, SkyboxBackground, Atmosphere, Instances, Layer, Points, Lines, SortKey, resolveMeshMaterialBindings, pointShapeFromU32, PostProcessParams, CubeCamera, cubeCameraUpdateIntentFromF32, ReflectionProbe, reflectionProbeUpdateIntentFromF32, tonemapToU32, resolveVisibility, Fog, VolumetricFog, resolveSelectedVolumetricLight, extractVolumetricFog, MotionBlur, Camera, bloomEnabledFromF32, antialiasFromF32, tonemapFromF32, cameraProjectionFromF32 } from './chunk-Q752SHI5.mjs';
2
+ import { MeshRenderer, MeshFilter, DirectionalLight, validateDirectionalLightData, PointLight, computeInvRangeSquared, SpotLight, degToCos, RectAreaLight, validateRectAreaLightData, directionalShadowQualityFromF32, PointLightShadow, Skylight, LightProbe, validateLightProbeData, SkyboxBackground, Atmosphere, Instances, Layer, Points, Lines, SortKey, resolveMeshMaterialBindings, pointShapeFromU32, PostProcessParams, CubeCamera, cubeCameraUpdateIntentFromF32, ReflectionProbe, reflectionProbeUpdateIntentFromF32, tonemapToU32, resolveVisibility, Fog, VolumetricFog, resolveSelectedVolumetricLight, extractVolumetricFog, MotionBlur, Camera, bloomEnabledFromF32, antialiasFromF32, tonemapFromF32, cameraProjectionFromF32 } from './chunk-ADHHVYLW.mjs';
3
3
  import { SpriteRegionOverride, SpriteInstances } from './chunk-JDWARUOI.mjs';
4
- import { PROBE_BLEND_RECORD_CAPACITY, GPU_BUFFER_USAGE_MAP_READ, GPU_BUFFER_USAGE_VERTEX, GPU_BUFFER_USAGE_COPY_DST, IES_SLICE_CAPACITY, COOKIE_SLICE_CAPACITY, isStandardPbrSkinMaterialShader, selectPasses, resolveRenderTargetMaterialSource, isCanonicalStandardPbrMaterialShader, isStandardPbrMaterialShader, PROBE_BLEND_RECORD_BYTE_SIZE, GPU_BUFFER_USAGE_QUERY_RESOLVE, GPU_BUFFER_USAGE_COPY_SRC, COOKIE_SLICE_SIZE } from './chunk-KZFTK6DO.mjs';
5
- import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID, SHADOW_ATLAS_DEFAULT_LAYERS, SkinMaterialMismatchError, MaterialSkinAttrMissingError, ShadowInvalidConfigError, EnvironmentSourceConflictError, FogCardinalityError, AtmosphereInvalidParameterError } from './chunk-RR5L4SRS.mjs';
4
+ import { PROBE_BLEND_RECORD_CAPACITY, GPU_BUFFER_USAGE_MAP_READ, GPU_BUFFER_USAGE_VERTEX, GPU_BUFFER_USAGE_COPY_DST, IES_SLICE_CAPACITY, COOKIE_SLICE_CAPACITY, isStandardPbrSkinMaterialShader, selectPasses, resolveRenderTargetMaterialSource, isCanonicalStandardPbrMaterialShader, isStandardPbrMaterialShader, PROBE_BLEND_RECORD_BYTE_SIZE, GPU_BUFFER_USAGE_QUERY_RESOLVE, GPU_BUFFER_USAGE_COPY_SRC, COOKIE_SLICE_SIZE } from './chunk-HKXTW355.mjs';
5
+ import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID, SHADOW_ATLAS_DEFAULT_LAYERS, SkinMaterialMismatchError, MaterialSkinAttrMissingError, ShadowInvalidConfigError, EnvironmentSourceConflictError, FogCardinalityError, AtmosphereInvalidParameterError } from './chunk-ZZ4YQ474.mjs';
6
6
  import { err, ok, RhiError } from '@forgeax/engine-rhi';
7
7
  import { resolveAssetHandle, walkMaterialPassesOverSharedRefs } from '@forgeax/engine-assets-runtime';
8
8
  import { SpawnLightInvalidBoundsError, routeWorldError, SpriteInstancesMutuallyExclusiveWithInstancesError, SpriteInstancesRequiresSpriteShaderError, SpriteInstancesCountMismatchError, InstanceTransformsStrideMismatchError, readRenderArrayView } from '@forgeax/engine-ecs/projection';
@@ -1641,7 +1641,10 @@ function extractFrames(worlds, owner, assets, pipelineState, materialSnapshotCac
1641
1641
  },
1642
1642
  cull: options.cull === "none" ? "none" : isCameraOwner ? "self" : "external",
1643
1643
  renderables: options.renderables ?? "full",
1644
+ ...options.renderableEntitiesByWorld?.[wi] === void 0 ? {} : { renderableEntities: options.renderableEntitiesByWorld[wi] },
1645
+ retainHidden: options.retainHidden ?? false,
1644
1646
  ...options.getMaterialShaderArtifact === void 0 ? {} : { getMaterialShaderArtifact: options.getMaterialShaderArtifact },
1647
+ ...options.instanceCollections === void 0 ? {} : { instanceCollections: options.instanceCollections },
1645
1648
  ...cameraOwnerFrame2 === void 0 ? {} : { cullCameras: cameraOwnerFrame2.cameras }
1646
1649
  });
1647
1650
  const frame = extractFrame(world, prepared);
@@ -1814,6 +1817,24 @@ function extractFrames(worlds, owner, assets, pipelineState, materialSnapshotCac
1814
1817
  const worldId = succeededIndices[index] ?? 0;
1815
1818
  return (f.reflectionProbes ?? []).map((probe) => ({ ...probe, worldId }));
1816
1819
  });
1820
+ if (options.renderables !== "none" && options.renderableEntitiesByWorld === void 0) {
1821
+ options.instanceCollections?.retain(
1822
+ new Set(
1823
+ renderables.flatMap(
1824
+ (row) => row.instances?.collectionId === void 0 ? [] : [row.instances.collectionId]
1825
+ )
1826
+ )
1827
+ );
1828
+ if (skinPaletteAllocator !== null && typeof skinPaletteAllocator.retainSliceKeys === "function") {
1829
+ skinPaletteAllocator.retainSliceKeys(
1830
+ new Set(
1831
+ renderables.flatMap(
1832
+ (row) => row.skin === void 0 ? [] : [`${worlds[row.worldId]?.identity ?? row.worldId}:${row.entityKey}`]
1833
+ )
1834
+ )
1835
+ );
1836
+ }
1837
+ }
1817
1838
  return {
1818
1839
  cameras,
1819
1840
  auxiliaryCameras,
@@ -1885,7 +1906,10 @@ function extractFrame(world, context) {
1885
1906
  materialSnapshotCache: persistentMaterialSnapshotCache,
1886
1907
  cull: cullMode,
1887
1908
  resourceOwnerFog,
1888
- getMaterialShaderArtifact
1909
+ getMaterialShaderArtifact,
1910
+ instanceCollections,
1911
+ renderableEntities,
1912
+ retainHidden
1889
1913
  } = context;
1890
1914
  const fog = resourceOwnerFog === void 0 ? selectFogFrame(world) : resourceOwnerFog ?? void 0;
1891
1915
  const fogFailure = fogState(world).failure;
@@ -2558,7 +2582,6 @@ function extractFrame(world, context) {
2558
2582
  }).unwrap();
2559
2583
  const resolveArchVersion = (entity) => {
2560
2584
  const values = [
2561
- worldInternal._getArrayView(entity, Instances, "transforms"),
2562
2585
  worldInternal._getArrayView(entity, SpriteInstances, "transforms"),
2563
2586
  worldInternal._getArrayView(entity, SpriteInstances, "regions")
2564
2587
  ];
@@ -2576,6 +2599,9 @@ function extractFrame(world, context) {
2576
2599
  for (const entry of pending) dispatch.push(entry);
2577
2600
  };
2578
2601
  for (const row of meshRendererQuery) {
2602
+ if (context.renderables === "full" && renderableEntities !== void 0 && !renderableEntities.has(row.entity)) {
2603
+ continue;
2604
+ }
2579
2605
  const hasTransform = row.has(Transform);
2580
2606
  const meshFilter = row.get(MeshFilter);
2581
2607
  const hasInstances = row.has(Instances);
@@ -2599,8 +2625,9 @@ function extractFrame(world, context) {
2599
2625
  }
2600
2626
  {
2601
2627
  const entity = row.entity;
2602
- if (isRenderable && visibility?.effective(entity) === "hidden") {
2603
- explicitlyHidden.add(entity);
2628
+ const authorVisible = !(isRenderable && visibility?.effective(entity) === "hidden");
2629
+ if (!authorVisible) explicitlyHidden.add(entity);
2630
+ if (!authorVisible && !retainHidden) {
2604
2631
  continue;
2605
2632
  }
2606
2633
  const layerVal = fLayerValue ?? 0;
@@ -2748,7 +2775,9 @@ function extractFrame(world, context) {
2748
2775
  handleRaw,
2749
2776
  renderables.length,
2750
2777
  layerVal,
2751
- materialSnap.paramSnapshot
2778
+ materialSnap.paramSnapshot,
2779
+ 0,
2780
+ materialSnap.materialShaderId
2752
2781
  );
2753
2782
  }
2754
2783
  } else if (handleRaw === 0 || assets === void 0 || assets === null) {
@@ -2771,7 +2800,9 @@ function extractFrame(world, context) {
2771
2800
  handleRaw,
2772
2801
  renderables.length,
2773
2802
  layerVal,
2774
- materialSnap.paramSnapshot
2803
+ materialSnap.paramSnapshot,
2804
+ 0,
2805
+ materialSnap.materialShaderId
2775
2806
  );
2776
2807
  }
2777
2808
  } else {
@@ -2825,7 +2856,7 @@ function extractFrame(world, context) {
2825
2856
  }
2826
2857
  const resolved = resolvedResult.value;
2827
2858
  const allPasses = resolved.passes;
2828
- const firstPassShader = allPasses.length > 0 ? runtimeMaterialShaderId(allPasses[0]?.program.module, allPasses[0]?.name) : void 0;
2859
+ const firstPassShader = runtimeMaterialShaderIdForMaterial(asset, allPasses, assets);
2829
2860
  const pv = materialValuesToLinearRuntime(
2830
2861
  resolved.values,
2831
2862
  materialColorParameterSchema(resolved.parameters ?? [], firstPassShader, assets),
@@ -3065,7 +3096,9 @@ function extractFrame(world, context) {
3065
3096
  handleRaw,
3066
3097
  renderables.length,
3067
3098
  layerVal,
3068
- paramSnap
3099
+ paramSnap,
3100
+ 0,
3101
+ firstPassShader
3069
3102
  );
3070
3103
  }
3071
3104
  }
@@ -3162,7 +3195,10 @@ function extractFrame(world, context) {
3162
3195
  ibms[jIdx] = ibmFlat.subarray(jIdx * 16, jIdx * 16 + 16);
3163
3196
  }
3164
3197
  if (skinPaletteAllocator !== null) {
3165
- const slice = skinPaletteAllocator.allocateSlice(skeleton.jointCount);
3198
+ const slice = typeof skinPaletteAllocator.allocateSliceFor === "function" ? skinPaletteAllocator.allocateSliceFor(
3199
+ `${world.identity}:${entity}`,
3200
+ skeleton.jointCount
3201
+ ) : skinPaletteAllocator.allocateSlice(skeleton.jointCount);
3166
3202
  skinPaletteAllocator.writeJointPalette(slice, ibms, jointWorlds);
3167
3203
  skinSlice = {
3168
3204
  jointCount: slice.jointCount,
@@ -3208,7 +3244,9 @@ function extractFrame(world, context) {
3208
3244
  subHandle,
3209
3245
  renderables.length,
3210
3246
  layerVal,
3211
- materialsArr[mi]?.paramSnapshot
3247
+ materialsArr[mi]?.paramSnapshot,
3248
+ 0,
3249
+ materialsArr[mi]?.materialShaderId
3212
3250
  );
3213
3251
  }
3214
3252
  }
@@ -3306,31 +3344,28 @@ function extractFrame(world, context) {
3306
3344
  };
3307
3345
  let instancesSnap;
3308
3346
  if (hasInstances) {
3309
- const transforms = worldInternal._getArrayView(entity, Instances, "transforms");
3310
- if (transforms === void 0) {
3311
- instancesSnap = {
3312
- transforms: new Float32Array(),
3313
- instanceCount: 0,
3314
- cacheKey: entity,
3315
- archVersion
3316
- };
3317
- } else {
3318
- const actualLength = transforms.length;
3319
- if (actualLength % 16 !== 0) {
3320
- worldInternal._routeError(new InstanceTransformsStrideMismatchError(actualLength), {
3347
+ const transforms = worldInternal._getArrayView(entity, Instances, "transforms") ?? new Float32Array();
3348
+ if (transforms.length % 16 !== 0) {
3349
+ worldInternal._routeError(
3350
+ new InstanceTransformsStrideMismatchError(transforms.length),
3351
+ {
3321
3352
  severity: Severity.Error,
3322
3353
  systemName: "RenderSystem.extract (Instances stride)"
3323
- });
3324
- continue;
3325
- }
3326
- const snapshotCopy = new Float32Array(transforms);
3327
- instancesSnap = {
3328
- transforms: snapshotCopy,
3329
- instanceCount: actualLength / 16,
3330
- cacheKey: entity,
3331
- archVersion
3332
- };
3354
+ }
3355
+ );
3356
+ continue;
3333
3357
  }
3358
+ const projected = instanceCollections?.project(world, entity, transforms);
3359
+ instancesSnap = {
3360
+ transforms: projected?.transforms ?? new Float32Array(transforms),
3361
+ instanceCount: transforms.length / 16,
3362
+ cacheKey: entity,
3363
+ archVersion: projected === void 0 ? fingerprintNumericArray(transforms) : 0,
3364
+ ...projected === void 0 ? {} : {
3365
+ collectionId: projected.collectionId,
3366
+ revision: projected.revision
3367
+ }
3368
+ };
3334
3369
  }
3335
3370
  const baseRenderable = {
3336
3371
  assetHandle: Math.round(fAssetHandle ?? 0),
@@ -3344,7 +3379,9 @@ function extractFrame(world, context) {
3344
3379
  materialBindingDiagnostics,
3345
3380
  worldId: 0,
3346
3381
  entityKey: entity,
3382
+ ...authorVisible ? {} : { authorVisible: false },
3347
3383
  ...skinSlice !== void 0 ? { skin: skinSlice } : {},
3384
+ ...skin?.joints === void 0 ? {} : { skinJointEntities: Array.from(skin.joints, (joint) => Number(joint)) },
3348
3385
  ...morph !== void 0 ? { morph } : {},
3349
3386
  ...instancesSnap !== void 0 ? { instances: instancesSnap } : {},
3350
3387
  ...spriteInstancesSnap !== void 0 ? { spriteInstances: spriteInstancesSnap } : {},
@@ -3516,12 +3553,14 @@ var DEFAULT_FORWARD_PASS = {
3516
3553
  program: { module: "forgeax::default-unlit", vertexEntry: "vs_main", fragmentEntry: "fs_main" },
3517
3554
  renderState: { tags: { LightMode: "Forward" }, queue: 2e3 }
3518
3555
  };
3519
- function appendMaterialDispatchEntries(pendingDispatch, passes, entity, materialHandle, renderableIndex, layer, paramSnapshot, passIndexOffset = 0) {
3556
+ function appendMaterialDispatchEntries(pendingDispatch, passes, entity, materialHandle, renderableIndex, layer, paramSnapshot, passIndexOffset = 0, materialShaderIdOverride) {
3520
3557
  const matchedPasses = selectPasses(passes, {});
3521
3558
  for (let pIdx = 0; pIdx < matchedPasses.length; pIdx++) {
3522
3559
  const pass = matchedPasses[pIdx];
3523
3560
  if (pass === void 0) continue;
3524
3561
  const passState = pass.renderState ?? {};
3562
+ const authoredShaderId = runtimeMaterialShaderId(pass.program.module, pass.name);
3563
+ const dispatchShaderId = authoredShaderId === "forgeax::default-shadow-caster" ? authoredShaderId : materialShaderIdOverride ?? authoredShaderId;
3525
3564
  pendingDispatch.push({
3526
3565
  entityIndex: entity,
3527
3566
  materialHandle,
@@ -3536,7 +3575,14 @@ function appendMaterialDispatchEntries(pendingDispatch, passes, entity, material
3536
3575
  defines: void 0,
3537
3576
  vertexEntry: pass.program.vertexEntry,
3538
3577
  fragmentEntry: pass.program.fragmentEntry,
3539
- materialShaderId: runtimeMaterialShaderId(pass.program.module, pass.name),
3578
+ // A cooked Standard publication supplies one specialization key for its
3579
+ // forward/deferred artifact, but its ShadowCaster pass still owns the
3580
+ // engine depth-only shader. Keep the pass-local canonical identity so a
3581
+ // specialized Standard source (which only declares fs_main/fs_gbuffer)
3582
+ // is never asked to build an fs_shadow pipeline. Authored non-Standard
3583
+ // ShadowCaster modules retain the publication override and continue to
3584
+ // use their producer-owned source.
3585
+ materialShaderId: dispatchShaderId,
3540
3586
  paramSnapshot,
3541
3587
  ...passState.stencilReference !== void 0 && {
3542
3588
  stencilReference: passState.stencilReference
@@ -3632,6 +3678,10 @@ function runtimeMaterialShaderId(module, passName) {
3632
3678
  return module;
3633
3679
  }
3634
3680
  }
3681
+ function runtimeMaterialShaderIdForMaterial(material, passes, assets) {
3682
+ const authored = runtimeMaterialShaderId(passes[0]?.program.module, passes[0]?.name);
3683
+ return assets.getMaterialProjectionForPayload(material)?.specializationKey ?? authored;
3684
+ }
3635
3685
  function pipelineRenderState(renderState) {
3636
3686
  if (renderState === void 0) return void 0;
3637
3687
  const {
@@ -3888,7 +3938,7 @@ function resolveMaterialSnapshot(handleRaw, world, assetsRef, materialSnapshotCa
3888
3938
  if (!resolvedResult.ok) return defaultMaterialSnapshot(handleRaw);
3889
3939
  const resolved = resolvedResult.value;
3890
3940
  const allPasses = resolved.passes;
3891
- const firstPassShader = allPasses.length > 0 ? runtimeMaterialShaderId(allPasses[0]?.program.module, allPasses[0]?.name) : void 0;
3941
+ const firstPassShader = runtimeMaterialShaderIdForMaterial(asset, allPasses, assetsRef);
3892
3942
  const pv = materialValuesToLinearRuntime(
3893
3943
  resolved.values,
3894
3944
  materialColorParameterSchema(resolved.parameters ?? [], firstPassShader, assetsRef),
@@ -4359,8 +4409,11 @@ function prepareExtractContext(world, options = {}) {
4359
4409
  cull: options.cull ?? "self",
4360
4410
  cullCameras: options.cullCameras,
4361
4411
  renderables,
4412
+ renderableEntities: options.renderableEntities,
4413
+ retainHidden: options.retainHidden ?? false,
4362
4414
  visibility: renderables === "none" ? ALL_VISIBLE : resolveVisibility(world),
4363
- getMaterialShaderArtifact: options.getMaterialShaderArtifact
4415
+ getMaterialShaderArtifact: options.getMaterialShaderArtifact,
4416
+ instanceCollections: options.instanceCollections
4364
4417
  };
4365
4418
  }
4366
4419
  var fogQueries = /* @__PURE__ */ new WeakMap();
@@ -5078,5 +5131,5 @@ var ProbeBlendSceneProjection = class {
5078
5131
  };
5079
5132
 
5080
5133
  export { InstanceBoundsCache, OcclusionRenderRuntime, PROBE_MAX_CONTRIBUTORS, ProbeBlendSceneProjection, SKYLIGHT_RECOVERY_FALLBACK, admitProbeContributors, blendLightProbes, buildRectAreaWorldFrame, createCookieProjectionMatrixData, createExtendedLightingState, extractFrames, fingerprintNumericArray, glyphTextLayoutSystem, primitiveKey, primitiveKeyId, projectExtendedLightingInspection, promoteExtendedLightingCandidate, recordExtendedLightingFailure, rectAreaFacesPoint, scaledProbeWeight, setOcclusionRuntimeTestHooks, viewKey, viewKeyId };
5081
- //# sourceMappingURL=chunk-Z3YYH2MB.mjs.map
5082
- //# sourceMappingURL=chunk-Z3YYH2MB.mjs.map
5134
+ //# sourceMappingURL=chunk-N3RT2EUR.mjs.map
5135
+ //# sourceMappingURL=chunk-N3RT2EUR.mjs.map