@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.
- package/README.md +100 -1
- package/dist/assembly/factory.d.ts +1 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/material/surface-projection.d.ts +24 -0
- package/dist/assembly/material/surface-projection.d.ts.map +1 -0
- package/dist/assembly/material-shader-policy.d.ts +20 -0
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer.d.ts +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/assembly/webgpu-vertex-layouts.d.ts +89 -0
- package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -0
- package/dist/assets/asset-decoders.d.ts.map +1 -1
- package/dist/authoring.mjs +1 -1
- package/dist/{chunk-Q752SHI5.mjs → chunk-ADHHVYLW.mjs} +3 -3
- package/dist/chunk-ADHHVYLW.mjs.map +1 -0
- package/dist/{chunk-TFH5I7JJ.mjs → chunk-E34VL5VI.mjs} +3 -3
- package/dist/{chunk-TFH5I7JJ.mjs.map → chunk-E34VL5VI.mjs.map} +1 -1
- package/dist/{chunk-KZFTK6DO.mjs → chunk-HKXTW355.mjs} +7 -4
- package/dist/chunk-HKXTW355.mjs.map +1 -0
- package/dist/{chunk-YKB5DQV7.mjs → chunk-JSEDTZYS.mjs} +87 -19
- package/dist/chunk-JSEDTZYS.mjs.map +1 -0
- package/dist/{chunk-UQYS7FRM.mjs → chunk-KM2NOX2I.mjs} +4 -4
- package/dist/{chunk-UQYS7FRM.mjs.map → chunk-KM2NOX2I.mjs.map} +1 -1
- package/dist/{chunk-Z3YYH2MB.mjs → chunk-N3RT2EUR.mjs} +94 -41
- package/dist/chunk-N3RT2EUR.mjs.map +1 -0
- package/dist/{chunk-YRUYGA4A.mjs → chunk-TCLDX7SZ.mjs} +559 -138
- package/dist/chunk-TCLDX7SZ.mjs.map +1 -0
- package/dist/{chunk-RR5L4SRS.mjs → chunk-ZZ4YQ474.mjs} +2 -2
- package/dist/{chunk-RR5L4SRS.mjs.map → chunk-ZZ4YQ474.mjs.map} +1 -1
- package/dist/components/instances.d.ts +13 -31
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +865 -142
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +6 -1
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +4 -0
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +27 -9
- package/dist/index.mjs.map +1 -1
- package/dist/instance-buffer-cache.d.ts +7 -1
- package/dist/instance-buffer-cache.d.ts.map +1 -1
- package/dist/instances.d.ts +101 -0
- package/dist/instances.d.ts.map +1 -0
- package/dist/internal.mjs +5 -5
- package/dist/materials.d.ts +63 -2
- package/dist/materials.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +13 -2
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +22 -3
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +2 -1
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +11 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +1 -1
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/render-contract.d.ts +4 -0
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +4 -0
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +25 -1
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +4 -1
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene-types.d.ts +2 -0
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +12 -1
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/systems/skin-palette-allocator.d.ts +6 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/temporal/index.mjs +5 -5
- package/package.json +20 -20
- package/src/__tests__/gpu-scene.unit.test.ts +38 -2
- package/src/__tests__/instances-store.unit.test.ts +46 -0
- package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +5 -13
- package/src/__tests__/material-pass-policy.unit.test.ts +69 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +69 -0
- package/src/__tests__/material-surface-authoring.test-d.ts +62 -0
- package/src/__tests__/materials-transmission-validation.unit.test.ts +24 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +0 -4
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +42 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +33 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +30 -2
- package/src/__tests__/surface-adjacent-regressions.integration.test.ts +60 -0
- package/src/__tests__/surface-standard-pipeline.browser.test.ts +20 -0
- package/src/__tests__/surface-standard-pipeline.dawn.test.ts +20 -0
- package/src/__tests__/surface-standard-pipeline.fixture.ts +132 -0
- package/src/__tests__/surface-variant-provenance.integration.test.ts +33 -0
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +1 -1
- package/src/assembly/factory.ts +2 -0
- package/src/assembly/material/__tests__/standard-layer-plan-projection.integration.test.ts +18 -0
- package/src/assembly/material/__tests__/surface-pass-projection.integration.test.ts +62 -0
- package/src/assembly/material/surface-projection.ts +90 -0
- package/src/assembly/material-shader-policy.ts +88 -10
- package/src/assembly/recovery/renderer-recover.ts +1 -1
- package/src/assembly/webgpu-ready.ts +3 -16
- package/src/assembly/webgpu-renderer.ts +90 -158
- package/src/assembly/webgpu-vertex-layouts.ts +132 -0
- package/src/assets/asset-decoders.ts +27 -4
- package/src/components/instances.ts +14 -197
- package/src/gpu-driven/production-raster.ts +34 -1
- package/src/gpu-scene.ts +84 -29
- package/src/index.ts +1 -0
- package/src/instance-buffer-cache.ts +14 -1
- package/src/instances.ts +288 -0
- package/src/materials.ts +107 -12
- package/src/pipeline-builder.ts +14 -10
- package/src/pipeline-spec.ts +6 -14
- package/src/record/frame-snapshot.ts +19 -2
- package/src/record/frame.ts +31 -2
- package/src/record/main-pass-geometry.ts +498 -59
- package/src/record/main-pass-sprite-draws.ts +1 -1
- package/src/record/render-context.ts +4 -0
- package/src/record/shadow-pass.ts +46 -99
- package/src/recovery/render-system-candidate.ts +41 -4
- package/src/render-contract.ts +4 -0
- package/src/render-system-extract-tail.ts +107 -51
- package/src/render-system-extract.ts +53 -26
- package/src/render-system.ts +40 -5
- package/src/scene/render-scene-types.ts +2 -0
- package/src/scene/render-scene.ts +579 -36
- package/src/systems/skin-palette-allocator.ts +129 -7
- package/src/transmission/__tests__/surface-compatibility.integration.test.ts +32 -0
- package/dist/chunk-KZFTK6DO.mjs.map +0 -1
- package/dist/chunk-Q752SHI5.mjs.map +0 -1
- package/dist/chunk-YKB5DQV7.mjs.map +0 -1
- package/dist/chunk-YRUYGA4A.mjs.map +0 -1
- package/dist/chunk-Z3YYH2MB.mjs.map +0 -1
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { inspectVolumetricFog, inspectLodOcclusion, resolveSsrAdmissionGeneration, projectSsrDependencies, inspectReflectionFallback, admitReflectionProbe, DEFAULT_REFLECTION_PROBE_LIMITS, buildReflectionProbeTable, advanceProbeFilter, buildCubeCameraFaceViews, commitProbeFilterStep, resolveReflectionFallbackSource, deriveReflectionFallbackProjection, reflectionFallbackCoverage, reflectionFallbackSourceKey, reflectionFallbackProjectionSignature, createProbeFilterState, ReflectionProbeProjection, admitPointsLines, inspectPointShadow } from './chunk-
|
|
2
|
-
import { createExtendedLightingState, promoteExtendedLightingCandidate, OcclusionRenderRuntime, extractFrames, viewKey, primitiveKey, glyphTextLayoutSystem, projectExtendedLightingInspection, viewKeyId, primitiveKeyId, ProbeBlendSceneProjection, SKYLIGHT_RECOVERY_FALLBACK, InstanceBoundsCache, fingerprintNumericArray, createCookieProjectionMatrixData } from './chunk-
|
|
1
|
+
import { inspectVolumetricFog, inspectLodOcclusion, resolveSsrAdmissionGeneration, projectSsrDependencies, inspectReflectionFallback, admitReflectionProbe, DEFAULT_REFLECTION_PROBE_LIMITS, buildReflectionProbeTable, advanceProbeFilter, buildCubeCameraFaceViews, commitProbeFilterStep, resolveReflectionFallbackSource, deriveReflectionFallbackProjection, reflectionFallbackCoverage, reflectionFallbackSourceKey, reflectionFallbackProjectionSignature, createProbeFilterState, ReflectionProbeProjection, admitPointsLines, inspectPointShadow } from './chunk-KM2NOX2I.mjs';
|
|
2
|
+
import { createExtendedLightingState, promoteExtendedLightingCandidate, OcclusionRenderRuntime, extractFrames, viewKey, primitiveKey, glyphTextLayoutSystem, projectExtendedLightingInspection, viewKeyId, primitiveKeyId, ProbeBlendSceneProjection, SKYLIGHT_RECOVERY_FALLBACK, InstanceBoundsCache, fingerprintNumericArray, createCookieProjectionMatrixData } from './chunk-N3RT2EUR.mjs';
|
|
3
3
|
import './chunk-FJ6P52EE.mjs';
|
|
4
|
-
import { MeshFilter, MeshRenderer, Instances, Layer, Visibility, Camera, MotionBlur, DirectionalLight, LightProbe, PointLight, PointLightShadow, SpotLight, Skylight, SkyboxBackground, PostProcessParams, ReflectionProbe, VolumetricFog, projectMeshMaterialBindingObservation, createVisibilityBudget, hasVolumetricFogCapability, CUBE_CAMERA_FACE_ORDER, CAMERA_PROJECTION_ORTHOGRAPHIC } from './chunk-
|
|
4
|
+
import { MeshFilter, MeshRenderer, Instances, Layer, Visibility, Points, Lines, SortKey, Camera, MotionBlur, DirectionalLight, LightProbe, PointLight, PointLightShadow, SpotLight, Skylight, SkyboxBackground, PostProcessParams, ReflectionProbe, VolumetricFog, projectMeshMaterialBindingObservation, createVisibilityBudget, hasVolumetricFogCapability, CUBE_CAMERA_FACE_ORDER, CAMERA_PROJECTION_ORTHOGRAPHIC } from './chunk-ADHHVYLW.mjs';
|
|
5
5
|
import { SpriteInstances, SpriteRegionOverride, TileLayer, decodeSortScope, Tilemap } from './chunk-JDWARUOI.mjs';
|
|
6
|
-
import { assertStorageBufferCap, GpuBuffer, GpuTexture, deriveRenderDataTexture, deriveRenderDataMesh, deriveRenderDataCubemap, createIblPipelines, CUBEMAP_FACE_VERTICES, runIblPrecompute, createClusterBinScratch, resetHdrpBuffers, retireTemporalGpuState, PostProcessError, entryHasDepthRead, DEPTH_MIN_PARAMS_BYTE_SIZE, postProcessShaderModuleLabel, resolveSsaoParameters, buildPerFrameBindGroups, postProcessShaderEntrySignature, PipelineSpecError, CAPTURE_VIEW_PROJS, PREFILTER_MIP_LEVELS, selectSwapChainFormat, setIblComposedShaders, POINTS_LINES_MATERIAL_SHADER_ID, createHdrpClusterMembershipBindGroupLayoutDescriptor, createSkylightFallback, buildSpecConstTable, buildLinearLdrMaterialSpecTable, getOrBuildPipeline, cacheKeyOf, REFLECTION_PROBE_VIEW_SLOT_BASE, VIEW_UNIFORM_SLOT_STRIDE, getOrCreateIblCache, postProcessShaderPipelineLabel, createPointsLinesLaneAdapter, computeViewMatrix, computeProjectionMatrix, prepareFrameLighting, warnMultiSkylight, warnMultiSkybox, selectLazyEquirectHandle, driveLazyEquirectProjection, warnZeroLightStandard, writeShadowParamsBuffer, writeSpotModifierTextures, writeHdrpClusterAndSsaoBuffers, resolveSkyboxActive, computeSplitLdrSprite, writeViewUbo, writePointsLinesViewUbo, writeShadowCasterUniforms, uploadMeshSsboBatch, passKindPolicyTable, colorFormatsForPassKind, configureSurface, VIEW_UNIFORM_BUFFER_SIZE, POINTS_LINES_VIEW_BUFFER_SIZE, SHADOW_CASTER_BUFFER_SIZE, FALLBACK_BYTES_PER_ROW, PREFILTER_SIZE, geometryRenderStateForTopology, assembleMaterialWithSkylightEntries, MESH_SSBO_BYTES, createPointsLinesLaneContract, foldDispatchBuckets, CUBE_CAPTURE_VIEW_SLOT_BASE, variantSetFromDefines, cleanPerEntityCache, ensureMeshSsboCapacity, buildFoldDispatchPlan, evaluateFoldBucketUniformCap, incrementFoldedDrawsMetric, buildFullscreenPostProcessPass, getTemporalGpuState, getTemporalParamsBuffer, getTemporalBindGroupResources, resolveSurfaceFormatPair, resolveSurfaceProfile, encodeMainPass, abortTemporalGpuSubmit, commitTemporalGpuSubmit, retireTemporalGpuStateAfterFence, hasPendingTemporalGpuSubmit, importRenderPipelineSurface, DEFERRED_COLOR_FORMATS, aggregateTemporalDemand, standardTemporalLaneAdmission, addTypedScenePass, addTypedSsaoPasses, typedFrameClearColor, addTypedSkyboxPass, createStandardSceneDataTarget, addStandardSceneDataPass, addTypedFrameObservationPass, temporalReadIndex, temporalWriteIndex, addReflectionFallbackObservationPass, BYTES_PER_DIRECT_LIGHT_SLOT, createRenderPipelineTarget, resolveOutputDither, addTypedTemporalResolvePass, addTypedBloomPasses, addTypedOutputTransformPass, addTypedFullscreenPass, addTypedCompositePostEffects, standardTopologyVariantSet, geometryRenderStateForPass, standardStorageVariantSet, getOrCreateHdrpBuffers, encodeDirectionalShadowPass, encodePointShadowPass, encodeSpotShadowPass, VIEW_UNIFORM_BYTES, variantSetFromVertexLayoutProjection, MATERIAL_PER_ENTITY_STRIDE, isTemporalFullscreenBinding, createFullscreenBindGroup, applyParamSnapshotToUbo, residentTextureView, TYPED_BLOOM_PASS_NAMES } from './chunk-
|
|
6
|
+
import { assertStorageBufferCap, GpuBuffer, GpuTexture, deriveRenderDataTexture, deriveRenderDataMesh, deriveRenderDataCubemap, createIblPipelines, CUBEMAP_FACE_VERTICES, runIblPrecompute, InstanceProjectionStore, createClusterBinScratch, resetHdrpBuffers, retireTemporalGpuState, PostProcessError, entryHasDepthRead, DEPTH_MIN_PARAMS_BYTE_SIZE, postProcessShaderModuleLabel, resolveSsaoParameters, buildPerFrameBindGroups, postProcessShaderEntrySignature, PipelineSpecError, CAPTURE_VIEW_PROJS, PREFILTER_MIP_LEVELS, selectSwapChainFormat, setIblComposedShaders, POINTS_LINES_MATERIAL_SHADER_ID, createHdrpClusterMembershipBindGroupLayoutDescriptor, createSkylightFallback, buildSpecConstTable, buildLinearLdrMaterialSpecTable, getOrBuildPipeline, cacheKeyOf, REFLECTION_PROBE_VIEW_SLOT_BASE, VIEW_UNIFORM_SLOT_STRIDE, getOrCreateIblCache, postProcessShaderPipelineLabel, createPointsLinesLaneAdapter, computeViewMatrix, computeProjectionMatrix, prepareFrameLighting, warnMultiSkylight, warnMultiSkybox, selectLazyEquirectHandle, driveLazyEquirectProjection, warnZeroLightStandard, writeShadowParamsBuffer, writeSpotModifierTextures, writeHdrpClusterAndSsaoBuffers, resolveSkyboxActive, computeSplitLdrSprite, writeViewUbo, writePointsLinesViewUbo, writeShadowCasterUniforms, uploadMeshSsboBatch, passKindPolicyTable, colorFormatsForPassKind, configureSurface, VIEW_UNIFORM_BUFFER_SIZE, POINTS_LINES_VIEW_BUFFER_SIZE, SHADOW_CASTER_BUFFER_SIZE, FALLBACK_BYTES_PER_ROW, PREFILTER_SIZE, geometryRenderStateForTopology, assembleMaterialWithSkylightEntries, MESH_SSBO_BYTES, createPointsLinesLaneContract, foldDispatchBuckets, CUBE_CAPTURE_VIEW_SLOT_BASE, variantSetFromDefines, cleanPerEntityCache, ensureMeshSsboCapacity, buildFoldDispatchPlan, evaluateFoldBucketUniformCap, incrementFoldedDrawsMetric, resolveGeometryInstanceBuffer, buildFullscreenPostProcessPass, getTemporalGpuState, getTemporalParamsBuffer, getTemporalBindGroupResources, resolveSurfaceFormatPair, resolveSurfaceProfile, encodeMainPass, abortTemporalGpuSubmit, commitTemporalGpuSubmit, retireTemporalGpuStateAfterFence, hasPendingTemporalGpuSubmit, importRenderPipelineSurface, DEFERRED_COLOR_FORMATS, aggregateTemporalDemand, standardTemporalLaneAdmission, addTypedScenePass, addTypedSsaoPasses, typedFrameClearColor, addTypedSkyboxPass, createStandardSceneDataTarget, addStandardSceneDataPass, addTypedFrameObservationPass, temporalReadIndex, temporalWriteIndex, addReflectionFallbackObservationPass, BYTES_PER_DIRECT_LIGHT_SLOT, createRenderPipelineTarget, resolveOutputDither, addTypedTemporalResolvePass, addTypedBloomPasses, addTypedOutputTransformPass, addTypedFullscreenPass, addTypedCompositePostEffects, standardTopologyVariantSet, geometryRenderStateForPass, standardStorageVariantSet, getOrCreateHdrpBuffers, encodeDirectionalShadowPass, encodePointShadowPass, encodeSpotShadowPass, VIEW_UNIFORM_BYTES, variantSetFromVertexLayoutProjection, MATERIAL_PER_ENTITY_STRIDE, isTemporalFullscreenBinding, createFullscreenBindGroup, applyParamSnapshotToUbo, residentTextureView, TYPED_BLOOM_PASS_NAMES } from './chunk-TCLDX7SZ.mjs';
|
|
7
7
|
import { getTransparentSortConfig, TRANSPARENT_SORT_MODE_DISTANCE, TRANSPARENT_SORT_MODE_LAYER_Z, TRANSPARENT_SORT_MODE_LAYER_Y, TRANSPARENT_SORT_MODE_LAYER_YZ } from './chunk-RXZ3RGOU.mjs';
|
|
8
|
-
import { DEFAULT_STANDARD_PROFILE, DEFAULT_CLUSTER_GRID, createSceneDataCatalog, STANDARD_PIPELINE_ID, STANDARD_LIGHT_COUNTS, STANDARD_POST_STAGE_NAMES, resolveVolumetricFogProfile, isSceneDataTarget } from './chunk-
|
|
9
|
-
import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from './chunk-
|
|
10
|
-
import { DeviceScope, SKIN_MATERIAL_SHADER_ID, EXTENDED_LIGHTING_REQUIRED_SAMPLED_TEXTURES, GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_MAP_READ, resolveRenderTargetMaterialSource, createRenderTargetMaterialSource, deriveExtendedLightingCapability, GPU_BUFFER_USAGE_VERTEX, GPU_BUFFER_USAGE_INDEX, EXTENDED_LIGHTING_TOPOLOGY, GPU_BUFFER_USAGE_UNIFORM, getTextureIdentity, worldEntityKey, createHdrpBindGroupLayoutDescriptor, createHdrpSkinBindGroupLayoutDescriptor, IES_SLICE_WIDTH, IES_SLICE_HEIGHT, COOKIE_SLICE_SIZE, COOKIE_MATRIX_BYTES, makeZeroCameraFallbackSnapshot, GPU_BUFFER_USAGE_QUERY_RESOLVE, GPU_BUFFER_USAGE_COPY_SRC, buildPbrPipelineLayouts, buildPbrSkinLayouts, GPU_BUFFER_USAGE_STORAGE, resolvePipelineGroup2Contract, GPU_SHADER_STAGE_FRAGMENT, validateGraphTargetCaptureReadback, isCanonicalStandardPbrMaterialShader, isStandardPbrMaterialShader, buildBindGroupLayoutDescriptor, GPU_BUFFER_USAGE_INDIRECT, buildPbrMaterialUserRegionEntries, extendedLightingSampledTextureCapacityAvailable, GPU_SHADER_STAGE_VERTEX, SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET, shadowCasterVariantSet, SHADOW_CASTER_SHADER_ID, LifecycleTransaction } from './chunk-
|
|
11
|
-
import { RendererContractFailureError, RendererOperationError, STANDARD_OUTPUT_TRANSFORM_FEATURE_ID, RenderTargetStateInvalidError, RenderTargetOperationFailedError, RenderTargetCapabilityMissingError, RenderTargetDescriptorInvalidError, GPU_TEXTURE_USAGE_TEXTURE_BINDING, GPU_TEXTURE_USAGE_COPY_DST, RENDER_PHASE_CATALOG, FrameReceiptStaleError, RenderFeatureStageFailedError, RenderFeatureCapabilityMissingError, RenderFeatureRegistrationConflictError, GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING, GPU_TEXTURE_USAGE_COPY_SRC, EnvironmentGenerationFailedError, PointsLinesMaterialUnsupportedError, StandardProfileInvalidError, TransmissionCapabilityMissingError, SHADOW_ATLAS_DEFAULT_LAYERS, GPU_TEXTURE_USAGE_RENDER_ATTACHMENT, TemporalFrameSubmitError, ObservationUnavailableError, RenderFeaturePreparationFailedError, PointsLinesPrepareFailedError, SHADOW_ATLAS_DEFAULT_FACE_SIZE, SceneDataUnavailableError, RenderFeatureDrawRecordingFailedError, PointShadowAtlasUninitializedError, SkinPaletteOverflowError, RenderFeaturePreparedStateMismatchError, FXAA_POST_PROCESS_ID } from './chunk-
|
|
8
|
+
import { DEFAULT_STANDARD_PROFILE, DEFAULT_CLUSTER_GRID, createSceneDataCatalog, STANDARD_PIPELINE_ID, STANDARD_LIGHT_COUNTS, STANDARD_POST_STAGE_NAMES, resolveVolumetricFogProfile, isSceneDataTarget } from './chunk-E34VL5VI.mjs';
|
|
9
|
+
import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from './chunk-JSEDTZYS.mjs';
|
|
10
|
+
import { DeviceScope, SKIN_MATERIAL_SHADER_ID, EXTENDED_LIGHTING_REQUIRED_SAMPLED_TEXTURES, GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_MAP_READ, resolveRenderTargetMaterialSource, createRenderTargetMaterialSource, deriveExtendedLightingCapability, GPU_BUFFER_USAGE_VERTEX, GPU_BUFFER_USAGE_INDEX, EXTENDED_LIGHTING_TOPOLOGY, GPU_BUFFER_USAGE_UNIFORM, getTextureIdentity, worldEntityKey, createHdrpBindGroupLayoutDescriptor, createHdrpSkinBindGroupLayoutDescriptor, IES_SLICE_WIDTH, IES_SLICE_HEIGHT, COOKIE_SLICE_SIZE, COOKIE_MATRIX_BYTES, makeZeroCameraFallbackSnapshot, GPU_BUFFER_USAGE_QUERY_RESOLVE, GPU_BUFFER_USAGE_COPY_SRC, buildPbrPipelineLayouts, buildPbrSkinLayouts, GPU_BUFFER_USAGE_STORAGE, resolvePipelineGroup2Contract, GPU_SHADER_STAGE_FRAGMENT, instanceCollectionCacheKey, validateGraphTargetCaptureReadback, isCanonicalStandardPbrMaterialShader, isStandardPbrMaterialShader, buildBindGroupLayoutDescriptor, GPU_BUFFER_USAGE_INDIRECT, buildPbrMaterialUserRegionEntries, extendedLightingSampledTextureCapacityAvailable, GPU_SHADER_STAGE_VERTEX, SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET, shadowCasterVariantSet, SHADOW_CASTER_SHADER_ID, LifecycleTransaction } from './chunk-HKXTW355.mjs';
|
|
11
|
+
import { RendererContractFailureError, RendererOperationError, STANDARD_OUTPUT_TRANSFORM_FEATURE_ID, RenderTargetStateInvalidError, RenderTargetOperationFailedError, RenderTargetCapabilityMissingError, RenderTargetDescriptorInvalidError, GPU_TEXTURE_USAGE_TEXTURE_BINDING, GPU_TEXTURE_USAGE_COPY_DST, RENDER_PHASE_CATALOG, FrameReceiptStaleError, RenderFeatureStageFailedError, RenderFeatureCapabilityMissingError, RenderFeatureRegistrationConflictError, GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING, GPU_TEXTURE_USAGE_COPY_SRC, EnvironmentGenerationFailedError, PointsLinesMaterialUnsupportedError, StandardProfileInvalidError, TransmissionCapabilityMissingError, SHADOW_ATLAS_DEFAULT_LAYERS, GPU_TEXTURE_USAGE_RENDER_ATTACHMENT, TemporalFrameSubmitError, ObservationUnavailableError, RenderFeaturePreparationFailedError, PointsLinesPrepareFailedError, SHADOW_ATLAS_DEFAULT_FACE_SIZE, SceneDataUnavailableError, RenderFeatureDrawRecordingFailedError, PointShadowAtlasUninitializedError, SkinPaletteOverflowError, RenderFeaturePreparedStateMismatchError, FXAA_POST_PROCESS_ID } from './chunk-ZZ4YQ474.mjs';
|
|
12
12
|
import { ok, err, RhiError, validateDrawArgs } from '@forgeax/engine-rhi';
|
|
13
13
|
import { AssetRegistry, DynamicTextureStore, adaptDynamicTextureDevice, getOrCreateMipmapPipeline, prepareMipmaps, blitMipmapsSync, HANDLE_CUBE, HANDLE_TRIANGLE, HANDLE_QUAD, HANDLE_SPHERE, HANDLE_NINESLICE_QUAD, BuiltinAssetRegistry, resolveAssetHandle, numMipLevels, encodeMipmapLevel, resolveTilesetRuntime, MeshSsboCeilingReachedError, MeshSsboCapacityExceededError } from '@forgeax/engine-assets-runtime';
|
|
14
14
|
import { audioLoader } from '@forgeax/engine-audio-webaudio';
|
|
15
15
|
import { Update } from '@forgeax/engine-ecs';
|
|
16
16
|
import { createRenderReadLease } from '@forgeax/engine-ecs/projection';
|
|
17
17
|
import { PROCEDURAL_FLOATS_PER_VERTEX, deriveVertexLayoutProjection, deriveVertexBufferLayoutFromProjection, deriveVertexBufferLayout } from '@forgeax/engine-geometry';
|
|
18
|
-
import {
|
|
19
|
-
import { ShaderCatalog, findVariantByKey, LTC_TABLES, standardPhysicalTextureFields, LTC_TABLE_HEIGHT, LTC_TABLE_WIDTH, DEFAULT_STANDARD_PBR_PARAM_SCHEMA } from '@forgeax/engine-shader';
|
|
18
|
+
import { GlobalTransform, ChildOf, MorphWeights, collectSubtree, Name, registerPropagateTransforms, Children, Transform } from '@forgeax/engine-scene';
|
|
19
|
+
import { ShaderCatalog, findVariantByKey, STANDARD_PIPELINE_PARAM_SCHEMA, LTC_TABLES, standardPhysicalTextureFields, LTC_TABLE_HEIGHT, LTC_TABLE_WIDTH, DEFAULT_STANDARD_PBR_PARAM_SCHEMA } from '@forgeax/engine-shader';
|
|
20
20
|
import { halfFloat, mat4, vec3, frustum, box3, mat3 } from '@forgeax/engine-math';
|
|
21
21
|
import { err as err$1, ok as ok$1, derive, handleSlot, toShared, deriveTextureLayout, ASSET_ERROR_HINTS, countExtraUvSets, RenderQueue, IMAGE_ERROR_HINTS, unwrapHandle } from '@forgeax/engine-types';
|
|
22
22
|
import { createCurrentFrameObservationLease, RenderGraphError, RenderGraphBuilder } from '@forgeax/engine-render-graph';
|
|
@@ -5905,7 +5905,7 @@ function pipelineCreationHint(error) {
|
|
|
5905
5905
|
function buildPipelineForMaterialShader(id, entry, ctx, renderState, geometry, vertexEntry, fragmentEntry, defines, passKind = "forward", sampleCount = 1) {
|
|
5906
5906
|
const label = ctx.label ?? `pbr-pipeline-${id}`;
|
|
5907
5907
|
const vsEntry = (passKind === "temporal" ? "vs_temporal" : "vs_main");
|
|
5908
|
-
const fsEntry = fragmentEntry ?? (passKind === "temporal" ? "fs_temporal" : passKind === "deferred" ? "fs_gbuffer" : "fs_main");
|
|
5908
|
+
const fsEntry = fragmentEntry ?? (passKind === "temporal" ? "fs_temporal" : passKind === "deferred" ? "fs_gbuffer" : passKind === "shadow-caster" ? "fs_shadow" : "fs_main");
|
|
5909
5909
|
let source = entry.source;
|
|
5910
5910
|
const moduleResult = ctx.shaderModuleFactory.createShaderModule({
|
|
5911
5911
|
code: source,
|
|
@@ -5928,12 +5928,13 @@ function buildPipelineForMaterialShader(id, entry, ctx, renderState, geometry, v
|
|
|
5928
5928
|
vertex: {
|
|
5929
5929
|
module: shaderModule,
|
|
5930
5930
|
entryPoint: vsEntry,
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5931
|
+
// Surface-backed Standard shadow entries evaluate the same material
|
|
5932
|
+
// surface as Forward/Deferred, so their vertex stage consumes normal,
|
|
5933
|
+
// UV, and tangent inputs in addition to position. Keep the complete
|
|
5934
|
+
// derived mesh layout here; extra attributes remain legal for legacy
|
|
5935
|
+
// position-only custom casters, while trimming to position would make
|
|
5936
|
+
// the built-in Surface shadow shader fail WebGPU validation.
|
|
5937
|
+
buffers: [...ctx.vertexBuffers]
|
|
5937
5938
|
},
|
|
5938
5939
|
// Vertex-only depth pass writes `fragment: undefined` (GPU derives
|
|
5939
5940
|
// depth from gl_Position.z). A custom ShadowCaster shader with a
|
|
@@ -8880,6 +8881,7 @@ function popMin(heap) {
|
|
|
8880
8881
|
return first;
|
|
8881
8882
|
}
|
|
8882
8883
|
function decideVisibility(input) {
|
|
8884
|
+
if (!input.authorVisible) return { draw: false, stage: "author" };
|
|
8883
8885
|
if (!input.validBounds) return { draw: true, stage: "bounds" };
|
|
8884
8886
|
if (input.occlusion.status === "hidden" && input.occlusion.queryable) {
|
|
8885
8887
|
return { draw: false, stage: "occlusion" };
|
|
@@ -10438,6 +10440,26 @@ var GpuDrivenProduction = class _GpuDrivenProduction {
|
|
|
10438
10440
|
static forDevice(device, shaderModuleFactory) {
|
|
10439
10441
|
return new _GpuDrivenProduction(device, shaderModuleFactory);
|
|
10440
10442
|
}
|
|
10443
|
+
/** Recovery has no frame retry: await generated programs before preparing the graph. */
|
|
10444
|
+
static async forRecoveryDevice(device, factory, createShaderModule) {
|
|
10445
|
+
const modules = /* @__PURE__ */ new Map();
|
|
10446
|
+
for (const descriptor of [
|
|
10447
|
+
{ label: "gpu-driven-view", code: GPU_DRIVEN_VIEW_WGSL },
|
|
10448
|
+
{ label: "gpu-driven-rigid-unlit", code: GPU_DRIVEN_RIGID_UNLIT_WGSL }
|
|
10449
|
+
]) {
|
|
10450
|
+
const module = await createShaderModule(descriptor);
|
|
10451
|
+
if (!module.ok) return module;
|
|
10452
|
+
modules.set(descriptor.code, module.value);
|
|
10453
|
+
}
|
|
10454
|
+
return ok(
|
|
10455
|
+
new _GpuDrivenProduction(device, {
|
|
10456
|
+
createShaderModule: (descriptor) => {
|
|
10457
|
+
const module = modules.get(descriptor.code);
|
|
10458
|
+
return module === void 0 ? factory.createShaderModule(descriptor) : ok(module);
|
|
10459
|
+
}
|
|
10460
|
+
})
|
|
10461
|
+
);
|
|
10462
|
+
}
|
|
10441
10463
|
createRecoveryRoot(scope) {
|
|
10442
10464
|
return {
|
|
10443
10465
|
kind: "scene-table",
|
|
@@ -11661,6 +11683,27 @@ var StandardPointsLinesOwner = class {
|
|
|
11661
11683
|
}
|
|
11662
11684
|
};
|
|
11663
11685
|
|
|
11686
|
+
// src/instance-buffer-cache.ts
|
|
11687
|
+
function destroyInstanceBufferEntries(entries, errorRegistry) {
|
|
11688
|
+
for (const entry of entries) {
|
|
11689
|
+
if (entry.buffer.isDestroyed) continue;
|
|
11690
|
+
const r = entry.buffer.destroy();
|
|
11691
|
+
if (!r.ok && errorRegistry) errorRegistry.fire(r.error);
|
|
11692
|
+
}
|
|
11693
|
+
}
|
|
11694
|
+
function disposeInstanceBuffers(map, errorRegistry) {
|
|
11695
|
+
destroyInstanceBufferEntries(map.values(), errorRegistry);
|
|
11696
|
+
map.clear();
|
|
11697
|
+
}
|
|
11698
|
+
function disposeInstanceBufferChunks(map, errorRegistry) {
|
|
11699
|
+
destroyInstanceBufferEntries(map.values(), errorRegistry);
|
|
11700
|
+
map.clear();
|
|
11701
|
+
}
|
|
11702
|
+
function disposeTransientInstanceBuffers(entries, errorRegistry) {
|
|
11703
|
+
destroyInstanceBufferEntries(entries, errorRegistry);
|
|
11704
|
+
entries.length = 0;
|
|
11705
|
+
}
|
|
11706
|
+
|
|
11664
11707
|
// src/pipeline/standard-lighting/inspection.ts
|
|
11665
11708
|
function inspectStandardClusterTransport(transport, prepared) {
|
|
11666
11709
|
return Object.freeze({
|
|
@@ -11704,23 +11747,6 @@ function inspectStandardLighting(input) {
|
|
|
11704
11747
|
return inspectStandardClusterTransport(input.transport, input.prepared);
|
|
11705
11748
|
}
|
|
11706
11749
|
|
|
11707
|
-
// src/instance-buffer-cache.ts
|
|
11708
|
-
function destroyInstanceBufferEntries(entries, errorRegistry) {
|
|
11709
|
-
for (const entry of entries) {
|
|
11710
|
-
if (entry.buffer.isDestroyed) continue;
|
|
11711
|
-
const r = entry.buffer.destroy();
|
|
11712
|
-
if (!r.ok && errorRegistry) errorRegistry.fire(r.error);
|
|
11713
|
-
}
|
|
11714
|
-
}
|
|
11715
|
-
function disposeInstanceBuffers(map, errorRegistry) {
|
|
11716
|
-
destroyInstanceBufferEntries(map.values(), errorRegistry);
|
|
11717
|
-
map.clear();
|
|
11718
|
-
}
|
|
11719
|
-
function disposeTransientInstanceBuffers(entries, errorRegistry) {
|
|
11720
|
-
destroyInstanceBufferEntries(entries, errorRegistry);
|
|
11721
|
-
entries.length = 0;
|
|
11722
|
-
}
|
|
11723
|
-
|
|
11724
11750
|
// src/volume/temporal.ts
|
|
11725
11751
|
function resolveVolumeTemporalReset(previous, next, options = {}) {
|
|
11726
11752
|
if (options.reprojection === "out-of-screen") {
|
|
@@ -15592,13 +15618,19 @@ function cleanPerFrameCaches(internals, frameState, validated, retainedEntityKey
|
|
|
15592
15618
|
disposeTransientInstanceBuffers(frameState.transientInstanceBuffers, internals.errorRegistry);
|
|
15593
15619
|
}
|
|
15594
15620
|
const validatedEntityKeys = new Set(retainedEntityKeys);
|
|
15621
|
+
const validatedInstanceKeys = new Set(retainedEntityKeys);
|
|
15595
15622
|
for (const v of validated) {
|
|
15596
|
-
|
|
15623
|
+
const entityKey = worldEntityKey(v.source.worldId, v.source.entityKey);
|
|
15624
|
+
validatedEntityKeys.add(entityKey);
|
|
15625
|
+
validatedInstanceKeys.add(entityKey);
|
|
15626
|
+
if (v.source.instances !== void 0) {
|
|
15627
|
+
validatedInstanceKeys.add(instanceCollectionCacheKey(v.source.worldId, v.source.instances));
|
|
15628
|
+
}
|
|
15597
15629
|
}
|
|
15598
15630
|
cleanPerEntityCache(frameState.materialBgPerEntity, validatedEntityKeys);
|
|
15599
15631
|
cleanPerEntityCache(frameState.instancesBgPerEntity, validatedEntityKeys);
|
|
15600
15632
|
for (const [key, entry] of frameState.instanceBuffers.entries()) {
|
|
15601
|
-
if (!
|
|
15633
|
+
if (!validatedInstanceKeys.has(key)) {
|
|
15602
15634
|
if (!entry.buffer.isDestroyed) {
|
|
15603
15635
|
const r = entry.buffer.destroy();
|
|
15604
15636
|
if (!r.ok) internals.errorRegistry.fire(r.error);
|
|
@@ -15606,6 +15638,24 @@ function cleanPerFrameCaches(internals, frameState, validated, retainedEntityKey
|
|
|
15606
15638
|
frameState.instanceBuffers.delete(key);
|
|
15607
15639
|
}
|
|
15608
15640
|
}
|
|
15641
|
+
if (frameState.instanceResidency !== void 0) {
|
|
15642
|
+
const liveCollections = new Set(validated.map((entry) => entry.source.instances?.collectionId));
|
|
15643
|
+
for (const id of frameState.instanceResidency.keys()) {
|
|
15644
|
+
if (!liveCollections.has(id)) frameState.instanceResidency.delete(id);
|
|
15645
|
+
}
|
|
15646
|
+
}
|
|
15647
|
+
if (frameState.instanceBufferChunks !== void 0) {
|
|
15648
|
+
for (const [key, entry] of frameState.instanceBufferChunks.entries()) {
|
|
15649
|
+
const separator = key.indexOf(":");
|
|
15650
|
+
const ownerKey = separator < 0 ? Number.NaN : Number(key.slice(0, separator));
|
|
15651
|
+
if (validatedInstanceKeys.has(ownerKey)) continue;
|
|
15652
|
+
if (!entry.buffer.isDestroyed) {
|
|
15653
|
+
const r = entry.buffer.destroy();
|
|
15654
|
+
if (!r.ok) internals.errorRegistry.fire(r.error);
|
|
15655
|
+
}
|
|
15656
|
+
frameState.instanceBufferChunks.delete(key);
|
|
15657
|
+
}
|
|
15658
|
+
}
|
|
15609
15659
|
if (frameState.morphBuffers !== void 0) {
|
|
15610
15660
|
for (const [key, entry] of frameState.morphBuffers.entries()) {
|
|
15611
15661
|
if (validatedEntityKeys.has(key)) continue;
|
|
@@ -16271,6 +16321,8 @@ function createRenderSystemRecovery(deps) {
|
|
|
16271
16321
|
currentDirectionalShadowView: null,
|
|
16272
16322
|
currentSpotShadowView: null,
|
|
16273
16323
|
instanceBuffers: /* @__PURE__ */ new Map(),
|
|
16324
|
+
instanceBufferChunks: /* @__PURE__ */ new Map(),
|
|
16325
|
+
instanceResidency: /* @__PURE__ */ new Map(),
|
|
16274
16326
|
morphBuffers: /* @__PURE__ */ new Map(),
|
|
16275
16327
|
hdrpClusterBinScratch: createClusterBinScratch(),
|
|
16276
16328
|
hdrpClusterGridScratch: null,
|
|
@@ -16346,7 +16398,7 @@ function createRenderSystemRecovery(deps) {
|
|
|
16346
16398
|
const discardRecoveryGraphCandidate = (candidate) => {
|
|
16347
16399
|
candidate.release();
|
|
16348
16400
|
};
|
|
16349
|
-
const prepareRecoveryGraphCandidate = (runtime) => {
|
|
16401
|
+
const prepareRecoveryGraphCandidate = async (runtime) => {
|
|
16350
16402
|
const seed = lastSuccessfulFrameSeed;
|
|
16351
16403
|
if (seed === void 0) return { kind: "no-seed" };
|
|
16352
16404
|
const camera = seed.frame.cameras[0];
|
|
@@ -16404,6 +16456,13 @@ function createRenderSystemRecovery(deps) {
|
|
|
16404
16456
|
candidateGpuDrivenScene = void 0;
|
|
16405
16457
|
candidatePointsLines?.release();
|
|
16406
16458
|
candidatePointsLines = void 0;
|
|
16459
|
+
disposeInstanceBuffers(candidateFrameState.instanceBuffers, runtime.internals.errorRegistry);
|
|
16460
|
+
if (candidateFrameState.instanceBufferChunks !== void 0) {
|
|
16461
|
+
disposeInstanceBufferChunks(
|
|
16462
|
+
candidateFrameState.instanceBufferChunks,
|
|
16463
|
+
runtime.internals.errorRegistry
|
|
16464
|
+
);
|
|
16465
|
+
}
|
|
16407
16466
|
candidateGpuStore.destroyAll();
|
|
16408
16467
|
};
|
|
16409
16468
|
const markPublished = () => {
|
|
@@ -16421,10 +16480,14 @@ function createRenderSystemRecovery(deps) {
|
|
|
16421
16480
|
if (!gpuScene.ok) return failed2("candidate GPU scene preparation failed", gpuScene.error);
|
|
16422
16481
|
candidateGpuDrivenScene = gpuScene.value;
|
|
16423
16482
|
if (candidateGpuDrivenScene.state !== void 0) {
|
|
16424
|
-
|
|
16483
|
+
const production = await GpuDrivenProduction.forRecoveryDevice(
|
|
16425
16484
|
runtime.internals.device,
|
|
16426
|
-
gpuDrivenShaderFactory
|
|
16485
|
+
gpuDrivenShaderFactory,
|
|
16486
|
+
(descriptor) => internals.createShaderModule === void 0 ? Promise.resolve(gpuDrivenShaderFactory.createShaderModule(descriptor)) : internals.createShaderModule(runtime.internals.device, descriptor)
|
|
16427
16487
|
);
|
|
16488
|
+
if (!production.ok)
|
|
16489
|
+
return failed2("candidate GPU-driven shader preparation failed", production.error);
|
|
16490
|
+
candidateGpuDrivenProduction = production.value;
|
|
16428
16491
|
const prepared = candidateGpuDrivenProduction.prepare({
|
|
16429
16492
|
scene: candidateGpuDrivenScene.state,
|
|
16430
16493
|
camera,
|
|
@@ -16583,6 +16646,24 @@ function createRenderSystemRecovery(deps) {
|
|
|
16583
16646
|
if (candidateValidated.length !== seed.frame.renderables.length) {
|
|
16584
16647
|
return failed2("candidate validation did not retain every LKG-visible renderable");
|
|
16585
16648
|
}
|
|
16649
|
+
for (const entry of candidateValidated) {
|
|
16650
|
+
if (entry.source.instances === void 0) continue;
|
|
16651
|
+
const prepared = resolveGeometryInstanceBuffer(
|
|
16652
|
+
{
|
|
16653
|
+
runtime: runtime.internals,
|
|
16654
|
+
pipelineState: runtime.pipelineState,
|
|
16655
|
+
frameState: candidateFrameState,
|
|
16656
|
+
bindGroupCounts: { createBindGroup: 0, keys: [] }
|
|
16657
|
+
},
|
|
16658
|
+
entry,
|
|
16659
|
+
[],
|
|
16660
|
+
false
|
|
16661
|
+
);
|
|
16662
|
+
if (prepared === null) return failed2("candidate instance preparation failed");
|
|
16663
|
+
}
|
|
16664
|
+
for (const [id, residency] of candidateFrameState.instanceResidency ?? []) {
|
|
16665
|
+
candidateFrameState.instanceResidency?.set(id, { ...residency, frameNumber: -1 });
|
|
16666
|
+
}
|
|
16586
16667
|
const lighting = prepareFrameLighting(
|
|
16587
16668
|
runtime.internals,
|
|
16588
16669
|
candidateFrameState,
|
|
@@ -18319,6 +18400,10 @@ var GpuScene = class _GpuScene {
|
|
|
18319
18400
|
drawTemplate: [],
|
|
18320
18401
|
material: []
|
|
18321
18402
|
};
|
|
18403
|
+
/** Transform rows whose previous value advances only after submit. */
|
|
18404
|
+
pendingTemporalTransforms = /* @__PURE__ */ new Set();
|
|
18405
|
+
/** Previous rows whose post-submit upload must be retried before the next draw. */
|
|
18406
|
+
pendingTemporalUploads = /* @__PURE__ */ new Set();
|
|
18322
18407
|
static create(device, initialCapacity = 256) {
|
|
18323
18408
|
if (!device.caps.storageBuffer) {
|
|
18324
18409
|
return ok({ status: "unavailable", reason: "storage-buffer-unavailable" });
|
|
@@ -18345,26 +18430,37 @@ var GpuScene = class _GpuScene {
|
|
|
18345
18430
|
return this.buffers.material;
|
|
18346
18431
|
}
|
|
18347
18432
|
sync(delta) {
|
|
18348
|
-
|
|
18433
|
+
for (const transformIndex of this.pendingTemporalUploads) {
|
|
18434
|
+
this.writesByTable.transform.push(transformIndex);
|
|
18435
|
+
}
|
|
18436
|
+
const pendingWrites = TABLE_NAMES.some((name) => this.writesByTable[name].length > 0);
|
|
18437
|
+
if (delta.createdSlots.length === 0 && delta.updatedSlots.length === 0 && delta.recreatedSlots.length === 0 && delta.removedSlots.length === 0 && !pendingWrites) {
|
|
18349
18438
|
this.noChangeFrames += 1;
|
|
18350
18439
|
return ok({ ranges: 0, bytes: 0, grew: false, cleared: 0 });
|
|
18351
18440
|
}
|
|
18352
18441
|
const writesByTable = this.writesByTable;
|
|
18353
|
-
|
|
18354
|
-
|
|
18442
|
+
if (!this.identityUploaded && !writesByTable.transform.includes(0)) {
|
|
18443
|
+
writesByTable.transform.push(0);
|
|
18444
|
+
}
|
|
18355
18445
|
let highestChangedSlot = -1;
|
|
18356
|
-
|
|
18446
|
+
const contentUpdatedSlots = delta.contentUpdatedSlots ?? [];
|
|
18447
|
+
const contentUpdatedSlotIds = new Set(contentUpdatedSlots.map((record) => record.slot));
|
|
18448
|
+
const allocationResets = /* @__PURE__ */ new Set();
|
|
18449
|
+
for (const record of delta.removedSlots) {
|
|
18450
|
+
if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
|
|
18451
|
+
this.clearSlot(record.slot, writesByTable);
|
|
18452
|
+
}
|
|
18453
|
+
for (const records of [delta.createdSlots, contentUpdatedSlots, delta.recreatedSlots]) {
|
|
18357
18454
|
for (const record of records) {
|
|
18455
|
+
const previous = this.allocations[record.slot];
|
|
18358
18456
|
this.ensureAllocation(record, writesByTable);
|
|
18457
|
+
if (previous !== this.allocations[record.slot]) allocationResets.add(record.slot);
|
|
18359
18458
|
if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
|
|
18360
18459
|
}
|
|
18361
18460
|
}
|
|
18362
18461
|
for (const record of delta.updatedSlots) {
|
|
18363
18462
|
if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
|
|
18364
18463
|
}
|
|
18365
|
-
for (const record of delta.removedSlots) {
|
|
18366
|
-
if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
|
|
18367
|
-
}
|
|
18368
18464
|
const requiredCapacity = Math.max(
|
|
18369
18465
|
highestChangedSlot + 1,
|
|
18370
18466
|
this.instances.requiredCapacity(),
|
|
@@ -18378,11 +18474,18 @@ var GpuScene = class _GpuScene {
|
|
|
18378
18474
|
if (!grown.ok) return grown;
|
|
18379
18475
|
}
|
|
18380
18476
|
for (const record of delta.createdSlots) this.writeSlot(record, true, writesByTable);
|
|
18381
|
-
for (const record of
|
|
18477
|
+
for (const record of contentUpdatedSlots) {
|
|
18478
|
+
this.writeSlot(record, allocationResets.has(record.slot), writesByTable);
|
|
18479
|
+
}
|
|
18480
|
+
for (const record of delta.updatedSlots) {
|
|
18481
|
+
if (contentUpdatedSlotIds.has(record.slot)) continue;
|
|
18482
|
+
this.writeRootTransform(record, false, writesByTable);
|
|
18483
|
+
}
|
|
18382
18484
|
for (const record of delta.recreatedSlots) this.writeSlot(record, true, writesByTable);
|
|
18383
|
-
for (const record of delta.removedSlots) this.clearSlot(record.slot, writesByTable);
|
|
18384
18485
|
const uploaded = this.uploadRows(writesByTable);
|
|
18385
18486
|
if (!uploaded.ok) return uploaded;
|
|
18487
|
+
this.pendingTemporalUploads.clear();
|
|
18488
|
+
for (const name of TABLE_NAMES) writesByTable[name].length = 0;
|
|
18386
18489
|
this.identityUploaded = true;
|
|
18387
18490
|
this.clearedSlots += delta.removedSlots.length;
|
|
18388
18491
|
return ok({
|
|
@@ -18394,27 +18497,47 @@ var GpuScene = class _GpuScene {
|
|
|
18394
18497
|
}
|
|
18395
18498
|
/** Publish current transforms as previous only after a successful submit. */
|
|
18396
18499
|
commitTemporalFrame(enabled = true) {
|
|
18397
|
-
if (!enabled)
|
|
18398
|
-
|
|
18399
|
-
|
|
18400
|
-
|
|
18500
|
+
if (!enabled) {
|
|
18501
|
+
this.pendingTemporalTransforms.clear();
|
|
18502
|
+
this.pendingTemporalUploads.clear();
|
|
18503
|
+
return ok(void 0);
|
|
18504
|
+
}
|
|
18505
|
+
if (this.pendingTemporalTransforms.size === 0) return ok(void 0);
|
|
18401
18506
|
const currentOffset = offset(TRANSFORM, "currentWorld");
|
|
18402
18507
|
const previousOffset = offset(TRANSFORM, "previousWorld");
|
|
18403
|
-
|
|
18404
|
-
|
|
18405
|
-
|
|
18508
|
+
const ranges = coalesceSlots([...this.pendingTemporalTransforms]);
|
|
18509
|
+
for (const range of ranges) {
|
|
18510
|
+
for (let index = range.start; index < range.end; index += 1) {
|
|
18511
|
+
this.pendingTemporalUploads.add(index);
|
|
18512
|
+
}
|
|
18513
|
+
}
|
|
18514
|
+
for (const range of ranges) {
|
|
18515
|
+
for (let index = range.start; index < range.end; index += 1) {
|
|
18516
|
+
this.transformBytes.copyWithin(
|
|
18517
|
+
index * TRANSFORM.stride + previousOffset,
|
|
18406
18518
|
index * TRANSFORM.stride + currentOffset,
|
|
18407
18519
|
index * TRANSFORM.stride + currentOffset + 64
|
|
18408
|
-
)
|
|
18409
|
-
|
|
18520
|
+
);
|
|
18521
|
+
}
|
|
18522
|
+
}
|
|
18523
|
+
for (const range of ranges) {
|
|
18524
|
+
const firstOffset = range.start * TRANSFORM.stride;
|
|
18525
|
+
const lastOffset = range.end * TRANSFORM.stride;
|
|
18526
|
+
const uploaded = this.device.queue.writeBuffer(
|
|
18527
|
+
this.buffers.transform,
|
|
18528
|
+
firstOffset,
|
|
18529
|
+
this.transformBytes.subarray(firstOffset, lastOffset)
|
|
18410
18530
|
);
|
|
18531
|
+
if (!uploaded.ok) return uploaded;
|
|
18411
18532
|
}
|
|
18412
|
-
|
|
18413
|
-
|
|
18414
|
-
|
|
18415
|
-
|
|
18416
|
-
|
|
18417
|
-
|
|
18533
|
+
this.pendingTemporalTransforms.clear();
|
|
18534
|
+
this.pendingTemporalUploads.clear();
|
|
18535
|
+
const bytes2 = ranges.reduce(
|
|
18536
|
+
(total, range) => total + (range.end - range.start) * TRANSFORM.stride,
|
|
18537
|
+
0
|
|
18538
|
+
);
|
|
18539
|
+
this.uploadRanges += ranges.length;
|
|
18540
|
+
this.uploadBytes += bytes2;
|
|
18418
18541
|
return ok(void 0);
|
|
18419
18542
|
}
|
|
18420
18543
|
rebuild(slots) {
|
|
@@ -18423,6 +18546,9 @@ var GpuScene = class _GpuScene {
|
|
|
18423
18546
|
this.transforms.reset(1);
|
|
18424
18547
|
this.draws.reset();
|
|
18425
18548
|
this.materials.reset();
|
|
18549
|
+
this.pendingTemporalTransforms.clear();
|
|
18550
|
+
this.pendingTemporalUploads.clear();
|
|
18551
|
+
for (const name of TABLE_NAMES) this.writesByTable[name].length = 0;
|
|
18426
18552
|
const writesByTable = {
|
|
18427
18553
|
primitive: [],
|
|
18428
18554
|
instance: [],
|
|
@@ -18573,7 +18699,8 @@ var GpuScene = class _GpuScene {
|
|
|
18573
18699
|
const localCurrentOffset = localOffset + offset(TRANSFORM, "currentWorld");
|
|
18574
18700
|
const localPreviousOffset = localOffset + offset(TRANSFORM, "previousWorld");
|
|
18575
18701
|
writeMat4(transform, localCurrentOffset, localWorld);
|
|
18576
|
-
writeMat4(transform, localPreviousOffset, localWorld);
|
|
18702
|
+
if (resetPrevious) writeMat4(transform, localPreviousOffset, localWorld);
|
|
18703
|
+
else this.pendingTemporalTransforms.add(transformIndex);
|
|
18577
18704
|
writes.transform.push(transformIndex);
|
|
18578
18705
|
}
|
|
18579
18706
|
writes.instance.push(instanceIndex);
|
|
@@ -18672,14 +18799,16 @@ var GpuScene = class _GpuScene {
|
|
|
18672
18799
|
const allocation = this.allocations[record.slot];
|
|
18673
18800
|
if (allocation === void 0) throw new RangeError("GPU Scene allocation unavailable");
|
|
18674
18801
|
const transformOffset = allocation.transformStart * TRANSFORM.stride;
|
|
18675
|
-
const currentOffset = transformOffset + offset(TRANSFORM, "currentWorld");
|
|
18676
18802
|
const previousOffset = transformOffset + offset(TRANSFORM, "previousWorld");
|
|
18677
18803
|
if (resetPrevious) {
|
|
18678
18804
|
writeMat4(this.transformView, previousOffset, record.snapshot.transform.world);
|
|
18679
|
-
} else {
|
|
18680
|
-
this.transformBytes.copyWithin(previousOffset, currentOffset, currentOffset + 64);
|
|
18681
18805
|
}
|
|
18682
|
-
writeMat4(
|
|
18806
|
+
writeMat4(
|
|
18807
|
+
this.transformView,
|
|
18808
|
+
transformOffset + offset(TRANSFORM, "currentWorld"),
|
|
18809
|
+
record.snapshot.transform.world
|
|
18810
|
+
);
|
|
18811
|
+
if (!resetPrevious) this.pendingTemporalTransforms.add(allocation.transformStart);
|
|
18683
18812
|
writes.transform.push(allocation.transformStart);
|
|
18684
18813
|
}
|
|
18685
18814
|
clearSlot(slot, writes) {
|
|
@@ -18758,6 +18887,8 @@ var GpuScene = class _GpuScene {
|
|
|
18758
18887
|
TRANSFORM.stride
|
|
18759
18888
|
).fill(0);
|
|
18760
18889
|
writes.transform.push(transformIndex);
|
|
18890
|
+
this.pendingTemporalTransforms.delete(transformIndex);
|
|
18891
|
+
this.pendingTemporalUploads.delete(transformIndex);
|
|
18761
18892
|
}
|
|
18762
18893
|
for (let ordinal = 0; ordinal < allocation.drawCount; ordinal += 1) {
|
|
18763
18894
|
const drawIndex = allocation.drawStart + ordinal;
|
|
@@ -19214,7 +19345,8 @@ function ownSnapshot(snapshot) {
|
|
|
19214
19345
|
regions: new Float32Array(snapshot.spriteInstances.regions)
|
|
19215
19346
|
}
|
|
19216
19347
|
},
|
|
19217
|
-
...snapshot.pointsLines === void 0 ? {} : { pointsLines: ownPointsLinesSnapshot(snapshot.pointsLines) }
|
|
19348
|
+
...snapshot.pointsLines === void 0 ? {} : { pointsLines: ownPointsLinesSnapshot(snapshot.pointsLines) },
|
|
19349
|
+
...snapshot.skinJointEntities === void 0 ? {} : { skinJointEntities: [...snapshot.skinJointEntities] }
|
|
19218
19350
|
};
|
|
19219
19351
|
}
|
|
19220
19352
|
function ownPointsLinesSnapshot(snapshot) {
|
|
@@ -19327,7 +19459,8 @@ var RenderScene = class {
|
|
|
19327
19459
|
entityKey,
|
|
19328
19460
|
initial,
|
|
19329
19461
|
current: initial?.snapshot,
|
|
19330
|
-
removed: false
|
|
19462
|
+
removed: false,
|
|
19463
|
+
contentChanged: false
|
|
19331
19464
|
};
|
|
19332
19465
|
entities.set(entityKey, pending);
|
|
19333
19466
|
pendingOrder.push(pending);
|
|
@@ -19338,6 +19471,7 @@ var RenderScene = class {
|
|
|
19338
19471
|
const { worldId, entityKey } = operation.snapshot;
|
|
19339
19472
|
const pending2 = pendingFor(worldId, entityKey);
|
|
19340
19473
|
pending2.current = ownSnapshot(operation.snapshot);
|
|
19474
|
+
pending2.contentChanged = true;
|
|
19341
19475
|
continue;
|
|
19342
19476
|
}
|
|
19343
19477
|
const pending = pendingFor(operation.worldId, operation.entityKey);
|
|
@@ -19358,6 +19492,7 @@ var RenderScene = class {
|
|
|
19358
19492
|
let recreated = 0;
|
|
19359
19493
|
const createdSlots = [];
|
|
19360
19494
|
const updatedSlots = [];
|
|
19495
|
+
const contentUpdatedSlots = [];
|
|
19361
19496
|
const removedSlots = [];
|
|
19362
19497
|
const recreatedSlots = [];
|
|
19363
19498
|
for (const pending of pendingOrder) {
|
|
@@ -19395,6 +19530,7 @@ var RenderScene = class {
|
|
|
19395
19530
|
this.indexMaterials(updatedSlot);
|
|
19396
19531
|
this.dirtySinceSubmitted.add(updatedSlot.slot);
|
|
19397
19532
|
updatedSlots.push(updatedSlot);
|
|
19533
|
+
if (pending.contentChanged) contentUpdatedSlots.push(updatedSlot);
|
|
19398
19534
|
updated += 1;
|
|
19399
19535
|
}
|
|
19400
19536
|
const changed = created + updated + removed + recreated > 0;
|
|
@@ -19410,6 +19546,7 @@ var RenderScene = class {
|
|
|
19410
19546
|
ignoredLateUpdates,
|
|
19411
19547
|
createdSlots,
|
|
19412
19548
|
updatedSlots,
|
|
19549
|
+
contentUpdatedSlots,
|
|
19413
19550
|
removedSlots,
|
|
19414
19551
|
recreatedSlots,
|
|
19415
19552
|
resynced: 0
|
|
@@ -19783,7 +19920,7 @@ var RenderScene = class {
|
|
|
19783
19920
|
entityKey: snapshot.entityKey,
|
|
19784
19921
|
meshGeneration: fingerprintNumericArray(snapshot.localAabb) ^ snapshot.assetHandle >>> 0,
|
|
19785
19922
|
transformGeneration: fingerprintNumericArray(snapshot.transform.world),
|
|
19786
|
-
matrixGeneration: snapshot.instances.archVersion,
|
|
19923
|
+
matrixGeneration: snapshot.instances.revision ?? snapshot.instances.archVersion,
|
|
19787
19924
|
meshAabb: snapshot.localAabb,
|
|
19788
19925
|
entityWorld: snapshot.transform.world,
|
|
19789
19926
|
transforms: snapshot.instances.transforms
|
|
@@ -19801,7 +19938,6 @@ var RenderScene = class {
|
|
|
19801
19938
|
}
|
|
19802
19939
|
};
|
|
19803
19940
|
var RENDER_RELEVANT_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
19804
|
-
componentId(Transform),
|
|
19805
19941
|
componentId(GlobalTransform),
|
|
19806
19942
|
componentId(ChildOf),
|
|
19807
19943
|
componentId(MeshFilter),
|
|
@@ -19812,6 +19948,10 @@ var RENDER_RELEVANT_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
|
19812
19948
|
componentId(Skin),
|
|
19813
19949
|
componentId(Layer),
|
|
19814
19950
|
componentId(Visibility),
|
|
19951
|
+
componentId(MorphWeights),
|
|
19952
|
+
componentId(Points),
|
|
19953
|
+
componentId(Lines),
|
|
19954
|
+
componentId(SortKey),
|
|
19815
19955
|
componentId(Camera),
|
|
19816
19956
|
componentId(MotionBlur),
|
|
19817
19957
|
componentId(DirectionalLight),
|
|
@@ -19825,6 +19965,36 @@ var RENDER_RELEVANT_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
|
19825
19965
|
componentId(ReflectionProbe),
|
|
19826
19966
|
componentId(VolumetricFog)
|
|
19827
19967
|
]);
|
|
19968
|
+
var RENDERABLE_SOURCE_COMPONENTS = [
|
|
19969
|
+
GlobalTransform,
|
|
19970
|
+
ChildOf,
|
|
19971
|
+
MeshFilter,
|
|
19972
|
+
MeshRenderer,
|
|
19973
|
+
Instances,
|
|
19974
|
+
SpriteInstances,
|
|
19975
|
+
SpriteRegionOverride,
|
|
19976
|
+
Skin,
|
|
19977
|
+
Layer,
|
|
19978
|
+
Visibility,
|
|
19979
|
+
MorphWeights,
|
|
19980
|
+
Points,
|
|
19981
|
+
Lines,
|
|
19982
|
+
SortKey
|
|
19983
|
+
];
|
|
19984
|
+
var RENDERABLE_SOURCE_COMPONENT_IDS = new Set(
|
|
19985
|
+
RENDERABLE_SOURCE_COMPONENTS.map((component) => componentId(component))
|
|
19986
|
+
);
|
|
19987
|
+
var VISIBILITY_DEPENDENCY_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
19988
|
+
componentId(ChildOf),
|
|
19989
|
+
componentId(Visibility)
|
|
19990
|
+
]);
|
|
19991
|
+
var STRUCTURAL_MEMBERSHIP_SCAN_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
19992
|
+
componentId(ChildOf),
|
|
19993
|
+
componentId(Layer),
|
|
19994
|
+
componentId(Visibility),
|
|
19995
|
+
componentId(SpriteRegionOverride),
|
|
19996
|
+
componentId(SortKey)
|
|
19997
|
+
]);
|
|
19828
19998
|
function createGlobalTransformChangeQuery(world) {
|
|
19829
19999
|
const result = world.query({ read: [GlobalTransform], changed: [GlobalTransform] });
|
|
19830
20000
|
if (!result.ok) throw result.error;
|
|
@@ -19833,6 +20003,107 @@ function createGlobalTransformChangeQuery(world) {
|
|
|
19833
20003
|
}
|
|
19834
20004
|
return query;
|
|
19835
20005
|
}
|
|
20006
|
+
function createRenderChangeQueries(world) {
|
|
20007
|
+
const queries = /* @__PURE__ */ new Map();
|
|
20008
|
+
for (const component of RENDERABLE_SOURCE_COMPONENTS) {
|
|
20009
|
+
const result = world.query({ read: [component], changed: [component] });
|
|
20010
|
+
if (!result.ok) throw result.error;
|
|
20011
|
+
const query = result.value;
|
|
20012
|
+
for (const _span of query.spans().unwrap()) {
|
|
20013
|
+
}
|
|
20014
|
+
queries.set(componentId(component), query);
|
|
20015
|
+
}
|
|
20016
|
+
return queries;
|
|
20017
|
+
}
|
|
20018
|
+
function collectRenderableEntities(world) {
|
|
20019
|
+
const result = /* @__PURE__ */ new Set();
|
|
20020
|
+
const query = world.query({ read: [MeshRenderer], with: [Transform, MeshFilter] }).unwrap();
|
|
20021
|
+
for (const row of query) result.add(row.entity);
|
|
20022
|
+
return result;
|
|
20023
|
+
}
|
|
20024
|
+
function sourceMembershipChanged(world, slot) {
|
|
20025
|
+
const entity = slot.entityKey;
|
|
20026
|
+
const snapshot = slot.snapshot;
|
|
20027
|
+
return !world.hasComponent(entity, GlobalTransform) || snapshot.instances !== void 0 !== world.hasComponent(entity, Instances) || snapshot.spriteInstances !== void 0 !== world.hasComponent(entity, SpriteInstances) || snapshot.skin !== void 0 !== world.hasComponent(entity, Skin) || snapshot.morph !== void 0 !== world.hasComponent(entity, MorphWeights) || snapshot.pointsLines?.component === "Points" !== world.hasComponent(entity, Points) || snapshot.pointsLines?.component === "Lines" !== world.hasComponent(entity, Lines);
|
|
20028
|
+
}
|
|
20029
|
+
function skinJointKey(worldId, jointEntity) {
|
|
20030
|
+
return `${worldId}:${jointEntity}`;
|
|
20031
|
+
}
|
|
20032
|
+
function addSkinConsumer(index, snapshot) {
|
|
20033
|
+
for (const jointEntity of snapshot.skinJointEntities ?? []) {
|
|
20034
|
+
const key = skinJointKey(snapshot.worldId, jointEntity);
|
|
20035
|
+
let consumers = index.get(key);
|
|
20036
|
+
if (consumers === void 0) {
|
|
20037
|
+
consumers = /* @__PURE__ */ new Set();
|
|
20038
|
+
index.set(key, consumers);
|
|
20039
|
+
}
|
|
20040
|
+
consumers.add(snapshot.entityKey);
|
|
20041
|
+
}
|
|
20042
|
+
}
|
|
20043
|
+
function removeSkinConsumer(index, snapshot) {
|
|
20044
|
+
for (const jointEntity of snapshot.skinJointEntities ?? []) {
|
|
20045
|
+
const key = skinJointKey(snapshot.worldId, jointEntity);
|
|
20046
|
+
const consumers = index.get(key);
|
|
20047
|
+
consumers?.delete(snapshot.entityKey);
|
|
20048
|
+
if (consumers?.size === 0) index.delete(key);
|
|
20049
|
+
}
|
|
20050
|
+
}
|
|
20051
|
+
function dispatchEntriesBySlot(frame, projection) {
|
|
20052
|
+
const bySlot = /* @__PURE__ */ new Map();
|
|
20053
|
+
const byRenderable = /* @__PURE__ */ new Map();
|
|
20054
|
+
for (const entry of frame.dispatch) {
|
|
20055
|
+
const list = byRenderable.get(entry.renderableIndex);
|
|
20056
|
+
if (list === void 0) byRenderable.set(entry.renderableIndex, [entry]);
|
|
20057
|
+
else list.push(entry);
|
|
20058
|
+
}
|
|
20059
|
+
for (let index = 0; index < frame.renderables.length; index += 1) {
|
|
20060
|
+
const renderable = frame.renderables[index];
|
|
20061
|
+
if (renderable === void 0) continue;
|
|
20062
|
+
const slot = projection.slot(renderable.worldId, renderable.entityKey);
|
|
20063
|
+
if (slot === void 0) continue;
|
|
20064
|
+
bySlot.set(slot.slot, byRenderable.get(index) ?? []);
|
|
20065
|
+
}
|
|
20066
|
+
return bySlot;
|
|
20067
|
+
}
|
|
20068
|
+
function dispatchForProjection(dispatchBySlot, projection, unavailableSlots) {
|
|
20069
|
+
const dispatch = [];
|
|
20070
|
+
const renderables = projection.materialize();
|
|
20071
|
+
for (let renderableIndex = 0; renderableIndex < renderables.length; renderableIndex += 1) {
|
|
20072
|
+
const renderable = renderables[renderableIndex];
|
|
20073
|
+
if (renderable === void 0) continue;
|
|
20074
|
+
const slot = projection.slot(renderable.worldId, renderable.entityKey);
|
|
20075
|
+
if (slot === void 0) continue;
|
|
20076
|
+
if (unavailableSlots.has(slot.slot)) continue;
|
|
20077
|
+
for (const entry of dispatchBySlot.get(slot.slot) ?? []) {
|
|
20078
|
+
dispatch.push({ ...entry, renderableIndex });
|
|
20079
|
+
}
|
|
20080
|
+
}
|
|
20081
|
+
return dispatch;
|
|
20082
|
+
}
|
|
20083
|
+
function topologyDeltaForAvailable(delta, unavailableSlots, newlyUnavailable) {
|
|
20084
|
+
const updatedSlots = delta.updatedSlots.filter((slot) => !unavailableSlots.has(slot.slot));
|
|
20085
|
+
const contentUpdatedSlots = delta.contentUpdatedSlots?.filter(
|
|
20086
|
+
(slot) => !unavailableSlots.has(slot.slot)
|
|
20087
|
+
);
|
|
20088
|
+
return {
|
|
20089
|
+
...delta,
|
|
20090
|
+
updatedSlots: [
|
|
20091
|
+
...updatedSlots,
|
|
20092
|
+
...newlyUnavailable.map((slot) => ({
|
|
20093
|
+
...slot,
|
|
20094
|
+
snapshot: { ...slot.snapshot, gpuDrivenDraws: [] }
|
|
20095
|
+
}))
|
|
20096
|
+
],
|
|
20097
|
+
...contentUpdatedSlots === void 0 ? {} : { contentUpdatedSlots }
|
|
20098
|
+
};
|
|
20099
|
+
}
|
|
20100
|
+
function addSharedRefConsumers(projection, worldId, handle, target4) {
|
|
20101
|
+
for (const slot of projection.slotsSnapshot()) {
|
|
20102
|
+
if (slot.worldId === worldId && (slot.snapshot.assetHandle === handle || slot.snapshot.materials.some((material) => material.materialHandle === handle))) {
|
|
20103
|
+
target4.add(slot.entityKey);
|
|
20104
|
+
}
|
|
20105
|
+
}
|
|
20106
|
+
}
|
|
19836
20107
|
function frameDemandsTemporal(frame) {
|
|
19837
20108
|
const camera = frame.cameras[0];
|
|
19838
20109
|
return camera?.antialias === "taa" || (camera?.motionBlur?.shutterAngle ?? 0) > 0;
|
|
@@ -19883,6 +20154,10 @@ function cullPersistentFrame(frame, candidates, boundsOf2 = (snapshot) => worldB
|
|
|
19883
20154
|
for (let index = 0; index < candidates.length; index += 1) {
|
|
19884
20155
|
const candidate = candidates[index];
|
|
19885
20156
|
if (candidate === void 0) continue;
|
|
20157
|
+
if (candidate.authorVisible === false) {
|
|
20158
|
+
culled += 1;
|
|
20159
|
+
continue;
|
|
20160
|
+
}
|
|
19886
20161
|
let isVisible = true;
|
|
19887
20162
|
const candidateBounds = boundsOf2(candidate, index);
|
|
19888
20163
|
if (candidateBounds !== void 0) {
|
|
@@ -20112,6 +20387,7 @@ var PersistentRenderScene = class {
|
|
|
20112
20387
|
const bounds = renderable.localAabb;
|
|
20113
20388
|
const validBounds = bounds !== void 0 && bounds.length >= 6 && [...bounds].every((value) => Number.isFinite(value));
|
|
20114
20389
|
draw = decideVisibility({
|
|
20390
|
+
authorVisible: renderable.authorVisible !== false,
|
|
20115
20391
|
validBounds,
|
|
20116
20392
|
occlusion: this.visibilityFacets.getConfidence(view, primitive)}).draw;
|
|
20117
20393
|
}
|
|
@@ -20213,10 +20489,16 @@ var PersistentRenderScene = class {
|
|
|
20213
20489
|
preserveVisibilityOnReorder
|
|
20214
20490
|
);
|
|
20215
20491
|
}
|
|
20216
|
-
if (!entry.rigidOnly) {
|
|
20217
|
-
return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
|
|
20218
|
-
}
|
|
20219
20492
|
let requiresRebuild = false;
|
|
20493
|
+
const changedEntitiesByWorld = worlds.map(
|
|
20494
|
+
(_, worldId) => new Set(entry.pendingRenderableEntitiesByWorld[worldId] ?? [])
|
|
20495
|
+
);
|
|
20496
|
+
const nextReadVersions = entry.readVersions.slice();
|
|
20497
|
+
const structureChangedWorlds = /* @__PURE__ */ new Set();
|
|
20498
|
+
const structuralComponentIdsByWorld = worlds.map(() => /* @__PURE__ */ new Set());
|
|
20499
|
+
let refreshStructureFacts = false;
|
|
20500
|
+
let currentRenderableEntitiesByWorld;
|
|
20501
|
+
const removedSlots = [];
|
|
20220
20502
|
for (let worldId = 0; worldId < worlds.length; worldId += 1) {
|
|
20221
20503
|
const world = worlds[worldId];
|
|
20222
20504
|
if (world === void 0) continue;
|
|
@@ -20237,32 +20519,239 @@ var PersistentRenderScene = class {
|
|
|
20237
20519
|
requiresRebuild = true;
|
|
20238
20520
|
break;
|
|
20239
20521
|
}
|
|
20240
|
-
if (read.status
|
|
20241
|
-
|
|
20242
|
-
|
|
20522
|
+
if (read.status === "rebuild") {
|
|
20523
|
+
structureChangedWorlds.add(worldId);
|
|
20524
|
+
refreshStructureFacts = true;
|
|
20243
20525
|
}
|
|
20244
20526
|
const changes = read.world;
|
|
20245
20527
|
const shared = read.sharedRefs;
|
|
20246
20528
|
if (shared.records.length > 0) {
|
|
20247
20529
|
for (const record of shared.records) {
|
|
20248
20530
|
this.options.onSharedRefMutation?.(worldId, record.handle);
|
|
20531
|
+
const changed = changedEntitiesByWorld[worldId];
|
|
20532
|
+
if (changed !== void 0)
|
|
20533
|
+
addSharedRefConsumers(entry.projection, worldId, record.handle, changed);
|
|
20249
20534
|
}
|
|
20250
|
-
requiresRebuild = true;
|
|
20251
|
-
break;
|
|
20252
20535
|
}
|
|
20253
20536
|
for (const changedComponentId of changes.changedComponentIds) {
|
|
20537
|
+
if (read.status === "rebuild") {
|
|
20538
|
+
structuralComponentIdsByWorld[worldId]?.add(changedComponentId);
|
|
20539
|
+
}
|
|
20254
20540
|
if (!RENDER_RELEVANT_COMPONENT_IDS.has(changedComponentId)) continue;
|
|
20255
|
-
if (
|
|
20541
|
+
if (!RENDERABLE_SOURCE_COMPONENT_IDS.has(changedComponentId)) {
|
|
20256
20542
|
requiresRebuild = true;
|
|
20257
20543
|
break;
|
|
20258
20544
|
}
|
|
20545
|
+
const changed = changedEntitiesByWorld[worldId];
|
|
20546
|
+
if (changed === void 0) continue;
|
|
20547
|
+
if (VISIBILITY_DEPENDENCY_COMPONENT_IDS.has(changedComponentId)) {
|
|
20548
|
+
refreshStructureFacts = true;
|
|
20549
|
+
for (const entity of collectRenderableEntities(world)) changed.add(entity);
|
|
20550
|
+
continue;
|
|
20551
|
+
}
|
|
20552
|
+
if (changedComponentId === componentId(GlobalTransform)) {
|
|
20553
|
+
const query2 = entry.renderChangeQueries[worldId]?.get(changedComponentId);
|
|
20554
|
+
for (const row of query2 ?? []) {
|
|
20555
|
+
const consumers = entry.skinConsumersByJoint.get(
|
|
20556
|
+
skinJointKey(worldId, row.entity)
|
|
20557
|
+
);
|
|
20558
|
+
for (const consumer of consumers ?? []) changed.add(consumer);
|
|
20559
|
+
}
|
|
20560
|
+
continue;
|
|
20561
|
+
}
|
|
20562
|
+
const query = entry.renderChangeQueries[worldId]?.get(changedComponentId);
|
|
20563
|
+
if (query !== void 0) {
|
|
20564
|
+
for (const row of query) changed.add(row.entity);
|
|
20565
|
+
}
|
|
20259
20566
|
}
|
|
20260
20567
|
if (requiresRebuild) break;
|
|
20261
|
-
|
|
20568
|
+
nextReadVersions[worldId] = read.version;
|
|
20262
20569
|
}
|
|
20263
20570
|
if (requiresRebuild) {
|
|
20264
20571
|
return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
|
|
20265
20572
|
}
|
|
20573
|
+
if (structureChangedWorlds.size > 0) {
|
|
20574
|
+
this.visibilityFacets.clear();
|
|
20575
|
+
this.invalidateActiveEntityRevision();
|
|
20576
|
+
const currentByWorld = worlds.map((world) => collectRenderableEntities(world));
|
|
20577
|
+
currentRenderableEntitiesByWorld = currentByWorld;
|
|
20578
|
+
for (let worldId = 0; worldId < currentByWorld.length; worldId += 1) {
|
|
20579
|
+
const world = worlds[worldId];
|
|
20580
|
+
const current = currentByWorld[worldId];
|
|
20581
|
+
if (world === void 0 || current === void 0) continue;
|
|
20582
|
+
const changed = changedEntitiesByWorld[worldId];
|
|
20583
|
+
if (changed !== void 0 && structureChangedWorlds.has(worldId)) {
|
|
20584
|
+
for (const [jointKey, consumers] of entry.skinConsumersByJoint) {
|
|
20585
|
+
const separator = jointKey.indexOf(":");
|
|
20586
|
+
const indexedWorldId = Number(jointKey.slice(0, separator));
|
|
20587
|
+
if (indexedWorldId !== worldId) continue;
|
|
20588
|
+
const jointEntity = Number(jointKey.slice(separator + 1));
|
|
20589
|
+
if (world.hasComponent(jointEntity, GlobalTransform)) continue;
|
|
20590
|
+
for (const consumer of consumers) changed.add(consumer);
|
|
20591
|
+
}
|
|
20592
|
+
for (const entity of current) {
|
|
20593
|
+
if (entry.projection.slot(worldId, entity) === void 0) changed.add(entity);
|
|
20594
|
+
}
|
|
20595
|
+
const structuralComponentIds = structuralComponentIdsByWorld[worldId];
|
|
20596
|
+
const scanAllMembership = structuralComponentIds !== void 0 && [...structuralComponentIds].some(
|
|
20597
|
+
(id) => STRUCTURAL_MEMBERSHIP_SCAN_COMPONENT_IDS.has(id)
|
|
20598
|
+
);
|
|
20599
|
+
for (const slot of entry.projection.slotsSnapshot()) {
|
|
20600
|
+
if (slot.worldId !== worldId || !current.has(slot.entityKey)) continue;
|
|
20601
|
+
const membershipChanged = sourceMembershipChanged(world, slot);
|
|
20602
|
+
if (scanAllMembership || membershipChanged) {
|
|
20603
|
+
changed.add(slot.entityKey);
|
|
20604
|
+
if (slot.snapshot.instances !== void 0 && !world.hasComponent(slot.entityKey, Instances)) {
|
|
20605
|
+
this.options.instanceCollections?.release(world, slot.entityKey);
|
|
20606
|
+
}
|
|
20607
|
+
if (slot.snapshot.skin !== void 0 && !world.hasComponent(slot.entityKey, Skin)) {
|
|
20608
|
+
this.options.getSkinPaletteAllocator?.()?.releaseSliceFor(`${world.identity}:${slot.entityKey}`);
|
|
20609
|
+
}
|
|
20610
|
+
}
|
|
20611
|
+
}
|
|
20612
|
+
}
|
|
20613
|
+
for (const slot of entry.projection.slotsSnapshot()) {
|
|
20614
|
+
if (slot.worldId !== worldId || current.has(slot.entityKey)) continue;
|
|
20615
|
+
removedSlots.push(slot);
|
|
20616
|
+
}
|
|
20617
|
+
this.worldEntitiesScanned += current.size;
|
|
20618
|
+
}
|
|
20619
|
+
}
|
|
20620
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20621
|
+
const pending = entry.pendingRenderableEntitiesByWorld[worldId];
|
|
20622
|
+
if (pending === void 0) continue;
|
|
20623
|
+
for (const entityKey of changedEntitiesByWorld[worldId] ?? []) pending.add(entityKey);
|
|
20624
|
+
}
|
|
20625
|
+
let changedDelta;
|
|
20626
|
+
const hasChangedEntities = changedEntitiesByWorld.some((entities) => entities.size > 0);
|
|
20627
|
+
if (hasChangedEntities || removedSlots.length > 0) {
|
|
20628
|
+
const operations = [];
|
|
20629
|
+
const removedDemand = [];
|
|
20630
|
+
const replacedSkinSnapshots = [];
|
|
20631
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20632
|
+
for (const entityKey of changedEntitiesByWorld[worldId] ?? []) {
|
|
20633
|
+
const slot = entry.projection.slot(worldId, entityKey);
|
|
20634
|
+
if (slot !== void 0) replacedSkinSnapshots.push(slot.snapshot);
|
|
20635
|
+
}
|
|
20636
|
+
}
|
|
20637
|
+
for (const slot of removedSlots) {
|
|
20638
|
+
operations.push({ kind: "remove", worldId: slot.worldId, entityKey: slot.entityKey });
|
|
20639
|
+
if (slot.snapshot.skinJointEntities !== void 0) {
|
|
20640
|
+
removeSkinConsumer(entry.skinConsumersByJoint, slot.snapshot);
|
|
20641
|
+
}
|
|
20642
|
+
const world = worlds[slot.worldId];
|
|
20643
|
+
if (world !== void 0) this.options.instanceCollections?.release(world, slot.entityKey);
|
|
20644
|
+
this.options.getSkinPaletteAllocator?.()?.releaseSliceFor(`${world?.identity ?? slot.worldId}:${slot.entityKey}`);
|
|
20645
|
+
for (let materialIndex = 0; materialIndex < slot.snapshot.materials.length; materialIndex += 1) {
|
|
20646
|
+
removedDemand.push({
|
|
20647
|
+
kind: "remove",
|
|
20648
|
+
key: `${slot.worldId}:${slot.entityKey}:${materialIndex}`
|
|
20649
|
+
});
|
|
20650
|
+
}
|
|
20651
|
+
}
|
|
20652
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20653
|
+
for (const entityKey of changedEntitiesByWorld[worldId] ?? []) {
|
|
20654
|
+
const slot = entry.projection.slot(worldId, entityKey);
|
|
20655
|
+
if (slot === void 0) continue;
|
|
20656
|
+
for (let materialIndex = 0; materialIndex < slot.snapshot.materials.length; materialIndex += 1) {
|
|
20657
|
+
removedDemand.push({ kind: "remove", key: `${worldId}:${entityKey}:${materialIndex}` });
|
|
20658
|
+
}
|
|
20659
|
+
}
|
|
20660
|
+
}
|
|
20661
|
+
const partial = hasChangedEntities ? buildCandidateFrame({ kind: "partial", entitiesByWorld: changedEntitiesByWorld }) : void 0;
|
|
20662
|
+
const publishedEntitiesByWorld = worlds.map(() => /* @__PURE__ */ new Set());
|
|
20663
|
+
for (const snapshot of partial?.renderables ?? []) {
|
|
20664
|
+
operations.push({ kind: "create", snapshot });
|
|
20665
|
+
publishedEntitiesByWorld[snapshot.worldId]?.add(snapshot.entityKey);
|
|
20666
|
+
}
|
|
20667
|
+
changedDelta = entry.projection.apply(operations);
|
|
20668
|
+
const publishedSkinKeys = /* @__PURE__ */ new Set();
|
|
20669
|
+
for (const snapshot of partial?.renderables ?? []) {
|
|
20670
|
+
publishedSkinKeys.add(`${snapshot.worldId}:${snapshot.entityKey}`);
|
|
20671
|
+
}
|
|
20672
|
+
for (const snapshot of replacedSkinSnapshots) {
|
|
20673
|
+
if (snapshot.skinJointEntities !== void 0 && publishedSkinKeys.has(`${snapshot.worldId}:${snapshot.entityKey}`)) {
|
|
20674
|
+
removeSkinConsumer(entry.skinConsumersByJoint, snapshot);
|
|
20675
|
+
}
|
|
20676
|
+
}
|
|
20677
|
+
for (const snapshot of partial?.renderables ?? []) {
|
|
20678
|
+
if (snapshot.skinJointEntities !== void 0) {
|
|
20679
|
+
addSkinConsumer(entry.skinConsumersByJoint, snapshot);
|
|
20680
|
+
}
|
|
20681
|
+
}
|
|
20682
|
+
entry.transmissionDemand.apply([
|
|
20683
|
+
...removedDemand,
|
|
20684
|
+
...transmissionDemandOperations(partial?.renderables ?? [])
|
|
20685
|
+
]);
|
|
20686
|
+
for (const removed of changedDelta.removedSlots) entry.dispatchBySlot.delete(removed.slot);
|
|
20687
|
+
for (const recreated of changedDelta.recreatedSlots)
|
|
20688
|
+
entry.dispatchBySlot.delete(recreated.slot);
|
|
20689
|
+
if (partial !== void 0) {
|
|
20690
|
+
if (refreshStructureFacts) {
|
|
20691
|
+
entry.structure = {
|
|
20692
|
+
...entry.structure,
|
|
20693
|
+
dispatch: partial.dispatch,
|
|
20694
|
+
visibilityStats: partial.visibilityStats,
|
|
20695
|
+
visibilitySnapshots: partial.visibilitySnapshots,
|
|
20696
|
+
featureVisibilitySnapshots: partial.featureVisibilitySnapshots,
|
|
20697
|
+
hiddenEntityReports: partial.hiddenEntityReports
|
|
20698
|
+
};
|
|
20699
|
+
}
|
|
20700
|
+
const partialDispatch = dispatchEntriesBySlot(partial, entry.projection);
|
|
20701
|
+
for (const [slot, dispatch] of partialDispatch) entry.dispatchBySlot.set(slot, dispatch);
|
|
20702
|
+
for (const snapshot of partial.renderables) {
|
|
20703
|
+
const slot = entry.projection.slot(snapshot.worldId, snapshot.entityKey);
|
|
20704
|
+
if (slot !== void 0 && !partialDispatch.has(slot.slot))
|
|
20705
|
+
entry.dispatchBySlot.set(slot.slot, []);
|
|
20706
|
+
}
|
|
20707
|
+
}
|
|
20708
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20709
|
+
const requested = changedEntitiesByWorld[worldId];
|
|
20710
|
+
const published = publishedEntitiesByWorld[worldId];
|
|
20711
|
+
if (requested === void 0 || published === void 0) continue;
|
|
20712
|
+
const pending = entry.pendingRenderableEntitiesByWorld[worldId];
|
|
20713
|
+
for (const entityKey of requested) {
|
|
20714
|
+
const slot = entry.projection.slot(worldId, entityKey);
|
|
20715
|
+
if (published.has(entityKey)) {
|
|
20716
|
+
pending?.delete(entityKey);
|
|
20717
|
+
continue;
|
|
20718
|
+
}
|
|
20719
|
+
if (slot === void 0) {
|
|
20720
|
+
const current = currentRenderableEntitiesByWorld?.[worldId];
|
|
20721
|
+
if (current !== void 0 && !current.has(entityKey)) pending?.delete(entityKey);
|
|
20722
|
+
continue;
|
|
20723
|
+
}
|
|
20724
|
+
pending?.add(entityKey);
|
|
20725
|
+
if (slot !== void 0) entry.dispatchBySlot.set(slot.slot, []);
|
|
20726
|
+
}
|
|
20727
|
+
}
|
|
20728
|
+
const newlyUnavailable = [];
|
|
20729
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20730
|
+
const requested = changedEntitiesByWorld[worldId];
|
|
20731
|
+
const published = publishedEntitiesByWorld[worldId];
|
|
20732
|
+
if (requested === void 0 || published === void 0) continue;
|
|
20733
|
+
for (const entityKey of requested) {
|
|
20734
|
+
const slot = entry.projection.slot(worldId, entityKey);
|
|
20735
|
+
if (slot === void 0 || published.has(entityKey)) {
|
|
20736
|
+
if (slot !== void 0) entry.unavailableSlots.delete(slot.slot);
|
|
20737
|
+
continue;
|
|
20738
|
+
}
|
|
20739
|
+
if (!entry.unavailableSlots.has(slot.slot)) newlyUnavailable.push(slot);
|
|
20740
|
+
entry.unavailableSlots.add(slot.slot);
|
|
20741
|
+
}
|
|
20742
|
+
}
|
|
20743
|
+
for (const removed of changedDelta.removedSlots) entry.unavailableSlots.delete(removed.slot);
|
|
20744
|
+
for (const recreated of changedDelta.recreatedSlots)
|
|
20745
|
+
entry.unavailableSlots.delete(recreated.slot);
|
|
20746
|
+
entry.dispatchRevision += 1;
|
|
20747
|
+
entry.dispatchCache = void 0;
|
|
20748
|
+
entry.topology.apply(
|
|
20749
|
+
topologyDeltaForAvailable(changedDelta, entry.unavailableSlots, newlyUnavailable)
|
|
20750
|
+
);
|
|
20751
|
+
this.syncGpuOwner(entry.token, entry.projection, changedDelta);
|
|
20752
|
+
this.deltaFrames += changedDelta.created + changedDelta.updated + changedDelta.removed + changedDelta.recreated > 0 ? 1 : 0;
|
|
20753
|
+
this.transformUpdates += changedDelta.updated;
|
|
20754
|
+
}
|
|
20266
20755
|
const transformSpans = [];
|
|
20267
20756
|
for (let worldId = 0; worldId < entry.transformQueries.length; worldId += 1) {
|
|
20268
20757
|
const query = entry.transformQueries[worldId];
|
|
@@ -20280,17 +20769,29 @@ var PersistentRenderScene = class {
|
|
|
20280
20769
|
if (requiresRebuild) {
|
|
20281
20770
|
return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
|
|
20282
20771
|
}
|
|
20283
|
-
if (transformSpans.length === 0) {
|
|
20772
|
+
if (transformSpans.length === 0 && changedDelta === void 0) {
|
|
20284
20773
|
this.noChangeFrames += 1;
|
|
20285
20774
|
this.syncGpuOwner(entry.token, entry.projection);
|
|
20286
|
-
|
|
20775
|
+
const result2 = this.deriveFramePlan(entry, buildCandidateFrame);
|
|
20776
|
+
for (let worldId = 0; worldId < nextReadVersions.length; worldId += 1) {
|
|
20777
|
+
const version = nextReadVersions[worldId];
|
|
20778
|
+
if (version !== void 0) entry.readVersions[worldId] = version;
|
|
20779
|
+
}
|
|
20780
|
+
return result2;
|
|
20287
20781
|
}
|
|
20288
|
-
|
|
20289
|
-
|
|
20290
|
-
|
|
20291
|
-
|
|
20292
|
-
|
|
20293
|
-
|
|
20782
|
+
if (transformSpans.length > 0) {
|
|
20783
|
+
const delta = entry.projection.applyTransformSpans(transformSpans);
|
|
20784
|
+
entry.topology.apply(topologyDeltaForAvailable(delta, entry.unavailableSlots, []));
|
|
20785
|
+
this.syncGpuOwner(entry.token, entry.projection, delta);
|
|
20786
|
+
this.deltaFrames += 1;
|
|
20787
|
+
this.transformUpdates += delta.updated;
|
|
20788
|
+
}
|
|
20789
|
+
const result = this.deriveFramePlan(entry, buildCandidateFrame);
|
|
20790
|
+
for (let worldId = 0; worldId < nextReadVersions.length; worldId += 1) {
|
|
20791
|
+
const version = nextReadVersions[worldId];
|
|
20792
|
+
if (version !== void 0) entry.readVersions[worldId] = version;
|
|
20793
|
+
}
|
|
20794
|
+
return result;
|
|
20294
20795
|
}
|
|
20295
20796
|
invalidate() {
|
|
20296
20797
|
this.composition = void 0;
|
|
@@ -20311,6 +20812,14 @@ var PersistentRenderScene = class {
|
|
|
20311
20812
|
this.visibilityFacets.detachAttachment(world.identity);
|
|
20312
20813
|
this.materialSnapshotCaches.delete(world);
|
|
20313
20814
|
const detachedComposition = this.composition?.worlds.includes(world) ? this.composition : void 0;
|
|
20815
|
+
if (detachedComposition !== void 0) {
|
|
20816
|
+
for (const slot of detachedComposition.projection.slotsSnapshot()) {
|
|
20817
|
+
if (detachedComposition.worlds[slot.worldId] !== world) continue;
|
|
20818
|
+
this.options.instanceCollections?.release(world, slot.entityKey);
|
|
20819
|
+
if (slot.snapshot.skin === void 0) continue;
|
|
20820
|
+
this.options.getSkinPaletteAllocator?.()?.releaseSliceFor(`${world.identity}:${slot.entityKey}`);
|
|
20821
|
+
}
|
|
20822
|
+
}
|
|
20314
20823
|
if (detachedComposition !== void 0) this.composition = void 0;
|
|
20315
20824
|
if (detachedComposition !== void 0) this.temporalCapture = void 0;
|
|
20316
20825
|
if (detachedComposition !== void 0) {
|
|
@@ -20592,6 +21101,10 @@ var PersistentRenderScene = class {
|
|
|
20592
21101
|
transmissionDemand.apply(transmissionDemandOperations(candidateFrame.renderables));
|
|
20593
21102
|
const topology = new BatchTopology();
|
|
20594
21103
|
topology.rebuild(projection.slotsSnapshot());
|
|
21104
|
+
const skinConsumersByJoint = /* @__PURE__ */ new Map();
|
|
21105
|
+
for (const snapshot of stableCandidateFrame.renderables) {
|
|
21106
|
+
if (snapshot.skinJointEntities !== void 0) addSkinConsumer(skinConsumersByJoint, snapshot);
|
|
21107
|
+
}
|
|
20595
21108
|
const token2 = {};
|
|
20596
21109
|
const entry = {
|
|
20597
21110
|
token: token2,
|
|
@@ -20612,8 +21125,14 @@ var PersistentRenderScene = class {
|
|
|
20612
21125
|
readVersions: leases === void 0 || leases.length !== worlds.length ? [] : leases.map((lease) => lease.captureVersion()),
|
|
20613
21126
|
leaseIdentities: leases === void 0 || leases.length !== worlds.length ? [] : leases.map((lease) => lease.worldIdentity),
|
|
20614
21127
|
transformQueries: leases === void 0 || leases.length !== worlds.length ? [] : worlds.map(createGlobalTransformChangeQuery),
|
|
21128
|
+
renderChangeQueries: leases === void 0 || leases.length !== worlds.length ? [] : worlds.map(createRenderChangeQueries),
|
|
21129
|
+
dispatchBySlot: dispatchEntriesBySlot(stableCandidateFrame, projection),
|
|
21130
|
+
dispatchRevision: 0,
|
|
21131
|
+
dispatchCache: void 0,
|
|
21132
|
+
skinConsumersByJoint,
|
|
21133
|
+
pendingRenderableEntitiesByWorld: worlds.map(() => /* @__PURE__ */ new Set()),
|
|
21134
|
+
unavailableSlots: /* @__PURE__ */ new Set(),
|
|
20615
21135
|
catalogEpoch,
|
|
20616
|
-
rigidOnly: candidateFrame.renderables.every((renderable) => renderable.skin === void 0),
|
|
20617
21136
|
probeProjection: new ProbeBlendSceneProjection(),
|
|
20618
21137
|
temporalDemanded: frameDemandsTemporal(candidateFrame),
|
|
20619
21138
|
gpuDrivenSceneRequired: true
|
|
@@ -20660,16 +21179,31 @@ var PersistentRenderScene = class {
|
|
|
20660
21179
|
*/
|
|
20661
21180
|
deriveFramePlan(entry, buildCandidateFrame) {
|
|
20662
21181
|
const resourceFrame = buildCandidateFrame("none");
|
|
20663
|
-
const
|
|
21182
|
+
const cachedDispatch = entry.dispatchCache;
|
|
21183
|
+
const dispatch = [
|
|
21184
|
+
...cachedDispatch?.revision === entry.dispatchRevision ? cachedDispatch.value : dispatchForProjection(entry.dispatchBySlot, entry.projection, entry.unavailableSlots)
|
|
21185
|
+
];
|
|
21186
|
+
if (cachedDispatch?.revision !== entry.dispatchRevision) {
|
|
21187
|
+
entry.dispatchCache = { revision: entry.dispatchRevision, value: dispatch };
|
|
21188
|
+
}
|
|
21189
|
+
const candidateFrame = {
|
|
21190
|
+
...resourceFrame,
|
|
21191
|
+
...entry.structure,
|
|
21192
|
+
dispatch
|
|
21193
|
+
};
|
|
20664
21194
|
entry.temporalDemanded = frameDemandsTemporal(candidateFrame);
|
|
20665
21195
|
entry.projection.setTemporalTracking(entry.temporalDemanded);
|
|
20666
21196
|
this.projectProbes(entry, candidateFrame);
|
|
20667
21197
|
this.projectReflectionProbes(candidateFrame.reflectionProbes ?? []);
|
|
20668
21198
|
const materialized = entry.projection.materialize();
|
|
20669
21199
|
const candidates = entry.temporalDemanded ? materialized.map((snapshot) => entry.projection.withTemporal(snapshot)) : materialized;
|
|
21200
|
+
const drawableCandidates = entry.unavailableSlots.size === 0 ? candidates : candidates.map((snapshot) => {
|
|
21201
|
+
const slot = entry.projection.slot(snapshot.worldId, snapshot.entityKey);
|
|
21202
|
+
return slot !== void 0 && entry.unavailableSlots.has(slot.slot) ? { ...snapshot, authorVisible: false } : snapshot;
|
|
21203
|
+
});
|
|
20670
21204
|
const frameWithProbes = attachProbeRecords(
|
|
20671
|
-
{ ...candidateFrame, renderables:
|
|
20672
|
-
|
|
21205
|
+
{ ...candidateFrame, renderables: drawableCandidates },
|
|
21206
|
+
drawableCandidates,
|
|
20673
21207
|
entry.projection.slotsSnapshot(),
|
|
20674
21208
|
entry.probeProjection
|
|
20675
21209
|
);
|
|
@@ -21314,6 +21848,7 @@ function createRenderSystem(internals) {
|
|
|
21314
21848
|
let preparedWorlds = [];
|
|
21315
21849
|
let latestCamera;
|
|
21316
21850
|
const pointsLinesOwner = new StandardPointsLinesOwner(internals);
|
|
21851
|
+
const instanceCollections = new InstanceProjectionStore();
|
|
21317
21852
|
const reflectionProbeOwner = new ReflectionProbeRecordOwner(internals);
|
|
21318
21853
|
let ssrFormatReceipt;
|
|
21319
21854
|
let ssrFormatProbeGeneration = -1;
|
|
@@ -21345,7 +21880,9 @@ function createRenderSystem(internals) {
|
|
|
21345
21880
|
onGpuError: (error) => internals.errorRegistry.fire(error),
|
|
21346
21881
|
onSharedRefMutation: (worldId, handle) => {
|
|
21347
21882
|
internals.gpuStore.invalidateMesh(handle, preparedWorlds[worldId] ?? worldId);
|
|
21348
|
-
}
|
|
21883
|
+
},
|
|
21884
|
+
instanceCollections,
|
|
21885
|
+
getSkinPaletteAllocator: () => internals.getPipelineState()?.skinPaletteAllocator ?? null
|
|
21349
21886
|
});
|
|
21350
21887
|
let environmentLifecycle = new EnvironmentLifecycle(internals.deviceScope);
|
|
21351
21888
|
const transmissionAdmission = new TransmissionCandidateAdmission();
|
|
@@ -21559,6 +22096,8 @@ function createRenderSystem(internals) {
|
|
|
21559
22096
|
currentDirectionalShadowView: null,
|
|
21560
22097
|
currentSpotShadowView: null,
|
|
21561
22098
|
instanceBuffers: /* @__PURE__ */ new Map(),
|
|
22099
|
+
instanceResidency: /* @__PURE__ */ new Map(),
|
|
22100
|
+
instanceBufferChunks: /* @__PURE__ */ new Map(),
|
|
21562
22101
|
probeBlendBuffers: /* @__PURE__ */ new Map(),
|
|
21563
22102
|
probeBlendRecordBufferCapacity: 0,
|
|
21564
22103
|
morphBuffers: /* @__PURE__ */ new Map(),
|
|
@@ -22282,6 +22821,12 @@ function createRenderSystem(internals) {
|
|
|
22282
22821
|
createPreparedResolverCaches
|
|
22283
22822
|
});
|
|
22284
22823
|
return {
|
|
22824
|
+
get instanceCollectionsInspection() {
|
|
22825
|
+
return instanceCollections._inspections(
|
|
22826
|
+
frameState.instanceResidency,
|
|
22827
|
+
frameState.frameNumber - 1
|
|
22828
|
+
);
|
|
22829
|
+
},
|
|
22285
22830
|
releaseProfilerCatalog() {
|
|
22286
22831
|
releaseProfilerCatalog?.();
|
|
22287
22832
|
releaseProfilerCatalog = void 0;
|
|
@@ -22487,7 +23032,7 @@ function createRenderSystem(internals) {
|
|
|
22487
23032
|
compositionWorlds,
|
|
22488
23033
|
{ cameraOwner, resourceOwner },
|
|
22489
23034
|
internals.assets.catalogEpoch,
|
|
22490
|
-
(
|
|
23035
|
+
(request) => extractFrames(
|
|
22491
23036
|
compositionWorlds,
|
|
22492
23037
|
{ cameraOwner, resourceOwner },
|
|
22493
23038
|
internals.assets,
|
|
@@ -22495,7 +23040,10 @@ function createRenderSystem(internals) {
|
|
|
22495
23040
|
persistentRenderScene.materialSnapshotCacheStore(),
|
|
22496
23041
|
{
|
|
22497
23042
|
cull: "none",
|
|
22498
|
-
renderables:
|
|
23043
|
+
renderables: request === "none" ? "none" : "full",
|
|
23044
|
+
...request === "none" || request === "full" ? {} : { renderableEntitiesByWorld: request.entitiesByWorld },
|
|
23045
|
+
retainHidden: true,
|
|
23046
|
+
instanceCollections,
|
|
22499
23047
|
...internals.getMaterialShaderArtifact === void 0 ? {} : { getMaterialShaderArtifact: internals.getMaterialShaderArtifact }
|
|
22500
23048
|
}
|
|
22501
23049
|
),
|
|
@@ -23281,6 +23829,7 @@ function createRenderSystem(internals) {
|
|
|
23281
23829
|
internals.gpuPassTimingBeginReason = void 0;
|
|
23282
23830
|
pointsLinesOwner.dispose();
|
|
23283
23831
|
persistentRenderScene.dispose();
|
|
23832
|
+
instanceCollections.dispose();
|
|
23284
23833
|
gpuDrivenProduction.dispose();
|
|
23285
23834
|
occlusionRuntime?.dispose();
|
|
23286
23835
|
disposeFeatureGpuWork();
|
|
@@ -23337,6 +23886,10 @@ function createRenderSystem(internals) {
|
|
|
23337
23886
|
}
|
|
23338
23887
|
frameState.retiredCompiledFrameGraphs.clear();
|
|
23339
23888
|
disposeInstanceBuffers(frameState.instanceBuffers, internals.errorRegistry);
|
|
23889
|
+
frameState.instanceResidency?.clear();
|
|
23890
|
+
if (frameState.instanceBufferChunks !== void 0) {
|
|
23891
|
+
disposeInstanceBufferChunks(frameState.instanceBufferChunks, internals.errorRegistry);
|
|
23892
|
+
}
|
|
23340
23893
|
disposeTransientInstanceBuffers(frameState.transientInstanceBuffers, internals.errorRegistry);
|
|
23341
23894
|
if (frameState.probeBlendRecordBuffer !== void 0) {
|
|
23342
23895
|
if (!frameState.probeBlendRecordBuffer.isDestroyed) {
|
|
@@ -23439,6 +23992,8 @@ function createRenderSystem(internals) {
|
|
|
23439
23992
|
}
|
|
23440
23993
|
frameState.retiredCompiledFrameGraphs.clear();
|
|
23441
23994
|
frameState.instanceBuffers.clear();
|
|
23995
|
+
frameState.instanceBufferChunks?.clear();
|
|
23996
|
+
frameState.instanceResidency?.clear();
|
|
23442
23997
|
delete frameState.probeBlendRecordBuffer;
|
|
23443
23998
|
frameState.probeBlendRecordBufferCapacity = 0;
|
|
23444
23999
|
frameState.probeBlendBuffers.clear();
|
|
@@ -24577,11 +25132,10 @@ async function prepareMaterialShaders(rhiDevice, getShader, assets, materialShad
|
|
|
24577
25132
|
]);
|
|
24578
25133
|
const capValue = rhiDevice.limits.maxStorageBuffersPerShaderStage;
|
|
24579
25134
|
const webgl2Downlevel = rhiDevice.caps.backendKind === "wgpu-webgl2";
|
|
24580
|
-
|
|
24581
|
-
if (typeof capValue === "number") {
|
|
25135
|
+
const storageBufferCapable = rhiDevice.caps.storageBuffer;
|
|
25136
|
+
if (storageBufferCapable && typeof capValue === "number") {
|
|
24582
25137
|
const capCheck = assertStorageBufferCap(capValue);
|
|
24583
25138
|
if (!capCheck.ok) throw capCheck.error;
|
|
24584
|
-
storageBufferCapable = !webgl2Downlevel && capCheck.value;
|
|
24585
25139
|
}
|
|
24586
25140
|
const extendedLightingShaderAvailable = deriveExtendedLightingCapability(rhiDevice).admitted;
|
|
24587
25141
|
const projectorAvailable = (rhiDevice.limits.maxSampledTexturesPerShaderStage ?? 0) >= STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES2;
|
|
@@ -24593,9 +25147,10 @@ async function prepareMaterialShaders(rhiDevice, getShader, assets, materialShad
|
|
|
24593
25147
|
const isHdrpActive = false;
|
|
24594
25148
|
for (const msEntry of registry.materialShaderManifestEntries()) {
|
|
24595
25149
|
if (msEntry.identifier.startsWith("forgeax::engine-")) continue;
|
|
24596
|
-
const variantDefines = {
|
|
24597
|
-
|
|
24598
|
-
|
|
25150
|
+
const variantDefines = {};
|
|
25151
|
+
if (msEntry.variants.some((variant) => "STORAGE_BUFFER_AVAILABLE" in variant.defines)) {
|
|
25152
|
+
variantDefines.STORAGE_BUFFER_AVAILABLE = storageBufferCapable;
|
|
25153
|
+
}
|
|
24599
25154
|
if (msEntry.variants.some((v) => "WEBGL2_COMPAT" in v.defines)) {
|
|
24600
25155
|
variantDefines.WEBGL2_COMPAT = webgl2Downlevel;
|
|
24601
25156
|
}
|
|
@@ -24678,7 +25233,7 @@ async function prepareMaterialShaders(rhiDevice, getShader, assets, materialShad
|
|
|
24678
25233
|
if (manifestEntry !== void 0) {
|
|
24679
25234
|
registry.installMaterialArtifact(shadowCasterIdentifier, {
|
|
24680
25235
|
source: manifestEntry.composedWgsl,
|
|
24681
|
-
paramSchema:
|
|
25236
|
+
paramSchema: STANDARD_PIPELINE_PARAM_SCHEMA
|
|
24682
25237
|
});
|
|
24683
25238
|
const shaderGuid = ENGINE_SHADER_GUIDS.get(shadowCasterIdentifier);
|
|
24684
25239
|
if (shaderGuid !== void 0) {
|
|
@@ -24686,7 +25241,7 @@ async function prepareMaterialShaders(rhiDevice, getShader, assets, materialShad
|
|
|
24686
25241
|
kind: "shader",
|
|
24687
25242
|
name: shadowCasterIdentifier,
|
|
24688
25243
|
source: manifestEntry.composedWgsl,
|
|
24689
|
-
paramSchema:
|
|
25244
|
+
paramSchema: STANDARD_PIPELINE_PARAM_SCHEMA
|
|
24690
25245
|
};
|
|
24691
25246
|
assets.catalog(shaderGuid, shaderAsset);
|
|
24692
25247
|
}
|
|
@@ -24775,6 +25330,47 @@ function resolveMaterialShaderVertexInputContract(source) {
|
|
|
24775
25330
|
}
|
|
24776
25331
|
return /@vertex\s*fn[^{]*\([^)]*@location\s*\(/u.test(withoutComments) ? "render-material" : "none";
|
|
24777
25332
|
}
|
|
25333
|
+
function resolveMaterialShaderUvSetCount(source, reflectedCount) {
|
|
25334
|
+
if (reflectedCount !== void 0) return reflectedCount;
|
|
25335
|
+
if (source === void 0) return void 0;
|
|
25336
|
+
const withoutComments = source.replace(/\/\*[\s\S]*?\*\//gu, "").replace(/\/\/.*$/gmu, "");
|
|
25337
|
+
const inputStructs = [
|
|
25338
|
+
...withoutComments.matchAll(/struct\s+([A-Za-z_]\w*)\s*\{([^}]*)\}/gu)
|
|
25339
|
+
].filter((match) => /@location\s*\(/u.test(match[2] ?? ""));
|
|
25340
|
+
for (const inputStruct of inputStructs) {
|
|
25341
|
+
const name = inputStruct[1];
|
|
25342
|
+
const body = inputStruct[2];
|
|
25343
|
+
if (name === void 0 || body === void 0) continue;
|
|
25344
|
+
const firstParameter = new RegExp(
|
|
25345
|
+
`@vertex\\s*fn\\s+\\w+\\s*\\(\\s*\\w+\\s*:\\s*${name}\\b`,
|
|
25346
|
+
"u"
|
|
25347
|
+
);
|
|
25348
|
+
if (!firstParameter.test(withoutComments)) continue;
|
|
25349
|
+
let uvSetCount = 0;
|
|
25350
|
+
for (const location of body.matchAll(/@location\s*\(\s*(\d+)\s*\)\s+([A-Za-z_]\w*)/gu)) {
|
|
25351
|
+
const field = location[2];
|
|
25352
|
+
if (field === "uv") {
|
|
25353
|
+
uvSetCount = Math.max(uvSetCount, 1);
|
|
25354
|
+
continue;
|
|
25355
|
+
}
|
|
25356
|
+
const uvIndex = field?.match(/^uv(\d+)_?$/u)?.[1];
|
|
25357
|
+
if (uvIndex !== void 0) uvSetCount = Math.max(uvSetCount, Number(uvIndex) + 1);
|
|
25358
|
+
}
|
|
25359
|
+
return uvSetCount > 0 ? uvSetCount : void 0;
|
|
25360
|
+
}
|
|
25361
|
+
return void 0;
|
|
25362
|
+
}
|
|
25363
|
+
function resolveMaterialShaderBackendArtifactKey(materialShaderId, backendKind, artifact) {
|
|
25364
|
+
if (backendKind !== "wgpu-webgl2") return materialShaderId;
|
|
25365
|
+
const variants = artifact?.metadata?.variants;
|
|
25366
|
+
if (!Array.isArray(variants)) return materialShaderId;
|
|
25367
|
+
const fallback = variants.find((variant) => {
|
|
25368
|
+
if (typeof variant !== "object" || variant === null) return false;
|
|
25369
|
+
const candidate = variant;
|
|
25370
|
+
return candidate.backend === "webgl2" && candidate.capability === "uniform-fallback" && typeof candidate.specializationKey === "string" && candidate.specializationKey.length > 0;
|
|
25371
|
+
});
|
|
25372
|
+
return fallback?.specializationKey ?? materialShaderId;
|
|
25373
|
+
}
|
|
24778
25374
|
function allowsUnlitPreparedFallback(depthFormatOverride, vertexLayout, materialShaderId) {
|
|
24779
25375
|
return depthFormatOverride === null && (vertexLayout === void 0 || !materialShaderId?.startsWith("forgeax::"));
|
|
24780
25376
|
}
|
|
@@ -26016,7 +26612,7 @@ function createRendererRecovery(deps) {
|
|
|
26016
26612
|
releaseCandidate();
|
|
26017
26613
|
return err(new RecoverError("recover-device-unavailable"));
|
|
26018
26614
|
}
|
|
26019
|
-
const graphPreparation = renderSystem.prepareRecoveryGraphCandidate({
|
|
26615
|
+
const graphPreparation = await renderSystem.prepareRecoveryGraphCandidate({
|
|
26020
26616
|
internals: candidateInternals,
|
|
26021
26617
|
pipelineState: candidatePipelineState
|
|
26022
26618
|
});
|
|
@@ -27283,6 +27879,11 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27283
27879
|
let storageBuffer = null;
|
|
27284
27880
|
let storageCapacity = 0;
|
|
27285
27881
|
let storageCursor = 0;
|
|
27882
|
+
let stableStorageCursor = 0;
|
|
27883
|
+
const stableSlices = /* @__PURE__ */ new Map();
|
|
27884
|
+
const stableUniformBuffers = /* @__PURE__ */ new Map();
|
|
27885
|
+
const storageBufferCapacities = /* @__PURE__ */ new WeakMap();
|
|
27886
|
+
const stableFreeRanges = [];
|
|
27286
27887
|
const pool = [];
|
|
27287
27888
|
let poolCursor = 0;
|
|
27288
27889
|
function ensureStorageCapacity(needed) {
|
|
@@ -27303,12 +27904,9 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27303
27904
|
if (!bufRes.ok) throw bufRes.error;
|
|
27304
27905
|
storageBuffer = bufRes.value;
|
|
27305
27906
|
storageCapacity = newCapacity;
|
|
27907
|
+
storageBufferCapacities.set(storageBuffer, newCapacity);
|
|
27306
27908
|
}
|
|
27307
|
-
function
|
|
27308
|
-
if (poolCursor < pool.length) {
|
|
27309
|
-
const reused = pool[poolCursor];
|
|
27310
|
-
return reused;
|
|
27311
|
-
}
|
|
27909
|
+
function createUniformBuffer() {
|
|
27312
27910
|
if (BINDING_WINDOW_BYTES > maxBindingSize) {
|
|
27313
27911
|
throw new SkinPaletteOverflowError(BINDING_WINDOW_BYTES, maxBindingSize);
|
|
27314
27912
|
}
|
|
@@ -27319,9 +27917,17 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27319
27917
|
mappedAtCreation: false
|
|
27320
27918
|
});
|
|
27321
27919
|
if (!bufRes.ok) throw bufRes.error;
|
|
27322
|
-
pool.push(bufRes.value);
|
|
27323
27920
|
return bufRes.value;
|
|
27324
27921
|
}
|
|
27922
|
+
function acquirePoolBuffer() {
|
|
27923
|
+
if (poolCursor < pool.length) {
|
|
27924
|
+
const reused = pool[poolCursor];
|
|
27925
|
+
return reused;
|
|
27926
|
+
}
|
|
27927
|
+
const buffer = createUniformBuffer();
|
|
27928
|
+
pool.push(buffer);
|
|
27929
|
+
return buffer;
|
|
27930
|
+
}
|
|
27325
27931
|
function allocateSlice(jointCount) {
|
|
27326
27932
|
if (useStorageBuffer) {
|
|
27327
27933
|
const offset2 = storageCursor;
|
|
@@ -27335,6 +27941,88 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27335
27941
|
poolCursor += 1;
|
|
27336
27942
|
return { jointCount, byteOffset: 0, buffer };
|
|
27337
27943
|
}
|
|
27944
|
+
function allocateSliceFor(key, jointCount) {
|
|
27945
|
+
const existing = stableSlices.get(key);
|
|
27946
|
+
if (existing !== void 0 && existing.jointCount === jointCount) return existing;
|
|
27947
|
+
if (existing !== void 0) releaseSliceFor(key);
|
|
27948
|
+
if (useStorageBuffer) {
|
|
27949
|
+
const span = jointCount * MAT4_BYTES + (PALETTE_OFFSET_ALIGN - 1) & -256;
|
|
27950
|
+
const freeIndex = stableFreeRanges.findIndex(
|
|
27951
|
+
(range) => range.buffer === storageBuffer && range.count >= span && range.start + BINDING_WINDOW_BYTES <= range.capacity
|
|
27952
|
+
);
|
|
27953
|
+
let offset2;
|
|
27954
|
+
let buffer2;
|
|
27955
|
+
if (freeIndex >= 0) {
|
|
27956
|
+
const range = stableFreeRanges[freeIndex];
|
|
27957
|
+
if (range === void 0) throw new Error("Skin palette free range disappeared.");
|
|
27958
|
+
offset2 = range.start;
|
|
27959
|
+
buffer2 = range.buffer;
|
|
27960
|
+
if (range.count === span) stableFreeRanges.splice(freeIndex, 1);
|
|
27961
|
+
else {
|
|
27962
|
+
stableFreeRanges[freeIndex] = {
|
|
27963
|
+
...range,
|
|
27964
|
+
start: range.start + span,
|
|
27965
|
+
count: range.count - span
|
|
27966
|
+
};
|
|
27967
|
+
}
|
|
27968
|
+
} else {
|
|
27969
|
+
offset2 = stableStorageCursor;
|
|
27970
|
+
ensureStorageCapacity(offset2 + BINDING_WINDOW_BYTES);
|
|
27971
|
+
const currentBuffer = storageBuffer;
|
|
27972
|
+
if (currentBuffer === null) throw new Error("Skin palette storage buffer was not created.");
|
|
27973
|
+
buffer2 = currentBuffer;
|
|
27974
|
+
stableStorageCursor = offset2 + span;
|
|
27975
|
+
}
|
|
27976
|
+
const slice2 = { jointCount, byteOffset: offset2, buffer: buffer2 };
|
|
27977
|
+
stableSlices.set(key, slice2);
|
|
27978
|
+
return slice2;
|
|
27979
|
+
}
|
|
27980
|
+
let buffer = stableUniformBuffers.get(key);
|
|
27981
|
+
if (buffer === void 0) {
|
|
27982
|
+
buffer = createUniformBuffer();
|
|
27983
|
+
stableUniformBuffers.set(key, buffer);
|
|
27984
|
+
}
|
|
27985
|
+
const slice = { jointCount, byteOffset: 0, buffer };
|
|
27986
|
+
stableSlices.set(key, slice);
|
|
27987
|
+
return slice;
|
|
27988
|
+
}
|
|
27989
|
+
function releaseSliceFor(key) {
|
|
27990
|
+
const slice = stableSlices.get(key);
|
|
27991
|
+
if (slice === void 0) return;
|
|
27992
|
+
stableSlices.delete(key);
|
|
27993
|
+
if (!useStorageBuffer) {
|
|
27994
|
+
stableUniformBuffers.delete(key);
|
|
27995
|
+
device.destroyBuffer(slice.buffer);
|
|
27996
|
+
return;
|
|
27997
|
+
}
|
|
27998
|
+
const count = slice.jointCount * MAT4_BYTES + (PALETTE_OFFSET_ALIGN - 1) & -256;
|
|
27999
|
+
stableFreeRanges.push({
|
|
28000
|
+
start: slice.byteOffset,
|
|
28001
|
+
count,
|
|
28002
|
+
buffer: slice.buffer,
|
|
28003
|
+
capacity: storageBufferCapacities.get(slice.buffer) ?? storageCapacity
|
|
28004
|
+
});
|
|
28005
|
+
stableFreeRanges.sort((left, right) => left.start - right.start);
|
|
28006
|
+
for (let index = stableFreeRanges.length - 1; index > 0; index -= 1) {
|
|
28007
|
+
const current = stableFreeRanges[index];
|
|
28008
|
+
const previous = stableFreeRanges[index - 1];
|
|
28009
|
+
if (current === void 0 || previous === void 0 || current.buffer !== previous.buffer || previous.start + previous.count !== current.start) {
|
|
28010
|
+
continue;
|
|
28011
|
+
}
|
|
28012
|
+
stableFreeRanges[index - 1] = {
|
|
28013
|
+
start: previous.start,
|
|
28014
|
+
count: previous.count + current.count,
|
|
28015
|
+
buffer: previous.buffer,
|
|
28016
|
+
capacity: previous.capacity
|
|
28017
|
+
};
|
|
28018
|
+
stableFreeRanges.splice(index, 1);
|
|
28019
|
+
}
|
|
28020
|
+
}
|
|
28021
|
+
function retainSliceKeys(keys) {
|
|
28022
|
+
for (const key of stableSlices.keys()) {
|
|
28023
|
+
if (!keys.has(key)) releaseSliceFor(key);
|
|
28024
|
+
}
|
|
28025
|
+
}
|
|
27338
28026
|
function writeJointPalette(slice, ibms, jointWorlds) {
|
|
27339
28027
|
const count = Math.min(slice.jointCount, ibms.length, jointWorlds.length);
|
|
27340
28028
|
if (count === 0) return;
|
|
@@ -27365,6 +28053,9 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27365
28053
|
bindingWindowBytes: BINDING_WINDOW_BYTES,
|
|
27366
28054
|
useStorageBuffer,
|
|
27367
28055
|
allocateSlice,
|
|
28056
|
+
allocateSliceFor,
|
|
28057
|
+
releaseSliceFor,
|
|
28058
|
+
retainSliceKeys,
|
|
27368
28059
|
writeJointPalette,
|
|
27369
28060
|
resetForFrame
|
|
27370
28061
|
};
|
|
@@ -27695,13 +28386,8 @@ var DEPTH_TEXTURE_FORMAT = "depth24plus-stencil8";
|
|
|
27695
28386
|
// src/assembly/webgpu-ready.ts
|
|
27696
28387
|
async function buildReadyWebGPU(rhiDevice, rendererScope, getShader, gpuStore, asyncCreateShaderModule, errorRegistry, requiredMaterialShaders, requiredFullscreenPostProcesses, setGrowMeshSsboHook, seedShaderModule, seedMaterialShaderPipelineCache, registerBuiltinTonemap, registerBuiltinFxaa, registerBuiltinTemporalPostProcesses, setVolumetricFogShaderSources) {
|
|
27697
28388
|
const extendedLightingShaderAvailable = deriveExtendedLightingCapability(rhiDevice).admitted;
|
|
27698
|
-
const
|
|
28389
|
+
const storageBufferCapable = rhiDevice.caps.storageBuffer;
|
|
27699
28390
|
const webgl2Downlevel = rhiDevice.caps.backendKind === "wgpu-webgl2";
|
|
27700
|
-
let storageBufferCapable = !webgl2Downlevel;
|
|
27701
|
-
if (typeof capValue === "number") {
|
|
27702
|
-
const capCheck = assertStorageBufferCap(capValue);
|
|
27703
|
-
storageBufferCapable = capCheck.ok ? !webgl2Downlevel && capCheck.value : !webgl2Downlevel;
|
|
27704
|
-
}
|
|
27705
28391
|
const directionalPcssAvailable = rhiDevice.caps.backendKind === "webgpu" || rhiDevice.caps.backendKind === "wgpu-native";
|
|
27706
28392
|
const projectorAvailable = (rhiDevice.limits.maxSampledTexturesPerShaderStage ?? 0) >= STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES2;
|
|
27707
28393
|
const surfaceViewFormats = rhiDevice.surfaceViewFormats ?? !webgl2Downlevel;
|
|
@@ -30333,11 +31019,7 @@ async function buildReadyWebGPU(rhiDevice, rendererScope, getShader, gpuStore, a
|
|
|
30333
31019
|
return pipelineState;
|
|
30334
31020
|
}
|
|
30335
31021
|
|
|
30336
|
-
// src/assembly/webgpu-
|
|
30337
|
-
function adaptMipmapShaderModuleFactory(factory) {
|
|
30338
|
-
if (factory === void 0) return void 0;
|
|
30339
|
-
return (device, descriptor) => factory(device, descriptor);
|
|
30340
|
-
}
|
|
31022
|
+
// src/assembly/webgpu-vertex-layouts.ts
|
|
30341
31023
|
var PBR_SKIN_SENTINEL_ATTR_BUFFER = new ArrayBuffer(0);
|
|
30342
31024
|
var DEFAULT_VERTEX_ATTRS = {
|
|
30343
31025
|
position: new Float32Array(0),
|
|
@@ -30448,6 +31130,12 @@ function toGpuVertexBufferLayouts(entries) {
|
|
|
30448
31130
|
}))
|
|
30449
31131
|
}));
|
|
30450
31132
|
}
|
|
31133
|
+
|
|
31134
|
+
// src/assembly/webgpu-renderer.ts
|
|
31135
|
+
function adaptMipmapShaderModuleFactory(factory) {
|
|
31136
|
+
if (factory === void 0) return void 0;
|
|
31137
|
+
return (device, descriptor) => factory(device, descriptor);
|
|
31138
|
+
}
|
|
30451
31139
|
var nextDerivedSystemId = 0;
|
|
30452
31140
|
async function tryCreateWebGPURenderer(canvas, options, pack, bundler) {
|
|
30453
31141
|
const importTransport = bundler?.importTransport;
|
|
@@ -31333,14 +32021,17 @@ async function makeWebGPURenderer(internals) {
|
|
|
31333
32021
|
const viewOnlyLayout = bindingContract === "view-only" ? getOrBuildViewOnlyMaterialPipelineLayout() : null;
|
|
31334
32022
|
const viewAndSceneDepthLayout = bindingContract === "view-and-scene-depth" ? getOrBuildViewAndSceneDepthMaterialPipelineLayout() : null;
|
|
31335
32023
|
const preparedMaterialLayout = bindingContract === "render-material" && materialShaderId !== void 0 && (vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.billboardMaterialInstance || vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.meshGeometryMaterialInstance) ? getOrBuildPreparedMaterialPipelineLayout(materialShaderId) : null;
|
|
31336
|
-
const
|
|
31337
|
-
|
|
31338
|
-
|
|
31339
|
-
})();
|
|
32024
|
+
const materialShaderLookup = materialShaderId === void 0 ? void 0 : getShader().findMaterialArtifact(materialShaderId);
|
|
32025
|
+
const materialShaderSource = materialShaderLookup?.ok ? materialShaderLookup.value.source : void 0;
|
|
32026
|
+
const vertexInputContract = materialShaderId === void 0 ? "render-material" : materialShaderSource !== void 0 ? resolveMaterialShaderVertexInputContract(materialShaderSource) : "render-material";
|
|
31340
32027
|
const currentState = currentPipelineState();
|
|
31341
32028
|
const pipelineLayout = group0Layout !== null ? group0Layout.pipelineLayout : group0ResourceLayout !== null ? group0ResourceLayout.pipelineLayout : viewOnlyLayout !== null ? viewOnlyLayout : viewAndSceneDepthLayout !== null ? viewAndSceneDepthLayout : preparedMaterialLayout !== null ? preparedMaterialLayout : perShaderLayout !== null ? perShaderLayout.pipelineLayout : selectPipelineLayoutForVariant(currentState, variantSet, layoutKind);
|
|
31342
32029
|
if (pipelineLayout === null) return null;
|
|
31343
|
-
const
|
|
32030
|
+
const currentMaterialUvSetCounts = currentMaterialShaderUvSetCounts();
|
|
32031
|
+
const resolvedUvSetCount = materialShaderId !== void 0 ? currentMaterialUvSetCounts.get(materialShaderId) ?? (materialShaderSource !== void 0 ? resolveMaterialShaderUvSetCount(
|
|
32032
|
+
materialShaderSource,
|
|
32033
|
+
currentMaterialUvSetCounts.get(materialShaderId)
|
|
32034
|
+
) : void 0) : void 0;
|
|
31344
32035
|
const vertexBuffers = vertexInputContract === "none" ? [] : vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.positionSizeColorInstance ? POSITION_SIZE_COLOR_INSTANCE_VERTEX_BUFFERS : vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.billboardMaterialInstance ? BILLBOARD_MATERIAL_INSTANCE_VERTEX_BUFFERS : vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.topologySegmentInstance ? TOPOLOGY_SEGMENT_INSTANCE_VERTEX_BUFFERS : vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.meshGeometryMaterialInstance ? MESH_GEOMETRY_MATERIAL_INSTANCE_VERTEX_BUFFERS : vertexLayoutProjection !== void 0 ? toGpuVertexBufferLayouts(
|
|
31345
32036
|
deriveVertexBufferLayoutFromProjection(
|
|
31346
32037
|
vertexLayoutProjection,
|
|
@@ -31451,10 +32142,26 @@ async function makeWebGPURenderer(internals) {
|
|
|
31451
32142
|
const getMaterialShaderPipeline = (materialShaderId, isHdr, renderState, topology, indexFormat, variantSet, passKind = "forward", meshAttributes, sampleCount = 1, colorFormatOverride, shaderUvSetCount, depthFormatOverride, vertexLayout, vertexLayoutProjection, shaderModuleMode = "validated", layoutKindOverride, additionalColorFormats) => {
|
|
31452
32143
|
const currentState = currentPipelineState();
|
|
31453
32144
|
const ldrColorFormat = colorFormatOverride ?? (currentState !== null ? currentState.colorAttachmentFormat : "bgra8unorm-srgb");
|
|
31454
|
-
const
|
|
31455
|
-
|
|
31456
|
-
|
|
32145
|
+
const pipelineShaderId = resolveMaterialShaderBackendArtifactKey(
|
|
32146
|
+
materialShaderId,
|
|
32147
|
+
internals.device.caps.backendKind,
|
|
32148
|
+
assets.getMaterialArtifact(materialShaderId)
|
|
32149
|
+
);
|
|
32150
|
+
const materialShaderLookup = getShader().findMaterialArtifact(pipelineShaderId);
|
|
32151
|
+
const materialShaderSource = materialShaderLookup.ok ? materialShaderLookup.value.source : void 0;
|
|
32152
|
+
const currentMaterialUvSetCounts = currentMaterialShaderUvSetCounts();
|
|
32153
|
+
const materialUvSetCount = resolveMaterialShaderUvSetCount(
|
|
32154
|
+
materialShaderSource,
|
|
32155
|
+
currentMaterialUvSetCounts.get(pipelineShaderId)
|
|
32156
|
+
);
|
|
32157
|
+
if (materialUvSetCount !== void 0) {
|
|
32158
|
+
currentMaterialUvSetCounts.set(pipelineShaderId, materialUvSetCount);
|
|
32159
|
+
}
|
|
32160
|
+
const resolvedUvSetCount = shaderUvSetCount ?? materialUvSetCount;
|
|
32161
|
+
const manifestEntry = findMaterialShaderManifestEntry(pipelineShaderId);
|
|
32162
|
+
const resolvedVariantSet = variantSet === void 0 && (pipelineShaderId === "forgeax::sprite" || pipelineShaderId === "forgeax::sprite-lit") ? void 0 : resolveCachedMaterialShaderVariantSet(variantSet, manifestEntry);
|
|
31457
32163
|
let effectiveVariantSet = normalizeMaterialShaderVariantSet(resolvedVariantSet, manifestEntry);
|
|
32164
|
+
if (manifestEntry === void 0) effectiveVariantSet = void 0;
|
|
31458
32165
|
if (vertexLayoutProjection === void 0 && manifestEntry?.variants.some((variant) => "VERTEX_COLOR_AVAILABLE" in variant.defines)) {
|
|
31459
32166
|
if (effectiveVariantSet === "") {
|
|
31460
32167
|
const noColorVariant = manifestEntry.variants.find(
|
|
@@ -31470,7 +32177,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31470
32177
|
);
|
|
31471
32178
|
}
|
|
31472
32179
|
}
|
|
31473
|
-
if (manifestEntry !== void 0 && !
|
|
32180
|
+
if (manifestEntry !== void 0 && !pipelineShaderId.startsWith("forgeax::") && effectiveVariantSet !== void 0 && effectiveVariantSet !== "") {
|
|
31474
32181
|
const declaredAxes = /* @__PURE__ */ new Set();
|
|
31475
32182
|
for (const variant of manifestEntry.variants) {
|
|
31476
32183
|
for (const axis of Object.keys(variant.defines)) declaredAxes.add(axis);
|
|
@@ -31481,7 +32188,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31481
32188
|
const colorFormat = isHdr ? "rgba16float" : ldrColorFormat;
|
|
31482
32189
|
const isDepthOnlyPass = passKindPolicyTable[passKind]?.shape === "depth-only";
|
|
31483
32190
|
const spec = {
|
|
31484
|
-
shader: { id:
|
|
32191
|
+
shader: { id: pipelineShaderId, passKind, variantSet: effectiveVariantSet },
|
|
31485
32192
|
attachments: {
|
|
31486
32193
|
colorFormats: additionalColorFormats === void 0 ? colorFormatsForPassKind(passKind, colorFormat) : [colorFormat, ...additionalColorFormats],
|
|
31487
32194
|
depthFormat: isDepthOnlyPass ? "depth32float" : depthFormatOverride === null ? void 0 : depthFormatOverride ?? "depth24plus-stencil8",
|
|
@@ -31503,12 +32210,12 @@ async function makeWebGPURenderer(internals) {
|
|
|
31503
32210
|
const cached = currentPipelineCacheState().materialShaderPipelineCache.get(cacheKey);
|
|
31504
32211
|
if (cached !== void 0) return cached;
|
|
31505
32212
|
if (pipelineState === null) return null;
|
|
31506
|
-
const lookup = getShader().findMaterialArtifact(
|
|
32213
|
+
const lookup = getShader().findMaterialArtifact(pipelineShaderId);
|
|
31507
32214
|
if (!lookup.ok) {
|
|
31508
32215
|
if (shouldDeferMissingPreparedMaterialShader(vertexLayout)) {
|
|
31509
32216
|
return null;
|
|
31510
32217
|
}
|
|
31511
|
-
if (renderState === void 0 && !allowsUnlitPreparedFallback(depthFormatOverride, vertexLayout,
|
|
32218
|
+
if (renderState === void 0 && !allowsUnlitPreparedFallback(depthFormatOverride, vertexLayout, pipelineShaderId)) {
|
|
31512
32219
|
return null;
|
|
31513
32220
|
}
|
|
31514
32221
|
if (renderState === void 0) {
|
|
@@ -31517,7 +32224,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31517
32224
|
return buildAndCachePipeline(
|
|
31518
32225
|
cacheKey,
|
|
31519
32226
|
unlitLookup.value,
|
|
31520
|
-
`pbr-pipeline-prepared-${
|
|
32227
|
+
`pbr-pipeline-prepared-${pipelineShaderId}`,
|
|
31521
32228
|
// Reuse the eagerly compiled engine unlit module. The adapter cache
|
|
31522
32229
|
// is seeded under this label during renderer readiness; a new label
|
|
31523
32230
|
// would keep color-only prepared passes in perpetual warm-up.
|
|
@@ -31545,7 +32252,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31545
32252
|
return buildAndCachePipeline(
|
|
31546
32253
|
cacheKey,
|
|
31547
32254
|
{ source: pbrEntry.wgsl},
|
|
31548
|
-
`pbr-pipeline-fallback-${
|
|
32255
|
+
`pbr-pipeline-fallback-${pipelineShaderId}${isHdr ? "-hdr" : ""}`,
|
|
31549
32256
|
// w16-b: module identity is the fallback PBR source, stable across
|
|
31550
32257
|
// topology / renderState / HDR (all baked into the PSO) so every
|
|
31551
32258
|
// variant reuses one compiled module.
|
|
@@ -31579,7 +32286,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31579
32286
|
// layout resolution so buildPipelineContext derives the layout that
|
|
31580
32287
|
// matches the compiled module. Skin keeps its
|
|
31581
32288
|
// own id so the pbr-skin fail-fast (null layout) is preserved.
|
|
31582
|
-
|
|
32289
|
+
pipelineShaderId === SKIN_MATERIAL_SHADER_ID ? pipelineShaderId : "forgeax::default-standard-pbr",
|
|
31583
32290
|
// feat-20260611-fox-skinning-vertex-attribute-chain M4 / w16 (D-4):
|
|
31584
32291
|
// forward meshAttributes through the fallback path so the pbr-skin
|
|
31585
32292
|
// layout chain reads from the deriveVertexBufferLayout SSOT here too.
|
|
@@ -31598,7 +32305,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31598
32305
|
if (effectiveVariantSet !== void 0) {
|
|
31599
32306
|
const registry = getShader();
|
|
31600
32307
|
for (const msEntry of registry.materialShaderManifestEntries()) {
|
|
31601
|
-
if (msEntry.identifier ===
|
|
32308
|
+
if (msEntry.identifier === pipelineShaderId) {
|
|
31602
32309
|
const variant = findVariantByKey(msEntry, effectiveVariantSet);
|
|
31603
32310
|
if (variant) {
|
|
31604
32311
|
shaderEntry = {
|
|
@@ -31615,7 +32322,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31615
32322
|
return buildAndCachePipeline(
|
|
31616
32323
|
cacheKey,
|
|
31617
32324
|
shaderEntry,
|
|
31618
|
-
`pbr-pipeline-${
|
|
32325
|
+
`pbr-pipeline-${pipelineShaderId}${isHdr ? "-hdr" : ""}${passKindLabelSegment}`,
|
|
31619
32326
|
// feat-20260609 M4 / w31: when variantSet is non-empty, the module identity
|
|
31620
32327
|
// includes the variant key so URP (STORAGE_BUFFER_AVAILABLE=true) and HDRP
|
|
31621
32328
|
// (CLUSTER_FORWARD_AVAILABLE=true+STORAGE_BUFFER_AVAILABLE=true) variants
|
|
@@ -31628,7 +32335,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31628
32335
|
// case is intentional (parallel to the cache key's `:variant:`
|
|
31629
32336
|
// empty-tail segment); module identity stays a function of the
|
|
31630
32337
|
// exact variantSet string.
|
|
31631
|
-
effectiveVariantSet !== void 0 ? `module-${
|
|
32338
|
+
effectiveVariantSet !== void 0 ? `module-${pipelineShaderId}#${effectiveVariantSet}` : `module-${pipelineShaderId}`,
|
|
31632
32339
|
isHdr,
|
|
31633
32340
|
renderState,
|
|
31634
32341
|
topology,
|
|
@@ -31644,7 +32351,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31644
32351
|
// bug-20260611-skin-pipeline-layout: thread the registered materialShaderId
|
|
31645
32352
|
// so buildPipelineContext can resolve LayoutKind='pbr-skin' for the skin
|
|
31646
32353
|
// shader (2-entry mesh-array BGL).
|
|
31647
|
-
|
|
32354
|
+
pipelineShaderId,
|
|
31648
32355
|
// feat-20260611-fox-skinning-vertex-attribute-chain M4 / w16 (D-4):
|
|
31649
32356
|
// forward meshAttributes so the pbr-skin path's vertex buffer layout
|
|
31650
32357
|
// is derived via the SSOT (deriveVertexBufferLayout). For URP/HDRP
|
|
@@ -31989,6 +32696,22 @@ async function makeWebGPURenderer(internals) {
|
|
|
31989
32696
|
featureDiagnostics: internals.featureHost?.diagnostics() ?? Object.freeze([]),
|
|
31990
32697
|
frustumStats: Object.freeze({ ...renderSystem.frustumStats }),
|
|
31991
32698
|
visibilityStats: Object.freeze({ ...renderSystem.visibilityStats }),
|
|
32699
|
+
instanceCollections: Object.freeze(
|
|
32700
|
+
renderSystem.instanceCollectionsInspection.map(
|
|
32701
|
+
(collection) => Object.freeze({
|
|
32702
|
+
...collection,
|
|
32703
|
+
uploadRanges: Object.freeze(
|
|
32704
|
+
collection.uploadRanges.map((range) => Object.freeze({ ...range }))
|
|
32705
|
+
),
|
|
32706
|
+
...collection.error === void 0 ? {} : {
|
|
32707
|
+
error: Object.freeze({
|
|
32708
|
+
...collection.error,
|
|
32709
|
+
detail: Object.freeze({ ...collection.error.detail })
|
|
32710
|
+
})
|
|
32711
|
+
}
|
|
32712
|
+
})
|
|
32713
|
+
)
|
|
32714
|
+
),
|
|
31992
32715
|
renderScene: renderSystem.renderScene,
|
|
31993
32716
|
reflectionProbes: renderSystem.reflectionProbes,
|
|
31994
32717
|
ssrDependencies: renderSystem.ssrDependencies,
|