@forgeax/engine-render 0.1.24 → 0.1.26
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 +118 -1
- package/dist/assembly/factory.d.ts +1 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +4 -17
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/standard-layer-projection.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 -2
- 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-YKB5DQV7.mjs → chunk-GF523LHF.mjs} +89 -21
- package/dist/chunk-GF523LHF.mjs.map +1 -0
- package/dist/{chunk-KZFTK6DO.mjs → chunk-HKXTW355.mjs} +7 -4
- package/dist/chunk-HKXTW355.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-YRUYGA4A.mjs → chunk-TMIASV2N.mjs} +944 -577
- package/dist/chunk-TMIASV2N.mjs.map +1 -0
- package/dist/{chunk-Z3YYH2MB.mjs → chunk-YUQXSEHG.mjs} +160 -73
- package/dist/chunk-YUQXSEHG.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 +1012 -149
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/extract/contracts.d.ts +6 -6
- package/dist/extract/contracts.d.ts.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-types.d.ts +2 -0
- package/dist/pipeline-spec-types.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 +23 -4
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +20 -2
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +3 -3
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/material-uniforms.d.ts +4 -0
- package/dist/record/material-uniforms.d.ts.map +1 -0
- package/dist/record/render-context.d.ts +4 -3
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +10 -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 +6 -0
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +44 -9
- 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__/fixtures/ai-weapon-spirit/README.md +20 -0
- package/src/__tests__/fixtures/ai-weapon-spirit/low-poly-toon.wgsl +178 -0
- package/src/__tests__/fixtures/ai-weapon-spirit/material.json +97 -0
- package/src/__tests__/fixtures/ai-weapon-spirit/painterly-surface.wgsl +55 -0
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +3 -3
- package/src/__tests__/gpu-driven-view.browser.test.ts +11 -3
- 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 +48 -13
- package/src/__tests__/{material-static-dynamic-route.unit.test.ts → material-layer-projection.unit.test.ts} +30 -47
- package/src/__tests__/material-pass-policy.unit.test.ts +69 -0
- package/src/__tests__/material-program-dispatch.unit.test.ts +48 -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 +44 -2
- 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 -3
- 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/assembly.ts +8 -40
- package/src/assembly/material/standard-layer-projection.ts +3 -1
- package/src/assembly/material/surface-projection.ts +91 -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 +106 -166
- 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/extract/contracts.ts +6 -6
- 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 +109 -14
- package/src/pipeline-builder.ts +14 -10
- package/src/pipeline-spec-types.ts +2 -0
- package/src/pipeline-spec.ts +13 -17
- package/src/record/frame-snapshot.ts +19 -2
- package/src/record/frame.ts +38 -3
- package/src/record/main-pass-geometry.ts +837 -337
- package/src/record/main-pass-material.ts +87 -2
- package/src/record/main-pass-sprite-draws.ts +66 -169
- package/src/record/main-pass.ts +24 -246
- package/src/record/material-uniforms.ts +186 -0
- package/src/record/render-context.ts +8 -0
- package/src/record/shadow-pass.ts +120 -115
- package/src/recovery/render-system-candidate.ts +46 -5
- package/src/render-contract.ts +4 -0
- package/src/render-system-extract-tail.ts +153 -57
- package/src/render-system-extract.ts +110 -73
- package/src/render-system.ts +59 -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/assembly/material/pipeline-projection.d.ts +0 -30
- package/dist/assembly/material/pipeline-projection.d.ts.map +0 -1
- 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
- package/src/assembly/material/pipeline-projection.ts +0 -63
|
@@ -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-YUQXSEHG.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,
|
|
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, writePbrMaterialUboPayload, applyParamSnapshotToUbo, applyMaterialTextureUvScales, residentTextureView, MATERIAL_PER_ENTITY_STRIDE, detectNineSliceScaleTooSmall, resolveGeometryInstanceBuffer, buildFullscreenPostProcessPass, getTemporalGpuState, getTemporalParamsBuffer, getTemporalBindGroupResources, resolveSurfaceFormatPair, resolveSurfaceProfile, encodeMainPass, STANDARD_PBR_UBO_SIZE, 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, isTemporalFullscreenBinding, createFullscreenBindGroup, TYPED_BLOOM_PASS_NAMES } from './chunk-TMIASV2N.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-GF523LHF.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';
|
|
@@ -5904,8 +5904,8 @@ function pipelineCreationHint(error) {
|
|
|
5904
5904
|
}
|
|
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
|
-
const vsEntry = (passKind === "temporal" ? "vs_temporal" : "vs_main");
|
|
5908
|
-
const fsEntry = fragmentEntry ?? (passKind === "temporal" ? "fs_temporal" : passKind === "deferred" ? "fs_gbuffer" : "fs_main");
|
|
5907
|
+
const vsEntry = vertexEntry ?? (passKind === "temporal" ? "vs_temporal" : "vs_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({
|
|
@@ -11703,22 +11746,117 @@ function inspectStandardLighting(input) {
|
|
|
11703
11746
|
}
|
|
11704
11747
|
return inspectStandardClusterTransport(input.transport, input.prepared);
|
|
11705
11748
|
}
|
|
11706
|
-
|
|
11707
|
-
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11749
|
+
function uploadMaterialUniforms(c) {
|
|
11750
|
+
const {
|
|
11751
|
+
runtime,
|
|
11752
|
+
world,
|
|
11753
|
+
store,
|
|
11754
|
+
pipelineState,
|
|
11755
|
+
validatedOrdered,
|
|
11756
|
+
frameState,
|
|
11757
|
+
materialSlots,
|
|
11758
|
+
materialSlotOwners,
|
|
11759
|
+
materialSlotCount
|
|
11760
|
+
} = c;
|
|
11761
|
+
if (materialSlotCount === 0) return;
|
|
11762
|
+
const cachedMaterialUboPayload = c.materialUboPayloadCache;
|
|
11763
|
+
let materialUboPayload;
|
|
11764
|
+
if (cachedMaterialUboPayload?.materialSlots === materialSlots && cachedMaterialUboPayload.materialSlotCount === materialSlotCount) {
|
|
11765
|
+
materialUboPayload = cachedMaterialUboPayload.payload;
|
|
11766
|
+
} else {
|
|
11767
|
+
materialUboPayload = new Uint8Array(materialSlotCount * MATERIAL_PER_ENTITY_STRIDE);
|
|
11768
|
+
const slotPayload = new Uint8Array(STANDARD_PBR_UBO_SIZE);
|
|
11769
|
+
const slotPayloadF32 = new Float32Array(
|
|
11770
|
+
slotPayload.buffer,
|
|
11771
|
+
slotPayload.byteOffset,
|
|
11772
|
+
slotPayload.byteLength / 4
|
|
11773
|
+
);
|
|
11774
|
+
for (let materialSlot = 0; materialSlot < materialSlots.length; materialSlot += 1) {
|
|
11775
|
+
const mat = materialSlots[materialSlot];
|
|
11776
|
+
const entry = validatedOrdered[materialSlotOwners[materialSlot] ?? -1];
|
|
11777
|
+
if (mat === void 0 || entry === void 0) continue;
|
|
11778
|
+
writePbrMaterialUboPayload(slotPayloadF32, mat);
|
|
11779
|
+
const materialShaderId = mat.materialShaderId;
|
|
11780
|
+
const schema = mat.materialParamSchema ?? (materialShaderId !== void 0 ? runtime.getParamSchema?.(materialShaderId) : void 0);
|
|
11781
|
+
applyParamSnapshotToUbo(slotPayloadF32, schema, mat.paramSnapshot);
|
|
11782
|
+
const processValue = globalThis.process;
|
|
11783
|
+
if (processValue?.env?.FORGEAX_MATERIAL_PIPELINE_DIAGNOSTICS === "1" && (materialShaderId === "forgeax::default-standard-pbr" || materialShaderId === "forgeax::pbr-skin")) {
|
|
11784
|
+
console.error(
|
|
11785
|
+
`[render-material] UBO receipt: ${JSON.stringify({
|
|
11786
|
+
entityIndex: entry.renderableIndex,
|
|
11787
|
+
materialHandle: mat.materialHandle,
|
|
11788
|
+
materialShaderId,
|
|
11789
|
+
clearcoat: slotPayloadF32[32],
|
|
11790
|
+
clearcoatRoughness: slotPayloadF32[33],
|
|
11791
|
+
clearcoatNormalScale: slotPayloadF32[34],
|
|
11792
|
+
paramSnapshot: mat.paramSnapshot
|
|
11793
|
+
})}`
|
|
11794
|
+
);
|
|
11795
|
+
}
|
|
11796
|
+
applyMaterialTextureUvScales(slotPayloadF32, mat, world);
|
|
11797
|
+
{
|
|
11798
|
+
const matHandleRaw = mat.baseColorTexture;
|
|
11799
|
+
if (matHandleRaw !== void 0) {
|
|
11800
|
+
const view = residentTextureView(entry.world ?? world, store, runtime, matHandleRaw);
|
|
11801
|
+
if (view === void 0) {
|
|
11802
|
+
const rawId = matHandleRaw;
|
|
11803
|
+
if (!frameState.warnedMissingBaseColorTextureHandles.has(rawId)) {
|
|
11804
|
+
frameState.warnedMissingBaseColorTextureHandles.add(rawId);
|
|
11805
|
+
console.warn(
|
|
11806
|
+
`[forgeax] baseColor texture ${rawId} missing GPU view, rendering debug pink (shader=${materialShaderId ?? "<none>"} entityIndex=${entry.renderableIndex})`
|
|
11807
|
+
);
|
|
11808
|
+
}
|
|
11809
|
+
runtime.errorRegistry.fire(
|
|
11810
|
+
new RhiError({
|
|
11811
|
+
code: "asset-not-registered",
|
|
11812
|
+
expected: "material baseColor TextureAsset uploaded to GPU",
|
|
11813
|
+
hint: "register + uploadTexture the baseColor texture before draw([world], { cameraOwner: 0, resourceOwner: 0 }); rendering falls back to debug pink until then",
|
|
11814
|
+
detail: { assetHandle: rawId }
|
|
11815
|
+
})
|
|
11816
|
+
);
|
|
11817
|
+
slotPayloadF32[0] = 1;
|
|
11818
|
+
slotPayloadF32[1] = 0.4;
|
|
11819
|
+
slotPayloadF32[2] = 0.7;
|
|
11820
|
+
}
|
|
11821
|
+
}
|
|
11822
|
+
}
|
|
11823
|
+
materialUboPayload.set(slotPayload, materialSlot * MATERIAL_PER_ENTITY_STRIDE);
|
|
11824
|
+
}
|
|
11825
|
+
for (const entry of validatedOrdered) {
|
|
11826
|
+
const mat = entry.source.material;
|
|
11827
|
+
const materialShaderId = mat.materialShaderId;
|
|
11828
|
+
if (materialShaderId !== "forgeax::sprite" && materialShaderId !== "forgeax::sprite-lit")
|
|
11829
|
+
continue;
|
|
11830
|
+
const slicesAndMode = mat.paramSnapshot?.slicesAndMode;
|
|
11831
|
+
if (slicesAndMode === void 0 || slicesAndMode.length < 4) continue;
|
|
11832
|
+
const slicesArr = [
|
|
11833
|
+
slicesAndMode[0] ?? 0,
|
|
11834
|
+
slicesAndMode[1] ?? 0,
|
|
11835
|
+
slicesAndMode[2] ?? 0,
|
|
11836
|
+
slicesAndMode[3] ?? 0
|
|
11837
|
+
];
|
|
11838
|
+
if (slicesArr[0] === 0 && slicesArr[1] === 0 && slicesArr[2] === 0 && slicesArr[3] === 0)
|
|
11839
|
+
continue;
|
|
11840
|
+
detectNineSliceScaleTooSmall(
|
|
11841
|
+
entry.source.transform.world,
|
|
11842
|
+
slicesArr,
|
|
11843
|
+
entry.renderableIndex,
|
|
11844
|
+
frameState.warnedNineSliceScaleEntities,
|
|
11845
|
+
runtime.metrics
|
|
11846
|
+
);
|
|
11847
|
+
}
|
|
11848
|
+
c.materialUboPayloadCache = {
|
|
11849
|
+
materialSlots,
|
|
11850
|
+
materialSlotCount,
|
|
11851
|
+
payload: materialUboPayload
|
|
11852
|
+
};
|
|
11713
11853
|
}
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
destroyInstanceBufferEntries(entries, errorRegistry);
|
|
11721
|
-
entries.length = 0;
|
|
11854
|
+
const materialUboUpload = runtime.device.queue.writeBuffer(
|
|
11855
|
+
pipelineState.materialUniformBuffer.buffer,
|
|
11856
|
+
0,
|
|
11857
|
+
materialUboPayload
|
|
11858
|
+
);
|
|
11859
|
+
if (!materialUboUpload.ok) throw materialUboUpload.error;
|
|
11722
11860
|
}
|
|
11723
11861
|
|
|
11724
11862
|
// src/volume/temporal.ts
|
|
@@ -14908,7 +15046,11 @@ function recordFrame(internals, world, cameras, lights, renderables, transparent
|
|
|
14908
15046
|
const materialSlots = dispatchPlan.materialSlots;
|
|
14909
15047
|
const materialSlotOwners = dispatchPlan.materialSlotOwners;
|
|
14910
15048
|
const materialSlotCount = dispatchPlan.materialSlotCount;
|
|
14911
|
-
const splitLdrSprite = computeSplitLdrSprite(
|
|
15049
|
+
const splitLdrSprite = computeSplitLdrSprite(
|
|
15050
|
+
validatedOrdered,
|
|
15051
|
+
tonemapActive,
|
|
15052
|
+
transparentDispatch
|
|
15053
|
+
);
|
|
14912
15054
|
let ldrSpritePassView = null;
|
|
14913
15055
|
if (splitLdrSprite) {
|
|
14914
15056
|
const unormViewRes = internals.device.createTextureView(currentTexture, {});
|
|
@@ -15084,6 +15226,7 @@ function recordFrame(internals, world, cameras, lights, renderables, transparent
|
|
|
15084
15226
|
directionalShadowCacheReuse: directionalShadowCache.reuse,
|
|
15085
15227
|
...profilePhase !== void 0 ? { profilePhase } : {}
|
|
15086
15228
|
};
|
|
15229
|
+
uploadMaterialUniforms(passCtx);
|
|
15087
15230
|
const fallbackReadbackRequest = createReflectionFallbackReadbackRequest(internals, frameState);
|
|
15088
15231
|
if (fallbackReadbackRequest !== void 0) {
|
|
15089
15232
|
frameState.reflectionFallbackReadback = fallbackReadbackRequest;
|
|
@@ -15592,13 +15735,19 @@ function cleanPerFrameCaches(internals, frameState, validated, retainedEntityKey
|
|
|
15592
15735
|
disposeTransientInstanceBuffers(frameState.transientInstanceBuffers, internals.errorRegistry);
|
|
15593
15736
|
}
|
|
15594
15737
|
const validatedEntityKeys = new Set(retainedEntityKeys);
|
|
15738
|
+
const validatedInstanceKeys = new Set(retainedEntityKeys);
|
|
15595
15739
|
for (const v of validated) {
|
|
15596
|
-
|
|
15740
|
+
const entityKey = worldEntityKey(v.source.worldId, v.source.entityKey);
|
|
15741
|
+
validatedEntityKeys.add(entityKey);
|
|
15742
|
+
validatedInstanceKeys.add(entityKey);
|
|
15743
|
+
if (v.source.instances !== void 0) {
|
|
15744
|
+
validatedInstanceKeys.add(instanceCollectionCacheKey(v.source.worldId, v.source.instances));
|
|
15745
|
+
}
|
|
15597
15746
|
}
|
|
15598
15747
|
cleanPerEntityCache(frameState.materialBgPerEntity, validatedEntityKeys);
|
|
15599
15748
|
cleanPerEntityCache(frameState.instancesBgPerEntity, validatedEntityKeys);
|
|
15600
15749
|
for (const [key, entry] of frameState.instanceBuffers.entries()) {
|
|
15601
|
-
if (!
|
|
15750
|
+
if (!validatedInstanceKeys.has(key)) {
|
|
15602
15751
|
if (!entry.buffer.isDestroyed) {
|
|
15603
15752
|
const r = entry.buffer.destroy();
|
|
15604
15753
|
if (!r.ok) internals.errorRegistry.fire(r.error);
|
|
@@ -15606,6 +15755,24 @@ function cleanPerFrameCaches(internals, frameState, validated, retainedEntityKey
|
|
|
15606
15755
|
frameState.instanceBuffers.delete(key);
|
|
15607
15756
|
}
|
|
15608
15757
|
}
|
|
15758
|
+
if (frameState.instanceResidency !== void 0) {
|
|
15759
|
+
const liveCollections = new Set(validated.map((entry) => entry.source.instances?.collectionId));
|
|
15760
|
+
for (const id of frameState.instanceResidency.keys()) {
|
|
15761
|
+
if (!liveCollections.has(id)) frameState.instanceResidency.delete(id);
|
|
15762
|
+
}
|
|
15763
|
+
}
|
|
15764
|
+
if (frameState.instanceBufferChunks !== void 0) {
|
|
15765
|
+
for (const [key, entry] of frameState.instanceBufferChunks.entries()) {
|
|
15766
|
+
const separator = key.indexOf(":");
|
|
15767
|
+
const ownerKey = separator < 0 ? Number.NaN : Number(key.slice(0, separator));
|
|
15768
|
+
if (validatedInstanceKeys.has(ownerKey)) continue;
|
|
15769
|
+
if (!entry.buffer.isDestroyed) {
|
|
15770
|
+
const r = entry.buffer.destroy();
|
|
15771
|
+
if (!r.ok) internals.errorRegistry.fire(r.error);
|
|
15772
|
+
}
|
|
15773
|
+
frameState.instanceBufferChunks.delete(key);
|
|
15774
|
+
}
|
|
15775
|
+
}
|
|
15609
15776
|
if (frameState.morphBuffers !== void 0) {
|
|
15610
15777
|
for (const [key, entry] of frameState.morphBuffers.entries()) {
|
|
15611
15778
|
if (validatedEntityKeys.has(key)) continue;
|
|
@@ -16271,6 +16438,8 @@ function createRenderSystemRecovery(deps) {
|
|
|
16271
16438
|
currentDirectionalShadowView: null,
|
|
16272
16439
|
currentSpotShadowView: null,
|
|
16273
16440
|
instanceBuffers: /* @__PURE__ */ new Map(),
|
|
16441
|
+
instanceBufferChunks: /* @__PURE__ */ new Map(),
|
|
16442
|
+
instanceResidency: /* @__PURE__ */ new Map(),
|
|
16274
16443
|
morphBuffers: /* @__PURE__ */ new Map(),
|
|
16275
16444
|
hdrpClusterBinScratch: createClusterBinScratch(),
|
|
16276
16445
|
hdrpClusterGridScratch: null,
|
|
@@ -16346,7 +16515,7 @@ function createRenderSystemRecovery(deps) {
|
|
|
16346
16515
|
const discardRecoveryGraphCandidate = (candidate) => {
|
|
16347
16516
|
candidate.release();
|
|
16348
16517
|
};
|
|
16349
|
-
const prepareRecoveryGraphCandidate = (runtime) => {
|
|
16518
|
+
const prepareRecoveryGraphCandidate = async (runtime) => {
|
|
16350
16519
|
const seed = lastSuccessfulFrameSeed;
|
|
16351
16520
|
if (seed === void 0) return { kind: "no-seed" };
|
|
16352
16521
|
const camera = seed.frame.cameras[0];
|
|
@@ -16404,6 +16573,13 @@ function createRenderSystemRecovery(deps) {
|
|
|
16404
16573
|
candidateGpuDrivenScene = void 0;
|
|
16405
16574
|
candidatePointsLines?.release();
|
|
16406
16575
|
candidatePointsLines = void 0;
|
|
16576
|
+
disposeInstanceBuffers(candidateFrameState.instanceBuffers, runtime.internals.errorRegistry);
|
|
16577
|
+
if (candidateFrameState.instanceBufferChunks !== void 0) {
|
|
16578
|
+
disposeInstanceBufferChunks(
|
|
16579
|
+
candidateFrameState.instanceBufferChunks,
|
|
16580
|
+
runtime.internals.errorRegistry
|
|
16581
|
+
);
|
|
16582
|
+
}
|
|
16407
16583
|
candidateGpuStore.destroyAll();
|
|
16408
16584
|
};
|
|
16409
16585
|
const markPublished = () => {
|
|
@@ -16421,10 +16597,14 @@ function createRenderSystemRecovery(deps) {
|
|
|
16421
16597
|
if (!gpuScene.ok) return failed2("candidate GPU scene preparation failed", gpuScene.error);
|
|
16422
16598
|
candidateGpuDrivenScene = gpuScene.value;
|
|
16423
16599
|
if (candidateGpuDrivenScene.state !== void 0) {
|
|
16424
|
-
|
|
16600
|
+
const production = await GpuDrivenProduction.forRecoveryDevice(
|
|
16425
16601
|
runtime.internals.device,
|
|
16426
|
-
gpuDrivenShaderFactory
|
|
16602
|
+
gpuDrivenShaderFactory,
|
|
16603
|
+
(descriptor) => internals.createShaderModule === void 0 ? Promise.resolve(gpuDrivenShaderFactory.createShaderModule(descriptor)) : internals.createShaderModule(runtime.internals.device, descriptor)
|
|
16427
16604
|
);
|
|
16605
|
+
if (!production.ok)
|
|
16606
|
+
return failed2("candidate GPU-driven shader preparation failed", production.error);
|
|
16607
|
+
candidateGpuDrivenProduction = production.value;
|
|
16428
16608
|
const prepared = candidateGpuDrivenProduction.prepare({
|
|
16429
16609
|
scene: candidateGpuDrivenScene.state,
|
|
16430
16610
|
camera,
|
|
@@ -16583,6 +16763,24 @@ function createRenderSystemRecovery(deps) {
|
|
|
16583
16763
|
if (candidateValidated.length !== seed.frame.renderables.length) {
|
|
16584
16764
|
return failed2("candidate validation did not retain every LKG-visible renderable");
|
|
16585
16765
|
}
|
|
16766
|
+
for (const entry of candidateValidated) {
|
|
16767
|
+
if (entry.source.instances === void 0) continue;
|
|
16768
|
+
const prepared = resolveGeometryInstanceBuffer(
|
|
16769
|
+
{
|
|
16770
|
+
runtime: runtime.internals,
|
|
16771
|
+
pipelineState: runtime.pipelineState,
|
|
16772
|
+
frameState: candidateFrameState,
|
|
16773
|
+
bindGroupCounts: { createBindGroup: 0, keys: [] }
|
|
16774
|
+
},
|
|
16775
|
+
entry,
|
|
16776
|
+
[],
|
|
16777
|
+
false
|
|
16778
|
+
);
|
|
16779
|
+
if (prepared === null) return failed2("candidate instance preparation failed");
|
|
16780
|
+
}
|
|
16781
|
+
for (const [id, residency] of candidateFrameState.instanceResidency ?? []) {
|
|
16782
|
+
candidateFrameState.instanceResidency?.set(id, { ...residency, frameNumber: -1 });
|
|
16783
|
+
}
|
|
16586
16784
|
const lighting = prepareFrameLighting(
|
|
16587
16785
|
runtime.internals,
|
|
16588
16786
|
candidateFrameState,
|
|
@@ -16604,7 +16802,11 @@ function createRenderSystemRecovery(deps) {
|
|
|
16604
16802
|
validated: candidateValidated,
|
|
16605
16803
|
dispatch: seed.frame.dispatch,
|
|
16606
16804
|
shadowCastersActive: seed.frame.lights.pointShadow.length > 0 || seed.frame.lights.spot.some((spot) => spot.castShadow === true) || (seed.frame.lights.lightViewProj?.length ?? 0) > 0,
|
|
16607
|
-
splitLdrSprite: computeSplitLdrSprite(
|
|
16805
|
+
splitLdrSprite: computeSplitLdrSprite(
|
|
16806
|
+
candidateValidated,
|
|
16807
|
+
camera.tonemap !== "none",
|
|
16808
|
+
seed.frame.dispatch
|
|
16809
|
+
),
|
|
16608
16810
|
reflectionFallbackAvailable: candidateFrameState.reflectionFallbackDemand === true
|
|
16609
16811
|
});
|
|
16610
16812
|
const candidatePostProcessIds = /* @__PURE__ */ new Set([
|
|
@@ -18319,6 +18521,10 @@ var GpuScene = class _GpuScene {
|
|
|
18319
18521
|
drawTemplate: [],
|
|
18320
18522
|
material: []
|
|
18321
18523
|
};
|
|
18524
|
+
/** Transform rows whose previous value advances only after submit. */
|
|
18525
|
+
pendingTemporalTransforms = /* @__PURE__ */ new Set();
|
|
18526
|
+
/** Previous rows whose post-submit upload must be retried before the next draw. */
|
|
18527
|
+
pendingTemporalUploads = /* @__PURE__ */ new Set();
|
|
18322
18528
|
static create(device, initialCapacity = 256) {
|
|
18323
18529
|
if (!device.caps.storageBuffer) {
|
|
18324
18530
|
return ok({ status: "unavailable", reason: "storage-buffer-unavailable" });
|
|
@@ -18345,26 +18551,37 @@ var GpuScene = class _GpuScene {
|
|
|
18345
18551
|
return this.buffers.material;
|
|
18346
18552
|
}
|
|
18347
18553
|
sync(delta) {
|
|
18348
|
-
|
|
18554
|
+
for (const transformIndex of this.pendingTemporalUploads) {
|
|
18555
|
+
this.writesByTable.transform.push(transformIndex);
|
|
18556
|
+
}
|
|
18557
|
+
const pendingWrites = TABLE_NAMES.some((name) => this.writesByTable[name].length > 0);
|
|
18558
|
+
if (delta.createdSlots.length === 0 && delta.updatedSlots.length === 0 && delta.recreatedSlots.length === 0 && delta.removedSlots.length === 0 && !pendingWrites) {
|
|
18349
18559
|
this.noChangeFrames += 1;
|
|
18350
18560
|
return ok({ ranges: 0, bytes: 0, grew: false, cleared: 0 });
|
|
18351
18561
|
}
|
|
18352
18562
|
const writesByTable = this.writesByTable;
|
|
18353
|
-
|
|
18354
|
-
|
|
18563
|
+
if (!this.identityUploaded && !writesByTable.transform.includes(0)) {
|
|
18564
|
+
writesByTable.transform.push(0);
|
|
18565
|
+
}
|
|
18355
18566
|
let highestChangedSlot = -1;
|
|
18356
|
-
|
|
18567
|
+
const contentUpdatedSlots = delta.contentUpdatedSlots ?? [];
|
|
18568
|
+
const contentUpdatedSlotIds = new Set(contentUpdatedSlots.map((record) => record.slot));
|
|
18569
|
+
const allocationResets = /* @__PURE__ */ new Set();
|
|
18570
|
+
for (const record of delta.removedSlots) {
|
|
18571
|
+
if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
|
|
18572
|
+
this.clearSlot(record.slot, writesByTable);
|
|
18573
|
+
}
|
|
18574
|
+
for (const records of [delta.createdSlots, contentUpdatedSlots, delta.recreatedSlots]) {
|
|
18357
18575
|
for (const record of records) {
|
|
18576
|
+
const previous = this.allocations[record.slot];
|
|
18358
18577
|
this.ensureAllocation(record, writesByTable);
|
|
18578
|
+
if (previous !== this.allocations[record.slot]) allocationResets.add(record.slot);
|
|
18359
18579
|
if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
|
|
18360
18580
|
}
|
|
18361
18581
|
}
|
|
18362
18582
|
for (const record of delta.updatedSlots) {
|
|
18363
18583
|
if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
|
|
18364
18584
|
}
|
|
18365
|
-
for (const record of delta.removedSlots) {
|
|
18366
|
-
if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
|
|
18367
|
-
}
|
|
18368
18585
|
const requiredCapacity = Math.max(
|
|
18369
18586
|
highestChangedSlot + 1,
|
|
18370
18587
|
this.instances.requiredCapacity(),
|
|
@@ -18378,11 +18595,18 @@ var GpuScene = class _GpuScene {
|
|
|
18378
18595
|
if (!grown.ok) return grown;
|
|
18379
18596
|
}
|
|
18380
18597
|
for (const record of delta.createdSlots) this.writeSlot(record, true, writesByTable);
|
|
18381
|
-
for (const record of
|
|
18598
|
+
for (const record of contentUpdatedSlots) {
|
|
18599
|
+
this.writeSlot(record, allocationResets.has(record.slot), writesByTable);
|
|
18600
|
+
}
|
|
18601
|
+
for (const record of delta.updatedSlots) {
|
|
18602
|
+
if (contentUpdatedSlotIds.has(record.slot)) continue;
|
|
18603
|
+
this.writeRootTransform(record, false, writesByTable);
|
|
18604
|
+
}
|
|
18382
18605
|
for (const record of delta.recreatedSlots) this.writeSlot(record, true, writesByTable);
|
|
18383
|
-
for (const record of delta.removedSlots) this.clearSlot(record.slot, writesByTable);
|
|
18384
18606
|
const uploaded = this.uploadRows(writesByTable);
|
|
18385
18607
|
if (!uploaded.ok) return uploaded;
|
|
18608
|
+
this.pendingTemporalUploads.clear();
|
|
18609
|
+
for (const name of TABLE_NAMES) writesByTable[name].length = 0;
|
|
18386
18610
|
this.identityUploaded = true;
|
|
18387
18611
|
this.clearedSlots += delta.removedSlots.length;
|
|
18388
18612
|
return ok({
|
|
@@ -18394,27 +18618,47 @@ var GpuScene = class _GpuScene {
|
|
|
18394
18618
|
}
|
|
18395
18619
|
/** Publish current transforms as previous only after a successful submit. */
|
|
18396
18620
|
commitTemporalFrame(enabled = true) {
|
|
18397
|
-
if (!enabled)
|
|
18398
|
-
|
|
18399
|
-
|
|
18400
|
-
|
|
18621
|
+
if (!enabled) {
|
|
18622
|
+
this.pendingTemporalTransforms.clear();
|
|
18623
|
+
this.pendingTemporalUploads.clear();
|
|
18624
|
+
return ok(void 0);
|
|
18625
|
+
}
|
|
18626
|
+
if (this.pendingTemporalTransforms.size === 0) return ok(void 0);
|
|
18401
18627
|
const currentOffset = offset(TRANSFORM, "currentWorld");
|
|
18402
18628
|
const previousOffset = offset(TRANSFORM, "previousWorld");
|
|
18403
|
-
|
|
18404
|
-
|
|
18405
|
-
|
|
18629
|
+
const ranges = coalesceSlots([...this.pendingTemporalTransforms]);
|
|
18630
|
+
for (const range of ranges) {
|
|
18631
|
+
for (let index = range.start; index < range.end; index += 1) {
|
|
18632
|
+
this.pendingTemporalUploads.add(index);
|
|
18633
|
+
}
|
|
18634
|
+
}
|
|
18635
|
+
for (const range of ranges) {
|
|
18636
|
+
for (let index = range.start; index < range.end; index += 1) {
|
|
18637
|
+
this.transformBytes.copyWithin(
|
|
18638
|
+
index * TRANSFORM.stride + previousOffset,
|
|
18406
18639
|
index * TRANSFORM.stride + currentOffset,
|
|
18407
18640
|
index * TRANSFORM.stride + currentOffset + 64
|
|
18408
|
-
)
|
|
18409
|
-
|
|
18641
|
+
);
|
|
18642
|
+
}
|
|
18643
|
+
}
|
|
18644
|
+
for (const range of ranges) {
|
|
18645
|
+
const firstOffset = range.start * TRANSFORM.stride;
|
|
18646
|
+
const lastOffset = range.end * TRANSFORM.stride;
|
|
18647
|
+
const uploaded = this.device.queue.writeBuffer(
|
|
18648
|
+
this.buffers.transform,
|
|
18649
|
+
firstOffset,
|
|
18650
|
+
this.transformBytes.subarray(firstOffset, lastOffset)
|
|
18410
18651
|
);
|
|
18652
|
+
if (!uploaded.ok) return uploaded;
|
|
18411
18653
|
}
|
|
18412
|
-
|
|
18413
|
-
|
|
18414
|
-
|
|
18415
|
-
|
|
18416
|
-
|
|
18417
|
-
|
|
18654
|
+
this.pendingTemporalTransforms.clear();
|
|
18655
|
+
this.pendingTemporalUploads.clear();
|
|
18656
|
+
const bytes2 = ranges.reduce(
|
|
18657
|
+
(total, range) => total + (range.end - range.start) * TRANSFORM.stride,
|
|
18658
|
+
0
|
|
18659
|
+
);
|
|
18660
|
+
this.uploadRanges += ranges.length;
|
|
18661
|
+
this.uploadBytes += bytes2;
|
|
18418
18662
|
return ok(void 0);
|
|
18419
18663
|
}
|
|
18420
18664
|
rebuild(slots) {
|
|
@@ -18423,6 +18667,9 @@ var GpuScene = class _GpuScene {
|
|
|
18423
18667
|
this.transforms.reset(1);
|
|
18424
18668
|
this.draws.reset();
|
|
18425
18669
|
this.materials.reset();
|
|
18670
|
+
this.pendingTemporalTransforms.clear();
|
|
18671
|
+
this.pendingTemporalUploads.clear();
|
|
18672
|
+
for (const name of TABLE_NAMES) this.writesByTable[name].length = 0;
|
|
18426
18673
|
const writesByTable = {
|
|
18427
18674
|
primitive: [],
|
|
18428
18675
|
instance: [],
|
|
@@ -18573,7 +18820,8 @@ var GpuScene = class _GpuScene {
|
|
|
18573
18820
|
const localCurrentOffset = localOffset + offset(TRANSFORM, "currentWorld");
|
|
18574
18821
|
const localPreviousOffset = localOffset + offset(TRANSFORM, "previousWorld");
|
|
18575
18822
|
writeMat4(transform, localCurrentOffset, localWorld);
|
|
18576
|
-
writeMat4(transform, localPreviousOffset, localWorld);
|
|
18823
|
+
if (resetPrevious) writeMat4(transform, localPreviousOffset, localWorld);
|
|
18824
|
+
else this.pendingTemporalTransforms.add(transformIndex);
|
|
18577
18825
|
writes.transform.push(transformIndex);
|
|
18578
18826
|
}
|
|
18579
18827
|
writes.instance.push(instanceIndex);
|
|
@@ -18672,14 +18920,16 @@ var GpuScene = class _GpuScene {
|
|
|
18672
18920
|
const allocation = this.allocations[record.slot];
|
|
18673
18921
|
if (allocation === void 0) throw new RangeError("GPU Scene allocation unavailable");
|
|
18674
18922
|
const transformOffset = allocation.transformStart * TRANSFORM.stride;
|
|
18675
|
-
const currentOffset = transformOffset + offset(TRANSFORM, "currentWorld");
|
|
18676
18923
|
const previousOffset = transformOffset + offset(TRANSFORM, "previousWorld");
|
|
18677
18924
|
if (resetPrevious) {
|
|
18678
18925
|
writeMat4(this.transformView, previousOffset, record.snapshot.transform.world);
|
|
18679
|
-
} else {
|
|
18680
|
-
this.transformBytes.copyWithin(previousOffset, currentOffset, currentOffset + 64);
|
|
18681
18926
|
}
|
|
18682
|
-
writeMat4(
|
|
18927
|
+
writeMat4(
|
|
18928
|
+
this.transformView,
|
|
18929
|
+
transformOffset + offset(TRANSFORM, "currentWorld"),
|
|
18930
|
+
record.snapshot.transform.world
|
|
18931
|
+
);
|
|
18932
|
+
if (!resetPrevious) this.pendingTemporalTransforms.add(allocation.transformStart);
|
|
18683
18933
|
writes.transform.push(allocation.transformStart);
|
|
18684
18934
|
}
|
|
18685
18935
|
clearSlot(slot, writes) {
|
|
@@ -18758,6 +19008,8 @@ var GpuScene = class _GpuScene {
|
|
|
18758
19008
|
TRANSFORM.stride
|
|
18759
19009
|
).fill(0);
|
|
18760
19010
|
writes.transform.push(transformIndex);
|
|
19011
|
+
this.pendingTemporalTransforms.delete(transformIndex);
|
|
19012
|
+
this.pendingTemporalUploads.delete(transformIndex);
|
|
18761
19013
|
}
|
|
18762
19014
|
for (let ordinal = 0; ordinal < allocation.drawCount; ordinal += 1) {
|
|
18763
19015
|
const drawIndex = allocation.drawStart + ordinal;
|
|
@@ -19214,7 +19466,8 @@ function ownSnapshot(snapshot) {
|
|
|
19214
19466
|
regions: new Float32Array(snapshot.spriteInstances.regions)
|
|
19215
19467
|
}
|
|
19216
19468
|
},
|
|
19217
|
-
...snapshot.pointsLines === void 0 ? {} : { pointsLines: ownPointsLinesSnapshot(snapshot.pointsLines) }
|
|
19469
|
+
...snapshot.pointsLines === void 0 ? {} : { pointsLines: ownPointsLinesSnapshot(snapshot.pointsLines) },
|
|
19470
|
+
...snapshot.skinJointEntities === void 0 ? {} : { skinJointEntities: [...snapshot.skinJointEntities] }
|
|
19218
19471
|
};
|
|
19219
19472
|
}
|
|
19220
19473
|
function ownPointsLinesSnapshot(snapshot) {
|
|
@@ -19327,7 +19580,8 @@ var RenderScene = class {
|
|
|
19327
19580
|
entityKey,
|
|
19328
19581
|
initial,
|
|
19329
19582
|
current: initial?.snapshot,
|
|
19330
|
-
removed: false
|
|
19583
|
+
removed: false,
|
|
19584
|
+
contentChanged: false
|
|
19331
19585
|
};
|
|
19332
19586
|
entities.set(entityKey, pending);
|
|
19333
19587
|
pendingOrder.push(pending);
|
|
@@ -19338,6 +19592,7 @@ var RenderScene = class {
|
|
|
19338
19592
|
const { worldId, entityKey } = operation.snapshot;
|
|
19339
19593
|
const pending2 = pendingFor(worldId, entityKey);
|
|
19340
19594
|
pending2.current = ownSnapshot(operation.snapshot);
|
|
19595
|
+
pending2.contentChanged = true;
|
|
19341
19596
|
continue;
|
|
19342
19597
|
}
|
|
19343
19598
|
const pending = pendingFor(operation.worldId, operation.entityKey);
|
|
@@ -19358,6 +19613,7 @@ var RenderScene = class {
|
|
|
19358
19613
|
let recreated = 0;
|
|
19359
19614
|
const createdSlots = [];
|
|
19360
19615
|
const updatedSlots = [];
|
|
19616
|
+
const contentUpdatedSlots = [];
|
|
19361
19617
|
const removedSlots = [];
|
|
19362
19618
|
const recreatedSlots = [];
|
|
19363
19619
|
for (const pending of pendingOrder) {
|
|
@@ -19395,6 +19651,7 @@ var RenderScene = class {
|
|
|
19395
19651
|
this.indexMaterials(updatedSlot);
|
|
19396
19652
|
this.dirtySinceSubmitted.add(updatedSlot.slot);
|
|
19397
19653
|
updatedSlots.push(updatedSlot);
|
|
19654
|
+
if (pending.contentChanged) contentUpdatedSlots.push(updatedSlot);
|
|
19398
19655
|
updated += 1;
|
|
19399
19656
|
}
|
|
19400
19657
|
const changed = created + updated + removed + recreated > 0;
|
|
@@ -19410,6 +19667,7 @@ var RenderScene = class {
|
|
|
19410
19667
|
ignoredLateUpdates,
|
|
19411
19668
|
createdSlots,
|
|
19412
19669
|
updatedSlots,
|
|
19670
|
+
contentUpdatedSlots,
|
|
19413
19671
|
removedSlots,
|
|
19414
19672
|
recreatedSlots,
|
|
19415
19673
|
resynced: 0
|
|
@@ -19783,7 +20041,7 @@ var RenderScene = class {
|
|
|
19783
20041
|
entityKey: snapshot.entityKey,
|
|
19784
20042
|
meshGeneration: fingerprintNumericArray(snapshot.localAabb) ^ snapshot.assetHandle >>> 0,
|
|
19785
20043
|
transformGeneration: fingerprintNumericArray(snapshot.transform.world),
|
|
19786
|
-
matrixGeneration: snapshot.instances.archVersion,
|
|
20044
|
+
matrixGeneration: snapshot.instances.revision ?? snapshot.instances.archVersion,
|
|
19787
20045
|
meshAabb: snapshot.localAabb,
|
|
19788
20046
|
entityWorld: snapshot.transform.world,
|
|
19789
20047
|
transforms: snapshot.instances.transforms
|
|
@@ -19801,7 +20059,6 @@ var RenderScene = class {
|
|
|
19801
20059
|
}
|
|
19802
20060
|
};
|
|
19803
20061
|
var RENDER_RELEVANT_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
19804
|
-
componentId(Transform),
|
|
19805
20062
|
componentId(GlobalTransform),
|
|
19806
20063
|
componentId(ChildOf),
|
|
19807
20064
|
componentId(MeshFilter),
|
|
@@ -19812,6 +20069,10 @@ var RENDER_RELEVANT_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
|
19812
20069
|
componentId(Skin),
|
|
19813
20070
|
componentId(Layer),
|
|
19814
20071
|
componentId(Visibility),
|
|
20072
|
+
componentId(MorphWeights),
|
|
20073
|
+
componentId(Points),
|
|
20074
|
+
componentId(Lines),
|
|
20075
|
+
componentId(SortKey),
|
|
19815
20076
|
componentId(Camera),
|
|
19816
20077
|
componentId(MotionBlur),
|
|
19817
20078
|
componentId(DirectionalLight),
|
|
@@ -19825,6 +20086,36 @@ var RENDER_RELEVANT_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
|
19825
20086
|
componentId(ReflectionProbe),
|
|
19826
20087
|
componentId(VolumetricFog)
|
|
19827
20088
|
]);
|
|
20089
|
+
var RENDERABLE_SOURCE_COMPONENTS = [
|
|
20090
|
+
GlobalTransform,
|
|
20091
|
+
ChildOf,
|
|
20092
|
+
MeshFilter,
|
|
20093
|
+
MeshRenderer,
|
|
20094
|
+
Instances,
|
|
20095
|
+
SpriteInstances,
|
|
20096
|
+
SpriteRegionOverride,
|
|
20097
|
+
Skin,
|
|
20098
|
+
Layer,
|
|
20099
|
+
Visibility,
|
|
20100
|
+
MorphWeights,
|
|
20101
|
+
Points,
|
|
20102
|
+
Lines,
|
|
20103
|
+
SortKey
|
|
20104
|
+
];
|
|
20105
|
+
var RENDERABLE_SOURCE_COMPONENT_IDS = new Set(
|
|
20106
|
+
RENDERABLE_SOURCE_COMPONENTS.map((component) => componentId(component))
|
|
20107
|
+
);
|
|
20108
|
+
var VISIBILITY_DEPENDENCY_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
20109
|
+
componentId(ChildOf),
|
|
20110
|
+
componentId(Visibility)
|
|
20111
|
+
]);
|
|
20112
|
+
var STRUCTURAL_MEMBERSHIP_SCAN_COMPONENT_IDS = /* @__PURE__ */ new Set([
|
|
20113
|
+
componentId(ChildOf),
|
|
20114
|
+
componentId(Layer),
|
|
20115
|
+
componentId(Visibility),
|
|
20116
|
+
componentId(SpriteRegionOverride),
|
|
20117
|
+
componentId(SortKey)
|
|
20118
|
+
]);
|
|
19828
20119
|
function createGlobalTransformChangeQuery(world) {
|
|
19829
20120
|
const result = world.query({ read: [GlobalTransform], changed: [GlobalTransform] });
|
|
19830
20121
|
if (!result.ok) throw result.error;
|
|
@@ -19833,6 +20124,107 @@ function createGlobalTransformChangeQuery(world) {
|
|
|
19833
20124
|
}
|
|
19834
20125
|
return query;
|
|
19835
20126
|
}
|
|
20127
|
+
function createRenderChangeQueries(world) {
|
|
20128
|
+
const queries = /* @__PURE__ */ new Map();
|
|
20129
|
+
for (const component of RENDERABLE_SOURCE_COMPONENTS) {
|
|
20130
|
+
const result = world.query({ read: [component], changed: [component] });
|
|
20131
|
+
if (!result.ok) throw result.error;
|
|
20132
|
+
const query = result.value;
|
|
20133
|
+
for (const _span of query.spans().unwrap()) {
|
|
20134
|
+
}
|
|
20135
|
+
queries.set(componentId(component), query);
|
|
20136
|
+
}
|
|
20137
|
+
return queries;
|
|
20138
|
+
}
|
|
20139
|
+
function collectRenderableEntities(world) {
|
|
20140
|
+
const result = /* @__PURE__ */ new Set();
|
|
20141
|
+
const query = world.query({ read: [MeshRenderer], with: [Transform, MeshFilter] }).unwrap();
|
|
20142
|
+
for (const row of query) result.add(row.entity);
|
|
20143
|
+
return result;
|
|
20144
|
+
}
|
|
20145
|
+
function sourceMembershipChanged(world, slot) {
|
|
20146
|
+
const entity = slot.entityKey;
|
|
20147
|
+
const snapshot = slot.snapshot;
|
|
20148
|
+
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);
|
|
20149
|
+
}
|
|
20150
|
+
function skinJointKey(worldId, jointEntity) {
|
|
20151
|
+
return `${worldId}:${jointEntity}`;
|
|
20152
|
+
}
|
|
20153
|
+
function addSkinConsumer(index, snapshot) {
|
|
20154
|
+
for (const jointEntity of snapshot.skinJointEntities ?? []) {
|
|
20155
|
+
const key = skinJointKey(snapshot.worldId, jointEntity);
|
|
20156
|
+
let consumers = index.get(key);
|
|
20157
|
+
if (consumers === void 0) {
|
|
20158
|
+
consumers = /* @__PURE__ */ new Set();
|
|
20159
|
+
index.set(key, consumers);
|
|
20160
|
+
}
|
|
20161
|
+
consumers.add(snapshot.entityKey);
|
|
20162
|
+
}
|
|
20163
|
+
}
|
|
20164
|
+
function removeSkinConsumer(index, snapshot) {
|
|
20165
|
+
for (const jointEntity of snapshot.skinJointEntities ?? []) {
|
|
20166
|
+
const key = skinJointKey(snapshot.worldId, jointEntity);
|
|
20167
|
+
const consumers = index.get(key);
|
|
20168
|
+
consumers?.delete(snapshot.entityKey);
|
|
20169
|
+
if (consumers?.size === 0) index.delete(key);
|
|
20170
|
+
}
|
|
20171
|
+
}
|
|
20172
|
+
function dispatchEntriesBySlot(frame, projection) {
|
|
20173
|
+
const bySlot = /* @__PURE__ */ new Map();
|
|
20174
|
+
const byRenderable = /* @__PURE__ */ new Map();
|
|
20175
|
+
for (const entry of frame.dispatch) {
|
|
20176
|
+
const list = byRenderable.get(entry.renderableIndex);
|
|
20177
|
+
if (list === void 0) byRenderable.set(entry.renderableIndex, [entry]);
|
|
20178
|
+
else list.push(entry);
|
|
20179
|
+
}
|
|
20180
|
+
for (let index = 0; index < frame.renderables.length; index += 1) {
|
|
20181
|
+
const renderable = frame.renderables[index];
|
|
20182
|
+
if (renderable === void 0) continue;
|
|
20183
|
+
const slot = projection.slot(renderable.worldId, renderable.entityKey);
|
|
20184
|
+
if (slot === void 0) continue;
|
|
20185
|
+
bySlot.set(slot.slot, byRenderable.get(index) ?? []);
|
|
20186
|
+
}
|
|
20187
|
+
return bySlot;
|
|
20188
|
+
}
|
|
20189
|
+
function dispatchForProjection(dispatchBySlot, projection, unavailableSlots) {
|
|
20190
|
+
const dispatch = [];
|
|
20191
|
+
const renderables = projection.materialize();
|
|
20192
|
+
for (let renderableIndex = 0; renderableIndex < renderables.length; renderableIndex += 1) {
|
|
20193
|
+
const renderable = renderables[renderableIndex];
|
|
20194
|
+
if (renderable === void 0) continue;
|
|
20195
|
+
const slot = projection.slot(renderable.worldId, renderable.entityKey);
|
|
20196
|
+
if (slot === void 0) continue;
|
|
20197
|
+
if (unavailableSlots.has(slot.slot)) continue;
|
|
20198
|
+
for (const entry of dispatchBySlot.get(slot.slot) ?? []) {
|
|
20199
|
+
dispatch.push({ ...entry, renderableIndex });
|
|
20200
|
+
}
|
|
20201
|
+
}
|
|
20202
|
+
return dispatch;
|
|
20203
|
+
}
|
|
20204
|
+
function topologyDeltaForAvailable(delta, unavailableSlots, newlyUnavailable) {
|
|
20205
|
+
const updatedSlots = delta.updatedSlots.filter((slot) => !unavailableSlots.has(slot.slot));
|
|
20206
|
+
const contentUpdatedSlots = delta.contentUpdatedSlots?.filter(
|
|
20207
|
+
(slot) => !unavailableSlots.has(slot.slot)
|
|
20208
|
+
);
|
|
20209
|
+
return {
|
|
20210
|
+
...delta,
|
|
20211
|
+
updatedSlots: [
|
|
20212
|
+
...updatedSlots,
|
|
20213
|
+
...newlyUnavailable.map((slot) => ({
|
|
20214
|
+
...slot,
|
|
20215
|
+
snapshot: { ...slot.snapshot, gpuDrivenDraws: [] }
|
|
20216
|
+
}))
|
|
20217
|
+
],
|
|
20218
|
+
...contentUpdatedSlots === void 0 ? {} : { contentUpdatedSlots }
|
|
20219
|
+
};
|
|
20220
|
+
}
|
|
20221
|
+
function addSharedRefConsumers(projection, worldId, handle, target4) {
|
|
20222
|
+
for (const slot of projection.slotsSnapshot()) {
|
|
20223
|
+
if (slot.worldId === worldId && (slot.snapshot.assetHandle === handle || slot.snapshot.materials.some((material) => material.materialHandle === handle))) {
|
|
20224
|
+
target4.add(slot.entityKey);
|
|
20225
|
+
}
|
|
20226
|
+
}
|
|
20227
|
+
}
|
|
19836
20228
|
function frameDemandsTemporal(frame) {
|
|
19837
20229
|
const camera = frame.cameras[0];
|
|
19838
20230
|
return camera?.antialias === "taa" || (camera?.motionBlur?.shutterAngle ?? 0) > 0;
|
|
@@ -19883,6 +20275,10 @@ function cullPersistentFrame(frame, candidates, boundsOf2 = (snapshot) => worldB
|
|
|
19883
20275
|
for (let index = 0; index < candidates.length; index += 1) {
|
|
19884
20276
|
const candidate = candidates[index];
|
|
19885
20277
|
if (candidate === void 0) continue;
|
|
20278
|
+
if (candidate.authorVisible === false) {
|
|
20279
|
+
culled += 1;
|
|
20280
|
+
continue;
|
|
20281
|
+
}
|
|
19886
20282
|
let isVisible = true;
|
|
19887
20283
|
const candidateBounds = boundsOf2(candidate, index);
|
|
19888
20284
|
if (candidateBounds !== void 0) {
|
|
@@ -20112,6 +20508,7 @@ var PersistentRenderScene = class {
|
|
|
20112
20508
|
const bounds = renderable.localAabb;
|
|
20113
20509
|
const validBounds = bounds !== void 0 && bounds.length >= 6 && [...bounds].every((value) => Number.isFinite(value));
|
|
20114
20510
|
draw = decideVisibility({
|
|
20511
|
+
authorVisible: renderable.authorVisible !== false,
|
|
20115
20512
|
validBounds,
|
|
20116
20513
|
occlusion: this.visibilityFacets.getConfidence(view, primitive)}).draw;
|
|
20117
20514
|
}
|
|
@@ -20213,10 +20610,16 @@ var PersistentRenderScene = class {
|
|
|
20213
20610
|
preserveVisibilityOnReorder
|
|
20214
20611
|
);
|
|
20215
20612
|
}
|
|
20216
|
-
if (!entry.rigidOnly) {
|
|
20217
|
-
return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
|
|
20218
|
-
}
|
|
20219
20613
|
let requiresRebuild = false;
|
|
20614
|
+
const changedEntitiesByWorld = worlds.map(
|
|
20615
|
+
(_, worldId) => new Set(entry.pendingRenderableEntitiesByWorld[worldId] ?? [])
|
|
20616
|
+
);
|
|
20617
|
+
const nextReadVersions = entry.readVersions.slice();
|
|
20618
|
+
const structureChangedWorlds = /* @__PURE__ */ new Set();
|
|
20619
|
+
const structuralComponentIdsByWorld = worlds.map(() => /* @__PURE__ */ new Set());
|
|
20620
|
+
let refreshStructureFacts = false;
|
|
20621
|
+
let currentRenderableEntitiesByWorld;
|
|
20622
|
+
const removedSlots = [];
|
|
20220
20623
|
for (let worldId = 0; worldId < worlds.length; worldId += 1) {
|
|
20221
20624
|
const world = worlds[worldId];
|
|
20222
20625
|
if (world === void 0) continue;
|
|
@@ -20237,32 +20640,239 @@ var PersistentRenderScene = class {
|
|
|
20237
20640
|
requiresRebuild = true;
|
|
20238
20641
|
break;
|
|
20239
20642
|
}
|
|
20240
|
-
if (read.status
|
|
20241
|
-
|
|
20242
|
-
|
|
20643
|
+
if (read.status === "rebuild") {
|
|
20644
|
+
structureChangedWorlds.add(worldId);
|
|
20645
|
+
refreshStructureFacts = true;
|
|
20243
20646
|
}
|
|
20244
20647
|
const changes = read.world;
|
|
20245
20648
|
const shared = read.sharedRefs;
|
|
20246
20649
|
if (shared.records.length > 0) {
|
|
20247
20650
|
for (const record of shared.records) {
|
|
20248
20651
|
this.options.onSharedRefMutation?.(worldId, record.handle);
|
|
20652
|
+
const changed = changedEntitiesByWorld[worldId];
|
|
20653
|
+
if (changed !== void 0)
|
|
20654
|
+
addSharedRefConsumers(entry.projection, worldId, record.handle, changed);
|
|
20249
20655
|
}
|
|
20250
|
-
requiresRebuild = true;
|
|
20251
|
-
break;
|
|
20252
20656
|
}
|
|
20253
20657
|
for (const changedComponentId of changes.changedComponentIds) {
|
|
20658
|
+
if (read.status === "rebuild") {
|
|
20659
|
+
structuralComponentIdsByWorld[worldId]?.add(changedComponentId);
|
|
20660
|
+
}
|
|
20254
20661
|
if (!RENDER_RELEVANT_COMPONENT_IDS.has(changedComponentId)) continue;
|
|
20255
|
-
if (
|
|
20662
|
+
if (!RENDERABLE_SOURCE_COMPONENT_IDS.has(changedComponentId)) {
|
|
20256
20663
|
requiresRebuild = true;
|
|
20257
20664
|
break;
|
|
20258
20665
|
}
|
|
20666
|
+
const changed = changedEntitiesByWorld[worldId];
|
|
20667
|
+
if (changed === void 0) continue;
|
|
20668
|
+
if (VISIBILITY_DEPENDENCY_COMPONENT_IDS.has(changedComponentId)) {
|
|
20669
|
+
refreshStructureFacts = true;
|
|
20670
|
+
for (const entity of collectRenderableEntities(world)) changed.add(entity);
|
|
20671
|
+
continue;
|
|
20672
|
+
}
|
|
20673
|
+
if (changedComponentId === componentId(GlobalTransform)) {
|
|
20674
|
+
const query2 = entry.renderChangeQueries[worldId]?.get(changedComponentId);
|
|
20675
|
+
for (const row of query2 ?? []) {
|
|
20676
|
+
const consumers = entry.skinConsumersByJoint.get(
|
|
20677
|
+
skinJointKey(worldId, row.entity)
|
|
20678
|
+
);
|
|
20679
|
+
for (const consumer of consumers ?? []) changed.add(consumer);
|
|
20680
|
+
}
|
|
20681
|
+
continue;
|
|
20682
|
+
}
|
|
20683
|
+
const query = entry.renderChangeQueries[worldId]?.get(changedComponentId);
|
|
20684
|
+
if (query !== void 0) {
|
|
20685
|
+
for (const row of query) changed.add(row.entity);
|
|
20686
|
+
}
|
|
20259
20687
|
}
|
|
20260
20688
|
if (requiresRebuild) break;
|
|
20261
|
-
|
|
20689
|
+
nextReadVersions[worldId] = read.version;
|
|
20262
20690
|
}
|
|
20263
20691
|
if (requiresRebuild) {
|
|
20264
20692
|
return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
|
|
20265
20693
|
}
|
|
20694
|
+
if (structureChangedWorlds.size > 0) {
|
|
20695
|
+
this.visibilityFacets.clear();
|
|
20696
|
+
this.invalidateActiveEntityRevision();
|
|
20697
|
+
const currentByWorld = worlds.map((world) => collectRenderableEntities(world));
|
|
20698
|
+
currentRenderableEntitiesByWorld = currentByWorld;
|
|
20699
|
+
for (let worldId = 0; worldId < currentByWorld.length; worldId += 1) {
|
|
20700
|
+
const world = worlds[worldId];
|
|
20701
|
+
const current = currentByWorld[worldId];
|
|
20702
|
+
if (world === void 0 || current === void 0) continue;
|
|
20703
|
+
const changed = changedEntitiesByWorld[worldId];
|
|
20704
|
+
if (changed !== void 0 && structureChangedWorlds.has(worldId)) {
|
|
20705
|
+
for (const [jointKey, consumers] of entry.skinConsumersByJoint) {
|
|
20706
|
+
const separator = jointKey.indexOf(":");
|
|
20707
|
+
const indexedWorldId = Number(jointKey.slice(0, separator));
|
|
20708
|
+
if (indexedWorldId !== worldId) continue;
|
|
20709
|
+
const jointEntity = Number(jointKey.slice(separator + 1));
|
|
20710
|
+
if (world.hasComponent(jointEntity, GlobalTransform)) continue;
|
|
20711
|
+
for (const consumer of consumers) changed.add(consumer);
|
|
20712
|
+
}
|
|
20713
|
+
for (const entity of current) {
|
|
20714
|
+
if (entry.projection.slot(worldId, entity) === void 0) changed.add(entity);
|
|
20715
|
+
}
|
|
20716
|
+
const structuralComponentIds = structuralComponentIdsByWorld[worldId];
|
|
20717
|
+
const scanAllMembership = structuralComponentIds !== void 0 && [...structuralComponentIds].some(
|
|
20718
|
+
(id) => STRUCTURAL_MEMBERSHIP_SCAN_COMPONENT_IDS.has(id)
|
|
20719
|
+
);
|
|
20720
|
+
for (const slot of entry.projection.slotsSnapshot()) {
|
|
20721
|
+
if (slot.worldId !== worldId || !current.has(slot.entityKey)) continue;
|
|
20722
|
+
const membershipChanged = sourceMembershipChanged(world, slot);
|
|
20723
|
+
if (scanAllMembership || membershipChanged) {
|
|
20724
|
+
changed.add(slot.entityKey);
|
|
20725
|
+
if (slot.snapshot.instances !== void 0 && !world.hasComponent(slot.entityKey, Instances)) {
|
|
20726
|
+
this.options.instanceCollections?.release(world, slot.entityKey);
|
|
20727
|
+
}
|
|
20728
|
+
if (slot.snapshot.skin !== void 0 && !world.hasComponent(slot.entityKey, Skin)) {
|
|
20729
|
+
this.options.getSkinPaletteAllocator?.()?.releaseSliceFor(`${world.identity}:${slot.entityKey}`);
|
|
20730
|
+
}
|
|
20731
|
+
}
|
|
20732
|
+
}
|
|
20733
|
+
}
|
|
20734
|
+
for (const slot of entry.projection.slotsSnapshot()) {
|
|
20735
|
+
if (slot.worldId !== worldId || current.has(slot.entityKey)) continue;
|
|
20736
|
+
removedSlots.push(slot);
|
|
20737
|
+
}
|
|
20738
|
+
this.worldEntitiesScanned += current.size;
|
|
20739
|
+
}
|
|
20740
|
+
}
|
|
20741
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20742
|
+
const pending = entry.pendingRenderableEntitiesByWorld[worldId];
|
|
20743
|
+
if (pending === void 0) continue;
|
|
20744
|
+
for (const entityKey of changedEntitiesByWorld[worldId] ?? []) pending.add(entityKey);
|
|
20745
|
+
}
|
|
20746
|
+
let changedDelta;
|
|
20747
|
+
const hasChangedEntities = changedEntitiesByWorld.some((entities) => entities.size > 0);
|
|
20748
|
+
if (hasChangedEntities || removedSlots.length > 0) {
|
|
20749
|
+
const operations = [];
|
|
20750
|
+
const removedDemand = [];
|
|
20751
|
+
const replacedSkinSnapshots = [];
|
|
20752
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20753
|
+
for (const entityKey of changedEntitiesByWorld[worldId] ?? []) {
|
|
20754
|
+
const slot = entry.projection.slot(worldId, entityKey);
|
|
20755
|
+
if (slot !== void 0) replacedSkinSnapshots.push(slot.snapshot);
|
|
20756
|
+
}
|
|
20757
|
+
}
|
|
20758
|
+
for (const slot of removedSlots) {
|
|
20759
|
+
operations.push({ kind: "remove", worldId: slot.worldId, entityKey: slot.entityKey });
|
|
20760
|
+
if (slot.snapshot.skinJointEntities !== void 0) {
|
|
20761
|
+
removeSkinConsumer(entry.skinConsumersByJoint, slot.snapshot);
|
|
20762
|
+
}
|
|
20763
|
+
const world = worlds[slot.worldId];
|
|
20764
|
+
if (world !== void 0) this.options.instanceCollections?.release(world, slot.entityKey);
|
|
20765
|
+
this.options.getSkinPaletteAllocator?.()?.releaseSliceFor(`${world?.identity ?? slot.worldId}:${slot.entityKey}`);
|
|
20766
|
+
for (let materialIndex = 0; materialIndex < slot.snapshot.materials.length; materialIndex += 1) {
|
|
20767
|
+
removedDemand.push({
|
|
20768
|
+
kind: "remove",
|
|
20769
|
+
key: `${slot.worldId}:${slot.entityKey}:${materialIndex}`
|
|
20770
|
+
});
|
|
20771
|
+
}
|
|
20772
|
+
}
|
|
20773
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20774
|
+
for (const entityKey of changedEntitiesByWorld[worldId] ?? []) {
|
|
20775
|
+
const slot = entry.projection.slot(worldId, entityKey);
|
|
20776
|
+
if (slot === void 0) continue;
|
|
20777
|
+
for (let materialIndex = 0; materialIndex < slot.snapshot.materials.length; materialIndex += 1) {
|
|
20778
|
+
removedDemand.push({ kind: "remove", key: `${worldId}:${entityKey}:${materialIndex}` });
|
|
20779
|
+
}
|
|
20780
|
+
}
|
|
20781
|
+
}
|
|
20782
|
+
const partial = hasChangedEntities ? buildCandidateFrame({ kind: "partial", entitiesByWorld: changedEntitiesByWorld }) : void 0;
|
|
20783
|
+
const publishedEntitiesByWorld = worlds.map(() => /* @__PURE__ */ new Set());
|
|
20784
|
+
for (const snapshot of partial?.renderables ?? []) {
|
|
20785
|
+
operations.push({ kind: "create", snapshot });
|
|
20786
|
+
publishedEntitiesByWorld[snapshot.worldId]?.add(snapshot.entityKey);
|
|
20787
|
+
}
|
|
20788
|
+
changedDelta = entry.projection.apply(operations);
|
|
20789
|
+
const publishedSkinKeys = /* @__PURE__ */ new Set();
|
|
20790
|
+
for (const snapshot of partial?.renderables ?? []) {
|
|
20791
|
+
publishedSkinKeys.add(`${snapshot.worldId}:${snapshot.entityKey}`);
|
|
20792
|
+
}
|
|
20793
|
+
for (const snapshot of replacedSkinSnapshots) {
|
|
20794
|
+
if (snapshot.skinJointEntities !== void 0 && publishedSkinKeys.has(`${snapshot.worldId}:${snapshot.entityKey}`)) {
|
|
20795
|
+
removeSkinConsumer(entry.skinConsumersByJoint, snapshot);
|
|
20796
|
+
}
|
|
20797
|
+
}
|
|
20798
|
+
for (const snapshot of partial?.renderables ?? []) {
|
|
20799
|
+
if (snapshot.skinJointEntities !== void 0) {
|
|
20800
|
+
addSkinConsumer(entry.skinConsumersByJoint, snapshot);
|
|
20801
|
+
}
|
|
20802
|
+
}
|
|
20803
|
+
entry.transmissionDemand.apply([
|
|
20804
|
+
...removedDemand,
|
|
20805
|
+
...transmissionDemandOperations(partial?.renderables ?? [])
|
|
20806
|
+
]);
|
|
20807
|
+
for (const removed of changedDelta.removedSlots) entry.dispatchBySlot.delete(removed.slot);
|
|
20808
|
+
for (const recreated of changedDelta.recreatedSlots)
|
|
20809
|
+
entry.dispatchBySlot.delete(recreated.slot);
|
|
20810
|
+
if (partial !== void 0) {
|
|
20811
|
+
if (refreshStructureFacts) {
|
|
20812
|
+
entry.structure = {
|
|
20813
|
+
...entry.structure,
|
|
20814
|
+
dispatch: partial.dispatch,
|
|
20815
|
+
visibilityStats: partial.visibilityStats,
|
|
20816
|
+
visibilitySnapshots: partial.visibilitySnapshots,
|
|
20817
|
+
featureVisibilitySnapshots: partial.featureVisibilitySnapshots,
|
|
20818
|
+
hiddenEntityReports: partial.hiddenEntityReports
|
|
20819
|
+
};
|
|
20820
|
+
}
|
|
20821
|
+
const partialDispatch = dispatchEntriesBySlot(partial, entry.projection);
|
|
20822
|
+
for (const [slot, dispatch] of partialDispatch) entry.dispatchBySlot.set(slot, dispatch);
|
|
20823
|
+
for (const snapshot of partial.renderables) {
|
|
20824
|
+
const slot = entry.projection.slot(snapshot.worldId, snapshot.entityKey);
|
|
20825
|
+
if (slot !== void 0 && !partialDispatch.has(slot.slot))
|
|
20826
|
+
entry.dispatchBySlot.set(slot.slot, []);
|
|
20827
|
+
}
|
|
20828
|
+
}
|
|
20829
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20830
|
+
const requested = changedEntitiesByWorld[worldId];
|
|
20831
|
+
const published = publishedEntitiesByWorld[worldId];
|
|
20832
|
+
if (requested === void 0 || published === void 0) continue;
|
|
20833
|
+
const pending = entry.pendingRenderableEntitiesByWorld[worldId];
|
|
20834
|
+
for (const entityKey of requested) {
|
|
20835
|
+
const slot = entry.projection.slot(worldId, entityKey);
|
|
20836
|
+
if (published.has(entityKey)) {
|
|
20837
|
+
pending?.delete(entityKey);
|
|
20838
|
+
continue;
|
|
20839
|
+
}
|
|
20840
|
+
if (slot === void 0) {
|
|
20841
|
+
const current = currentRenderableEntitiesByWorld?.[worldId];
|
|
20842
|
+
if (current !== void 0 && !current.has(entityKey)) pending?.delete(entityKey);
|
|
20843
|
+
continue;
|
|
20844
|
+
}
|
|
20845
|
+
pending?.add(entityKey);
|
|
20846
|
+
if (slot !== void 0) entry.dispatchBySlot.set(slot.slot, []);
|
|
20847
|
+
}
|
|
20848
|
+
}
|
|
20849
|
+
const newlyUnavailable = [];
|
|
20850
|
+
for (let worldId = 0; worldId < changedEntitiesByWorld.length; worldId += 1) {
|
|
20851
|
+
const requested = changedEntitiesByWorld[worldId];
|
|
20852
|
+
const published = publishedEntitiesByWorld[worldId];
|
|
20853
|
+
if (requested === void 0 || published === void 0) continue;
|
|
20854
|
+
for (const entityKey of requested) {
|
|
20855
|
+
const slot = entry.projection.slot(worldId, entityKey);
|
|
20856
|
+
if (slot === void 0 || published.has(entityKey)) {
|
|
20857
|
+
if (slot !== void 0) entry.unavailableSlots.delete(slot.slot);
|
|
20858
|
+
continue;
|
|
20859
|
+
}
|
|
20860
|
+
if (!entry.unavailableSlots.has(slot.slot)) newlyUnavailable.push(slot);
|
|
20861
|
+
entry.unavailableSlots.add(slot.slot);
|
|
20862
|
+
}
|
|
20863
|
+
}
|
|
20864
|
+
for (const removed of changedDelta.removedSlots) entry.unavailableSlots.delete(removed.slot);
|
|
20865
|
+
for (const recreated of changedDelta.recreatedSlots)
|
|
20866
|
+
entry.unavailableSlots.delete(recreated.slot);
|
|
20867
|
+
entry.dispatchRevision += 1;
|
|
20868
|
+
entry.dispatchCache = void 0;
|
|
20869
|
+
entry.topology.apply(
|
|
20870
|
+
topologyDeltaForAvailable(changedDelta, entry.unavailableSlots, newlyUnavailable)
|
|
20871
|
+
);
|
|
20872
|
+
this.syncGpuOwner(entry.token, entry.projection, changedDelta);
|
|
20873
|
+
this.deltaFrames += changedDelta.created + changedDelta.updated + changedDelta.removed + changedDelta.recreated > 0 ? 1 : 0;
|
|
20874
|
+
this.transformUpdates += changedDelta.updated;
|
|
20875
|
+
}
|
|
20266
20876
|
const transformSpans = [];
|
|
20267
20877
|
for (let worldId = 0; worldId < entry.transformQueries.length; worldId += 1) {
|
|
20268
20878
|
const query = entry.transformQueries[worldId];
|
|
@@ -20280,17 +20890,29 @@ var PersistentRenderScene = class {
|
|
|
20280
20890
|
if (requiresRebuild) {
|
|
20281
20891
|
return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
|
|
20282
20892
|
}
|
|
20283
|
-
if (transformSpans.length === 0) {
|
|
20893
|
+
if (transformSpans.length === 0 && changedDelta === void 0) {
|
|
20284
20894
|
this.noChangeFrames += 1;
|
|
20285
20895
|
this.syncGpuOwner(entry.token, entry.projection);
|
|
20286
|
-
|
|
20896
|
+
const result2 = this.deriveFramePlan(entry, buildCandidateFrame);
|
|
20897
|
+
for (let worldId = 0; worldId < nextReadVersions.length; worldId += 1) {
|
|
20898
|
+
const version = nextReadVersions[worldId];
|
|
20899
|
+
if (version !== void 0) entry.readVersions[worldId] = version;
|
|
20900
|
+
}
|
|
20901
|
+
return result2;
|
|
20287
20902
|
}
|
|
20288
|
-
|
|
20289
|
-
|
|
20290
|
-
|
|
20291
|
-
|
|
20292
|
-
|
|
20293
|
-
|
|
20903
|
+
if (transformSpans.length > 0) {
|
|
20904
|
+
const delta = entry.projection.applyTransformSpans(transformSpans);
|
|
20905
|
+
entry.topology.apply(topologyDeltaForAvailable(delta, entry.unavailableSlots, []));
|
|
20906
|
+
this.syncGpuOwner(entry.token, entry.projection, delta);
|
|
20907
|
+
this.deltaFrames += 1;
|
|
20908
|
+
this.transformUpdates += delta.updated;
|
|
20909
|
+
}
|
|
20910
|
+
const result = this.deriveFramePlan(entry, buildCandidateFrame);
|
|
20911
|
+
for (let worldId = 0; worldId < nextReadVersions.length; worldId += 1) {
|
|
20912
|
+
const version = nextReadVersions[worldId];
|
|
20913
|
+
if (version !== void 0) entry.readVersions[worldId] = version;
|
|
20914
|
+
}
|
|
20915
|
+
return result;
|
|
20294
20916
|
}
|
|
20295
20917
|
invalidate() {
|
|
20296
20918
|
this.composition = void 0;
|
|
@@ -20311,6 +20933,14 @@ var PersistentRenderScene = class {
|
|
|
20311
20933
|
this.visibilityFacets.detachAttachment(world.identity);
|
|
20312
20934
|
this.materialSnapshotCaches.delete(world);
|
|
20313
20935
|
const detachedComposition = this.composition?.worlds.includes(world) ? this.composition : void 0;
|
|
20936
|
+
if (detachedComposition !== void 0) {
|
|
20937
|
+
for (const slot of detachedComposition.projection.slotsSnapshot()) {
|
|
20938
|
+
if (detachedComposition.worlds[slot.worldId] !== world) continue;
|
|
20939
|
+
this.options.instanceCollections?.release(world, slot.entityKey);
|
|
20940
|
+
if (slot.snapshot.skin === void 0) continue;
|
|
20941
|
+
this.options.getSkinPaletteAllocator?.()?.releaseSliceFor(`${world.identity}:${slot.entityKey}`);
|
|
20942
|
+
}
|
|
20943
|
+
}
|
|
20314
20944
|
if (detachedComposition !== void 0) this.composition = void 0;
|
|
20315
20945
|
if (detachedComposition !== void 0) this.temporalCapture = void 0;
|
|
20316
20946
|
if (detachedComposition !== void 0) {
|
|
@@ -20592,6 +21222,10 @@ var PersistentRenderScene = class {
|
|
|
20592
21222
|
transmissionDemand.apply(transmissionDemandOperations(candidateFrame.renderables));
|
|
20593
21223
|
const topology = new BatchTopology();
|
|
20594
21224
|
topology.rebuild(projection.slotsSnapshot());
|
|
21225
|
+
const skinConsumersByJoint = /* @__PURE__ */ new Map();
|
|
21226
|
+
for (const snapshot of stableCandidateFrame.renderables) {
|
|
21227
|
+
if (snapshot.skinJointEntities !== void 0) addSkinConsumer(skinConsumersByJoint, snapshot);
|
|
21228
|
+
}
|
|
20595
21229
|
const token2 = {};
|
|
20596
21230
|
const entry = {
|
|
20597
21231
|
token: token2,
|
|
@@ -20612,8 +21246,14 @@ var PersistentRenderScene = class {
|
|
|
20612
21246
|
readVersions: leases === void 0 || leases.length !== worlds.length ? [] : leases.map((lease) => lease.captureVersion()),
|
|
20613
21247
|
leaseIdentities: leases === void 0 || leases.length !== worlds.length ? [] : leases.map((lease) => lease.worldIdentity),
|
|
20614
21248
|
transformQueries: leases === void 0 || leases.length !== worlds.length ? [] : worlds.map(createGlobalTransformChangeQuery),
|
|
21249
|
+
renderChangeQueries: leases === void 0 || leases.length !== worlds.length ? [] : worlds.map(createRenderChangeQueries),
|
|
21250
|
+
dispatchBySlot: dispatchEntriesBySlot(stableCandidateFrame, projection),
|
|
21251
|
+
dispatchRevision: 0,
|
|
21252
|
+
dispatchCache: void 0,
|
|
21253
|
+
skinConsumersByJoint,
|
|
21254
|
+
pendingRenderableEntitiesByWorld: worlds.map(() => /* @__PURE__ */ new Set()),
|
|
21255
|
+
unavailableSlots: /* @__PURE__ */ new Set(),
|
|
20615
21256
|
catalogEpoch,
|
|
20616
|
-
rigidOnly: candidateFrame.renderables.every((renderable) => renderable.skin === void 0),
|
|
20617
21257
|
probeProjection: new ProbeBlendSceneProjection(),
|
|
20618
21258
|
temporalDemanded: frameDemandsTemporal(candidateFrame),
|
|
20619
21259
|
gpuDrivenSceneRequired: true
|
|
@@ -20660,16 +21300,31 @@ var PersistentRenderScene = class {
|
|
|
20660
21300
|
*/
|
|
20661
21301
|
deriveFramePlan(entry, buildCandidateFrame) {
|
|
20662
21302
|
const resourceFrame = buildCandidateFrame("none");
|
|
20663
|
-
const
|
|
21303
|
+
const cachedDispatch = entry.dispatchCache;
|
|
21304
|
+
const dispatch = [
|
|
21305
|
+
...cachedDispatch?.revision === entry.dispatchRevision ? cachedDispatch.value : dispatchForProjection(entry.dispatchBySlot, entry.projection, entry.unavailableSlots)
|
|
21306
|
+
];
|
|
21307
|
+
if (cachedDispatch?.revision !== entry.dispatchRevision) {
|
|
21308
|
+
entry.dispatchCache = { revision: entry.dispatchRevision, value: dispatch };
|
|
21309
|
+
}
|
|
21310
|
+
const candidateFrame = {
|
|
21311
|
+
...resourceFrame,
|
|
21312
|
+
...entry.structure,
|
|
21313
|
+
dispatch
|
|
21314
|
+
};
|
|
20664
21315
|
entry.temporalDemanded = frameDemandsTemporal(candidateFrame);
|
|
20665
21316
|
entry.projection.setTemporalTracking(entry.temporalDemanded);
|
|
20666
21317
|
this.projectProbes(entry, candidateFrame);
|
|
20667
21318
|
this.projectReflectionProbes(candidateFrame.reflectionProbes ?? []);
|
|
20668
21319
|
const materialized = entry.projection.materialize();
|
|
20669
21320
|
const candidates = entry.temporalDemanded ? materialized.map((snapshot) => entry.projection.withTemporal(snapshot)) : materialized;
|
|
21321
|
+
const drawableCandidates = entry.unavailableSlots.size === 0 ? candidates : candidates.map((snapshot) => {
|
|
21322
|
+
const slot = entry.projection.slot(snapshot.worldId, snapshot.entityKey);
|
|
21323
|
+
return slot !== void 0 && entry.unavailableSlots.has(slot.slot) ? { ...snapshot, authorVisible: false } : snapshot;
|
|
21324
|
+
});
|
|
20670
21325
|
const frameWithProbes = attachProbeRecords(
|
|
20671
|
-
{ ...candidateFrame, renderables:
|
|
20672
|
-
|
|
21326
|
+
{ ...candidateFrame, renderables: drawableCandidates },
|
|
21327
|
+
drawableCandidates,
|
|
20673
21328
|
entry.projection.slotsSnapshot(),
|
|
20674
21329
|
entry.probeProjection
|
|
20675
21330
|
);
|
|
@@ -21314,6 +21969,7 @@ function createRenderSystem(internals) {
|
|
|
21314
21969
|
let preparedWorlds = [];
|
|
21315
21970
|
let latestCamera;
|
|
21316
21971
|
const pointsLinesOwner = new StandardPointsLinesOwner(internals);
|
|
21972
|
+
const instanceCollections = new InstanceProjectionStore();
|
|
21317
21973
|
const reflectionProbeOwner = new ReflectionProbeRecordOwner(internals);
|
|
21318
21974
|
let ssrFormatReceipt;
|
|
21319
21975
|
let ssrFormatProbeGeneration = -1;
|
|
@@ -21345,7 +22001,9 @@ function createRenderSystem(internals) {
|
|
|
21345
22001
|
onGpuError: (error) => internals.errorRegistry.fire(error),
|
|
21346
22002
|
onSharedRefMutation: (worldId, handle) => {
|
|
21347
22003
|
internals.gpuStore.invalidateMesh(handle, preparedWorlds[worldId] ?? worldId);
|
|
21348
|
-
}
|
|
22004
|
+
},
|
|
22005
|
+
instanceCollections,
|
|
22006
|
+
getSkinPaletteAllocator: () => internals.getPipelineState()?.skinPaletteAllocator ?? null
|
|
21349
22007
|
});
|
|
21350
22008
|
let environmentLifecycle = new EnvironmentLifecycle(internals.deviceScope);
|
|
21351
22009
|
const transmissionAdmission = new TransmissionCandidateAdmission();
|
|
@@ -21559,6 +22217,8 @@ function createRenderSystem(internals) {
|
|
|
21559
22217
|
currentDirectionalShadowView: null,
|
|
21560
22218
|
currentSpotShadowView: null,
|
|
21561
22219
|
instanceBuffers: /* @__PURE__ */ new Map(),
|
|
22220
|
+
instanceResidency: /* @__PURE__ */ new Map(),
|
|
22221
|
+
instanceBufferChunks: /* @__PURE__ */ new Map(),
|
|
21562
22222
|
probeBlendBuffers: /* @__PURE__ */ new Map(),
|
|
21563
22223
|
probeBlendRecordBufferCapacity: 0,
|
|
21564
22224
|
morphBuffers: /* @__PURE__ */ new Map(),
|
|
@@ -22282,6 +22942,12 @@ function createRenderSystem(internals) {
|
|
|
22282
22942
|
createPreparedResolverCaches
|
|
22283
22943
|
});
|
|
22284
22944
|
return {
|
|
22945
|
+
get instanceCollectionsInspection() {
|
|
22946
|
+
return instanceCollections._inspections(
|
|
22947
|
+
frameState.instanceResidency,
|
|
22948
|
+
frameState.frameNumber - 1
|
|
22949
|
+
);
|
|
22950
|
+
},
|
|
22285
22951
|
releaseProfilerCatalog() {
|
|
22286
22952
|
releaseProfilerCatalog?.();
|
|
22287
22953
|
releaseProfilerCatalog = void 0;
|
|
@@ -22487,15 +23153,30 @@ function createRenderSystem(internals) {
|
|
|
22487
23153
|
compositionWorlds,
|
|
22488
23154
|
{ cameraOwner, resourceOwner },
|
|
22489
23155
|
internals.assets.catalogEpoch,
|
|
22490
|
-
(
|
|
23156
|
+
(request) => extractFrames(
|
|
22491
23157
|
compositionWorlds,
|
|
22492
23158
|
{ cameraOwner, resourceOwner },
|
|
22493
23159
|
internals.assets,
|
|
22494
23160
|
internals.getPipelineState(),
|
|
22495
23161
|
persistentRenderScene.materialSnapshotCacheStore(),
|
|
22496
23162
|
{
|
|
23163
|
+
...internals.device.caps.backendKind === "null" ? {} : {
|
|
23164
|
+
materialContext: {
|
|
23165
|
+
backend: internals.device.caps.backendKind === "wgpu-webgl2" ? "webgl2" : internals.device.caps.backendKind,
|
|
23166
|
+
capability: internals.device.caps.storageBuffer ? "storage-buffer" : "uniform-fallback",
|
|
23167
|
+
pipeline: "forward",
|
|
23168
|
+
geometry: "mesh",
|
|
23169
|
+
pass: "forward",
|
|
23170
|
+
profile: "forgeax-material-wgsl-v1",
|
|
23171
|
+
toolchain: "naga-oil",
|
|
23172
|
+
instrumentation: "none"
|
|
23173
|
+
}
|
|
23174
|
+
},
|
|
22497
23175
|
cull: "none",
|
|
22498
|
-
renderables:
|
|
23176
|
+
renderables: request === "none" ? "none" : "full",
|
|
23177
|
+
...request === "none" || request === "full" ? {} : { renderableEntitiesByWorld: request.entitiesByWorld },
|
|
23178
|
+
retainHidden: true,
|
|
23179
|
+
instanceCollections,
|
|
22499
23180
|
...internals.getMaterialShaderArtifact === void 0 ? {} : { getMaterialShaderArtifact: internals.getMaterialShaderArtifact }
|
|
22500
23181
|
}
|
|
22501
23182
|
),
|
|
@@ -23281,6 +23962,7 @@ function createRenderSystem(internals) {
|
|
|
23281
23962
|
internals.gpuPassTimingBeginReason = void 0;
|
|
23282
23963
|
pointsLinesOwner.dispose();
|
|
23283
23964
|
persistentRenderScene.dispose();
|
|
23965
|
+
instanceCollections.dispose();
|
|
23284
23966
|
gpuDrivenProduction.dispose();
|
|
23285
23967
|
occlusionRuntime?.dispose();
|
|
23286
23968
|
disposeFeatureGpuWork();
|
|
@@ -23337,6 +24019,10 @@ function createRenderSystem(internals) {
|
|
|
23337
24019
|
}
|
|
23338
24020
|
frameState.retiredCompiledFrameGraphs.clear();
|
|
23339
24021
|
disposeInstanceBuffers(frameState.instanceBuffers, internals.errorRegistry);
|
|
24022
|
+
frameState.instanceResidency?.clear();
|
|
24023
|
+
if (frameState.instanceBufferChunks !== void 0) {
|
|
24024
|
+
disposeInstanceBufferChunks(frameState.instanceBufferChunks, internals.errorRegistry);
|
|
24025
|
+
}
|
|
23340
24026
|
disposeTransientInstanceBuffers(frameState.transientInstanceBuffers, internals.errorRegistry);
|
|
23341
24027
|
if (frameState.probeBlendRecordBuffer !== void 0) {
|
|
23342
24028
|
if (!frameState.probeBlendRecordBuffer.isDestroyed) {
|
|
@@ -23439,6 +24125,8 @@ function createRenderSystem(internals) {
|
|
|
23439
24125
|
}
|
|
23440
24126
|
frameState.retiredCompiledFrameGraphs.clear();
|
|
23441
24127
|
frameState.instanceBuffers.clear();
|
|
24128
|
+
frameState.instanceBufferChunks?.clear();
|
|
24129
|
+
frameState.instanceResidency?.clear();
|
|
23442
24130
|
delete frameState.probeBlendRecordBuffer;
|
|
23443
24131
|
frameState.probeBlendRecordBufferCapacity = 0;
|
|
23444
24132
|
frameState.probeBlendBuffers.clear();
|
|
@@ -24577,11 +25265,10 @@ async function prepareMaterialShaders(rhiDevice, getShader, assets, materialShad
|
|
|
24577
25265
|
]);
|
|
24578
25266
|
const capValue = rhiDevice.limits.maxStorageBuffersPerShaderStage;
|
|
24579
25267
|
const webgl2Downlevel = rhiDevice.caps.backendKind === "wgpu-webgl2";
|
|
24580
|
-
|
|
24581
|
-
if (typeof capValue === "number") {
|
|
25268
|
+
const storageBufferCapable = rhiDevice.caps.storageBuffer;
|
|
25269
|
+
if (storageBufferCapable && typeof capValue === "number") {
|
|
24582
25270
|
const capCheck = assertStorageBufferCap(capValue);
|
|
24583
25271
|
if (!capCheck.ok) throw capCheck.error;
|
|
24584
|
-
storageBufferCapable = !webgl2Downlevel && capCheck.value;
|
|
24585
25272
|
}
|
|
24586
25273
|
const extendedLightingShaderAvailable = deriveExtendedLightingCapability(rhiDevice).admitted;
|
|
24587
25274
|
const projectorAvailable = (rhiDevice.limits.maxSampledTexturesPerShaderStage ?? 0) >= STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES2;
|
|
@@ -24593,9 +25280,10 @@ async function prepareMaterialShaders(rhiDevice, getShader, assets, materialShad
|
|
|
24593
25280
|
const isHdrpActive = false;
|
|
24594
25281
|
for (const msEntry of registry.materialShaderManifestEntries()) {
|
|
24595
25282
|
if (msEntry.identifier.startsWith("forgeax::engine-")) continue;
|
|
24596
|
-
const variantDefines = {
|
|
24597
|
-
|
|
24598
|
-
|
|
25283
|
+
const variantDefines = {};
|
|
25284
|
+
if (msEntry.variants.some((variant) => "STORAGE_BUFFER_AVAILABLE" in variant.defines)) {
|
|
25285
|
+
variantDefines.STORAGE_BUFFER_AVAILABLE = storageBufferCapable;
|
|
25286
|
+
}
|
|
24599
25287
|
if (msEntry.variants.some((v) => "WEBGL2_COMPAT" in v.defines)) {
|
|
24600
25288
|
variantDefines.WEBGL2_COMPAT = webgl2Downlevel;
|
|
24601
25289
|
}
|
|
@@ -24678,7 +25366,7 @@ async function prepareMaterialShaders(rhiDevice, getShader, assets, materialShad
|
|
|
24678
25366
|
if (manifestEntry !== void 0) {
|
|
24679
25367
|
registry.installMaterialArtifact(shadowCasterIdentifier, {
|
|
24680
25368
|
source: manifestEntry.composedWgsl,
|
|
24681
|
-
paramSchema:
|
|
25369
|
+
paramSchema: STANDARD_PIPELINE_PARAM_SCHEMA
|
|
24682
25370
|
});
|
|
24683
25371
|
const shaderGuid = ENGINE_SHADER_GUIDS.get(shadowCasterIdentifier);
|
|
24684
25372
|
if (shaderGuid !== void 0) {
|
|
@@ -24686,7 +25374,7 @@ async function prepareMaterialShaders(rhiDevice, getShader, assets, materialShad
|
|
|
24686
25374
|
kind: "shader",
|
|
24687
25375
|
name: shadowCasterIdentifier,
|
|
24688
25376
|
source: manifestEntry.composedWgsl,
|
|
24689
|
-
paramSchema:
|
|
25377
|
+
paramSchema: STANDARD_PIPELINE_PARAM_SCHEMA
|
|
24690
25378
|
};
|
|
24691
25379
|
assets.catalog(shaderGuid, shaderAsset);
|
|
24692
25380
|
}
|
|
@@ -24775,6 +25463,47 @@ function resolveMaterialShaderVertexInputContract(source) {
|
|
|
24775
25463
|
}
|
|
24776
25464
|
return /@vertex\s*fn[^{]*\([^)]*@location\s*\(/u.test(withoutComments) ? "render-material" : "none";
|
|
24777
25465
|
}
|
|
25466
|
+
function resolveMaterialShaderUvSetCount(source, reflectedCount) {
|
|
25467
|
+
if (reflectedCount !== void 0) return reflectedCount;
|
|
25468
|
+
if (source === void 0) return void 0;
|
|
25469
|
+
const withoutComments = source.replace(/\/\*[\s\S]*?\*\//gu, "").replace(/\/\/.*$/gmu, "");
|
|
25470
|
+
const inputStructs = [
|
|
25471
|
+
...withoutComments.matchAll(/struct\s+([A-Za-z_]\w*)\s*\{([^}]*)\}/gu)
|
|
25472
|
+
].filter((match) => /@location\s*\(/u.test(match[2] ?? ""));
|
|
25473
|
+
for (const inputStruct of inputStructs) {
|
|
25474
|
+
const name = inputStruct[1];
|
|
25475
|
+
const body = inputStruct[2];
|
|
25476
|
+
if (name === void 0 || body === void 0) continue;
|
|
25477
|
+
const firstParameter = new RegExp(
|
|
25478
|
+
`@vertex\\s*fn\\s+\\w+\\s*\\(\\s*\\w+\\s*:\\s*${name}\\b`,
|
|
25479
|
+
"u"
|
|
25480
|
+
);
|
|
25481
|
+
if (!firstParameter.test(withoutComments)) continue;
|
|
25482
|
+
let uvSetCount = 0;
|
|
25483
|
+
for (const location of body.matchAll(/@location\s*\(\s*(\d+)\s*\)\s+([A-Za-z_]\w*)/gu)) {
|
|
25484
|
+
const field = location[2];
|
|
25485
|
+
if (field === "uv") {
|
|
25486
|
+
uvSetCount = Math.max(uvSetCount, 1);
|
|
25487
|
+
continue;
|
|
25488
|
+
}
|
|
25489
|
+
const uvIndex = field?.match(/^uv(\d+)_?$/u)?.[1];
|
|
25490
|
+
if (uvIndex !== void 0) uvSetCount = Math.max(uvSetCount, Number(uvIndex) + 1);
|
|
25491
|
+
}
|
|
25492
|
+
return uvSetCount > 0 ? uvSetCount : void 0;
|
|
25493
|
+
}
|
|
25494
|
+
return void 0;
|
|
25495
|
+
}
|
|
25496
|
+
function resolveMaterialShaderBackendArtifactKey(materialShaderId, backendKind, artifact) {
|
|
25497
|
+
if (backendKind !== "wgpu-webgl2") return materialShaderId;
|
|
25498
|
+
const variants = artifact?.metadata?.variants;
|
|
25499
|
+
if (!Array.isArray(variants)) return materialShaderId;
|
|
25500
|
+
const fallback = variants.find((variant) => {
|
|
25501
|
+
if (typeof variant !== "object" || variant === null) return false;
|
|
25502
|
+
const candidate = variant;
|
|
25503
|
+
return candidate.backend === "webgl2" && candidate.capability === "uniform-fallback" && typeof candidate.specializationKey === "string" && candidate.specializationKey.length > 0;
|
|
25504
|
+
});
|
|
25505
|
+
return fallback?.specializationKey ?? materialShaderId;
|
|
25506
|
+
}
|
|
24778
25507
|
function allowsUnlitPreparedFallback(depthFormatOverride, vertexLayout, materialShaderId) {
|
|
24779
25508
|
return depthFormatOverride === null && (vertexLayout === void 0 || !materialShaderId?.startsWith("forgeax::"));
|
|
24780
25509
|
}
|
|
@@ -26016,7 +26745,7 @@ function createRendererRecovery(deps) {
|
|
|
26016
26745
|
releaseCandidate();
|
|
26017
26746
|
return err(new RecoverError("recover-device-unavailable"));
|
|
26018
26747
|
}
|
|
26019
|
-
const graphPreparation = renderSystem.prepareRecoveryGraphCandidate({
|
|
26748
|
+
const graphPreparation = await renderSystem.prepareRecoveryGraphCandidate({
|
|
26020
26749
|
internals: candidateInternals,
|
|
26021
26750
|
pipelineState: candidatePipelineState
|
|
26022
26751
|
});
|
|
@@ -27283,6 +28012,11 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27283
28012
|
let storageBuffer = null;
|
|
27284
28013
|
let storageCapacity = 0;
|
|
27285
28014
|
let storageCursor = 0;
|
|
28015
|
+
let stableStorageCursor = 0;
|
|
28016
|
+
const stableSlices = /* @__PURE__ */ new Map();
|
|
28017
|
+
const stableUniformBuffers = /* @__PURE__ */ new Map();
|
|
28018
|
+
const storageBufferCapacities = /* @__PURE__ */ new WeakMap();
|
|
28019
|
+
const stableFreeRanges = [];
|
|
27286
28020
|
const pool = [];
|
|
27287
28021
|
let poolCursor = 0;
|
|
27288
28022
|
function ensureStorageCapacity(needed) {
|
|
@@ -27303,12 +28037,9 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27303
28037
|
if (!bufRes.ok) throw bufRes.error;
|
|
27304
28038
|
storageBuffer = bufRes.value;
|
|
27305
28039
|
storageCapacity = newCapacity;
|
|
28040
|
+
storageBufferCapacities.set(storageBuffer, newCapacity);
|
|
27306
28041
|
}
|
|
27307
|
-
function
|
|
27308
|
-
if (poolCursor < pool.length) {
|
|
27309
|
-
const reused = pool[poolCursor];
|
|
27310
|
-
return reused;
|
|
27311
|
-
}
|
|
28042
|
+
function createUniformBuffer() {
|
|
27312
28043
|
if (BINDING_WINDOW_BYTES > maxBindingSize) {
|
|
27313
28044
|
throw new SkinPaletteOverflowError(BINDING_WINDOW_BYTES, maxBindingSize);
|
|
27314
28045
|
}
|
|
@@ -27319,9 +28050,17 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27319
28050
|
mappedAtCreation: false
|
|
27320
28051
|
});
|
|
27321
28052
|
if (!bufRes.ok) throw bufRes.error;
|
|
27322
|
-
pool.push(bufRes.value);
|
|
27323
28053
|
return bufRes.value;
|
|
27324
28054
|
}
|
|
28055
|
+
function acquirePoolBuffer() {
|
|
28056
|
+
if (poolCursor < pool.length) {
|
|
28057
|
+
const reused = pool[poolCursor];
|
|
28058
|
+
return reused;
|
|
28059
|
+
}
|
|
28060
|
+
const buffer = createUniformBuffer();
|
|
28061
|
+
pool.push(buffer);
|
|
28062
|
+
return buffer;
|
|
28063
|
+
}
|
|
27325
28064
|
function allocateSlice(jointCount) {
|
|
27326
28065
|
if (useStorageBuffer) {
|
|
27327
28066
|
const offset2 = storageCursor;
|
|
@@ -27335,6 +28074,88 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27335
28074
|
poolCursor += 1;
|
|
27336
28075
|
return { jointCount, byteOffset: 0, buffer };
|
|
27337
28076
|
}
|
|
28077
|
+
function allocateSliceFor(key, jointCount) {
|
|
28078
|
+
const existing = stableSlices.get(key);
|
|
28079
|
+
if (existing !== void 0 && existing.jointCount === jointCount) return existing;
|
|
28080
|
+
if (existing !== void 0) releaseSliceFor(key);
|
|
28081
|
+
if (useStorageBuffer) {
|
|
28082
|
+
const span = jointCount * MAT4_BYTES + (PALETTE_OFFSET_ALIGN - 1) & -256;
|
|
28083
|
+
const freeIndex = stableFreeRanges.findIndex(
|
|
28084
|
+
(range) => range.buffer === storageBuffer && range.count >= span && range.start + BINDING_WINDOW_BYTES <= range.capacity
|
|
28085
|
+
);
|
|
28086
|
+
let offset2;
|
|
28087
|
+
let buffer2;
|
|
28088
|
+
if (freeIndex >= 0) {
|
|
28089
|
+
const range = stableFreeRanges[freeIndex];
|
|
28090
|
+
if (range === void 0) throw new Error("Skin palette free range disappeared.");
|
|
28091
|
+
offset2 = range.start;
|
|
28092
|
+
buffer2 = range.buffer;
|
|
28093
|
+
if (range.count === span) stableFreeRanges.splice(freeIndex, 1);
|
|
28094
|
+
else {
|
|
28095
|
+
stableFreeRanges[freeIndex] = {
|
|
28096
|
+
...range,
|
|
28097
|
+
start: range.start + span,
|
|
28098
|
+
count: range.count - span
|
|
28099
|
+
};
|
|
28100
|
+
}
|
|
28101
|
+
} else {
|
|
28102
|
+
offset2 = stableStorageCursor;
|
|
28103
|
+
ensureStorageCapacity(offset2 + BINDING_WINDOW_BYTES);
|
|
28104
|
+
const currentBuffer = storageBuffer;
|
|
28105
|
+
if (currentBuffer === null) throw new Error("Skin palette storage buffer was not created.");
|
|
28106
|
+
buffer2 = currentBuffer;
|
|
28107
|
+
stableStorageCursor = offset2 + span;
|
|
28108
|
+
}
|
|
28109
|
+
const slice2 = { jointCount, byteOffset: offset2, buffer: buffer2 };
|
|
28110
|
+
stableSlices.set(key, slice2);
|
|
28111
|
+
return slice2;
|
|
28112
|
+
}
|
|
28113
|
+
let buffer = stableUniformBuffers.get(key);
|
|
28114
|
+
if (buffer === void 0) {
|
|
28115
|
+
buffer = createUniformBuffer();
|
|
28116
|
+
stableUniformBuffers.set(key, buffer);
|
|
28117
|
+
}
|
|
28118
|
+
const slice = { jointCount, byteOffset: 0, buffer };
|
|
28119
|
+
stableSlices.set(key, slice);
|
|
28120
|
+
return slice;
|
|
28121
|
+
}
|
|
28122
|
+
function releaseSliceFor(key) {
|
|
28123
|
+
const slice = stableSlices.get(key);
|
|
28124
|
+
if (slice === void 0) return;
|
|
28125
|
+
stableSlices.delete(key);
|
|
28126
|
+
if (!useStorageBuffer) {
|
|
28127
|
+
stableUniformBuffers.delete(key);
|
|
28128
|
+
device.destroyBuffer(slice.buffer);
|
|
28129
|
+
return;
|
|
28130
|
+
}
|
|
28131
|
+
const count = slice.jointCount * MAT4_BYTES + (PALETTE_OFFSET_ALIGN - 1) & -256;
|
|
28132
|
+
stableFreeRanges.push({
|
|
28133
|
+
start: slice.byteOffset,
|
|
28134
|
+
count,
|
|
28135
|
+
buffer: slice.buffer,
|
|
28136
|
+
capacity: storageBufferCapacities.get(slice.buffer) ?? storageCapacity
|
|
28137
|
+
});
|
|
28138
|
+
stableFreeRanges.sort((left, right) => left.start - right.start);
|
|
28139
|
+
for (let index = stableFreeRanges.length - 1; index > 0; index -= 1) {
|
|
28140
|
+
const current = stableFreeRanges[index];
|
|
28141
|
+
const previous = stableFreeRanges[index - 1];
|
|
28142
|
+
if (current === void 0 || previous === void 0 || current.buffer !== previous.buffer || previous.start + previous.count !== current.start) {
|
|
28143
|
+
continue;
|
|
28144
|
+
}
|
|
28145
|
+
stableFreeRanges[index - 1] = {
|
|
28146
|
+
start: previous.start,
|
|
28147
|
+
count: previous.count + current.count,
|
|
28148
|
+
buffer: previous.buffer,
|
|
28149
|
+
capacity: previous.capacity
|
|
28150
|
+
};
|
|
28151
|
+
stableFreeRanges.splice(index, 1);
|
|
28152
|
+
}
|
|
28153
|
+
}
|
|
28154
|
+
function retainSliceKeys(keys) {
|
|
28155
|
+
for (const key of stableSlices.keys()) {
|
|
28156
|
+
if (!keys.has(key)) releaseSliceFor(key);
|
|
28157
|
+
}
|
|
28158
|
+
}
|
|
27338
28159
|
function writeJointPalette(slice, ibms, jointWorlds) {
|
|
27339
28160
|
const count = Math.min(slice.jointCount, ibms.length, jointWorlds.length);
|
|
27340
28161
|
if (count === 0) return;
|
|
@@ -27365,6 +28186,9 @@ function createSkinPaletteAllocator(device, maxBindingSize, useStorageBuffer = t
|
|
|
27365
28186
|
bindingWindowBytes: BINDING_WINDOW_BYTES,
|
|
27366
28187
|
useStorageBuffer,
|
|
27367
28188
|
allocateSlice,
|
|
28189
|
+
allocateSliceFor,
|
|
28190
|
+
releaseSliceFor,
|
|
28191
|
+
retainSliceKeys,
|
|
27368
28192
|
writeJointPalette,
|
|
27369
28193
|
resetForFrame
|
|
27370
28194
|
};
|
|
@@ -27695,13 +28519,8 @@ var DEPTH_TEXTURE_FORMAT = "depth24plus-stencil8";
|
|
|
27695
28519
|
// src/assembly/webgpu-ready.ts
|
|
27696
28520
|
async function buildReadyWebGPU(rhiDevice, rendererScope, getShader, gpuStore, asyncCreateShaderModule, errorRegistry, requiredMaterialShaders, requiredFullscreenPostProcesses, setGrowMeshSsboHook, seedShaderModule, seedMaterialShaderPipelineCache, registerBuiltinTonemap, registerBuiltinFxaa, registerBuiltinTemporalPostProcesses, setVolumetricFogShaderSources) {
|
|
27697
28521
|
const extendedLightingShaderAvailable = deriveExtendedLightingCapability(rhiDevice).admitted;
|
|
27698
|
-
const
|
|
28522
|
+
const storageBufferCapable = rhiDevice.caps.storageBuffer;
|
|
27699
28523
|
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
28524
|
const directionalPcssAvailable = rhiDevice.caps.backendKind === "webgpu" || rhiDevice.caps.backendKind === "wgpu-native";
|
|
27706
28525
|
const projectorAvailable = (rhiDevice.limits.maxSampledTexturesPerShaderStage ?? 0) >= STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES2;
|
|
27707
28526
|
const surfaceViewFormats = rhiDevice.surfaceViewFormats ?? !webgl2Downlevel;
|
|
@@ -30333,11 +31152,7 @@ async function buildReadyWebGPU(rhiDevice, rendererScope, getShader, gpuStore, a
|
|
|
30333
31152
|
return pipelineState;
|
|
30334
31153
|
}
|
|
30335
31154
|
|
|
30336
|
-
// src/assembly/webgpu-
|
|
30337
|
-
function adaptMipmapShaderModuleFactory(factory) {
|
|
30338
|
-
if (factory === void 0) return void 0;
|
|
30339
|
-
return (device, descriptor) => factory(device, descriptor);
|
|
30340
|
-
}
|
|
31155
|
+
// src/assembly/webgpu-vertex-layouts.ts
|
|
30341
31156
|
var PBR_SKIN_SENTINEL_ATTR_BUFFER = new ArrayBuffer(0);
|
|
30342
31157
|
var DEFAULT_VERTEX_ATTRS = {
|
|
30343
31158
|
position: new Float32Array(0),
|
|
@@ -30448,6 +31263,12 @@ function toGpuVertexBufferLayouts(entries) {
|
|
|
30448
31263
|
}))
|
|
30449
31264
|
}));
|
|
30450
31265
|
}
|
|
31266
|
+
|
|
31267
|
+
// src/assembly/webgpu-renderer.ts
|
|
31268
|
+
function adaptMipmapShaderModuleFactory(factory) {
|
|
31269
|
+
if (factory === void 0) return void 0;
|
|
31270
|
+
return (device, descriptor) => factory(device, descriptor);
|
|
31271
|
+
}
|
|
30451
31272
|
var nextDerivedSystemId = 0;
|
|
30452
31273
|
async function tryCreateWebGPURenderer(canvas, options, pack, bundler) {
|
|
30453
31274
|
const importTransport = bundler?.importTransport;
|
|
@@ -31333,14 +32154,17 @@ async function makeWebGPURenderer(internals) {
|
|
|
31333
32154
|
const viewOnlyLayout = bindingContract === "view-only" ? getOrBuildViewOnlyMaterialPipelineLayout() : null;
|
|
31334
32155
|
const viewAndSceneDepthLayout = bindingContract === "view-and-scene-depth" ? getOrBuildViewAndSceneDepthMaterialPipelineLayout() : null;
|
|
31335
32156
|
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
|
-
})();
|
|
32157
|
+
const materialShaderLookup = materialShaderId === void 0 ? void 0 : getShader().findMaterialArtifact(materialShaderId);
|
|
32158
|
+
const materialShaderSource = materialShaderLookup?.ok ? materialShaderLookup.value.source : void 0;
|
|
32159
|
+
const vertexInputContract = materialShaderId === void 0 ? "render-material" : materialShaderSource !== void 0 ? resolveMaterialShaderVertexInputContract(materialShaderSource) : "render-material";
|
|
31340
32160
|
const currentState = currentPipelineState();
|
|
31341
32161
|
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
32162
|
if (pipelineLayout === null) return null;
|
|
31343
|
-
const
|
|
32163
|
+
const currentMaterialUvSetCounts = currentMaterialShaderUvSetCounts();
|
|
32164
|
+
const resolvedUvSetCount = materialShaderId !== void 0 ? currentMaterialUvSetCounts.get(materialShaderId) ?? (materialShaderSource !== void 0 ? resolveMaterialShaderUvSetCount(
|
|
32165
|
+
materialShaderSource,
|
|
32166
|
+
currentMaterialUvSetCounts.get(materialShaderId)
|
|
32167
|
+
) : void 0) : void 0;
|
|
31344
32168
|
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
32169
|
deriveVertexBufferLayoutFromProjection(
|
|
31346
32170
|
vertexLayoutProjection,
|
|
@@ -31382,7 +32206,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31382
32206
|
...layoutKind === "pbr-skin" ? { layoutKind } : {}
|
|
31383
32207
|
};
|
|
31384
32208
|
};
|
|
31385
|
-
const buildAndCachePipeline = (cacheKey, entry, label, moduleLabel, isHdr, renderState, topology, stripIndexFormat, variantSet, passKind = "forward", materialShaderId, meshAttributes, sampleCount = 1, colorFormatOverride, depthFormatOverride, vertexLayout, vertexLayoutProjection, shaderModuleMode, layoutKindOverride, additionalColorFormats) => {
|
|
32209
|
+
const buildAndCachePipeline = (cacheKey, entry, label, moduleLabel, isHdr, renderState, topology, stripIndexFormat, variantSet, passKind = "forward", materialShaderId, meshAttributes, sampleCount = 1, colorFormatOverride, depthFormatOverride, vertexLayout, vertexLayoutProjection, shaderModuleMode, layoutKindOverride, additionalColorFormats, vertexEntry, authoredFragmentEntry) => {
|
|
31386
32210
|
const group2Contract = resolvePipelineGroup2Contract(entry.source);
|
|
31387
32211
|
const ctx = buildPipelineContext(
|
|
31388
32212
|
variantSet,
|
|
@@ -31398,7 +32222,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31398
32222
|
const currentState = currentPipelineState();
|
|
31399
32223
|
if (currentState === null) return null;
|
|
31400
32224
|
const ldrColorFormat = colorFormatOverride ?? currentState.colorAttachmentFormat;
|
|
31401
|
-
const fragmentEntry = isHdr && (materialShaderId === "forgeax::sprite" || materialShaderId === "forgeax::sprite-lit") ? "fs_main_hdr" : void 0;
|
|
32225
|
+
const fragmentEntry = authoredFragmentEntry ?? (isHdr && (materialShaderId === "forgeax::sprite" || materialShaderId === "forgeax::sprite-lit") ? "fs_main_hdr" : void 0);
|
|
31402
32226
|
const built = buildPipelineForMaterialShader(
|
|
31403
32227
|
cacheKey,
|
|
31404
32228
|
// The catalog entry is projected into the material-shader entry shape.
|
|
@@ -31427,8 +32251,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31427
32251
|
topology,
|
|
31428
32252
|
...topology === "line-strip" || topology === "triangle-strip" ? { stripIndexFormat: stripIndexFormat ?? "uint32" } : {}
|
|
31429
32253
|
} : void 0,
|
|
31430
|
-
|
|
31431
|
-
// vertexEntry — default vs_main
|
|
32254
|
+
vertexEntry,
|
|
31432
32255
|
fragmentEntry,
|
|
31433
32256
|
void 0,
|
|
31434
32257
|
// defines — none
|
|
@@ -31448,13 +32271,29 @@ async function makeWebGPURenderer(internals) {
|
|
|
31448
32271
|
);
|
|
31449
32272
|
return built.value;
|
|
31450
32273
|
};
|
|
31451
|
-
const getMaterialShaderPipeline = (materialShaderId, isHdr, renderState, topology, indexFormat, variantSet, passKind = "forward", meshAttributes, sampleCount = 1, colorFormatOverride, shaderUvSetCount, depthFormatOverride, vertexLayout, vertexLayoutProjection, shaderModuleMode = "validated", layoutKindOverride, additionalColorFormats) => {
|
|
32274
|
+
const getMaterialShaderPipeline = (materialShaderId, isHdr, renderState, topology, indexFormat, variantSet, passKind = "forward", meshAttributes, sampleCount = 1, colorFormatOverride, shaderUvSetCount, depthFormatOverride, vertexLayout, vertexLayoutProjection, shaderModuleMode = "validated", layoutKindOverride, additionalColorFormats, vertexEntry, fragmentEntry) => {
|
|
31452
32275
|
const currentState = currentPipelineState();
|
|
31453
32276
|
const ldrColorFormat = colorFormatOverride ?? (currentState !== null ? currentState.colorAttachmentFormat : "bgra8unorm-srgb");
|
|
31454
|
-
const
|
|
31455
|
-
|
|
31456
|
-
|
|
32277
|
+
const pipelineShaderId = resolveMaterialShaderBackendArtifactKey(
|
|
32278
|
+
materialShaderId,
|
|
32279
|
+
internals.device.caps.backendKind,
|
|
32280
|
+
assets.getMaterialArtifact(materialShaderId)
|
|
32281
|
+
);
|
|
32282
|
+
const materialShaderLookup = getShader().findMaterialArtifact(pipelineShaderId);
|
|
32283
|
+
const materialShaderSource = materialShaderLookup.ok ? materialShaderLookup.value.source : void 0;
|
|
32284
|
+
const currentMaterialUvSetCounts = currentMaterialShaderUvSetCounts();
|
|
32285
|
+
const materialUvSetCount = resolveMaterialShaderUvSetCount(
|
|
32286
|
+
materialShaderSource,
|
|
32287
|
+
currentMaterialUvSetCounts.get(pipelineShaderId)
|
|
32288
|
+
);
|
|
32289
|
+
if (materialUvSetCount !== void 0) {
|
|
32290
|
+
currentMaterialUvSetCounts.set(pipelineShaderId, materialUvSetCount);
|
|
32291
|
+
}
|
|
32292
|
+
const resolvedUvSetCount = shaderUvSetCount ?? materialUvSetCount;
|
|
32293
|
+
const manifestEntry = findMaterialShaderManifestEntry(pipelineShaderId);
|
|
32294
|
+
const resolvedVariantSet = variantSet === void 0 && (pipelineShaderId === "forgeax::sprite" || pipelineShaderId === "forgeax::sprite-lit") ? void 0 : resolveCachedMaterialShaderVariantSet(variantSet, manifestEntry);
|
|
31457
32295
|
let effectiveVariantSet = normalizeMaterialShaderVariantSet(resolvedVariantSet, manifestEntry);
|
|
32296
|
+
if (manifestEntry === void 0) effectiveVariantSet = void 0;
|
|
31458
32297
|
if (vertexLayoutProjection === void 0 && manifestEntry?.variants.some((variant) => "VERTEX_COLOR_AVAILABLE" in variant.defines)) {
|
|
31459
32298
|
if (effectiveVariantSet === "") {
|
|
31460
32299
|
const noColorVariant = manifestEntry.variants.find(
|
|
@@ -31470,7 +32309,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31470
32309
|
);
|
|
31471
32310
|
}
|
|
31472
32311
|
}
|
|
31473
|
-
if (manifestEntry !== void 0 && !
|
|
32312
|
+
if (manifestEntry !== void 0 && !pipelineShaderId.startsWith("forgeax::") && effectiveVariantSet !== void 0 && effectiveVariantSet !== "") {
|
|
31474
32313
|
const declaredAxes = /* @__PURE__ */ new Set();
|
|
31475
32314
|
for (const variant of manifestEntry.variants) {
|
|
31476
32315
|
for (const axis of Object.keys(variant.defines)) declaredAxes.add(axis);
|
|
@@ -31481,7 +32320,13 @@ async function makeWebGPURenderer(internals) {
|
|
|
31481
32320
|
const colorFormat = isHdr ? "rgba16float" : ldrColorFormat;
|
|
31482
32321
|
const isDepthOnlyPass = passKindPolicyTable[passKind]?.shape === "depth-only";
|
|
31483
32322
|
const spec = {
|
|
31484
|
-
shader: {
|
|
32323
|
+
shader: {
|
|
32324
|
+
id: pipelineShaderId,
|
|
32325
|
+
passKind,
|
|
32326
|
+
variantSet: effectiveVariantSet,
|
|
32327
|
+
...vertexEntry === void 0 ? {} : { vertexEntry },
|
|
32328
|
+
...fragmentEntry === void 0 ? {} : { fragmentEntry }
|
|
32329
|
+
},
|
|
31485
32330
|
attachments: {
|
|
31486
32331
|
colorFormats: additionalColorFormats === void 0 ? colorFormatsForPassKind(passKind, colorFormat) : [colorFormat, ...additionalColorFormats],
|
|
31487
32332
|
depthFormat: isDepthOnlyPass ? "depth32float" : depthFormatOverride === null ? void 0 : depthFormatOverride ?? "depth24plus-stencil8",
|
|
@@ -31503,12 +32348,12 @@ async function makeWebGPURenderer(internals) {
|
|
|
31503
32348
|
const cached = currentPipelineCacheState().materialShaderPipelineCache.get(cacheKey);
|
|
31504
32349
|
if (cached !== void 0) return cached;
|
|
31505
32350
|
if (pipelineState === null) return null;
|
|
31506
|
-
const lookup = getShader().findMaterialArtifact(
|
|
32351
|
+
const lookup = getShader().findMaterialArtifact(pipelineShaderId);
|
|
31507
32352
|
if (!lookup.ok) {
|
|
31508
32353
|
if (shouldDeferMissingPreparedMaterialShader(vertexLayout)) {
|
|
31509
32354
|
return null;
|
|
31510
32355
|
}
|
|
31511
|
-
if (renderState === void 0 && !allowsUnlitPreparedFallback(depthFormatOverride, vertexLayout,
|
|
32356
|
+
if (renderState === void 0 && !allowsUnlitPreparedFallback(depthFormatOverride, vertexLayout, pipelineShaderId)) {
|
|
31512
32357
|
return null;
|
|
31513
32358
|
}
|
|
31514
32359
|
if (renderState === void 0) {
|
|
@@ -31517,7 +32362,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31517
32362
|
return buildAndCachePipeline(
|
|
31518
32363
|
cacheKey,
|
|
31519
32364
|
unlitLookup.value,
|
|
31520
|
-
`pbr-pipeline-prepared-${
|
|
32365
|
+
`pbr-pipeline-prepared-${pipelineShaderId}`,
|
|
31521
32366
|
// Reuse the eagerly compiled engine unlit module. The adapter cache
|
|
31522
32367
|
// is seeded under this label during renderer readiness; a new label
|
|
31523
32368
|
// would keep color-only prepared passes in perpetual warm-up.
|
|
@@ -31545,7 +32390,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31545
32390
|
return buildAndCachePipeline(
|
|
31546
32391
|
cacheKey,
|
|
31547
32392
|
{ source: pbrEntry.wgsl},
|
|
31548
|
-
`pbr-pipeline-fallback-${
|
|
32393
|
+
`pbr-pipeline-fallback-${pipelineShaderId}${isHdr ? "-hdr" : ""}`,
|
|
31549
32394
|
// w16-b: module identity is the fallback PBR source, stable across
|
|
31550
32395
|
// topology / renderState / HDR (all baked into the PSO) so every
|
|
31551
32396
|
// variant reuses one compiled module.
|
|
@@ -31579,7 +32424,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31579
32424
|
// layout resolution so buildPipelineContext derives the layout that
|
|
31580
32425
|
// matches the compiled module. Skin keeps its
|
|
31581
32426
|
// own id so the pbr-skin fail-fast (null layout) is preserved.
|
|
31582
|
-
|
|
32427
|
+
pipelineShaderId === SKIN_MATERIAL_SHADER_ID ? pipelineShaderId : "forgeax::default-standard-pbr",
|
|
31583
32428
|
// feat-20260611-fox-skinning-vertex-attribute-chain M4 / w16 (D-4):
|
|
31584
32429
|
// forward meshAttributes through the fallback path so the pbr-skin
|
|
31585
32430
|
// layout chain reads from the deriveVertexBufferLayout SSOT here too.
|
|
@@ -31598,7 +32443,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31598
32443
|
if (effectiveVariantSet !== void 0) {
|
|
31599
32444
|
const registry = getShader();
|
|
31600
32445
|
for (const msEntry of registry.materialShaderManifestEntries()) {
|
|
31601
|
-
if (msEntry.identifier ===
|
|
32446
|
+
if (msEntry.identifier === pipelineShaderId) {
|
|
31602
32447
|
const variant = findVariantByKey(msEntry, effectiveVariantSet);
|
|
31603
32448
|
if (variant) {
|
|
31604
32449
|
shaderEntry = {
|
|
@@ -31615,7 +32460,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31615
32460
|
return buildAndCachePipeline(
|
|
31616
32461
|
cacheKey,
|
|
31617
32462
|
shaderEntry,
|
|
31618
|
-
`pbr-pipeline-${
|
|
32463
|
+
`pbr-pipeline-${pipelineShaderId}${isHdr ? "-hdr" : ""}${passKindLabelSegment}`,
|
|
31619
32464
|
// feat-20260609 M4 / w31: when variantSet is non-empty, the module identity
|
|
31620
32465
|
// includes the variant key so URP (STORAGE_BUFFER_AVAILABLE=true) and HDRP
|
|
31621
32466
|
// (CLUSTER_FORWARD_AVAILABLE=true+STORAGE_BUFFER_AVAILABLE=true) variants
|
|
@@ -31628,7 +32473,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31628
32473
|
// case is intentional (parallel to the cache key's `:variant:`
|
|
31629
32474
|
// empty-tail segment); module identity stays a function of the
|
|
31630
32475
|
// exact variantSet string.
|
|
31631
|
-
effectiveVariantSet !== void 0 ? `module-${
|
|
32476
|
+
effectiveVariantSet !== void 0 ? `module-${pipelineShaderId}#${effectiveVariantSet}` : `module-${pipelineShaderId}`,
|
|
31632
32477
|
isHdr,
|
|
31633
32478
|
renderState,
|
|
31634
32479
|
topology,
|
|
@@ -31644,7 +32489,7 @@ async function makeWebGPURenderer(internals) {
|
|
|
31644
32489
|
// bug-20260611-skin-pipeline-layout: thread the registered materialShaderId
|
|
31645
32490
|
// so buildPipelineContext can resolve LayoutKind='pbr-skin' for the skin
|
|
31646
32491
|
// shader (2-entry mesh-array BGL).
|
|
31647
|
-
|
|
32492
|
+
pipelineShaderId,
|
|
31648
32493
|
// feat-20260611-fox-skinning-vertex-attribute-chain M4 / w16 (D-4):
|
|
31649
32494
|
// forward meshAttributes so the pbr-skin path's vertex buffer layout
|
|
31650
32495
|
// is derived via the SSOT (deriveVertexBufferLayout). For URP/HDRP
|
|
@@ -31658,7 +32503,9 @@ async function makeWebGPURenderer(internals) {
|
|
|
31658
32503
|
vertexLayoutProjection,
|
|
31659
32504
|
shaderModuleMode,
|
|
31660
32505
|
layoutKindOverride,
|
|
31661
|
-
additionalColorFormats
|
|
32506
|
+
additionalColorFormats,
|
|
32507
|
+
vertexEntry,
|
|
32508
|
+
fragmentEntry
|
|
31662
32509
|
);
|
|
31663
32510
|
};
|
|
31664
32511
|
const getMaterialShaderPipelineEntry = (...args) => {
|
|
@@ -31989,6 +32836,22 @@ async function makeWebGPURenderer(internals) {
|
|
|
31989
32836
|
featureDiagnostics: internals.featureHost?.diagnostics() ?? Object.freeze([]),
|
|
31990
32837
|
frustumStats: Object.freeze({ ...renderSystem.frustumStats }),
|
|
31991
32838
|
visibilityStats: Object.freeze({ ...renderSystem.visibilityStats }),
|
|
32839
|
+
instanceCollections: Object.freeze(
|
|
32840
|
+
renderSystem.instanceCollectionsInspection.map(
|
|
32841
|
+
(collection) => Object.freeze({
|
|
32842
|
+
...collection,
|
|
32843
|
+
uploadRanges: Object.freeze(
|
|
32844
|
+
collection.uploadRanges.map((range) => Object.freeze({ ...range }))
|
|
32845
|
+
),
|
|
32846
|
+
...collection.error === void 0 ? {} : {
|
|
32847
|
+
error: Object.freeze({
|
|
32848
|
+
...collection.error,
|
|
32849
|
+
detail: Object.freeze({ ...collection.error.detail })
|
|
32850
|
+
})
|
|
32851
|
+
}
|
|
32852
|
+
})
|
|
32853
|
+
)
|
|
32854
|
+
),
|
|
31992
32855
|
renderScene: renderSystem.renderScene,
|
|
31993
32856
|
reflectionProbes: renderSystem.reflectionProbes,
|
|
31994
32857
|
ssrDependencies: renderSystem.ssrDependencies,
|