@forgeax/engine-render 0.1.19 → 0.1.20
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/dist/.tsbuildinfo +1 -1
- package/dist/assembly/factory.d.ts +16 -5
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/{chunk-RJRUS55L.mjs → chunk-4XINDLAY.mjs} +267 -186
- package/dist/chunk-4XINDLAY.mjs.map +1 -0
- package/dist/{chunk-YTQ5C7YQ.mjs → chunk-CDTWTHZR.mjs} +176 -8
- package/dist/chunk-CDTWTHZR.mjs.map +1 -0
- package/dist/{chunk-IPXCABEP.mjs → chunk-M2MP4ZOU.mjs} +2 -2
- package/dist/chunk-M2MP4ZOU.mjs.map +1 -0
- package/dist/{chunk-LOSO4CTV.mjs → chunk-TBQJOK2L.mjs} +67 -3
- package/dist/chunk-TBQJOK2L.mjs.map +1 -0
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/spot-light.d.ts +12 -0
- package/dist/components/spot-light.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +2281 -164
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -2
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/errors/render.d.ts +69 -1
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/gpu-usage.d.ts +2 -0
- package/dist/gpu-usage.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/internal.mjs +1 -1
- package/dist/light-buffer-layout.d.ts +20 -12
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +6 -3
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +13 -0
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/record/frame-lighting.d.ts +2 -0
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +37 -1
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +3 -2
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-timing.d.ts +32 -0
- package/dist/record/gpu-timing.d.ts.map +1 -0
- package/dist/record/main-pass-material.d.ts +1 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +5 -1
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +11 -3
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/render-contract.d.ts +66 -1
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-data.d.ts +10 -6
- package/dist/render-data.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +36 -0
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +55 -3
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +7 -1
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer-inspect.d.ts +29 -0
- package/dist/renderer-inspect.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +44 -0
- package/dist/temporal/frame.d.ts.map +1 -0
- package/dist/temporal/index.mjs +3 -3
- package/dist/typed-render-graph-primitives.d.ts +6 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-atlas.d.ts +10 -0
- package/dist/typed-shadow-atlas.d.ts.map +1 -0
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/capability.d.ts +57 -0
- package/dist/volume/capability.d.ts.map +1 -0
- package/dist/volume/component.d.ts +61 -0
- package/dist/volume/component.d.ts.map +1 -0
- package/dist/volume/extract.d.ts +11 -0
- package/dist/volume/extract.d.ts.map +1 -0
- package/dist/volume/inspection.d.ts +38 -0
- package/dist/volume/inspection.d.ts.map +1 -0
- package/dist/volume/passes.d.ts +38 -0
- package/dist/volume/passes.d.ts.map +1 -0
- package/dist/volume/recovery.d.ts +38 -0
- package/dist/volume/recovery.d.ts.map +1 -0
- package/dist/volume/resources.d.ts +57 -0
- package/dist/volume/resources.d.ts.map +1 -0
- package/dist/volume/temporal.d.ts +35 -0
- package/dist/volume/temporal.d.ts.map +1 -0
- package/package.json +20 -20
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -14
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
- package/src/__tests__/render-error-code-owner.test-d.ts +5 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +28 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +1 -1
- package/src/__tests__/skinned-shadow-caster.test.ts +21 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +7 -5
- package/src/__tests__/volume-optics-oracle.unit.test.ts +85 -0
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +655 -0
- package/src/__tests__/volumetric-fog-component.unit.test.ts +71 -0
- package/src/__tests__/volumetric-fog-composite-stage-readback.dawn.test.ts +376 -0
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +51 -0
- package/src/__tests__/volumetric-fog-inspection.unit.test.ts +77 -0
- package/src/__tests__/volumetric-fog-light-capability.unit.test.ts +19 -0
- package/src/__tests__/volumetric-fog-light-consumers.integration.test.ts +18 -0
- package/src/__tests__/volumetric-fog-light-errors.unit.test.ts +17 -0
- package/src/__tests__/volumetric-fog-light-topology.unit.test.ts +21 -0
- package/src/__tests__/volumetric-fog-light-transaction.integration.test.ts +53 -0
- package/src/__tests__/volumetric-fog-m9-watcher.integration.test.ts +27 -0
- package/src/__tests__/volumetric-fog-point-light-owner.integration.test.ts +44 -0
- package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +49 -0
- package/src/__tests__/volumetric-fog-point-spot-contract.unit.test.ts +28 -0
- package/src/__tests__/volumetric-fog-point-spot-lkg.integration.test.ts +65 -0
- package/src/__tests__/volumetric-fog-point-spot-selection.integration.test.ts +49 -0
- package/src/__tests__/volumetric-fog-point-spot-temporal.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-projector-contract.unit.test.ts +22 -0
- package/src/__tests__/volumetric-fog-projector-inspection.unit.test.ts +12 -0
- package/src/__tests__/volumetric-fog-projector-surface-volume.integration.test.ts +11 -0
- package/src/__tests__/volumetric-fog-projector-transaction.integration.test.ts +26 -0
- package/src/__tests__/volumetric-fog-recovery.integration.test.ts +47 -0
- package/src/__tests__/volumetric-fog-selected-light-resolution.integration.test.ts +63 -0
- package/src/__tests__/volumetric-fog-spot-closure.integration.test.ts +26 -0
- package/src/__tests__/volumetric-fog-spot-contract.test-d.ts +21 -0
- package/src/__tests__/volumetric-fog-spot-contract.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +14 -0
- package/src/__tests__/volumetric-fog-spot-optics.integration.test.ts +29 -0
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +550 -0
- package/src/__tests__/volumetric-fog-temporal-selected-light.unit.test.ts +33 -0
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +45 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +237 -0
- package/src/__tests__/volumetric-fog-transparent.integration.test.ts +27 -0
- package/src/assembly/factory.ts +271 -15
- package/src/components/light-helpers.ts +4 -0
- package/src/components/spot-light.ts +22 -3
- package/src/device/gpu-residency.ts +168 -58
- package/src/errors/render.ts +119 -1
- package/src/gpu-usage.ts +2 -0
- package/src/index.ts +38 -1
- package/src/light-buffer-layout.ts +59 -26
- package/src/pbr-pipeline.ts +33 -10
- package/src/pipeline/standard-forward-lane.ts +20 -0
- package/src/pipeline/standard-pipeline.ts +20 -0
- package/src/pipeline/standard-profile.ts +23 -0
- package/src/record/frame-lighting.ts +103 -89
- package/src/record/frame-snapshot.ts +41 -1
- package/src/record/frame-targets.ts +6 -2
- package/src/record/frame.ts +908 -5
- package/src/record/gpu-timing.ts +224 -0
- package/src/record/main-pass-material.ts +6 -2
- package/src/record/render-context.ts +5 -0
- package/src/record/shadow-pass.ts +87 -38
- package/src/record/typed-frame-graph.ts +143 -8
- package/src/render-contract.ts +72 -0
- package/src/render-data.ts +50 -22
- package/src/render-pipeline.ts +44 -0
- package/src/render-system-extract.ts +329 -3
- package/src/render-system.ts +79 -0
- package/src/renderer-inspect.ts +66 -0
- package/src/scene/render-scene.ts +2 -0
- package/src/temporal/frame.ts +128 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +2 -3
- package/src/typed-render-graph-primitives.ts +32 -2
- package/src/typed-shadow-atlas.ts +17 -0
- package/src/typed-shadow-passes.ts +6 -5
- package/src/volume/capability.ts +173 -0
- package/src/volume/component.ts +110 -0
- package/src/volume/extract.ts +21 -0
- package/src/volume/inspection.ts +78 -0
- package/src/volume/passes.ts +680 -0
- package/src/volume/recovery.ts +86 -0
- package/src/volume/resources.ts +236 -0
- package/src/volume/temporal.ts +89 -0
- package/dist/chunk-IPXCABEP.mjs.map +0 -1
- package/dist/chunk-LOSO4CTV.mjs.map +0 -1
- package/dist/chunk-RJRUS55L.mjs.map +0 -1
- package/dist/chunk-YTQ5C7YQ.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/gpu-texture-usage.ts","../src/render-pipeline.ts","../src/cluster-binner.ts","../src/gpu-stage.ts","../src/gpu-usage.ts","../src/light-buffer-layout.ts","../src/pbr-pipeline.ts","../src/pipeline-spec.ts","../src/record/mesh-ssbo.ts","../src/ssao-buffers.ts","../src/hdrp-buffers.ts","../src/shadow-atlas.ts","../src/post-process-errors.ts","../src/ssao-config.ts","../src/record/helpers.ts","../src/record/view-ubo.ts","../src/record/frame-lighting.ts","../src/ibl/IblPipelineCache.ts","../src/points-lines/record.ts","../src/gpu-resource.ts","../src/ibl/skylight-bind-group.ts","../src/render-data.ts","../src/record/render-context.ts","../src/record/main-pass-material.ts","../src/record/main-pass-geometry.ts","../src/record/main-pass-sprite-draws.ts","../src/systems/pass-selector.ts","../src/record/shadow-pass.ts","../src/record/main-pass.ts","../src/record/skybox-post-pass.ts","../src/fullscreen-post-process-pass.ts","../src/render-graph-primitives.ts","../src/temporal/gpu.ts","../src/typed-render-graph-primitives.ts","../src/temporal/standard-scene-data.ts"],"names":["ok","err","parts","cache","RhiError","mat4","vec3","clusterGrid","gridX","gridY","gridZ","clusterGridBuf","lightIndexListBuf","hdrpLights","projMatrix","viewMatrix","toShared","deriveVertexLayoutProjection","bytesPerRow","blockBytesPerRow","derive","resolveAssetHandle","DEFAULT_STANDARD_PBR_PARAM_SCHEMA","shadowPipeline","buildPerSubmeshMaterialBg"],"mappings":"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","file":"chunk-RJRUS55L.mjs","sourcesContent":["// @forgeax/engine-runtime - render package texture usage values.\n//\n// Keep the WebGPU bit values in one dependency-free owner because render\n// package descriptor and graph builders also run against null and WebGL2-\n// compatible RHI shims where the browser's GPUTextureUsage global is absent.\n\nexport const GPU_TEXTURE_USAGE_COPY_SRC = 0x01;\nexport const GPU_TEXTURE_USAGE_COPY_DST = 0x02;\nexport const GPU_TEXTURE_USAGE_TEXTURE_BINDING = 0x04;\nexport const GPU_TEXTURE_USAGE_RENDER_ATTACHMENT = 0x10;\nexport const GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING =\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT | GPU_TEXTURE_USAGE_TEXTURE_BINDING;\n","// @forgeax/engine-render - typed render-pipeline topology contract.\n//\n// `RenderPipeline` is the typed topology contribution used by the Standard host.\n// The host owns the single active pipeline identity and its lifecycle; producers\n// contribute graph declarations through this interface instead of publishing a\n// second renderer authority.\n//\n// Naming note (requirements line 155): `RenderPipeline` here is the forgeax engine\n// concept name. The RHI GPU `RenderPipeline` handle (`@forgeax/engine-rhi`) is a\n// separate, internal opaque-handle type distinguished by module path (AGENTS.md RHI\n// form rules - \"opaque handles distinguished by module path\"); it is not exposed to\n// AI users. Files importing both alias the RHI one locally.\n//\n// Pipelines declare topology once through a typed builder. The renderer compiles,\n// executes, retires, finishes, and submits the resulting graph.\n\nimport type {\n ColorValueDomain,\n GraphAccess,\n GraphResourceResolver,\n GraphTexture,\n GraphTextureDescriptor,\n GraphTextureView,\n GraphTextureViewDescriptor,\n RenderGraphBuilder,\n RenderGraphError,\n RenderGraphFrame,\n} from '@forgeax/engine-render-graph';\nimport type {\n BindGroup,\n RhiCaps,\n RhiError,\n RhiRenderPassEncoder,\n TextureFormat,\n} from '@forgeax/engine-rhi';\nimport { ok, type Result } from '@forgeax/engine-types';\nimport type { Tonemap } from './components/camera';\nimport type { RenderError } from './errors/render';\nimport type { RenderFeatureTargetKind } from './features/targets';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n} from './gpu-texture-usage';\nimport { STANDARD_POST_STAGE_NAMES, type StandardProfile } from './pipeline/standard-profile';\nimport type { SurfaceProfile } from './record/render-context';\nimport type { RenderPipelineContext } from './render-contract';\nimport type { TransmissionDemand } from './transmission/projection';\n\nexport type { RenderPipelineContext } from './render-contract';\n\nexport type RenderColorDomain = 'linearHdr' | 'linearLdr' | 'displayEncoded';\n\nexport interface ToneOutputContract {\n readonly input: RenderColorDomain;\n readonly toneMapped: boolean;\n readonly mapped: 'linearLdr';\n readonly finalCapture: 'displayEncoded';\n readonly exposureStage: 'linearHdr' | 'none';\n}\n\nexport type RenderPostStageName = (typeof STANDARD_POST_STAGE_NAMES)[number];\nexport type RenderPostDomainStage = readonly [\n RenderPostStageName,\n ColorValueDomain,\n ColorValueDomain,\n];\n\n/**\n * Single post-stage domain contract shared by the Standard lighting lanes.\n * The selected scene domain for transparent geometry is explicit; every later\n * stage follows the same linear blend, output-transform, anti-alias, post-effect, and present sequence.\n */\nexport function resolvePostColorDomainContract(\n sceneDomain: 'linear-ldr' | 'linear-hdr',\n): readonly RenderPostDomainStage[] {\n const scene: ColorValueDomain = sceneDomain;\n const [transparentBlend, bloom, outputTransform, fxaa, postEffect, present] =\n STANDARD_POST_STAGE_NAMES;\n return [\n [transparentBlend, scene, scene],\n [bloom, 'linear-hdr', 'linear-hdr'],\n [outputTransform, scene, 'display-encoded'],\n [fxaa, 'display-encoded', 'display-encoded'],\n [postEffect, 'display-encoded', 'display-encoded'],\n [present, 'display-encoded', 'display-encoded'],\n ];\n}\n\n/**\n * Describe the built-in output stages without moving color-domain policy into\n * a mode name. Tone-enabled cameras render HDR, apply exposure and the\n * selected curve in the fullscreen pass, then reach the encoded surface.\n */\nexport function resolveToneOutputContract(tonemap: Tonemap): ToneOutputContract {\n if (tonemap === 'none') {\n return {\n input: 'linearLdr',\n toneMapped: false,\n mapped: 'linearLdr',\n finalCapture: 'displayEncoded',\n exposureStage: 'none',\n };\n }\n return {\n input: 'linearHdr',\n toneMapped: true,\n mapped: 'linearLdr',\n finalCapture: 'displayEncoded',\n exposureStage: 'linearHdr',\n };\n}\n\n/** Stable facts that may change graph topology and therefore its compiled identity. */\nexport interface RenderPipelineTopology {\n readonly pipelineId: string;\n readonly standardProfile?: StandardProfile | undefined;\n readonly config: import('@forgeax/engine-types').RenderPipelineAsset['config'];\n /**\n * The record stage had no Camera and injected the synthetic clear-only\n * snapshot. Keep that fact explicit so a normal no-tone Camera still uses\n * the float Output Transform while the empty-scene contract can write its\n * clear directly to the surface.\n */\n readonly clearOnly?: boolean | undefined;\n readonly surface: {\n readonly width: number;\n readonly height: number;\n readonly storageFormat: import('@forgeax/engine-rhi').TextureFormat;\n readonly viewFormat: import('@forgeax/engine-rhi').TextureFormat;\n readonly profile?: SurfaceProfile | undefined;\n };\n readonly camera: Pick<RenderPipelineContext['camera'], 'tonemap' | 'antialias' | 'bloom'>;\n readonly temporal?: {\n readonly taa: boolean;\n readonly motionBlur: boolean;\n };\n readonly shadow: {\n readonly mapSize: number;\n readonly cascadeCount: 1 | 2 | 3 | 4;\n readonly pointCount: number;\n readonly pointFaceSize: number;\n readonly spotCount: number;\n };\n readonly lane: {\n readonly compute: boolean;\n readonly storageBuffer: boolean;\n readonly multisample: boolean;\n readonly maxColorAttachments: number;\n };\n readonly featureTopologySignature: string;\n readonly gpuDrivenTopologySignature: string;\n /** Internal graph fact; renderer callers do not configure transmission demand. */\n readonly transmissionDemand?: TransmissionDemand | undefined;\n}\n\nexport interface RenderPipelineFrame extends RenderPipelineContext, RenderGraphFrame {}\n\nexport interface RenderPipelineTarget {\n readonly texture: GraphTexture;\n readonly view: GraphTextureView;\n readonly format: TextureFormat;\n readonly sampleCount: 1 | 4;\n readonly domain?: ColorValueDomain | undefined;\n readonly resolveTarget?: GraphTextureView | undefined;\n}\n\nexport function createRenderPipelineTarget(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n label: string,\n descriptor: GraphTextureDescriptor,\n viewDescriptor: GraphTextureViewDescriptor = {},\n): Result<RenderPipelineTarget, RenderGraphError> {\n const texture = graph.createTexture(label, descriptor);\n if (!texture.ok) return texture;\n const view = graph.view(texture.value, { label: `${label}.view`, ...viewDescriptor });\n if (!view.ok) return view;\n return ok({\n texture: texture.value,\n view: view.value,\n format: viewDescriptor.format ?? descriptor.format,\n sampleCount: descriptor.sampleCount === 4 ? 4 : 1,\n ...(descriptor.domain === undefined ? {} : { domain: descriptor.domain }),\n });\n}\n\nexport function importRenderPipelineSurface(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n topology: RenderPipelineTopology,\n): Result<\n { readonly display?: RenderPipelineTarget; readonly storage: RenderPipelineTarget },\n RenderGraphError\n> {\n const texture = graph.importTexture(\n 'surface',\n {\n format: topology.surface.storageFormat,\n size: 'surface',\n // The imported surface is the final encoded endpoint. Keeping this\n // semantic fact on the graph resource lets detached inspection project\n // from the compiled graph instead of re-inferring it from format names.\n domain: 'display-encoded',\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n (topology.surface.profile?.kind === 'raw-only' ? 0 : GPU_TEXTURE_USAGE_COPY_SRC),\n viewFormats: [\n ...(topology.surface.profile?.viewFormats ??\n (topology.surface.storageFormat === topology.surface.viewFormat\n ? []\n : [topology.surface.viewFormat])),\n ],\n },\n (frame) => frame.currentTexture,\n );\n if (!texture.ok) return texture;\n const display =\n topology.surface.profile?.hasDisplayEndpoint === false\n ? undefined\n : graph.importView(\n texture.value,\n { label: 'surface.display', format: topology.surface.viewFormat },\n (frame) => frame.view,\n );\n if (display !== undefined && !display.ok) return display;\n const storage = graph.importView(\n texture.value,\n { label: 'surface.storage', format: topology.surface.storageFormat },\n (frame) => {\n if (topology.surface.storageFormat === topology.surface.viewFormat) return frame.view;\n const resolved = frame.runtime.device.createTextureView(frame.currentTexture, {\n format: topology.surface.storageFormat,\n });\n if (!resolved.ok) throw resolved.error;\n return resolved.value;\n },\n );\n if (!storage.ok) return storage;\n return ok({\n ...(display === undefined\n ? {}\n : {\n display: {\n texture: texture.value,\n view: display.value,\n format: topology.surface.viewFormat,\n sampleCount: 1 as const,\n domain: 'display-encoded' as const,\n },\n }),\n storage: {\n texture: texture.value,\n view: storage.value,\n format: topology.surface.storageFormat,\n sampleCount: 1,\n domain: 'display-encoded',\n },\n });\n}\n\nexport interface RenderPipelineFeatureTarget {\n readonly kind: RenderFeatureTargetKind;\n readonly texture: GraphTexture;\n readonly view: GraphTextureView;\n readonly resolveTarget?: GraphTextureView | undefined;\n readonly format: TextureFormat;\n readonly sampleCount: 1 | 4;\n}\n\nexport interface RenderPipelineGpuDrivenProjection {\n readonly accesses: readonly GraphAccess[];\n encode(\n viewBindGroup: BindGroup,\n pass: RhiRenderPassEncoder,\n resources: GraphResourceResolver,\n ): void;\n}\n\nexport interface RenderPipelineBuildContext<FrameCtx extends RenderPipelineFrame> {\n readonly graph: RenderGraphBuilder<FrameCtx>;\n /**\n * Renderer-owned capability facts needed for admission decisions. The\n * Standard temporal producer must use the live device probe rather than\n * inferring rgba16float support from the selected surface format.\n */\n readonly capabilities?: Pick<RhiCaps, 'rgba16floatRenderable'>;\n /**\n * Renderer-owned TAA history targets. The graph sees only imported typed\n * targets; opaque RHI handles remain inside RenderFrameState.\n */\n readonly taaHistory?: {\n readonly currentColor: RenderPipelineTarget;\n readonly previousColor: RenderPipelineTarget;\n readonly currentTemporal: RenderPipelineTarget;\n readonly previousTemporal: RenderPipelineTarget;\n };\n /** Renderer-owned, prewarmed encoder for one graph mip level. */\n readonly encodeTransmissionMip?: (input: {\n readonly pass: RhiRenderPassEncoder;\n readonly frame: FrameCtx;\n readonly resources: GraphResourceResolver;\n readonly source: GraphTextureView;\n readonly destination: GraphTextureView;\n readonly level: number;\n }) => void;\n projectGpuDriven(target: {\n readonly format: TextureFormat;\n readonly sampleCount: 1 | 4;\n }): Result<RenderPipelineGpuDrivenProjection | undefined, RenderPipelineBuildError>;\n contributeFeatures(\n targets: readonly RenderPipelineFeatureTarget[],\n semanticTargets?: readonly RenderPipelineTarget[],\n namedTargets?: Readonly<Record<string, RenderPipelineTarget>>,\n ): Result<void, RenderPipelineBuildError>;\n /** Whether a producer-owned feature is installed for this graph build. */\n hasFeature?(identity: string): boolean;\n}\n\nexport type RenderPipelineBuildError = RenderGraphError | RenderError | RhiError;\n\n/**\n * Registrable, installable, hot-swappable render topology.\n *\n * `build` declares resources and passes only. The renderer owns compilation,\n * last-known-good replacement, execution, retirement, and the single frame submit.\n * Feature contributions enter through `contributeFeatures`, so compute-produced\n * buffers and later raster reads remain inside the same typed dependency graph.\n */\nexport interface RenderPipeline<FrameCtx extends RenderPipelineFrame = RenderPipelineFrame> {\n build(\n context: RenderPipelineBuildContext<FrameCtx>,\n topology: RenderPipelineTopology,\n ): Result<void, RenderPipelineBuildError>;\n}\n","// @forgeax/engine-runtime — CPU cluster-forward binner (M3 pure functions)\n// feat-20260608-cluster-lighting.\n//\n// Transplants Bevy's clustered_forward CPU math skeleton (research Finding 1)\n// from WGSL to pure TypeScript. Four internal pure functions ported from\n// Bevy cluster.wgsl lines 75-200:\n// cluster_space_object_aabb — sphere -> view-space NDC AABB\n// ndc_position_to_cluster — NDC coords -> cluster index (XY+Z)\n// calculate_sphere_cluster_bounds — AABB -> cluster-cell range\n// view_z_to_z_slice — log-z inverse mapping (idTech6 formula)\n//\n// Public surface:\n// bin(lights, view, proj, grid, near, far, clusterGrid, lightIndexList, capacity)\n// -> Result<writtenLightIndexCount, ClusterBinError>\n//\n// deriveCullingRadius(range, intensity, threshold) — D-8 +Infinity fallback\n//\n// Constraints:\n// D-3: pure function + Result<number, ClusterBinError> + out param + no throw\n// D-8: spot uses sphere proxy (radius=range)\n// D-binner: CPU main thread, no GPU compute / worker\n// OOS-4: cone-AABB tight culling deferred\n// AGENTS.md conventions: structured errors, never throw for expected failures\n//\n// Capacity: max 65536 light index list entries (hard cap, AC-24).\n// Grid: {x,y,z} each in [1, 64] integers (validated at install time).\n\nimport { type Mat4, type Vec3, vec3 } from '@forgeax/engine-math';\nimport { err, ok, type Result } from '@forgeax/engine-rhi';\n\n// ── types ──────────────────────────────────────────────────────────────────\n\nexport type ClusterBinErrorCode = 'index-overflow';\n\nexport interface ClusterBinError {\n readonly code: ClusterBinErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail: IndexOverflowDetail;\n}\n\nexport interface IndexOverflowDetail {\n readonly actual: number;\n readonly capacity: number;\n}\n\n/**\n * View-space NDC axis-aligned bounding box.\n * `min` and `max` are NDC coordinates clamped to [-1, 1] for XY;\n * Z may extend to projection-space depth values.\n */\nexport interface ClusterAabb {\n readonly min: Vec3;\n readonly max: Vec3;\n}\n\n/** Unsigned integer 3D cluster cell coordinate. */\nexport interface Uvec3 {\n readonly x: number;\n readonly y: number;\n readonly z: number;\n}\n\n/** Cluster cell range in the unsigned grid. */\nexport interface ClusterBounds {\n readonly min: Uvec3;\n readonly max: Uvec3;\n}\n\ntype MutableClusterBounds = {\n min: { x: number; y: number; z: number };\n max: { x: number; y: number; z: number };\n};\n\n/**\n * Reusable typed scratch for cluster-major output. The binner must emit one\n * contiguous light-index run per cluster, so counts and cursors replace the\n * per-frame `number[][]` staging lists without changing output order.\n */\nexport interface ClusterBinScratch {\n clusterCounts: Uint32Array;\n clusterCursors: Uint32Array;\n lightBounds: Int32Array;\n clusterDeltas: Int32Array;\n aabbOutput: ClusterAabb;\n boundsOutput: MutableClusterBounds;\n}\n\n/**\n * Selects the membership materialization owner after bounds and occupancy are\n * derived. The default keeps the existing CPU list writer; the WebGPU\n * producer uses the same CPU-owned scratch and leaves the ordered list to a\n * later compute pass.\n */\nexport interface ClusterBinOptions {\n readonly writeMembership?: boolean;\n}\n\nexport type ClusterBinProfilePhase =\n | 'light-bounds-and-occupancy'\n | 'light-bounds-and-occupancy/light-aabb'\n | 'light-bounds-and-occupancy/cluster-occupancy'\n | 'cluster-reserve'\n | 'light-index-write'\n | 'light-index-write/bounds-read'\n | 'light-index-write/cluster-write';\n\nexport type ClusterBinProfileRunner = <T>(phase: ClusterBinProfilePhase, action: () => T) => T;\n\nfunction runClusterBinProfilePhase<T>(\n runner: ClusterBinProfileRunner | undefined,\n phase: ClusterBinProfilePhase,\n action: () => T,\n): T {\n return runner === undefined ? action() : runner(phase, action);\n}\n\nexport function createClusterBinScratch(): ClusterBinScratch {\n return {\n clusterCounts: new Uint32Array(0),\n clusterCursors: new Uint32Array(0),\n lightBounds: new Int32Array(0),\n clusterDeltas: new Int32Array(0),\n aabbOutput: {\n min: vec3.create(0, 0, 0),\n max: vec3.create(0, 0, 0),\n },\n boundsOutput: {\n min: { x: 0, y: 0, z: 0 },\n max: { x: 0, y: 0, z: 0 },\n },\n };\n}\n\nfunction ensureScratchCapacity(\n scratch: ClusterBinScratch,\n clusterCount: number,\n lightCount: number,\n gridX: number,\n gridY: number,\n gridZ: number,\n): void {\n if (scratch.clusterCounts.length < clusterCount) {\n scratch.clusterCounts = new Uint32Array(clusterCount);\n scratch.clusterCursors = new Uint32Array(clusterCount);\n }\n if (scratch.lightBounds.length < lightCount * 6) {\n scratch.lightBounds = new Int32Array(lightCount * 6);\n }\n const differenceVolumeSize = (gridX + 1) * (gridY + 1) * (gridZ + 1);\n if (scratch.clusterDeltas.length < differenceVolumeSize) {\n scratch.clusterDeltas = new Int32Array(differenceVolumeSize);\n }\n}\n\n// ── deriveCullingRadius ────────────────────────────────────────────────────\n\n/**\n * Compute a culling radius for a punctual light.\n *\n * If `range` is finite, returns it verbatim (D-8 sphere proxy).\n * If `range === +Infinity`, derives a finite radius from the distance at which\n * the light's perceptible contribution drops below `threshold`.\n *\n * Formula: `sqrt(intensity / threshold)` gives the distance at which attenuation\n * = threshold (assuming E=1/r^2 falloff for point lights).\n * Cap to a conservative 1000 units to prevent overly large bounds.\n */\nexport function deriveCullingRadius(range: number, intensity: number, threshold = 0.001): number {\n if (Number.isFinite(range)) {\n return Math.max(0, range);\n }\n const derived = Math.sqrt(intensity / threshold);\n return Math.min(derived, 1000);\n}\n\n// ── view_z_to_z_slice ──────────────────────────────────────────────────────\n\n/**\n * Map view-space z (negative, camera-forward) to a cluster Z slice index.\n *\n * Implements the idTech6 inverse log-z formula (research §2):\n * slice = floor(log(-view_z / near) / log(far / near) * gridZ)\n *\n * Clamped to [0, gridZ - 1].\n */\nexport function viewZToZSlice(viewZ: number, gridZ: number, near: number, far: number): number {\n if (viewZ >= -near) {\n return 0;\n }\n const logFarOverNear = Math.log(far / near);\n const slice = Math.floor((Math.log(-viewZ / near) / logFarOverNear) * gridZ);\n if (slice < 0) return 0;\n if (slice >= gridZ) return gridZ - 1;\n return slice;\n}\n\n// ── cluster_space_object_aabb ───────────────────────────────────────────────\n\n/**\n * Compute view-space NDC AABB for a sphere (light culling proxy).\n *\n * Ported from Bevy `cluster_space_object_aabb` (cluster.wgsl lines 75-140).\n *\n * Steps:\n * 1. Transform sphere center to view space via view matrix.\n * 2. Expand by radius to get view-AABB corners.\n * 3. Project 4 key corners to NDC.\n * 4. Clamp to [-1, 1] for XY ; Z is kept as projected depth.\n */\nexport function clusterSpaceObjectAabb(\n center: Vec3,\n radius: number,\n view: Mat4,\n proj: Mat4,\n output?: ClusterAabb,\n): ClusterAabb {\n const result =\n output ??\n ({\n min: vec3.create(0, 0, 0),\n max: vec3.create(0, 0, 0),\n } satisfies ClusterAabb);\n const cx = center[0] ?? 0;\n const cy = center[1] ?? 0;\n const cz = center[2] ?? 0;\n\n const v00 = view[0] ?? 0;\n const v01 = view[1] ?? 0;\n const v02 = view[2] ?? 0;\n const v10 = view[4] ?? 0;\n const v11 = view[5] ?? 0;\n const v12 = view[6] ?? 0;\n const v20 = view[8] ?? 0;\n const v21 = view[9] ?? 0;\n const v22 = view[10] ?? 0;\n const v30 = view[12] ?? 0;\n const v31 = view[13] ?? 0;\n const v32 = view[14] ?? 0;\n\n const vx = v00 * cx + v10 * cy + v20 * cz + v30;\n const vy = v01 * cx + v11 * cy + v21 * cz + v31;\n const vz = v02 * cx + v12 * cy + v22 * cz + v32;\n\n const viewScaleX = Math.hypot(v00, v01, v02);\n const viewScaleY = Math.hypot(v10, v11, v12);\n const viewScaleZ = Math.hypot(v20, v21, v22);\n\n const rx = radius * viewScaleX;\n const ry = radius * viewScaleY;\n const rz = radius * viewScaleZ;\n\n const vMinX = vx - rx;\n const vMaxX = vx + rx;\n const vMinY = vy - ry;\n const vMaxY = vy + ry;\n // View-space camera looks down -Z, so view_z < 0 in front of camera. The\n // sphere's view-space z-extent is [vMinZ, vMaxZ] with vMinZ <= vMaxZ in raw\n // sign-order; vMinZ is the FARTHEST (most negative) edge, vMaxZ is the\n // NEAREST edge (could be positive if the sphere crosses the near plane).\n //\n // M4.5-followup: previously we did `minViewZ = max(vMinZ, -1e-5)` which\n // collapses the FAR edge of every visible light to view_z ~= 0, which the\n // log-z slice mapping then bins as slice 0. Result: every light only ever\n // wrote into slice 0/0/0 .. {gx-1}/{gy-1}/0 -- floor pixels at view_z=-3..-9\n // (slice 13..17) found 0 lights and rendered black. The clamp must guard\n // the NEAR edge (vMaxZ) instead so projectToNdc never receives a positive\n // or zero view_z, while letting the far edge flow through to its real\n // log-z slice.\n const vMinZ = vz - rz;\n const vMaxZ = vz + rz;\n\n const minViewZ = vMinZ;\n const maxViewZ = Math.min(vMaxZ, -1e-5);\n\n // If even the near edge of the sphere is behind the camera, the light\n // contributes nothing. Caller (calculateSphereClusterBounds) returns\n // min > max which the bin loop treats as cull.\n if (minViewZ > maxViewZ) {\n result.min[0] = 1;\n result.min[1] = 1;\n result.min[2] = -1e-5;\n result.max[0] = -1;\n result.max[1] = -1;\n result.max[2] = -1e-5;\n return result;\n }\n\n let ndcMinX = Infinity;\n let ndcMaxX = -Infinity;\n let ndcMinY = Infinity;\n let ndcMaxY = -Infinity;\n\n const p00 = proj[0] ?? 0;\n const p10 = proj[4] ?? 0;\n const p20 = proj[8] ?? 0;\n const p30 = proj[12] ?? 0;\n const p01 = proj[1] ?? 0;\n const p11 = proj[5] ?? 0;\n const p21 = proj[9] ?? 0;\n const p31 = proj[13] ?? 0;\n const p23 = proj[11] ?? 0;\n\n // In the engine's perspective matrices clip.w depends only on view-space z.\n // The XY extrema of each z face are therefore the interval of one linear\n // form, avoiding eight corner projections and their temporary tuples.\n const perspectiveWOnlyZ =\n Math.abs(proj[3] ?? 0) < 1e-8 &&\n Math.abs(proj[7] ?? 0) < 1e-8 &&\n Math.abs(proj[15] ?? 0) < 1e-8 &&\n Math.abs(p23) >= 1e-5;\n\n if (perspectiveWOnlyZ) {\n const xExtent = Math.abs(p00) * rx + Math.abs(p10) * ry;\n const yExtent = Math.abs(p01) * rx + Math.abs(p11) * ry;\n for (let face = 0; face < 2; face++) {\n const zTest = face === 0 ? minViewZ : maxViewZ;\n if (zTest > 0) continue;\n const invW = 1 / (p23 * zTest);\n const xCenter = p20 * zTest + p30;\n const yCenter = p21 * zTest + p31;\n const x0 = (xCenter - xExtent) * invW;\n const x1 = (xCenter + xExtent) * invW;\n const y0 = (yCenter - yExtent) * invW;\n const y1 = (yCenter + yExtent) * invW;\n ndcMinX = Math.min(ndcMinX, x0, x1);\n ndcMaxX = Math.max(ndcMaxX, x0, x1);\n ndcMinY = Math.min(ndcMinY, y0, y1);\n ndcMaxY = Math.max(ndcMaxY, y0, y1);\n }\n } else {\n const corners: Array<[number, number]> = [\n [vMinX, vMinY],\n [vMinX, vMaxY],\n [vMaxX, vMinY],\n [vMaxX, vMaxY],\n ];\n\n for (const zTest of [minViewZ, maxViewZ]) {\n if (zTest <= 0) {\n for (const corner of corners) {\n const sx = corner[0];\n const sy = corner[1];\n const ndc = projectToNdc(sx, sy, zTest, proj);\n ndcMinX = Math.min(ndcMinX, ndc[0]);\n ndcMaxX = Math.max(ndcMaxX, ndc[0]);\n ndcMinY = Math.min(ndcMinY, ndc[1]);\n ndcMaxY = Math.max(ndcMaxY, ndc[1]);\n }\n }\n }\n }\n\n ndcMinX = Math.max(ndcMinX, -1);\n ndcMinY = Math.max(ndcMinY, -1);\n ndcMaxX = Math.min(ndcMaxX, 1);\n ndcMaxY = Math.min(ndcMaxY, 1);\n\n // M4.5-followup: aabb.min/max[2] now carries VIEW-SPACE z (negative), not\n // projected-NDC z. calculateSphereClusterBounds + ndcPositionToCluster +\n // viewZToZSlice all want view_z to do the log-z slice mapping; passing the\n // projected NDC z (>= 0) collapsed every light to slice 0 so cube/floor\n // fragments outside that slice received zero light.\n result.min[0] = ndcMinX;\n result.min[1] = ndcMinY;\n result.min[2] = minViewZ;\n result.max[0] = ndcMaxX;\n result.max[1] = ndcMaxY;\n result.max[2] = maxViewZ;\n return result;\n}\n\n/**\n * Project a view-space point to NDC via the perspective projection matrix.\n * Returns [ndc_x, ndc_y, ndc_z].\n */\nfunction projectToNdc(vx: number, vy: number, vz: number, proj: Mat4): [number, number, number] {\n const p00 = proj[0] ?? 0;\n const p10 = proj[4] ?? 0;\n const p20 = proj[8] ?? 0;\n const p30 = proj[12] ?? 0;\n const p01 = proj[1] ?? 0;\n const p11 = proj[5] ?? 0;\n const p21 = proj[9] ?? 0;\n const p31 = proj[13] ?? 0;\n const p02 = proj[2] ?? 0;\n const p12 = proj[6] ?? 0;\n const p22 = proj[10] ?? 0;\n const p32 = proj[14] ?? 0;\n const p03 = proj[3] ?? 0;\n const p13 = proj[7] ?? 0;\n const p23 = proj[11] ?? 0;\n const p33 = proj[15] ?? 0;\n\n const cx = p00 * vx + p10 * vy + p20 * vz + p30;\n const cy = p01 * vx + p11 * vy + p21 * vz + p31;\n const cz = p02 * vx + p12 * vy + p22 * vz + p32;\n const cw = p03 * vx + p13 * vy + p23 * vz + p33;\n\n if (Math.abs(cw) < 1e-10) {\n return [vx < 0 ? -1 : 1, vy < 0 ? -1 : 1, cz];\n }\n\n const invW = 1 / cw;\n return [cx * invW, cy * invW, cz * invW];\n}\n\n// ── ndc_position_to_cluster ─────────────────────────────────────────────────\n\n/**\n * Map an NDC point to its cluster cell index (XY + Z).\n *\n * XY: floor((ndc.xy * 0.5 + 0.5) * gridXy) clamped to [0, gridXy - 1].\n * Z: delegated to view_z_to_z_slice with the given view-space z.\n */\nexport function ndcPositionToCluster(\n ndc: Vec3,\n viewZ: number,\n gridX: number,\n gridY: number,\n gridZ: number,\n near: number,\n far: number,\n): Uvec3 {\n const ndcX = ndc[0] ?? 0;\n const ndcY = ndc[1] ?? 0;\n\n let cx = Math.floor((ndcX * 0.5 + 0.5) * gridX);\n let cy = Math.floor((ndcY * 0.5 + 0.5) * gridY);\n\n if (cx < 0) cx = 0;\n if (cx >= gridX) cx = gridX - 1;\n if (cy < 0) cy = 0;\n if (cy >= gridY) cy = gridY - 1;\n\n const cz = viewZToZSlice(viewZ, gridZ, near, far);\n\n return { x: cx, y: cy, z: cz };\n}\n\n// ── calculate_sphere_cluster_bounds ─────────────────────────────────────────\n\n/**\n * Convert an NDC AABB to a range of cluster cell indices.\n *\n * Computes cluster indices for AABB min and max, then clamps and\n * orders the result so `min <= max` in each axis.\n *\n * If the sphere is entirely behind the camera, returns min > max\n * in at least one axis (cull signal).\n */\nexport function calculateSphereClusterBounds(\n aabb: ClusterAabb,\n gridX: number,\n gridY: number,\n gridZ: number,\n near: number,\n far: number,\n output?: MutableClusterBounds,\n): ClusterBounds {\n const result =\n output ??\n ({\n min: { x: 0, y: 0, z: 0 },\n max: { x: 0, y: 0, z: 0 },\n } satisfies MutableClusterBounds);\n const minZ = aabb.min[2] ?? 0;\n const maxZ = aabb.max[2] ?? 0;\n\n const idxMin = ndcPositionToCluster(aabb.min, minZ, gridX, gridY, gridZ, near, far);\n const idxMax = ndcPositionToCluster(aabb.max, maxZ, gridX, gridY, gridZ, near, far);\n\n result.min.x = Math.min(idxMin.x, idxMax.x);\n result.min.y = Math.min(idxMin.y, idxMax.y);\n result.min.z = Math.min(idxMin.z, idxMax.z);\n result.max.x = Math.max(idxMin.x, idxMax.x);\n result.max.y = Math.max(idxMin.y, idxMax.y);\n result.max.z = Math.max(idxMin.z, idxMax.z);\n return result;\n}\n\n// ── bin ─────────────────────────────────────────────────────────────────────\n\n/**\n * Main entry point: assign punctual lights to cluster cells.\n *\n * Light-major loop: for each light, compute its sphere-AABB and iterate the\n * intersecting cluster cells, appending the light index to the light_index_list\n * and updating cluster_grid offsets.\n *\n * @param lights — array of { position: Vec3, range: number }\n * @param view — view matrix (column-major 16 floats)\n * @param proj — projection matrix (column-major 16 floats)\n * @param grid — cluster grid dimensions { x, y, z }\n * @param near — near plane distance\n * @param far — far plane distance\n * @param clusterGrid — caller-owned Uint32Array, length = grid.x * grid.y * grid.z * 2.\n * Format: [offset, count] pairs. offset = start index in lightIndexList; count = number of lights.\n * @param lightIndexList — caller-owned Uint32Array for light index storage.\n * @param capacity — max entries in lightIndexList (hard cap, typically 65536).\n * @param scratch — optional per-render-system typed scratch reused across frames.\n *\n * @returns `ok(written light-index entry count)` on success; `err(ClusterBinError)` with code\n * 'index-overflow' on overflow. The count lets the upload owner avoid copying unused capacity.\n */\nexport function bin(\n lights: ReadonlyArray<{ readonly position: Vec3; readonly range: number }>,\n view: Mat4,\n proj: Mat4,\n grid: { readonly x: number; readonly y: number; readonly z: number },\n near: number,\n far: number,\n clusterGrid: Uint32Array,\n lightIndexList: Uint32Array,\n capacity: number,\n scratch?: ClusterBinScratch,\n profile?: ClusterBinProfileRunner,\n options: ClusterBinOptions = {},\n): Result<number, ClusterBinError> {\n const gridX = grid.x;\n const gridY = grid.y;\n const gridZ = grid.z;\n const clusterCount = gridX * gridY * gridZ;\n const binScratch = scratch ?? createClusterBinScratch();\n\n ensureScratchCapacity(binScratch, clusterCount, lights.length, gridX, gridY, gridZ);\n const { clusterCounts, clusterCursors, lightBounds, clusterDeltas } = binScratch;\n\n clusterGrid.fill(0, 0, clusterCount * 2);\n clusterCounts.fill(0, 0, clusterCount);\n\n let attemptedTotal = 0;\n\n runClusterBinProfilePhase(profile, 'light-bounds-and-occupancy', () => {\n runClusterBinProfilePhase(profile, 'light-bounds-and-occupancy/light-aabb', () => {\n for (let lightIdx = 0; lightIdx < lights.length; lightIdx++) {\n const boundsOffset = lightIdx * 6;\n lightBounds[boundsOffset] = -1;\n const light = lights[lightIdx];\n if (!light) continue;\n const radius = deriveCullingRadius(light.range, 1);\n\n if (radius <= 0) {\n continue;\n }\n\n const aabb = clusterSpaceObjectAabb(\n light.position,\n radius,\n view,\n proj,\n binScratch.aabbOutput,\n );\n\n const bounds = calculateSphereClusterBounds(\n aabb,\n gridX,\n gridY,\n gridZ,\n near,\n far,\n binScratch.boundsOutput,\n );\n if (\n bounds.min.x > bounds.max.x ||\n bounds.min.y > bounds.max.y ||\n bounds.min.z > bounds.max.z\n ) {\n continue;\n }\n\n lightBounds[boundsOffset] = bounds.min.x;\n lightBounds[boundsOffset + 1] = bounds.min.y;\n lightBounds[boundsOffset + 2] = bounds.min.z;\n lightBounds[boundsOffset + 3] = bounds.max.x;\n lightBounds[boundsOffset + 4] = bounds.max.y;\n lightBounds[boundsOffset + 5] = bounds.max.z;\n }\n });\n\n runClusterBinProfilePhase(profile, 'light-bounds-and-occupancy/cluster-occupancy', () => {\n const diffX = gridX + 1;\n const diffY = gridY + 1;\n const diffRow = diffX * diffY;\n clusterDeltas.fill(0, 0, diffRow * (gridZ + 1));\n\n const addDifference = (x: number, y: number, z: number, delta: number): void => {\n const index = z * diffRow + y * diffX + x;\n clusterDeltas[index] = (clusterDeltas[index] ?? 0) + delta;\n };\n\n for (let lightIdx = 0; lightIdx < lights.length; lightIdx++) {\n const boundsOffset = lightIdx * 6;\n if ((lightBounds[boundsOffset] ?? -1) < 0) continue;\n const minX = lightBounds[boundsOffset] ?? 0;\n const minY = lightBounds[boundsOffset + 1] ?? 0;\n const minZ = lightBounds[boundsOffset + 2] ?? 0;\n const maxX = lightBounds[boundsOffset + 3] ?? -1;\n const maxY = lightBounds[boundsOffset + 4] ?? -1;\n const maxZ = lightBounds[boundsOffset + 5] ?? -1;\n const endX = maxX + 1;\n const endY = maxY + 1;\n const endZ = maxZ + 1;\n addDifference(minX, minY, minZ, 1);\n addDifference(endX, minY, minZ, -1);\n addDifference(minX, endY, minZ, -1);\n addDifference(minX, minY, endZ, -1);\n addDifference(endX, endY, minZ, 1);\n addDifference(endX, minY, endZ, 1);\n addDifference(minX, endY, endZ, 1);\n addDifference(endX, endY, endZ, -1);\n }\n for (let cz = 0; cz < gridZ; cz++) {\n for (let cy = 0; cy < gridY; cy++) {\n for (let cx = 0; cx < gridX; cx++) {\n const diffIdx = cz * diffRow + cy * diffX + cx;\n let count = clusterDeltas[diffIdx] ?? 0;\n if (cx > 0) count += clusterDeltas[diffIdx - 1] ?? 0;\n if (cy > 0) count += clusterDeltas[diffIdx - diffX] ?? 0;\n if (cz > 0) count += clusterDeltas[diffIdx - diffRow] ?? 0;\n if (cx > 0 && cy > 0) count -= clusterDeltas[diffIdx - diffX - 1] ?? 0;\n if (cx > 0 && cz > 0) count -= clusterDeltas[diffIdx - diffRow - 1] ?? 0;\n if (cy > 0 && cz > 0) count -= clusterDeltas[diffIdx - diffRow - diffX] ?? 0;\n if (cx > 0 && cy > 0 && cz > 0) {\n count += clusterDeltas[diffIdx - diffRow - diffX - 1] ?? 0;\n }\n clusterDeltas[diffIdx] = count;\n const clusterIdx = cz * gridY * gridX + cy * gridX + cx;\n clusterCounts[clusterIdx] = count;\n attemptedTotal += count;\n }\n }\n }\n });\n });\n\n if (attemptedTotal > capacity) {\n return err({\n code: 'index-overflow',\n expected: `writeCount <= ${capacity}`,\n hint: `light index list overflow: needed ${attemptedTotal} entries, capacity ${capacity}; reduce lights, shrink grid, or shrink ranges (overrun = ${attemptedTotal - capacity})`,\n detail: { actual: attemptedTotal, capacity },\n });\n }\n\n // Reserve one contiguous output run per cluster. The second light-major pass\n // below preserves each cluster's original light ordering without allocating\n // one JavaScript array per cluster.\n const writeCount = runClusterBinProfilePhase(profile, 'cluster-reserve', () => {\n let reserved = 0;\n for (let ci = 0; ci < clusterCount; ci++) {\n const base = ci * 2;\n clusterGrid[base] = reserved;\n clusterGrid[base + 1] = clusterCounts[ci] ?? 0;\n clusterCursors[ci] = reserved;\n reserved += clusterCounts[ci] ?? 0;\n }\n return reserved;\n });\n\n if (options.writeMembership !== false) {\n runClusterBinProfilePhase(profile, 'light-index-write', () => {\n for (let lightIdx = 0; lightIdx < lights.length; lightIdx++) {\n const boundsOffset = lightIdx * 6;\n let valid = false;\n let minX = 0;\n let minY = 0;\n let minZ = 0;\n let maxX = -1;\n let maxY = -1;\n let maxZ = -1;\n runClusterBinProfilePhase(profile, 'light-index-write/bounds-read', () => {\n if ((lightBounds[boundsOffset] ?? -1) < 0) return;\n valid = true;\n minX = lightBounds[boundsOffset] ?? 0;\n minY = lightBounds[boundsOffset + 1] ?? 0;\n minZ = lightBounds[boundsOffset + 2] ?? 0;\n maxX = lightBounds[boundsOffset + 3] ?? -1;\n maxY = lightBounds[boundsOffset + 4] ?? -1;\n maxZ = lightBounds[boundsOffset + 5] ?? -1;\n });\n if (!valid) continue;\n runClusterBinProfilePhase(profile, 'light-index-write/cluster-write', () => {\n for (let cz = minZ; cz <= maxZ; cz++) {\n for (let cy = minY; cy <= maxY; cy++) {\n for (let cx = minX; cx <= maxX; cx++) {\n const clusterIdx = cz * gridY * gridX + cy * gridX + cx;\n const cursor = clusterCursors[clusterIdx] ?? 0;\n lightIndexList[cursor] = lightIdx;\n clusterCursors[clusterIdx] = cursor + 1;\n }\n }\n }\n });\n }\n });\n }\n\n return ok(writeCount);\n}\n","// @forgeax/engine-runtime - render package shader-stage visibility values.\n//\n// Keep the WebGPU bit values in one dependency-free owner because render\n// package layout builders also run against the null and WebGL2-compatible RHI\n// shims where the browser's GPUShaderStage global is unavailable.\n\nexport const GPU_SHADER_STAGE_VERTEX = 0x1;\nexport const GPU_SHADER_STAGE_FRAGMENT = 0x2;\nexport const GPU_SHADER_STAGE_COMPUTE = 0x4;\n","// @forgeax/engine-runtime - render package GPU buffer usage values.\n//\n// Keep the WebGPU bit values in one dependency-free owner because the render\n// package also runs against the null and WebGL2-compatible RHI shims where the\n// browser's GPUBufferUsage global is unavailable.\n\nexport const GPU_BUFFER_USAGE_VERTEX = 0x20;\nexport const GPU_BUFFER_USAGE_INDEX = 0x10;\nexport const GPU_BUFFER_USAGE_COPY_DST = 0x08;\nexport const GPU_BUFFER_USAGE_COPY_SRC = 0x04;\nexport const GPU_BUFFER_USAGE_UNIFORM = 0x40;\nexport const GPU_BUFFER_USAGE_STORAGE = 0x80;\nexport const GPU_BUFFER_USAGE_INDIRECT = 0x100;\nexport const GPU_BUFFER_USAGE_MAP_READ = 0x01;\n","// @forgeax/engine-runtime - host-side packing helpers for the\n// PointLight + SpotLight std430 storage buffers + storage-buffer cap gate.\n//\n// Owns the byte-frozen std430 layout (D-S2):\n//\n// PointLight (32 B / 8 floats):\n// [ 0..2 ] position vec3<f32>\n// [ 3 ] invRangeSquared f32 (Bevy color_inverse_square_range.w)\n// [ 4..6 ] color vec3<f32> (host-pre-multiplied: color * intensity)\n// [ 7 ] shadowAtlasLayer i32 (sentinel -1 = no shadow; 0..3 = atlas layer)\n// — feat-20260612-point-light-shadows-urp-hdrp M1 / T-M1-8 (D-2):\n// repurposes the prior `pointPadW` lane. The lane is written as\n// i32 via an Int32Array view of the same backing ArrayBuffer; the\n// shader reads `shadowAtlasLayer: i32` from byte 28..32 of struct\n// PointLight in common.wgsl. -1 (0xFFFFFFFF) is the no-shadow\n// sentinel — shader path samples shadow only when layer >= 0.\n//\n// SpotLight (64 B / 16 floats):\n// [ 0..2 ] position vec3<f32>\n// [ 3 ] invRangeSquared f32\n// [ 4..6 ] color vec3<f32> (host-pre-multiplied)\n// [ 7 ] cosInner f32\n// [ 8..10] direction vec3<f32> (raw outgoing vector)\n// [ 11 ] cosOuter f32\n// [12..14] pad f32 = 0 (std430 vec4 stride alignment)\n// [ 15 ] shadowAtlasTile i32 (sentinel -1 = unassigned/clipped; 0..3 = tile)\n// — feat-20260625-spot-light-shadow-mapping M2 / w8 (D-4):\n// SpotLight GPU struct had no free pad lane (8 lanes full), so the\n// clip signal extends the struct to a 4th vec4 column. The lane is\n// written i32 via an Int32Array view of the same backing\n// ArrayBuffer; the shader reads `shadowAtlasTile: i32` from byte\n// 60..64 of struct SpotLight (common.wgsl). -1 (0xFFFFFFFF) is the\n// unassigned/clipped sentinel — shader samples shadow only when\n// tile >= 0. Mirrors point's slot-7 shadowAtlasLayer pattern.\n//\n// Array header (16 B, std430 stride alignment):\n// [ 0 ] count u32 (number of valid slots in the trailing array)\n// [ 1..3 ] pad u32 = 0\n//\n// AC anchor: requirements AC-04 (c) + C-7 (16 B alignment); plan-strategy\n// section 2 D-S2 (byte-frozen layout); research Finding 2 (Bevy\n// invRangeSquared naming) + Finding 9 (Bevy storage buffer pattern).\n//\n// Cap gate: maxStorageBuffersPerShaderStage >= 4 (M3 occupies 3 storage\n// entries: meshSSBO + pointLightsBuffer + spotLightsBuffer; default WebGPU\n// minimum is 8, requirements assumption A-7 + plan R-4). The closed\n// `RhiErrorCode` union has no `'rhi-not-supported'` member; the\n// plan-strategy phrasing collapses onto the spec-aligned `'limit-exceeded'`\n// arm which already documents \"input value exceeded device.limits.<name>\"\n// (RhiError JSDoc on packages/rhi/src/errors.ts). Reusing `'limit-exceeded'`\n// keeps `RhiErrorCode` count at 18 (AGENTS.md error model evolution\n// contract: minor add-only; w20a explicitly forbids count drift).\n\nimport { err, ok, type Result, RhiError } from '@forgeax/engine-rhi';\nimport type { PointLightSnapshot, SpotLightSnapshot } from './render-system-extract';\n\n// ── HDRP LightSlot cluster-forward unified struct ─────────────────────────────\n// feat-20260608-cluster-lighting M4 / w16.\n//\n// LightSlot is the single std430 struct shared by point and spot lights in the\n// HDRP cluster-forward path. Field layout is byte-frozen (AC-11 double-sided\n// lock with WGSL hdrp-cluster-forward.wgsl LightSlot struct):\n//\n// [ 0..2 ] position vec3<f32>\n// [ 3 ] invRangeSquared f32\n// [ 4..6 ] color vec3<f32> (host pre-multiplied: color * intensity)\n// [ 7 ] cosInner f32 (point: 1.0)\n// [ 8..10] direction vec3<f32> (point: vec3(0))\n// [ 11 ] cosOuter f32 (point: 0.0)\n// [ 12 ] kind u32 (POINT = 0, SPOT = 1)\n// [ 13 ] shadow identity i32 (point layer / spot tile, -1 sentinel)\n// [14..15] point depth f32x2 (point near/far; spot zero)\n//\n// Design: research Finding 1 (Bevy GpuClusteredLight 152B -> forgeax 64B),\n// plan-strategy D-light-slot (kind bit-tag discriminant).\n//\n// The existing URP PointLight (32B) / SpotLight (48B) pack functions remain\n// untouched; packLightSlot is the new HDRP-only entry.\n\n/** Byte size of one HDRP LightSlot in std430 (16 x f32). AC-11 absolute-value lock. */\nexport const BYTES_PER_LIGHT_SLOT = 64;\n\n/**\n * LightSlot kind discriminant — closed enum matching WGSL `KIND_POINT` / `KIND_SPOT`.\n * Values are u32 bit-tags (not sequential); AC-12 exhaustive switch.\n */\nexport const LightSlotKind = {\n POINT: 0,\n SPOT: 1,\n} as const;\nexport type LightSlotKind = (typeof LightSlotKind)[keyof typeof LightSlotKind];\n\n/**\n * Byte-offset layout of one LightSlot in std430 (16 f32 = 64 B).\n *\n * Mirrors the WGSL `LightSlot` struct field order byte-for-byte.\n * All offsets verified by w14 lightslot-layout.test.ts.\n *\n * feat-20260612-point-light-shadows-urp-hdrp M4 / T-M4-4 (plan-strategy §D-8):\n * the prior u32x3 pad lanes at byte 52..64 carry shadow-side data on the HDRP\n * path. `kind_and_pad.x = kind` (u32), `.y = shadow identity` (i32, sentinel\n * -1 = no shadow), `.z = near` (f32 via bitcast), `.w = far`\n * (f32 via bitcast). The shader reads near/far through `bitcast<f32>(...)`\n * to keep the WGSL struct as `vec4<u32>` (alignment + naga_oil unchanged).\n */\nexport const LIGHTSLOT_LAYOUT = {\n byteSize: BYTES_PER_LIGHT_SLOT,\n positionOffset: 0,\n invRangeSquaredOffset: 12,\n colorOffset: 16,\n cosInnerOffset: 28,\n directionOffset: 32,\n cosOuterOffset: 44,\n kindOffset: 48,\n shadowPayloadOffset: 52,\n shadowAtlasLayerOffset: 52,\n shadowAtlasTileOffset: 52,\n shadowNearOffset: 56,\n shadowFarOffset: 60,\n floatCount: 16,\n vec4Count: 4,\n} as const;\n\n/**\n * Minimum storage-buffer count needed by the M3 record stage.\n *\n * 1. Mesh SSBO (entity_world + normalMatrix; per-renderable dynamic\n * offset, 256 B stride).\n * 2. PointLight std430 array (this feat).\n * 3. SpotLight std430 array (this feat).\n *\n * Plan R-4 + plan-strategy section 4 risk table: assert >= 4 to keep the\n * head-room margin for todo-125 (cluster expansion lifts to 4-5 entries).\n */\nexport const STORAGE_BUFFER_MIN_REQUIRED = 4;\n\n/** Byte size of one PointLight std430 slot (vec4 * 2). */\nexport const POINT_LIGHT_STD430_BYTES = 32;\n/**\n * Byte size of one SpotLight std430 slot (vec4 * 4).\n *\n * feat-20260625-spot-light-shadow-mapping M2 / w8 (D-4): grew 48 -> 64 to make\n * room for the `shadowAtlasTile: i32` clip-signal lane (slot 15). Slots 0..11\n * keep the prior layout; slots 12..14 are vec4-alignment padding.\n */\nexport const SPOT_LIGHT_STD430_BYTES = 64;\n\n/** Sentinel value for SpotLight slot[15] meaning \"no shadow / clipped\". */\nexport const SPOT_LIGHT_SHADOW_TILE_SENTINEL = -1;\n/** Byte size of the array header (count u32 + 12 B pad to 16 B stride). */\nexport const LIGHT_ARRAY_HEADER_BYTES = 16;\n/** Maximum number of slots packed in the first-slice cap layout (D-S3). */\nexport const LIGHT_ARRAY_MAX_SLOTS = 4;\n\n/** Sentinel value for PointLight slot[7] / LightSlot pad meaning \"no shadow\". */\nexport const POINT_LIGHT_SHADOW_LAYER_SENTINEL = -1;\n\n/**\n * Pack one PointLightSnapshot into 8 floats / 32 B byte-for-byte std430.\n *\n * Returns a fresh `Float32Array` per call; `Float32Array.byteLength === 32`\n * by construction (Float32Array(8).buffer.byteLength === 32). Slot 7\n * (byte 28..32) carries `shadowAtlasLayer: i32` (sentinel -1 = no shadow,\n * 0..3 = cube_array atlas layer index for shadow casters). The lane is\n * written through an Int32Array view of the same backing ArrayBuffer so the\n * shader's `i32` read at byte 28..32 of `struct PointLight` (common.wgsl)\n * sees the correct two's-complement bits (-1 = 0xFFFFFFFF).\n */\nexport function packPointLight(snap: PointLightSnapshot): Float32Array {\n const out = new Float32Array(8);\n out[0] = snap.position[0] ?? 0;\n out[1] = snap.position[1] ?? 0;\n out[2] = snap.position[2] ?? 0;\n out[3] = snap.invRangeSquared;\n out[4] = snap.color[0] ?? 0;\n out[5] = snap.color[1] ?? 0;\n out[6] = snap.color[2] ?? 0;\n // Slot 7: shadowAtlasLayer i32 via Int32Array view (sentinel -1 default).\n const i32 = new Int32Array(out.buffer);\n i32[7] = snap.shadowAtlasLayer ?? POINT_LIGHT_SHADOW_LAYER_SENTINEL;\n return out;\n}\n\n/**\n * Pack one SpotLightSnapshot into 16 floats (64 B byte-for-byte std430).\n *\n * cosInner / cosOuter ride the otherwise-padding `.w` lanes of the\n * `color` and `direction` vec4 columns (AC-04 c + plan D-S2 16 B alignment\n * via packing rather than padding rows). Slot 15 carries `shadowAtlasTile: i32`\n * (sentinel -1 = unassigned/clipped, 0..3 = atlas tile) written through an\n * Int32Array view so the shader's `i32` read at byte 60..64 of struct SpotLight\n * (common.wgsl) sees the correct two's-complement bits (-1 = 0xFFFFFFFF).\n * Slots 12..14 stay zero (vec4-alignment padding). feat-20260625 M2 / w8 (D-4).\n */\nexport function packSpotLight(snap: SpotLightSnapshot): Float32Array {\n const out = new Float32Array(16);\n out[0] = snap.position[0] ?? 0;\n out[1] = snap.position[1] ?? 0;\n out[2] = snap.position[2] ?? 0;\n out[3] = snap.invRangeSquared;\n out[4] = snap.color[0] ?? 0;\n out[5] = snap.color[1] ?? 0;\n out[6] = snap.color[2] ?? 0;\n out[7] = snap.cosInner;\n out[8] = snap.direction[0] ?? 0;\n out[9] = snap.direction[1] ?? 0;\n out[10] = snap.direction[2] ?? 0;\n out[11] = snap.cosOuter;\n // Slots 12..14 stay zero (vec4-alignment padding).\n // Slot 15: shadowAtlasTile i32 via Int32Array view (sentinel -1 default).\n const i32 = new Int32Array(out.buffer);\n i32[15] = snap.shadowAtlasTile ?? SPOT_LIGHT_SHADOW_TILE_SENTINEL;\n return out;\n}\n\n/**\n * Pack the 16-byte std430 array header (count u32 + 12 B pad) for the\n * point/spot light storage buffers.\n *\n * Returns a fresh `ArrayBuffer` so callers can either re-view it as\n * `Uint8Array` for `queue.writeBuffer` or as `Uint32Array` for in-place\n * inspection.\n */\nexport function packLightArrayHeader(count: number): ArrayBuffer {\n const buf = new ArrayBuffer(LIGHT_ARRAY_HEADER_BYTES);\n const u32 = new Uint32Array(buf);\n u32[0] = count >>> 0;\n // Slots 1..3 stay zero (12 B pad to 16 B stride alignment).\n return buf;\n}\n\n/**\n * Cap gate at createRenderer time: check whether the device has enough\n * storage-buffer slots for the PBR pipeline (M3 requires\n * `STORAGE_BUFFER_MIN_REQUIRED = 4`). Returns a three-way signal:\n *\n * - `Result.ok(true)` — storage buffer capable (cap >= 4);\n * - `Result.ok(false)` — no storage buffer capability at all (cap === 0);\n * consumer walks the uniform-fallback path;\n * - `Result.err(RhiError)` — cap in (0, 4); not enough storage slots to run\n * but also not a clean zero-cap uniform-fallback case (e.g. downlevel\n * adapter with 1-3 slots). The error carries `'limit-exceeded'` with\n * `LimitExceededDetail` shape.\n *\n * Uniform-fallback path decision (plan D-5): `cap === 0` is the wgpu\n * WebGL2 backend signal (`downlevel_webgl2_defaults().limits.\n * maxStorageBuffersPerShaderStage = 0`). Uniform fallback covers pointLight\n * + spotLight + meshes + instances + skin palette — every storage-buffer\n * entry in the PBR pipeline switches to `uniform`.\n */\n/**\n * Optional shadow info attached to a HDRP LightSlot for point lights with a\n * companion `PointLightShadow` component. Sentinel `layer = -1` (the default\n * when the snapshot has no shadow) makes the shader skip cube_array sampling\n * and stay on the unshadowed `evalPoint` path.\n *\n * `near` / `far` ride the otherwise-pad lanes (`kind_and_pad.zw` in the WGSL\n * struct, byte 56..64) and feed the depth-ref reconstruction in\n * `evalPointShadowed`. Spot lights (and shadow-less point lights) leave these\n * lanes zero per std430 init.\n */\nexport interface PointShadowSlotInfo {\n readonly shadowAtlasLayer: number;\n readonly near: number;\n readonly far: number;\n}\n\n/**\n * Pack one PointLightSnapshot or SpotLightSnapshot into a 64-byte LightSlot\n * (16 floats, std430). Point lights fill `cosInner=1.0`, `direction=vec3(0)`,\n * `cosOuter=0.0`, `kind=POINT(0)`. Spot lights fill all fields verbatim;\n * `direction` is already normalized by extract and this owner never repeats\n * that operation.\n *\n * feat-20260612-point-light-shadows-urp-hdrp M4 / T-M4-4 (plan-strategy §D-8):\n * the optional point `shadow` info threads through to bytes 52..64 as\n * `(shadowAtlasLayer i32, near f32, far f32)`. Spot snapshots write their\n * `shadowAtlasTile` directly into the same identity lane and keep near/far 0.\n * The shader reads `near`/`far`\n * through `bitcast<f32>(kind_and_pad.zw)` so the WGSL struct stays\n * `kind_and_pad: vec4<u32>` (alignment + naga_oil compose unchanged). When\n * `shadow` is undefined (no PointLightShadow) the lanes default to\n * `(layer = -1, 0, 0)` -- shader gates on `layer >= 0` so unshadowed lights\n * stay on the `evaluate_point_light` path. Spot lights write their tile or -1.\n *\n * Returns a fresh `Float32Array(16)` per call.\n */\nexport function packLightSlot(\n snap: PointLightSnapshot | SpotLightSnapshot,\n shadow?: PointShadowSlotInfo,\n): Float32Array {\n const out = new Float32Array(16);\n // position (vec3<f32> + invRangeSquared at lane .w)\n out[0] = snap.position[0] ?? 0;\n out[1] = snap.position[1] ?? 0;\n out[2] = snap.position[2] ?? 0;\n out[3] = snap.invRangeSquared;\n // color (vec3<f32> + cosInner at lane .w)\n out[4] = snap.color[0] ?? 0;\n out[5] = snap.color[1] ?? 0;\n out[6] = snap.color[2] ?? 0;\n out[7] = snap.kind === 'point' ? 1.0 : snap.cosInner;\n // direction (vec3<f32> + cosOuter at lane .w)\n out[8] = snap.kind === 'point' ? 0 : (snap.direction[0] ?? 0);\n out[9] = snap.kind === 'point' ? 0 : (snap.direction[1] ?? 0);\n out[10] = snap.kind === 'point' ? 0 : (snap.direction[2] ?? 0);\n out[11] = snap.kind === 'point' ? 0.0 : snap.cosOuter;\n // Kind is a raw u32 discriminant at byte 48. Do not assign through the\n // Float32Array: SPOT=1 must be 0x00000001, not f32(1.0) bits.\n const u32 = new Uint32Array(out.buffer);\n u32[12] = snap.kind === 'point' ? LightSlotKind.POINT : LightSlotKind.SPOT;\n // Lanes 13..15 carry one kind-discriminated shadow identity. Point keeps\n // layer/near/far; spot writes its snapshot tile and leaves near/far zero.\n const i32 = new Int32Array(out.buffer);\n if (snap.kind === 'point' && shadow !== undefined) {\n i32[13] = shadow.shadowAtlasLayer;\n out[14] = shadow.near;\n out[15] = shadow.far;\n } else if (snap.kind === 'spot') {\n i32[13] = snap.shadowAtlasTile;\n } else {\n i32[13] = POINT_LIGHT_SHADOW_LAYER_SENTINEL;\n // out[14] / out[15] remain zero (Float32Array zero-init).\n }\n return out;\n}\n\nexport function assertStorageBufferCap(cap: number): Result<boolean, RhiError> {\n if (cap >= STORAGE_BUFFER_MIN_REQUIRED) {\n return ok(true);\n }\n if (cap === 0) {\n return ok(false);\n }\n return err(\n new RhiError({\n code: 'limit-exceeded',\n expected: `device.limits.maxStorageBuffersPerShaderStage >= ${STORAGE_BUFFER_MIN_REQUIRED}, or exactly 0 for uniform-fallback path`,\n hint: `device.limits.maxStorageBuffersPerShaderStage = ${cap} < ${STORAGE_BUFFER_MIN_REQUIRED} and != 0. WebGPU spec default minimum is 8; this may be a downlevel adapter with partial storage support. Wait for todo-125 multi-light-pack which collapses point + spot into a single cluster storage buffer (1 entry instead of 2) for 2-3 buffer environments.`,\n detail: {\n maxStorageBufferBindingSize: cap,\n requestedBytes: STORAGE_BUFFER_MIN_REQUIRED,\n },\n }),\n );\n}\n","// pbr-pipeline.ts -- PBR / unlit pipeline-layout factories (M4 round-4 D-5).\n//\n// Anchors:\n// - plan-strategy D-5 (round-4 REVISED): the PBR pipeline keeps a 4-slot\n// pipeline layout `[view, material, mesh-array, instances]`. The\n// material BGL grows from the derived user region by appending the 7\n// Skylight resources via `mergeSkylightIntoMaterialBgl`. The\n// unlit pipeline keeps its 7-entry material BGL (no Skylight binding\n// 7..13 contamination) so unlit demos don't carry IBL state.\n// - charter P4: same pipeline layout shape drives Skylight present +\n// absent paths -- AI users do not branch on Skylight existence.\n// - feat-20260520-skylight-ibl-cubemap M4 / t59 (round-4): the\n// pipeline-layout construction migrates out of `createRenderer.ts`\n// into this dedicated module so M4 round-4 tests can mock the device\n// and inspect the captured descriptors without standing up the full\n// createRenderer + asset registry + manifest stack.\n//\n// The factory functions return both the captured handles AND the\n// `bindGroupLayouts` array passed to `device.createPipelineLayout`. Callers\n// (the createRenderer step that wires the standard + standard-HDR\n// `RenderPipeline` instances) consume the result by name; tests inspect\n// `device.createBindGroupLayout.mock.calls` to verify shape (t57).\n\nimport type {\n BindGroup,\n BindGroupEntry,\n BindGroupLayout,\n BindGroupLayoutDescriptor,\n Buffer,\n PipelineLayout,\n RhiDevice,\n Sampler,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport { DEFAULT_STANDARD_PBR_PARAM_SCHEMA, type ShaderCatalog } from '@forgeax/engine-shader';\nimport { derive, type ParamSchemaEntry } from '@forgeax/engine-types';\nimport { GPU_SHADER_STAGE_FRAGMENT, GPU_SHADER_STAGE_VERTEX } from './gpu-stage';\nimport type { PipelineSpec } from './pipeline-spec-types';\n\n// Stub PipelineSpec used by the BGL-only call sites. The dispatcher only reads\n// `spec.shader` when a registry is supplied for reflection; for caps-driven\n// kinds (pbr-view / pbr-mesh-array / pbr-instances / pbr-skin-mesh-array) and\n// for the no-registry material path the spec content is unused. A single\n// frozen stub keeps the call sites readable and is allocation-free.\n//\n// D-13 round-2 dispatcher landing — see plan-decisions D-13.\nconst BGL_ONLY_SPEC_STUB: PipelineSpec = Object.freeze({\n shader: { id: '', passKind: 'forward', variantSet: undefined },\n attachments: { colorFormats: [], depthFormat: undefined, sampleCount: 1 },\n geometry: { topology: 'triangle-list', vertexLayout: {} },\n renderState: undefined,\n}) as PipelineSpec;\n\n// ─── Device owner ───────────────────────────────────────────────────────────\n\n/** The PBR layout builder consumes only the two creation methods it owns. */\nexport type PbrPipelineDevice = Pick<RhiDevice, 'createBindGroupLayout' | 'createPipelineLayout'>;\n\n// ─── Result shape ───────────────────────────────────────────────────────────\n\nexport interface PbrPipelineLayoutBundle {\n /** Pipeline layout passed to `createRenderPipeline({ layout })`. */\n readonly pipelineLayout: PipelineLayout;\n /** view BindGroupLayout (slot 0). */\n readonly viewBgl: BindGroupLayout;\n /**\n * PBR material BindGroupLayout (slot 1) -- derived user-region entries plus\n * Skylight and transmission injection.\n */\n readonly materialBgl: BindGroupLayout;\n /** Per-entity mesh BindGroupLayout (slot 2). */\n readonly meshArrayBgl: BindGroupLayout;\n /** Per-instance storage BindGroupLayout (slot 3). */\n readonly instancesBgl: BindGroupLayout;\n /**\n * Same 4 layouts in slot order. Useful for assertion sites that check the\n * pipeline-layout `bindGroupLayouts` array shape (t57 (a) + (d)).\n */\n readonly bindGroupLayouts: readonly [\n BindGroupLayout,\n BindGroupLayout,\n BindGroupLayout,\n BindGroupLayout,\n ];\n}\n\n// ─── Base entries (round-4 SSOT) ────────────────────────────────────────────\n\n/**\n * The built-in standard-PBR material paramSchema's texture/user-region shape,\n * used as the fallback when the material BGL is built without a registry\n * (the caps-driven `buildPbrPipelineLayouts` seam). Declares the 8 Standard\n * user-region textures + a numeric UBO run; `derive()` collapses the numerics\n * into binding 0 and emits sampler/texture pairs at 1..6 — byte-equivalent to\n * the legacy fixed base-7. The shared PBR parameter contract comes from the\n * shader package; this module only derives the GPU layout.\n */\n/**\n * Build the PBR material BGL **user-region** from a paramSchema via the\n * `derive()` SSOT (D-1). The user-region is binding 0 (the run-merged material\n * UBO) followed by one sampler/texture pair per declared texture. Engine\n * injection (IBL + transmission) is appended AFTER this region by the caller via\n * `appendInjection`, with start binding = `userRegion.length` — so a 4-texture\n * custom schema (e.g. parallax + heightTexture) shifts the injection region by\n * one sampler/texture pair automatically.\n *\n * The built-in `default-standard-pbr` paramSchema declares exactly 8 textures,\n * so this derives to binding 0 UBO + 8 pairs = 17 entries. Injection is appended\n * after that derived region.\n *\n * One material-UBO convention is layered on top of the pure `derive()` output:\n * binding 0 is patched to `{ type: 'uniform', hasDynamicOffset: true }` with\n * `VERTEX | FRAGMENT` visibility. The material UBO is bound with a per-submesh\n * dynamic offset (`render-system-record.ts setBindGroup(1, bg, [offset])`) and\n * the vertex stage reads material params, so this is required for GPU\n * validation. `derive()` stays FRAGMENT-only / no-dynamic-offset for its other\n * consumers (it is the generic SSOT, not the material-UBO authority).\n *\n * @param paramSchema - the material shader's paramSchema (defaults to the\n * built-in standard-PBR shape when omitted, for the caps-driven seam).\n */\nexport function buildPbrMaterialUserRegionEntries(\n paramSchema: readonly ParamSchemaEntry[] = DEFAULT_STANDARD_PBR_PARAM_SCHEMA,\n): GPUBindGroupLayoutEntry[] {\n const derived = derive(paramSchema);\n // Project the engine-owned entry shape into the DOM WebGPU descriptor. Omit\n // absent optional members so exactOptionalPropertyTypes remains true at the\n // boundary instead of leaking an `undefined` property into the descriptor.\n const entries = derived.bglEntries.map(\n (entry): GPUBindGroupLayoutEntry => ({\n binding: entry.binding,\n visibility: entry.visibility,\n ...(entry.buffer === undefined ? {} : { buffer: entry.buffer }),\n ...(entry.sampler === undefined ? {} : { sampler: entry.sampler }),\n ...(entry.texture === undefined ? {} : { texture: entry.texture }),\n ...(entry.storageTexture === undefined ? {} : { storageTexture: entry.storageTexture }),\n }),\n );\n // Patch binding 0 (the material UBO) to the dynamic-offset, vertex-visible\n // material-UBO contract. derive() emits binding 0 as the first numeric run's\n // merged UBO; an empty schema has no binding-0 UBO and needs no patch.\n const ubo = entries[0];\n if (ubo !== undefined && ubo.binding === 0 && ubo.buffer !== undefined) {\n entries[0] = {\n binding: 0,\n visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform', hasDynamicOffset: true },\n };\n }\n return entries;\n}\n\n// ─── appendInjection — generic engine-injection BGL appender (M3 / w15) ──────\n//\n// Decision anchors (plan-strategy §2):\n// - D-6 appendInjection(bgl, kind) replaces the previous hardcoded\n// emissive/AO start-binding literal (=14). The starting binding\n// number is computed from `bgl.length`, byte-equivalent to\n// `derive(schema).userRegionBindingEnd` when `bgl` is the BGL list\n// derive returned for the user paramSchema.\n// - R-1 the 14-slot user-region assumption breaks once D-3 merges UBO;\n// appendInjection lets the material BGL grow / shrink without\n// churning every injection site.\n//\n// Closed union of injection kinds (plan-strategy §2 D-6):\n// - 'shadow' reserved for future material-level shadow injection\n// (sampler_comparison + texture_depth_2d, 2 entries).\n// The active shadow bindings live in the view BGL today\n// (group(0) bindings 3..7); this kind is the seam for\n// each per-material shadow override surface a future feat\n// wires onto group(1).\n// - 'ibl' the 7 IBL / Skylight entries (irradiance / prefilter\n// cube + brdfLut 2d + 3 samplers + intensity uniform).\n// Used by `buildPbrPipelineLayouts` after the user-region\n// user paramSchema entries are emitted.\n// - 'lightmap' the 4 emissive + occlusion entries (sampler + texture\n// pair x 2). The historical name is \"emissive/AO\"; we\n// keep that meaning under the generic 'lightmap' label\n// (per-surface secondary-lighting injection) so future\n// lightmap support lands without renaming the kind.\n// - 'transmission' the engine-owned sampler + backdrop texture pair. The\n// record stage supplies a real backdrop only for the active\n// transmission pass; all other variants bind layout-safe\n// placeholders because their shaders do not read these slots.\nexport type InjectionKind = keyof typeof INJECTION_KIND_LENGTHS;\n\nconst IBL_INJECTION_LENGTH = 7;\nconst LIGHTMAP_INJECTION_LENGTH = 4;\nconst SHADOW_INJECTION_LENGTH = 2;\nconst TRANSMISSION_INJECTION_LENGTH = 2;\n\n/**\n * Append the engine-injection BGL entries for the given `kind` after the\n * user-region BGL entries, with binding numbers starting at `bgl.length`.\n *\n * The function reads `bgl.length` (NOT a hardcoded constant) so each\n * user-region size — derived from `derive(schema).userRegionBindingEnd` or\n * computed manually — flows through to the injection start binding without\n * a coupled edit.\n *\n * Returns ONLY the injected entries; the caller spreads them after `bgl`:\n *\n * ```ts\n * const merged = [...userBgl, ...appendInjection(userBgl, 'ibl')];\n * device.createBindGroupLayout({ entries: merged });\n * ```\n */\nexport function appendInjection(\n bgl: readonly GPUBindGroupLayoutEntry[],\n kind: InjectionKind,\n): GPUBindGroupLayoutEntry[] {\n const start = bgl.length;\n switch (kind) {\n case 'ibl':\n return [\n // binding start+0: irradianceMap (texture_cube)\n {\n binding: start,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: 'cube' },\n },\n // binding start+1: irradianceSampler\n {\n binding: start + 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n // binding start+2: prefilterMap (texture_cube)\n {\n binding: start + 2,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: 'cube' },\n },\n // binding start+3: prefilterSampler\n {\n binding: start + 3,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n // binding start+4: brdfLut (texture_2d)\n {\n binding: start + 4,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n },\n // binding start+5: brdfLutSampler\n {\n binding: start + 5,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n // binding start+6: uniform { intensity: f32 }\n {\n binding: start + 6,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n },\n ];\n case 'lightmap':\n return [\n // emissive sampler + texture pair\n {\n binding: start,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n {\n binding: start + 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n },\n // occlusion sampler + texture pair\n {\n binding: start + 2,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n {\n binding: start + 3,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n },\n ];\n case 'shadow':\n return [\n {\n binding: start,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'comparison' },\n },\n {\n binding: start + 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'depth', viewDimension: '2d' },\n },\n ];\n case 'transmission':\n return [\n {\n binding: start,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n {\n binding: start + 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n },\n ];\n }\n}\n\n// Closed-set length sentinels — the map is the membership owner.\nexport const INJECTION_KIND_LENGTHS = {\n shadow: SHADOW_INJECTION_LENGTH,\n ibl: IBL_INJECTION_LENGTH,\n lightmap: LIGHTMAP_INJECTION_LENGTH,\n transmission: TRANSMISSION_INJECTION_LENGTH,\n};\n\n/**\n * Caps shape consumed by the BGL factory functions for storage-buffer vs\n * uniform-buffer branching. Mirrors the two fields the engine reads from\n * `RhiCaps` (plan D-4 + D-5).\n */\nexport interface PbrCaps {\n readonly storageBuffer: boolean;\n}\n\n/**\n * The view BGL entry list. binding 0 = view UBO (vertex + fragment);\n * binding 1 = pointLights (storage or uniform, per caps);\n * binding 2 = spotLights (storage or uniform, per caps);\n * binding 3 = directional shadowMap atlas (texture_depth_2d, vertex+fragment).\n * feat-20260613-csm-cascaded-shadow-maps: this is the CSM atlas — N\n * cascades tiled into one 2D depth texture, sampled via per-cascade UV\n * mapping in `lighting-directional.wgsl`. Single binding survives N=1..4\n * (no array-layer form; cascades live in viewport offsets per the\n * check-csm-unique-shadow-path grep gate).\n * binding 4 = shadow comparison sampler (shared by directional + point);\n * binding 5 = point shadow cube_array depth atlas (texture_depth_cube_array;\n * fragment-only). feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1.\n * binding 6 = point shadow params UBO (`array<vec4<f32>, 4>`, 64 B;\n * fragment-only). One lane per shadow-casting point light slot\n * (shadowAtlasLayer in [0, 4)) carrying `(near, far, 1/(far-near), 0)`.\n * binding 7 = shadowCasterCascade UBO (16 B; vertex + fragment). Per-pass\n * cascade-index uniform consumed exclusively by `shadow_caster.wgsl` to\n * pick `view.lightViewProj_X` for the cascade currently being rasterized\n * (feat-20260613-csm-cascaded-shadow-maps M5 / w28). Forward PBR shaders\n * declare the binding via `common.wgsl` but do not reference it; WebGPU\n * still requires a populated entry on every view BG so the host writes a\n * stable singleton buffer.\n * binding 8 = spot shadow atlas (texture_depth_2d; fragment-only).\n * feat-20260625-spot-light-shadow-mapping M3 / w14 (D-5). A single 2D depth\n * texture holding up to 4 spot shadows in a 2x2 tile grid. ALWAYS-ON (no caps\n * gate — `texture_depth_2d` is compat-safe everywhere), matching the\n * unconditional `spotShadowMap` WGSL declaration in common.wgsl. Reuses the\n * comparison sampler at binding 4 (no binding 9). Every view BG must populate\n * binding 8 (real spotShadowDepth view when spot shadows run, else a 1x1\n * fallback depth view cleared to fully-lit).\n *\n * Mirrors feat-20260519-light-casters M3 D-S1 layout +\n * feat-20260520-directional-light-shadow-mapping M2 / w14 (D-1) shadow\n * map binding +\n * feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1 BGL hookup\n * (always-on bindings 5/6 paired with the unconditional `POINT_SHADOW_AVAILABLE`\n * define registered in vite-plugin-shader) +\n * feat-20260613-csm-cascaded-shadow-maps M5 / w28 (binding 7 cascade UBO).\n * binding 10 (Points/Lines viewport UBO; always bound for the shared view\n * layout and consumed only by the dedicated points-lines shader).\n * Isolated here so M4 round-4 tests can recreate the layout.\n *\n * feat-20260526-pbr-uniform-fallback-no-storage-buffer M3 / w9:\n * caps.storageBuffer===false switches bindings 1+2 from\n * 'read-only-storage' to 'uniform'.\n */\nexport function buildPbrViewBglEntries(caps: PbrCaps): GPUBindGroupLayoutEntry[] {\n const lightBufType: GPUBufferBindingType = caps.storageBuffer ? 'read-only-storage' : 'uniform';\n return [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: lightBufType },\n },\n {\n binding: 2,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: lightBufType },\n },\n {\n binding: 3,\n visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'depth', viewDimension: '2d' },\n },\n {\n binding: 4,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'comparison' },\n },\n // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1: point shadow\n // cube_array depth atlas. Bound to either the real ShadowAtlas\n // cube_array view (when point shadows are active) or a 1x1x6 fallback\n // cube_array view cleared to 1.0 (fully lit). Visibility is FRAGMENT\n // only -- the directional binding 3 is VERTEX|FRAGMENT for shadow\n // probe-debug sampling, but the cube atlas has no host-side probe path.\n {\n binding: 5,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'depth', viewDimension: 'cube-array' },\n },\n // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1: point shadow\n // params UBO. Carries `array<vec4<f32>, 4>` = 64 B with one lane per\n // shadow-casting point light slot (shadowAtlasLayer in [0, 4)). Each\n // lane stores `(near, far, 1/(far-near), 0)` so the fragment-shader\n // depth-ref reconstruction (lighting-punctual.wgsl evalPointShadowed)\n // can avoid sampling LightSlot for the URP path. HDRP rides the same\n // constants on `LightSlot.kind_and_pad.zw` so binding 6 is unused on\n // HDRP shaders even though the BGL declares it (charter P4 single SSOT\n // BGL across pipelines; the HDRP variant simply doesn't reference the\n // binding in WGSL, which is allowed).\n {\n binding: 6,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n },\n // feat-20260613-csm-cascaded-shadow-maps M5 / w28: shadowCasterCascade\n // UBO (16 B). Carries the 0-based cascade index of the shadow pass\n // currently being rasterized so `shadow_caster.wgsl` can index into\n // `view.lightViewProj_X` per cascade. Shifted from binding 5 to\n // binding 7 on 2026-06-13 to make room for point-shadow bindings 5/6\n // (they predate this feat in main; CSM's slot was the optimal-yield\n // give since point-shadow needs FRAGMENT-only and the cascade UBO\n // needs vertex-stage too — keeping cascade higher avoids interleaving\n // visibility flags within the contiguous shadow-binding cluster).\n {\n binding: 7,\n visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n },\n // feat-20260625-spot-light-shadow-mapping M3 / w14 (D-5): spot shadow\n // atlas. A single `texture_depth_2d` holding up to 4 spot shadows in a 2x2\n // tile grid (urp-pipeline.ts spotShadowDepth). FRAGMENT-only — the spot\n // shadow factor is reconstructed at fragment time via perspective-divide in\n // `evalSpotShadowed` (lighting-punctual.wgsl).\n //\n // ALWAYS-ON (no caps gate, unlike the point cube_array atlas at binding 5\n // which rides POINT_SHADOW_AVAILABLE): spot uses `texture_depth_2d` which is\n // compat-safe in every WebGPU profile, so the binding is unconditionally\n // declared. The matching WGSL declaration is `spotShadowMap` at @group(0)\n // binding 8 in common.wgsl (also unconditional) — the two must stay in\n // lock-step or WebGPU validation rejects the bind group at smoke time\n // (memory: BGL shape mismatch is a browser-path-only bug). No binding 9\n // sampler: spot reuses the comparison sampler at binding 4.\n // feat-20260625-spot-light-shadow-mapping M3 / w14 (D-5): spot shadow 2D\n // atlas, the LAST view-BG binding. The per-spot fragment-read perspective\n // lightViewProj matrices that w24 originally declared at a standalone\n // binding 9 uniform buffer were folded into the View UBO (binding 0,\n // `view.spotLightViewProj`) in w25 (scope-amend webkit-fallback): the\n // standalone binding pushed the WebGL2 fallback fragment uniform-buffer\n // count to 12, over GLES 3.0's `max_uniform_buffers_per_shader_stage = 11`,\n // crashing pipeline-layout creation on the compat path (this feat's target).\n {\n binding: 8,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'depth', viewDimension: '2d' },\n },\n {\n binding: 10,\n visibility: GPU_SHADER_STAGE_VERTEX,\n buffer: { type: 'uniform', hasDynamicOffset: true },\n },\n ];\n}\n\n// ─── PBR pipeline layout factory ────────────────────────────────────────────\n\n/**\n * Build the PBR pipeline layout under D-5 round-4: 4 slots `[view,\n * material, mesh-array, instances]`; the material BGL is derived from the\n * standard material schema and engine injection chain.\n *\n * `caps.storageBuffer===false` switches every storage-buffer BGL entry\n * (view bindings 1+2, mesh-array, instances) to `uniform`.\n *\n * Throws on each `createBindGroupLayout` / `createPipelineLayout` Result\n * failure -- the engine bootstrap path (createRenderer) wraps the call in\n * `runShimSyncStep` to fold the throw into the structured error pipe.\n */\nexport function buildPbrPipelineLayouts(\n device: PbrPipelineDevice,\n caps: PbrCaps,\n): PbrPipelineLayoutBundle {\n // D-13 round-2: 4 BGLs route through buildBindGroupLayoutDescriptor.\n // The dispatcher reads kind + caps; spec content is unused without a\n // registry (no shader-axis reflection at this seam — the 4 BGLs are\n // caps-driven literals + the deterministic Skylight + transmission merge\n // sequence that has no dependency on shader.id).\n const viewBglRes = device.createBindGroupLayout(\n buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, { kind: 'pbr-view', caps }),\n );\n if (!viewBglRes.ok) throw viewBglRes.error;\n\n // Material BGL: derived user region + Skylight + transmission injection.\n // The transmission start binding is computed from the post-Skylight BGL\n // length (= 24 for the built-in Standard schema) by appendInjection.\n const materialBglRes = device.createBindGroupLayout(\n buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, { kind: 'pbr-material-merged' }),\n );\n if (!materialBglRes.ok) throw materialBglRes.error;\n\n // mesh-array BGL.\n const meshArrayBglRes = device.createBindGroupLayout(\n buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, { kind: 'pbr-mesh-array', caps }),\n );\n if (!meshArrayBglRes.ok) throw meshArrayBglRes.error;\n\n // instances BGL.\n const instancesBglRes = device.createBindGroupLayout(\n buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, { kind: 'pbr-instances', caps }),\n );\n if (!instancesBglRes.ok) throw instancesBglRes.error;\n\n // Pipeline layout (4 slots).\n const layouts: readonly [BindGroupLayout, BindGroupLayout, BindGroupLayout, BindGroupLayout] = [\n viewBglRes.value,\n materialBglRes.value,\n meshArrayBglRes.value,\n instancesBglRes.value,\n ];\n const pipelineLayoutRes = device.createPipelineLayout({\n label: 'pbr-pl',\n bindGroupLayouts: layouts,\n });\n if (!pipelineLayoutRes.ok) throw pipelineLayoutRes.error;\n\n return {\n pipelineLayout: pipelineLayoutRes.value,\n viewBgl: viewBglRes.value,\n materialBgl: materialBglRes.value,\n meshArrayBgl: meshArrayBglRes.value,\n instancesBgl: instancesBglRes.value,\n bindGroupLayouts: layouts,\n };\n}\n\n// ─── PBR skin material-shader identifier (SSOT) ────────────────────────────\n\n/**\n * SSOT for the skin material shader's registered identifier. The shader\n * package registers under this string (see register-default-standard-pbr-skin.ts\n * `RESERVED_ID`); runtime dispatch sites import this constant rather than\n * carrying a literal so a future rename is a one-line change. AC-09 grep\n * gate: the body of `selectPipelineLayoutForVariant` MUST NOT contain a\n * literal `'forgeax::pbr-skin'` -- callers map this constant to\n * `LayoutKind = 'pbr-skin'` upstream.\n */\nexport const SKIN_MATERIAL_SHADER_ID = 'forgeax::pbr-skin' as const;\nexport const SHADOW_CASTER_SHADER_ID = 'forgeax::default-shadow-caster' as const;\n\nexport function shadowCasterVariantSet(storageBuffer: boolean, skinned: boolean): string {\n const skinningDisabled = !skinned;\n if (storageBuffer && skinningDisabled) return '';\n return `SKINNING_DISABLED=${String(skinningDisabled)}+STORAGE_BUFFER_AVAILABLE=${String(storageBuffer)}`;\n}\n\nexport function isSkinnedShadowCasterVariant(\n materialShaderId: string | undefined,\n variantSet: string | undefined,\n): boolean {\n return (\n materialShaderId === SHADOW_CASTER_SHADER_ID &&\n variantSet?.includes('SKINNING_DISABLED=false') === true\n );\n}\n\n/** Returns true for the engine-shipped standard-PBR material shader family. */\nexport function isStandardPbrMaterialShader(shaderId: string | undefined): boolean {\n return (\n shaderId === 'forgeax::default-standard-pbr' ||\n shaderId === SKIN_MATERIAL_SHADER_ID ||\n shaderId === 'forgeax::default-standard-pbr-skin'\n );\n}\n\n// ─── PBR skin pipeline layout factory (bug-20260611) ───────────────────────\n//\n// The skin material shader (`forgeax::pbr-skin`, registered by\n// `register-default-standard-pbr-skin.ts`) needs the same 4-slot layout shape\n// as standard PBR EXCEPT for slot 2: its mesh-array BGL declares **2**\n// dynamic-offset entries (binding 0 = meshes, binding 1 = palette) versus\n// standard PBR's single binding 0. Without a dedicated pipeline layout the\n// skin shader's `@group(2) @binding(1) palette : array<mat4x4<f32>>` reference\n// trips a `Binding doesn't exist in [BindGroupLayoutInternal \"pbr-mesh-array-bgl\"]`\n// validation error in `device.createRenderPipeline`, surfaced as\n// `RhiError limit-exceeded` and an invalid command buffer (Playwright TDD trace\n// captured 2026-06-11 in apps/hello/skin).\n//\n// The factory **reuses** view / material / instances BGL handles produced by\n// `buildPbrPipelineLayouts` (charter P4: a single SSOT BGL for each slot the\n// shapes actually share) and only creates a new mesh-array BGL + new pipeline\n// layout. This keeps the per-binding-shape SSOT in one place and avoids an\n// alternate skin-only material BGL (the skin shader's group(0) and group(1)\n// are byte-for-byte the standard-PBR contract).\n\n/**\n * Build the PBR skin pipeline layout (4 slots `[view, material,\n * mesh-array(2-entry), instances]`). View / material / instances BGLs are\n * shared with the standard-PBR layout (passed in via `pbr` bundle); the only\n * new BGL is the 2-entry mesh-array slot for `meshes` + `palette`.\n *\n * Throws on each `createBindGroupLayout` / `createPipelineLayout` Result\n * failure -- the engine bootstrap path wraps the call in `runShimSyncStep`\n * to fold the throw into the structured error pipe.\n */\nexport function buildPbrSkinLayouts(\n device: PbrPipelineDevice,\n caps: PbrCaps,\n pbr: PbrPipelineLayoutBundle,\n): PbrPipelineLayoutBundle {\n // 2-entry mesh-array BGL: binding 0 meshes + binding 1 palette. Both\n // dynamic-offset (palette window per-entity, like meshes window).\n const skinMeshArrayBglRes = device.createBindGroupLayout(\n buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, {\n kind: 'pbr-skin-mesh-array',\n caps,\n }),\n );\n if (!skinMeshArrayBglRes.ok) throw skinMeshArrayBglRes.error;\n\n const layouts: readonly [BindGroupLayout, BindGroupLayout, BindGroupLayout, BindGroupLayout] = [\n pbr.viewBgl,\n pbr.materialBgl,\n skinMeshArrayBglRes.value,\n pbr.instancesBgl,\n ];\n const pipelineLayoutRes = device.createPipelineLayout({\n label: 'pbr-skin-pl',\n bindGroupLayouts: layouts,\n });\n if (!pipelineLayoutRes.ok) throw pipelineLayoutRes.error;\n\n return {\n pipelineLayout: pipelineLayoutRes.value,\n viewBgl: pbr.viewBgl,\n materialBgl: pbr.materialBgl,\n meshArrayBgl: skinMeshArrayBglRes.value,\n instancesBgl: pbr.instancesBgl,\n bindGroupLayouts: layouts,\n };\n}\n\n// ─── Unlit material BGL factory ─────────────────────────────────────────────\n\n/**\n * Build a stand-alone 7-entry unlit material BGL. Round-4 D-5 keeps unlit\n * material BG isolated from Skylight binding 7..13 -- unlit demos do not\n * pay for IBL state. The unlit pipeline still binds material at slot 1,\n * just with a 7-entry layout.\n *\n * Note: at the moment the runtime still routes both unlit + standard\n * through a single 14-entry pipeline layout; the unlit material BG\n * carries fallback identity resources at binding 7..13. This factory is\n * exported as a future-proof seam for the moment when unlit demos own\n * their own pipeline layout (t57 (e) test pins the contract today so the\n * eventual split has a green target).\n */\nexport function buildUnlitMaterialBgl(device: PbrPipelineDevice): BindGroupLayout {\n const res = device.createBindGroupLayout(\n buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, { kind: 'unlit-material' }),\n );\n if (!res.ok) throw res.error;\n return res.value;\n}\n\n// ─── Material BG assembly helpers (unlit) ───────────────────────────────────\n\n/**\n * Inputs for `buildUnlitMaterialBindGroupEntries`. The fields mirror the\n * record-stage's local variables; isolating the assembler here lets t58\n * (e) test exercise the contract without recreating the entire record\n * stage.\n */\nexport interface UnlitMaterialBindGroupEntryInputs {\n readonly materialUniform: Buffer;\n readonly materialOffset: number;\n readonly materialSize: number;\n readonly defaultSampler: Sampler;\n readonly baseColorView: TextureView;\n readonly defaultWhiteView: TextureView;\n}\n\n/**\n * Build the 7 BindGroupEntry values for the unlit material BG (binding\n * 0..6). Output flows into `device.createBindGroup({ layout:\n * unlitMaterialBgl, entries })`.\n */\nexport function buildUnlitMaterialBindGroupEntries(\n inputs: UnlitMaterialBindGroupEntryInputs,\n): BindGroupEntry[] {\n return [\n {\n binding: 0,\n resource: {\n kind: 'buffer' as const,\n value: {\n buffer: inputs.materialUniform,\n offset: inputs.materialOffset,\n size: inputs.materialSize,\n },\n },\n },\n { binding: 1, resource: { kind: 'sampler' as const, value: inputs.defaultSampler } },\n { binding: 2, resource: { kind: 'textureView' as const, value: inputs.baseColorView } },\n { binding: 3, resource: { kind: 'sampler' as const, value: inputs.defaultSampler } },\n { binding: 4, resource: { kind: 'textureView' as const, value: inputs.defaultWhiteView } },\n { binding: 5, resource: { kind: 'sampler' as const, value: inputs.defaultSampler } },\n { binding: 6, resource: { kind: 'textureView' as const, value: inputs.defaultWhiteView } },\n ];\n}\n\n// Surface re-export so consumers can build a complete BindGroup pipeline\n// without reaching into multiple modules.\nexport type { BindGroup };\n\n// ─── feat-20260625 M3 / w10 — sprite-pass variantSet selector ────────────────\n//\n// Plan-strategy D-1 + D-4: when an entity carries `SpriteInstances` the\n// sprite-pass record stage must pick the `PER_INSTANCE_REGION=true` sprite\n// shader variant compiled in M2 (w7) so the WGSL `InstanceData` struct\n// includes the per-instance `region: vec4<f32>` field and reads region from\n// the interleaved 80B-per-instance buffer (not from the material UBO).\n//\n// Non-`SpriteInstances` sprite entities (e.g. the sprite-atlas demo) keep\n// the default variant where `PER_INSTANCE_REGION` is undefined and the\n// shader's `#else` branch reads region from material UBO — preserving\n// existing behaviour (plan-strategy D-4 \"pbr / unlit / sprite-atlas\n// behaviour unchanged\" / requirements Edge Cases).\n//\n// Variant set string format mirrors the existing `URP_PBR_VARIANT_SET` /\n// HDRP variant set string idiom in `pipeline-spec.ts` (`+`-separated kv\n// pairs); the record stage threads this string through the per-shader\n// pipeline-cache key + lazy-build `getMaterialShaderPipeline` lookup.\n\n/**\n * variantSet string fired into the sprite-pass pipeline cache when the\n * entity carries `SpriteInstances` (plan-strategy D-1 interleaved single\n * buffer + D-4 axis on `sprite.wgsl`).\n *\n * bug-20260708 M2 (c): aligned with the canonical all-true variant key\n * `''` — sprite's manifest emits `{PIR:true, SBA:true}` under the empty-\n * string key (all variant axes true → canonical). The runtime's\n * `getMaterialShaderPipeline` variant-substitution branch\n * (`createRenderer.ts:1730`) resolves this via\n * `findVariantByKey(msEntry, '')` returning the 5653B PIR=true variant.\n * Combined with the `cacheKeyOf` sentinel `~` (bug-20260708 M2 (b)) this\n * value produces a cache key distinct from the `variantSet=undefined`\n * character/default path (which now resolves to the PIR=false 5575B boot-\n * registered variant). Sprite pipeline layout routing is anchored via\n * `LayoutKind='sprite-urp'` so `variantSet=''` here does NOT trigger the\n * HDRP-layout branch of `selectPipelineLayoutForVariant` (research R-12\n * flow; plan-strategy §4 R-1' guard).\n */\nexport const SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET = '';\n\n// BglKind dispatch (M3 / D-13) — closed union of BGL shapes the runtime ships\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Closed union of bind-group-layout shapes the runtime constructs.\n *\n * Each kind names one physically distinct BGL the runtime has historically\n * built by hand. {@link buildBindGroupLayoutDescriptor} dispatches on this\n * union so every `device.createBindGroupLayout(...)` call site shares one\n * SSOT for entries / labels (plan-strategy §3.2; D-13 round-2 decision).\n *\n * Three groups by derivation source:\n * 1. Shader-derived (paramSchema reflection + injection chain):\n * - `'pbr-material-merged'` — derived user region + Skylight 7 + transmission 2\n * - `'unlit-material'` — 7 entries: base PBR material only (no inject)\n * - `'hdrp-7-slot'` — 7 entries (binding 0 + 3..8): HDRP cluster + SSAO group(2) BGL\n * 2. Caps-driven literal shapes (no shader):\n * - `'pbr-view'` — 10 entries: view UBO + lights + 6 shadow bindings\n * (directional 3/4, point 5/6, cascade 7, spot atlas 8, spot\n * lightViewProj matrices 9 — feat-20260625)\n * - `'pbr-mesh-array'` — 1 entry: per-entity mesh SSBO (dynamic-offset)\n * - `'pbr-instances'` — 1 entry: per-instance SSBO (no dynamic-offset)\n * - `'pbr-skin-mesh-array'` — 2 entries: meshes + skin palette\n * 3. Attachment-driven (fullscreen post-process):\n * - `'fullscreen-post'` — 2 entries: input texture + sampler. The texture\n * `sampleType` is derived from `spec.attachments` (plan §R3 fix):\n * `'depth32float'` → `'depth'`; `'r32float'` → `'unfilterable-float'`;\n * else → `'float'`.\n * - `'fullscreen-post-with-params'` — 3 entries: the same texture@0 +\n * sampler@1 as `'fullscreen-post'`, plus a `buffer@2` uniform for the\n * per-frame params UBO (feat-20260621 D-2: `entry.params !== undefined`\n * passes route here; the layout stays group(1), q3=B). `'fullscreen-post'`\n * stays byte-identical so param-less consumers degrade with no change.\n * - `'fullscreen-post-with-scene-depth-msaa'` — the depth-read layout with\n * `texture.multisampled=true`, selected for a 4-sample scene depth target.\n */\nexport type BglKind =\n | 'pbr-view'\n | 'pbr-material-merged'\n | 'pbr-mesh-array'\n | 'pbr-instances'\n | 'pbr-skin-mesh-array'\n | 'unlit-material'\n | 'hdrp-7-slot'\n | 'fullscreen-post'\n | 'fullscreen-post-with-params'\n | 'fullscreen-post-with-scene-depth'\n | 'fullscreen-post-with-scene-depth-msaa';\n\n/**\n * Output shape of {@link buildBindGroupLayoutDescriptor}: matches the RHI\n * `BindGroupLayoutDescriptor` (label + entries with `ExplicitUndefined`) so\n * the result can be passed directly to `device.createBindGroupLayout(...)`.\n *\n * `entries` is a mutable `Array` to match `GPUBindGroupLayoutDescriptor`\n * (WebGPU types declare it mutable). Callers MUST treat the array as\n * read-only — the dispatcher freezes neither the array nor its entries\n * for hot-path performance.\n */\nexport interface BindGroupLayoutDescriptorOutput {\n readonly label: string | undefined;\n readonly entries: GPUBindGroupLayoutEntry[];\n}\n\n/** Build the canonical HDRP group(2) bind-group layout. */\nexport function createHdrpBindGroupLayoutDescriptor(\n storageBuffer: boolean = true,\n): BindGroupLayoutDescriptor {\n const meshBufType: GPUBufferBindingType = storageBuffer ? 'read-only-storage' : 'uniform';\n const clusterBufType: GPUBufferBindingType = storageBuffer ? 'read-only-storage' : 'uniform';\n return {\n label: 'hdrp-unified-bgl-group2',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_VERTEX,\n buffer: { type: meshBufType, hasDynamicOffset: true },\n },\n // Bindings 1 and 2 stay absent for the URP physical isolation gap.\n {\n binding: 3,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: clusterBufType, hasDynamicOffset: false },\n },\n {\n binding: 4,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: clusterBufType, hasDynamicOffset: false },\n },\n {\n binding: 5,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: clusterBufType, hasDynamicOffset: false },\n },\n {\n binding: 6,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform', hasDynamicOffset: false },\n },\n {\n binding: 7,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d', multisampled: false },\n },\n {\n binding: 8,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n ],\n };\n}\n\n/**\n * Build a `GPUBindGroupLayoutDescriptor` from a PipelineSpec, dispatching on\n * `options.kind` to one of 9 closed BGL shapes (D-13 round-2).\n *\n * Shader-derived kinds (`'pbr-material-merged'` / `'unlit-material'` /\n * `'hdrp-7-slot'`) require `options.registry` to look up the shader entry\n * and reflect its `paramSchema` via {@link deriveBglShapeFromShader}; they\n * compose the per-entry injection chain (Skylight + transmission for material;\n * HDRP variantSet for cluster-forward).\n *\n * Caps-driven kinds (`'pbr-view'` / `'pbr-mesh-array'` / `'pbr-instances'` /\n * `'pbr-skin-mesh-array'`) require `options.caps` for the storage-buffer\n * vs uniform-buffer fallback (RhiCaps.storageBuffer; PBR feat-20260526 M3 /\n * w9). They are wholly determined by the caps shape.\n *\n * Attachment-driven kind (`'fullscreen-post'`) reads\n * `spec.attachments.depthFormat` and `spec.attachments.colorFormats[0]` to\n * pick the texture binding's `sampleType` (R3 fix: `'depth32float'` → `'depth'`,\n * `'r32float'` → `'unfilterable-float'`, else → `'float'`).\n *\n * @param spec - the pipeline spec (axis source for reflection / caps fallback)\n * @param options.kind - which BGL shape to build (closed {@link BglKind} union)\n * @param options.registry - ShaderCatalog for shader-derived kinds\n * @param options.caps - caps shape for caps-driven kinds (storageBuffer)\n * @returns a WebGPU bind-group-layout descriptor (entries + label)\n * @see plan-strategy §3.2 · plan-decisions D-13 · requirements AC-02\n */\n/**\n * Resolve the material paramSchema for a per-shader user-region BGL derivation.\n *\n * Priority (D-1): explicit `options.materialParamSchema` > registry lookup of\n * `spec.shader.id` > `undefined` (the user-region builder then falls back to\n * the built-in standard-PBR 4-texture schema, whose user region is 9 entries).\n */\nfunction resolveMaterialParamSchema(\n spec: PipelineSpec,\n options: { registry?: ShaderCatalog; materialParamSchema?: readonly ParamSchemaEntry[] },\n): readonly ParamSchemaEntry[] | undefined {\n if (options.materialParamSchema !== undefined) return options.materialParamSchema;\n if (options.registry !== undefined) {\n const lookup = options.registry.findMaterialArtifact(spec.shader.id);\n if (lookup.ok) return lookup.value.paramSchema;\n }\n return undefined;\n}\n\nexport function buildBindGroupLayoutDescriptor(\n spec: PipelineSpec,\n options: {\n kind: BglKind;\n registry?: ShaderCatalog;\n caps?: PbrCaps;\n /**\n * Material paramSchema for the per-shader user-region derivation\n * (`'pbr-material-merged'` / `'unlit-material'`). When supplied it is the\n * authoritative source for the user-region BGL shape (D-1); when omitted,\n * `buildPbrMaterialUserRegionEntries` falls back to the built-in\n * standard-PBR 4-texture schema (user region is 9 entries), so\n * the caps-driven `buildPbrPipelineLayouts` seam keeps working unchanged.\n * A registry + resolvable shader id takes precedence over this field.\n */\n materialParamSchema?: readonly ParamSchemaEntry[];\n },\n): BindGroupLayoutDescriptorOutput {\n switch (options.kind) {\n case 'pbr-view': {\n const caps = options.caps ?? { storageBuffer: true };\n return {\n label: 'pbr-view-bgl',\n entries: buildPbrViewBglEntries(caps),\n };\n }\n case 'pbr-mesh-array': {\n const caps = options.caps ?? { storageBuffer: true };\n const meshBufType: GPUBufferBindingType = caps.storageBuffer\n ? 'read-only-storage'\n : 'uniform';\n // sprite-lit's fragment stage does not read the mesh SSBO -- worldPos\n // is carried through the VsOut interpolant. Visibility is kept widened\n // to VERTEX|FRAGMENT because the BGL JSON is compared byte-identically\n // across the sprite / sprite-lit / PBR pipelines that share this\n // descriptor; narrowing here would change every sibling pipeline's\n // BGL fingerprint. WebGPU rejects createRenderPipeline when a fragment\n // stage accesses a binding whose BGL visibility excludes FRAGMENT --\n // widening is permissive (validation-only, no perf cost).\n return {\n label: 'pbr-mesh-array-bgl',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: meshBufType, hasDynamicOffset: true },\n },\n ],\n };\n }\n case 'pbr-instances': {\n const caps = options.caps ?? { storageBuffer: true };\n const meshBufType: GPUBufferBindingType = caps.storageBuffer\n ? 'read-only-storage'\n : 'uniform';\n return {\n label: 'pbr-instances-bgl',\n entries: [\n {\n binding: 0,\n // Standard transmission reads the same per-instance transform in\n // fs_main to convert glTF unit-space thickness into world metres.\n // Keep one shared instances BGL and widen its visibility instead\n // of introducing a second transform upload or six new varyings.\n visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: meshBufType, hasDynamicOffset: false },\n },\n ],\n };\n }\n case 'pbr-skin-mesh-array': {\n const caps = options.caps ?? { storageBuffer: true };\n const meshBufType: GPUBufferBindingType = caps.storageBuffer\n ? 'read-only-storage'\n : 'uniform';\n return {\n label: 'pbr-skin-mesh-array-bgl',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_VERTEX,\n buffer: { type: meshBufType, hasDynamicOffset: true },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_VERTEX,\n buffer: { type: meshBufType, hasDynamicOffset: true },\n },\n ],\n };\n }\n case 'pbr-material-merged': {\n // Material BGL: per-shader user-region (derive(paramSchema).bglEntries)\n // + IBL injection (7) + transmission injection (2). The user-region\n // size is the only variable; injection start = userRegion.length so a\n // custom schema shifts IBL/transmission by its sampler/texture pairs.\n // The built-in 8-texture standard-PBR schema is 17 + 7 + 2 = 26 entries.\n //\n // Schema source priority (D-1): explicit materialParamSchema option >\n // registry lookup of spec.shader.id > built-in standard-PBR fallback.\n const resolvedSchema = resolveMaterialParamSchema(spec, options);\n const userRegion = buildPbrMaterialUserRegionEntries(resolvedSchema);\n const afterIbl = [...userRegion, ...appendInjection(userRegion, 'ibl')];\n const merged = [...afterIbl, ...appendInjection(afterIbl, 'transmission')];\n return {\n label: 'pbr-material-skylight-bgl',\n entries: merged,\n };\n }\n case 'unlit-material': {\n // Unlit material BGL: per-shader user-region only. No IBL/transmission\n // injection (D-5 round-4: unlit demos do not pay for IBL state).\n const resolvedSchema = resolveMaterialParamSchema(spec, options);\n return {\n label: 'unlit-material-bgl',\n entries: buildPbrMaterialUserRegionEntries(resolvedSchema),\n };\n }\n case 'hdrp-7-slot': {\n // HDRP unified BGL for group(2): 9 entries (binding 0 + 3..8). The\n // shape depends on caps.storageBuffer for the cluster-buffer fallback.\n const caps = options.caps ?? { storageBuffer: true };\n const desc = createHdrpBindGroupLayoutDescriptor(caps.storageBuffer);\n return {\n label: desc.label ?? 'hdrp-unified-bgl-group2',\n entries: [...(desc.entries ?? [])],\n };\n }\n case 'fullscreen-post': {\n // Fullscreen post-process BGL: 2 entries (input texture + sampler).\n // R3 fix: derive sampleType from spec.attachments. Depth attachments\n // (depth32float) need `sampleType: 'depth'`; r32float needs\n // `'unfilterable-float'`; everything else (rgba8unorm-srgb, rgba16float,\n // bgra8unorm, …) is filterable `'float'`.\n return {\n label: 'fullscreen-post-bgl',\n entries: buildFullscreenPostInputEntries(spec),\n };\n }\n case 'fullscreen-post-with-params': {\n // feat-20260621 D-2: the same input texture@0 + sampler@1 as\n // 'fullscreen-post', plus binding 2 = per-frame params UBO (uniform).\n // The first two entries reuse buildFullscreenPostInputEntries so the\n // sampleType derivation stays a single SSOT; 'fullscreen-post' is\n // untouched (param-less zero-regression, R-A7).\n return {\n label: 'fullscreen-post-with-params-bgl',\n entries: [\n ...buildFullscreenPostInputEntries(spec),\n {\n binding: 2,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n },\n ],\n };\n }\n case 'fullscreen-post-with-scene-depth': {\n // plan-strategy D-3: 5-entry BGL for post-process passes that read the\n // camera scene depth. color@0 + sampler@1 reuse buildFullscreenPostInputEntries\n // (float+filtering for color). depthTex@3 uses `sampleType: 'depth'` and\n // `dimension: '2d'`; depthSampler@4 uses `type: 'non-filtering'` (nearest\n // + clamp-to-edge, D-2 — NOT comparison). params@2 is always present\n // (uniform) to avoid a 2x2 kind explosion per D-3.\n return {\n label: 'fullscreen-post-with-scene-depth-bgl',\n entries: [\n ...buildFullscreenPostInputEntries(spec),\n {\n binding: 2,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n },\n {\n binding: 3,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'depth', viewDimension: '2d' },\n },\n {\n binding: 4,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'non-filtering' },\n },\n ],\n };\n }\n case 'fullscreen-post-with-scene-depth-msaa': {\n return {\n label: 'fullscreen-post-with-scene-depth-msaa-bgl',\n entries: [\n ...buildFullscreenPostInputEntries(spec),\n {\n binding: 2,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n },\n {\n binding: 3,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'depth', viewDimension: '2d', multisampled: true },\n },\n {\n binding: 4,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'non-filtering' },\n },\n ],\n };\n }\n }\n}\n\n/**\n * The shared texture@0 + sampler@1 entries for fullscreen post-process BGLs.\n * sampleType is derived from `spec.attachments` (R3 fix): depth attachments →\n * `'depth'` + `'comparison'` sampler; `'r32float'` → `'unfilterable-float'`;\n * else → `'float'` + `'filtering'`. Both `'fullscreen-post'` and\n * `'fullscreen-post-with-params'` reuse this so the derivation is one SSOT.\n */\nfunction buildFullscreenPostInputEntries(spec: PipelineSpec): GPUBindGroupLayoutEntry[] {\n const inputFormat: GPUTextureFormat | undefined =\n spec.attachments.depthFormat ?? spec.attachments.colorFormats[0];\n const sampleType: GPUTextureSampleType =\n inputFormat === 'depth32float' ||\n inputFormat === 'depth24plus' ||\n inputFormat === 'depth24plus-stencil8' ||\n inputFormat === 'depth16unorm'\n ? 'depth'\n : inputFormat === 'r32float'\n ? 'unfilterable-float'\n : 'float';\n return [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType, viewDimension: '2d' },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: {\n type: sampleType === 'depth' ? 'comparison' : 'filtering',\n },\n },\n ];\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n","// PipelineSpec 4-axis SSOT — single-file type + derive-fn + entrypoint + error model.\n//\n// feat-20260615-pipeline-spec-ssot M1: Establish PipelineSpec 4-axis type SSOT.\n// M1-T1: type definitions + KNOWN_PASS_KINDS + PipelineSpecError closed union.\n// M1-T2: 6 pure derive functions.\n// M1-T3: deriveBglShapeFromShader helper.\n// M1-T4: getOrBuildPipeline entrypoint + PipelineCache.\n// M1-T5: 12 SPEC_CONST boot-time table.\n//\n// Design axiom: PipelineSpec is business-agnostic — no 'pbr' / 'sprite' / 'skybox'\n// / 'fullscreen-*' strings appear on the type surface (plan-strategy D-7).\n// BGL shape taxonomy lives in the ShaderCatalog implementation, not in spec.\n//\n// Charter alignment:\n// F1: single file entrypoint (getOrBuildPipeline) — AI user indexes once\n// P1: progressive disclosure — types at top, fns mid, error model bottom\n// P3: explicit failure — closed PipelineSpecError union, no silent routes\n// P4: consistent abstraction — 4-axis aligns with wgpu/Bevy/Three.js\n\nimport {\n deriveVertexBufferLayout,\n deriveVertexLayoutProjection,\n type VertexLayoutProjection,\n} from '@forgeax/engine-geometry';\nimport {\n err,\n KNOWN_PASS_KINDS,\n type MaterialRenderState,\n ok,\n type PrimitiveTopology,\n type Result,\n type VertexAttributeMap,\n} from '@forgeax/engine-types';\nimport { VertexColorVariantConflictError } from './errors/render';\n\nexport {\n type BglKind,\n type BindGroupLayoutDescriptorOutput,\n buildBindGroupLayoutDescriptor,\n createHdrpBindGroupLayoutDescriptor,\n} from './pbr-pipeline';\n\n// Re-export KNOWN_PASS_KINDS from @forgeax/engine-types for single-file discoverability (charter F1).\nexport { KNOWN_PASS_KINDS };\n\n/**\n * The engine-owned deferred material target layout. `fs_gbuffer` returns\n * normal+roughness, albedo+metallic, and emissive+AO in this order.\n */\nexport const DEFERRED_COLOR_FORMATS: readonly GPUTextureFormat[] = [\n 'rgba16float',\n 'rgba8unorm',\n 'rgba16float',\n];\n\n/** Derive the color attachment shape for a material pass kind. */\nexport function colorFormatsForPassKind(\n passKind: string,\n defaultColorFormat: GPUTextureFormat,\n): readonly GPUTextureFormat[] {\n if (passKindPolicyTable[passKind]?.shape === 'depth-only') return [];\n if (passKind === 'deferred') return DEFERRED_COLOR_FORMATS;\n return [defaultColorFormat];\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// PipelineSpec — immutable 4-axis data description (D-7: business-agnostic)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Pipeline specification — immutable 4-axis data that completely determines\n * what `device.createRenderPipeline(...)` does for a material shader pass.\n *\n * The 4 axes are:\n * - `shader`: which WGSL source + material param schema + pass kind + variant set\n * - `attachments`: color/depth/stencil formats + sample count (MSAA)\n * - `geometry`: primitive topology + vertex attribute layout + index format\n * - `renderState`: optional per-material render-state overrides (blend/cull/depth/stencil)\n *\n * Business-agnostic: no `'pbr'` / `'sprite'` / `'skybox'` strings pollute this\n * type. BGL shape taxonomy is derived from `ShaderCatalog` internal reflection\n * and never appears on the spec surface (plan-strategy D-7).\n *\n * @see plan-strategy §1 (4-axis) · D-7 (business-agnostic) · requirements §3.1\n */\nexport type { PipelineSpec } from './pipeline-spec-types';\n\nimport type { PipelineSpec } from './pipeline-spec-types';\n// ══════════════════════════════════════════════════════════════════════════════\n// PipelineSpecError — closed union (5 + 2 transit codes)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Closed union of PipelineSpec error codes.\n *\n * 5 business codes:\n * - `'spec-inconsistent'`: axis mutual exclusion violated\n * - `'unknown-pass-kind'`: passKind not in KNOWN_PASS_KINDS or registered\n * - `'shader-bgl-reflection-mismatch'`: reflected BGL shape != shader declaration\n * - `'attachment-format-incompatible'`: depth/stencil format vs PSO mismatch\n * - `'unsupported-vertex-layout'`: vertex attributes don't match shader vs_main\n *\n * 2 transit codes:\n * - `'pipeline-build-failed'`: wraps RhiError from device.createRenderPipeline\n * - `'shader-not-registered'`: ShaderCatalog lookup returned undefined\n *\n * @see requirements §3.4 · AC-10 · charter P3\n */\nexport type PipelineSpecErrorCode =\n | 'spec-inconsistent'\n | 'unknown-pass-kind'\n | 'shader-bgl-reflection-mismatch'\n | 'attachment-format-incompatible'\n | 'unsupported-vertex-layout'\n | 'pipeline-build-failed'\n | 'shader-not-registered';\n\n/**\n * Structured pipeline-spec error — carries `.code` (discriminated union) +\n * `.detail` (narrowed per code) + `.hint` (AI-user actionable prose).\n *\n * Inherits from `Error` so it integrates with existing catch blocks; the\n * `.code` field enables exhaustive `switch` narrowing without string parsing\n * (charter P3).\n */\nexport class PipelineSpecError extends Error {\n readonly code: PipelineSpecErrorCode;\n /**\n * Narrowed detail payload — shape depends on `code`.\n *\n * - `'spec-inconsistent'`: `{ reason: string }`\n * - `'unknown-pass-kind'`: `{ expected: readonly string[]; actual: string; hint?: string }`\n * - `'shader-bgl-reflection-mismatch'`: `{ reflected: unknown; declared: unknown }`\n * - `'attachment-format-incompatible'`: `{ reason: string; expected?: string; actual?: string }`\n * - `'unsupported-vertex-layout'`: `{ specAttrs: string[]; shaderAttrs: string[] }`\n * - `'pipeline-build-failed'`: `{ gpuMessage?: string; cause?: unknown }`\n * - `'shader-not-registered'`: `{ shaderId: string; hint?: string }`\n */\n readonly detail: Record<string, unknown>;\n\n constructor(args: {\n code: PipelineSpecErrorCode;\n detail: Record<string, unknown>;\n hint?: string;\n }) {\n super(\n args.hint !== undefined\n ? `PipelineSpecError [${args.code}]: ${args.hint}`\n : `PipelineSpecError [${args.code}]`,\n );\n this.name = 'PipelineSpecError';\n this.code = args.code;\n this.detail = args.detail;\n }\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// renderStateHashSuffix — deterministic hash of MaterialRenderState\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Material snapshots hand the renderer immutable render-state objects. Keep\n * the serialized suffix by object identity just like the vertex-layout\n * digest below; the hot path otherwise sorts keys and serializes the same\n * state once per renderable. Callers must not mutate a MaterialRenderState\n * after passing it to the renderer (the PipelineSpec contract is immutable).\n */\nconst RENDER_STATE_HASH_CACHE = new WeakMap<object, string>();\n\n/**\n * Deterministic hash suffix for MaterialRenderState (sorted keys, JSON.stringify).\n *\n * Returns `''` when `renderState` is `undefined` or has zero entries,\n * preserving cache-key byte-compatibility with the pre-M1 shape.\n */\nexport function renderStateHash(renderState: MaterialRenderState | undefined): string {\n if (renderState === undefined) return '';\n const cached = RENDER_STATE_HASH_CACHE.get(renderState);\n if (cached !== undefined) return cached;\n const sorted = Object.keys(renderState).sort();\n if (sorted.length === 0) {\n RENDER_STATE_HASH_CACHE.set(renderState, '');\n return '';\n }\n const payload: Record<string, unknown> = {};\n for (const k of sorted) {\n const v = renderState[k as keyof MaterialRenderState];\n if (v !== undefined) payload[k] = v;\n }\n const result = `:${JSON.stringify(payload)}`;\n RENDER_STATE_HASH_CACHE.set(renderState, result);\n return result;\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// 6 pure derive functions (M1-T2)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Compute a deterministic cache key from a PipelineSpec.\n *\n * The key covers all 4 axes + BGL shape hash (derived from ShaderCatalog\n * reflection via {@link deriveBglShapeFromShader}). Two specs that produce\n * the same cache key MUST produce byte-identical PSO descriptors.\n *\n * Algorithm: concatenate each axis segment with `:` separators, hash the\n * BGL shape for compactness, and emit a single cache-key string.\n *\n * @see plan-strategy §3.1 · requirements AC-02\n */\nexport function cacheKeyOf(spec: PipelineSpec): string {\n const { shader, attachments, geometry, renderState } = spec;\n const topoSegment = geometry.topology;\n const stripSegment =\n (topoSegment === 'line-strip' || topoSegment === 'triangle-strip') &&\n geometry.stripIndexFormat !== undefined\n ? `:${geometry.stripIndexFormat}`\n : '';\n\n // The geometry owner publishes one immutable projection. Legacy callers may\n // still provide only the map; derive the same projection at this boundary.\n const vlDigest =\n geometry.vertexLayoutProjection?.digest ??\n deriveVertexLayoutProjection(geometry.vertexLayout).digest;\n\n const uvSetCountSegment =\n geometry.shaderUvSetCount !== undefined ? `:uvsc${geometry.shaderUvSetCount}` : '';\n\n // bug-20260708 M2 (b): sentinel `~` distinguishes `variantSet=undefined`\n // (no-variant / default-variant request) from canonical all-true key `''`\n // (all variant axes true). Prior `?? ''` collapsed the two into the same\n // cache key, causing the first-cached pipeline to win and unrelated\n // variantSet requests to reuse its shader module (research R-11 / R-12).\n // `~` (ASCII 0x7E) is a reserved sentinel char — no legitimate\n // variantSet literal contains it; guarded by\n // `pipeline-cache-keying.unit.test.ts` sentinel-conflict assertions.\n const variantSegment = shader.variantSet === undefined ? '~' : shader.variantSet;\n return (\n [\n shader.id,\n shader.passKind,\n variantSegment,\n attachments.colorFormats.join(','),\n attachments.depthFormat ?? '',\n String(attachments.sampleCount),\n topoSegment,\n stripSegment,\n `vl:${vlDigest}`,\n renderStateHash(renderState),\n ].join(':') + uvSetCountSegment\n );\n}\n\n/**\n * Reconcile the authored vertex-color shader axis with the geometry-owned\n * projection. COLOR_0 is a geometry fact and cannot be selected independently\n * by a material variant.\n */\nexport function variantSetFromVertexLayoutProjection(\n projection: VertexLayoutProjection,\n authoredVariantSet: string | undefined,\n): Result<string, VertexColorVariantConflictError> {\n const projected = projection.attributes.some((attribute) => attribute.key === 'color');\n const axis = `VERTEX_COLOR_AVAILABLE=${projected ? 'true' : 'false'}`;\n if (authoredVariantSet === undefined) return ok(axis);\n if (projected && authoredVariantSet === '') return ok(authoredVariantSet);\n\n const authoredParts = authoredVariantSet.split('+');\n const authoredColorPart = authoredParts.find((part) =>\n part.startsWith('VERTEX_COLOR_AVAILABLE='),\n );\n if (authoredColorPart === undefined) {\n const parts = authoredParts.filter((part) => part.length > 0);\n parts.push(axis);\n return ok(parts.join('+'));\n }\n\n const authoredValue = authoredColorPart.slice('VERTEX_COLOR_AVAILABLE='.length);\n const authored = authoredValue === 'true';\n if ((authoredValue !== 'true' && authoredValue !== 'false') || authored !== projected) {\n return err(new VertexColorVariantConflictError(authoredValue, projected));\n }\n const parts = authoredParts.filter(\n (part) => part.length > 0 && !part.startsWith('VERTEX_COLOR_AVAILABLE='),\n );\n parts.push(axis);\n return ok(parts.join('+'));\n}\n\n/**\n * Build a `GPURenderPipelineDescriptor` from a PipelineSpec + shader modules.\n *\n * Pure derivation: same (spec, modules) always produces the same descriptor.\n * Consumed by `getOrBuildPipeline` on cache miss; also available as a public\n * helper for AI users who want the descriptor shape without going through the\n * cache entrypoint.\n *\n * @param spec - the pipeline spec (4 axes)\n * @param modules - `{ vertex: GPUShaderModule; fragment: GPUShaderModule }`\n * @returns a complete WebGPU render-pipeline descriptor\n * @see plan-strategy §3.2 · requirements AC-02\n */\nexport function buildPipelineDescriptor(\n spec: PipelineSpec,\n modules: {\n vertex: unknown;\n fragment: unknown;\n vertexEntryPoint?: string;\n fragmentEntryPoint?: string;\n layout?: unknown;\n },\n): Record<string, unknown> {\n // M2-T4: derive vertex buffers from spec.geometry.vertexLayout via\n // deriveVertexBufferLayout (imported from vertex-attribute-layout.ts).\n // Empty vertexLayout (fullscreen-post passes) → [].\n // Non-empty (material shaders) → interleaved single-buffer layout.\n //\n // Entry points default to 'vs_main' / 'fs_main' for the 3 standard material\n // shaders; fullscreen-post passes (skybox 'skybox_fs', SSAO 'vs_ssao' / 'fs_ssao_calc')\n // pass custom entry points through the modules parameter.\n //\n // The optional `layout` field, when present, is forwarded to the descriptor\n // so that the provider can detect it is already set and avoid overwriting.\n\n const { attachments, geometry, renderState } = spec;\n\n // A supplied projection is the geometry owner's immutable GPU descriptor.\n // Do not re-derive it from a possibly stale attribute map.\n const vertexBuffers =\n geometry.vertexLayoutProjection === undefined\n ? deriveVertexBufferLayout(geometry.vertexLayout, {\n ...(geometry.shaderUvSetCount !== undefined\n ? { shaderUvSetCount: geometry.shaderUvSetCount }\n : {}),\n })\n : geometry.vertexLayoutProjection.attributes.length === 0\n ? []\n : [\n {\n arrayStride: geometry.vertexLayoutProjection.arrayStride,\n attributes: geometry.vertexLayoutProjection.attributes.map(\n ({ shaderLocation, offset, format }) => ({\n shaderLocation,\n offset,\n format,\n }),\n ),\n },\n ];\n\n const descriptor: Record<string, unknown> = {\n vertex: {\n module: modules.vertex,\n entryPoint: modules.vertexEntryPoint ?? 'vs_main',\n buffers: vertexBuffers,\n },\n };\n\n // Fragment stage: absent for shadow-caster (depth-only), present for forward.\n if (attachments.colorFormats.length > 0) {\n descriptor.fragment = {\n module: modules.fragment,\n entryPoint: modules.fragmentEntryPoint ?? 'fs_main',\n targets: attachments.colorFormats.map((fmt) => {\n const target: Record<string, unknown> = { format: fmt };\n if (renderState?.blend !== undefined) {\n target.blend = renderState.blend;\n }\n return target;\n }),\n };\n }\n\n // Layout: forward if provided by caller (fullscreen-post passes set it).\n if (modules.layout !== undefined) {\n descriptor.layout = modules.layout;\n }\n\n // Primitive state.\n const primitive: Record<string, unknown> = {\n topology: geometry.topology,\n cullMode: renderState?.cullMode ?? 'back',\n frontFace: renderState?.frontFace ?? 'ccw',\n };\n if (geometry.topology.endsWith('strip') && geometry.stripIndexFormat !== undefined) {\n primitive.stripIndexFormat = geometry.stripIndexFormat;\n }\n descriptor.primitive = primitive;\n\n // Depth-stencil state.\n if (attachments.depthFormat !== undefined) {\n const ds: Record<string, unknown> = {\n format: attachments.depthFormat,\n depthWriteEnabled: renderState?.depthWriteEnabled ?? true,\n depthCompare: renderState?.depthCompare ?? 'less',\n };\n if (renderState?.stencilReadMask !== undefined) {\n ds.stencilReadMask = renderState.stencilReadMask;\n }\n if (renderState?.stencilWriteMask !== undefined) {\n ds.stencilWriteMask = renderState.stencilWriteMask;\n }\n if (renderState?.stencil !== undefined) {\n ds.stencilFront = renderState.stencil;\n ds.stencilBack = renderState.stencil;\n }\n descriptor.depthStencil = ds;\n }\n\n // Multisample: absent for sampleCount=1 (undefined). For each value > 1,\n // emit { count: sampleCount } so forward-compat sample counts (2, 8, …)\n // flow through to the descriptor without requiring a type change.\n if (attachments.sampleCount > 1) {\n descriptor.multisample = {\n count: attachments.sampleCount,\n ...(renderState?.alphaToCoverageEnabled === true && { alphaToCoverageEnabled: true }),\n };\n }\n\n return descriptor;\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// passKindPolicyTable — closed map: passKind → attachment shape + default ops\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Default colour-attachment ops carried by a passKind policy.\n *\n * `clearValue` is `undefined` for `loadOp='load'` policies (no clear value\n * is emitted into the descriptor when the prior contents are loaded).\n */\nexport interface AttachmentColorOps {\n readonly loadOp: 'clear' | 'load';\n readonly storeOp: 'store' | 'discard';\n readonly clearValue: GPUColor | undefined;\n}\n\n/**\n * Default depth-attachment ops carried by a passKind policy.\n *\n * `stencilLoadOp` / `stencilStoreOp` are absent on the policy itself — the\n * stencil-op gate is auto-derived from `specAttachments.depthFormat` at call\n * time (`'depth24plus-stencil8'` → `'clear'+'discard'`; everything else\n * elides stencil ops). This collapses the R3/R5 stencil-op duplicates that\n * previously lived inline at every forward-pass beginRenderPass call site.\n */\nexport interface AttachmentDepthOps {\n readonly loadOp: 'clear' | 'load';\n readonly storeOp: 'store' | 'discard';\n readonly clearValue: number;\n}\n\n/**\n * Attachment policy for a single passKind — declares the colour / depth shape\n * the pass produces and the default load/store ops. Per-call-site overrides\n * (skybox vs main forward differing on `colorLoadOp`, sprite-split forward\n * differing on both `colorLoadOp` and `depthLoadOp`) flow through the\n * `options` parameter of {@link buildBeginRenderPassDescriptor}.\n *\n * `shape` discriminator drives which attachment slots the descriptor emits:\n * - `'depth-only'` → empty `colorAttachments[]`, `depthStencilAttachment` set\n * - `'color-only'` → populated `colorAttachments[]`, no `depthStencilAttachment`\n * - `'color-and-depth'` → both\n */\nexport interface PassKindAttachmentPolicy {\n readonly shape: 'depth-only' | 'color-only' | 'color-and-depth';\n readonly defaultColorOps: AttachmentColorOps | undefined;\n readonly defaultDepthOps: AttachmentDepthOps | undefined;\n}\n\n/**\n * Closed map of passKind → attachment policy. Covers the 10 attachment shapes\n * the runtime ships (per plan-strategy M4):\n *\n * 1. `'forward'` — main geometry pass: color+depth(+stencil-gated)\n * 2. `'deferred'` — HDRP G-Buffer geometry pass: MRT color+depth\n * 3. `'shadow-caster'` — directional shadow caster: depth-only\n * 4. `'point-shadow-caster'` — HDRP point-shadow caster: depth-only\n * 5. `'skybox'` — fullscreen skybox: color-only clear/store\n * 6. `'tonemap'` — HDR→LDR tonemap fullscreen: color-only clear/store\n * 7. `'bloom-bright'` / `'bloom-blur'` — bloom downsample/blur: color-only\n * clear/store\n * 8. `'bloom-composite'` — bloom add-back: color-only load/store (NOT clear)\n * 9. `'fxaa'` — fullscreen FXAA: color-only clear/store\n * 10. `'post-process'` — generic fullscreen primitive (SSAO, render-graph\n * fullscreen-post-process-pass dispatcher, M2 tonemap pre-warm slot):\n * color-only clear/store\n *\n * Sprite-split forward sub-pass reuses the `'forward'` policy with\n * `options.colorLoadOp='load'` + `options.depthLoadOp='load'`.\n *\n * Stencil-op gate is NOT in this table — it is derived from\n * `specAttachments.depthFormat` inside the helper (depth24plus-stencil8\n * → emit `stencilLoadOp:'clear' / stencilStoreOp:'discard'`).\n */\nexport const passKindPolicyTable: Readonly<Record<string, PassKindAttachmentPolicy>> = {\n forward: {\n shape: 'color-and-depth',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n deferred: {\n shape: 'color-and-depth',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n },\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n temporal: {\n shape: 'color-and-depth',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: -1, a: 1 },\n },\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n 'shadow-caster': {\n shape: 'depth-only',\n defaultColorOps: undefined,\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n 'point-shadow-caster': {\n shape: 'depth-only',\n defaultColorOps: undefined,\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n skybox: {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n tonemap: {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n 'bloom-bright': {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n 'bloom-blur': {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n 'bloom-composite': {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'load',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n fxaa: {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n 'post-process': {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n};\n\n/**\n * Build a `GPURenderPassDescriptor` from spec attachments + resolved views +\n * a passKind policy lookup.\n *\n * The helper is the single SSOT for `device.beginRenderPass(...)` descriptor\n * shape — every record-stage call site routes through it (plan-strategy M4\n * AC-06). It dispatches on `passKindPolicyTable[passKind]` to pick the\n * attachment shape (depth-only / color-only / color-and-depth) and applies\n * default color/depth load+store ops; per-call overrides (sprite-split's\n * `loadOp:'load'`, main pass's dynamic `mainColorLoadOp`, skybox's specific\n * clearColor) flow through `options`.\n *\n * Stencil-op gate is auto-derived from `specAttachments.depthFormat`:\n * - `'depth24plus-stencil8'` → emits `stencilLoadOp:'clear', stencilStoreOp:'discard'`\n * - every other depth format → omits stencil ops entirely\n *\n * This collapses the R3/R5 stencil-op duplicates that previously lived inline\n * at every forward-pass beginRenderPass site.\n *\n * @param specAttachments - the attachments axis from a PipelineSpec\n * @param viewBindings - resolved texture views: `{ colorViews, depthView?, resolveTargets? }`\n * @param passKind - one of the keys in {@link passKindPolicyTable}\n * @param options - per-call ops overrides (loadOp / clearValue / label)\n * @returns a WebGPU render-pass descriptor\n * @throws PipelineSpecError(`'unknown-pass-kind'`) when passKind is not registered\n * @see plan-strategy M4 · requirements AC-06\n */\nexport function buildBeginRenderPassDescriptor(\n specAttachments: PipelineSpec['attachments'],\n viewBindings: {\n readonly colorViews: readonly unknown[];\n readonly resolveTargets?: readonly (unknown | undefined)[];\n readonly depthView?: unknown;\n },\n passKind: string,\n options?: {\n readonly colorLoadOp?: 'clear' | 'load';\n readonly colorStoreOp?: 'store' | 'discard';\n readonly clearColor?: GPUColor;\n readonly depthLoadOp?: 'clear' | 'load';\n readonly depthStoreOp?: 'store' | 'discard';\n readonly label?: string;\n },\n): Record<string, unknown> {\n const policy = passKindPolicyTable[passKind];\n if (policy === undefined) {\n throw new PipelineSpecError({\n code: 'unknown-pass-kind',\n detail: { expected: Object.keys(passKindPolicyTable), actual: passKind },\n hint: `passKind '${passKind}' is not in passKindPolicyTable; register an attachment policy or pick an existing one (e.g. 'post-process' for fullscreen-quad passes)`,\n });\n }\n\n const out: Record<string, unknown> = {};\n if (options?.label !== undefined) {\n out.label = options.label;\n }\n\n // Colour attachments: depth-only → empty array; otherwise iterate colorViews\n // and apply policy default ops + per-call overrides. resolveTargets[i] === undefined\n // means \"no resolve for this slot\"; only present slots emit a `resolveTarget`.\n if (policy.shape === 'depth-only') {\n out.colorAttachments = [];\n } else {\n const colorOps = policy.defaultColorOps;\n if (colorOps === undefined) {\n throw new PipelineSpecError({\n code: 'spec-inconsistent',\n detail: {\n reason: 'policy-shape-color-without-colorOps',\n actual: passKind,\n },\n hint: `passKind '${passKind}' has shape='${policy.shape}' but no defaultColorOps; fix passKindPolicyTable entry`,\n });\n }\n const loadOp = options?.colorLoadOp ?? colorOps.loadOp;\n const storeOp = options?.colorStoreOp ?? colorOps.storeOp;\n const clearValue = options?.clearColor ?? colorOps.clearValue;\n\n out.colorAttachments = viewBindings.colorViews.map((view, i) => {\n const slot: Record<string, unknown> = {\n view,\n loadOp,\n storeOp,\n };\n const resolveTarget = viewBindings.resolveTargets?.[i];\n if (resolveTarget !== undefined) {\n slot.resolveTarget = resolveTarget;\n }\n // Emit clearValue only when load is 'clear' AND a value is available.\n if (loadOp === 'clear' && clearValue !== undefined) {\n slot.clearValue = clearValue;\n }\n return slot;\n });\n }\n\n // Depth-stencil attachment: emitted iff policy declares depth ops AND\n // the spec carries a depthFormat. Stencil ops auto-derived from format.\n if (policy.shape !== 'color-only' && policy.defaultDepthOps !== undefined) {\n const dOps = policy.defaultDepthOps;\n const depthLoadOp = options?.depthLoadOp ?? dOps.loadOp;\n const depthStoreOp = options?.depthStoreOp ?? dOps.storeOp;\n const ds: Record<string, unknown> = {\n view: viewBindings.depthView,\n depthLoadOp,\n depthStoreOp,\n };\n if (depthLoadOp === 'clear') {\n ds.depthClearValue = dOps.clearValue;\n }\n // Stencil-op gate: only depth24plus-stencil8 carries a stencil aspect.\n if (specAttachments.depthFormat === 'depth24plus-stencil8') {\n ds.stencilClearValue = 0;\n ds.stencilLoadOp = 'clear';\n ds.stencilStoreOp = 'discard';\n }\n out.depthStencilAttachment = ds;\n }\n\n return out;\n}\n\n/**\n * Validate a PipelineSpec before attempting to build.\n *\n * Fail-fast checks (charter P5) covering axis mutual-exclusion rules.\n * Returns `Result<void, PipelineSpecError>` — ok for valid specs,\n * err with structured code + detail for invalid ones.\n *\n * Checks:\n * 1. `sampleCount=4` with empty `colorFormats` → `'spec-inconsistent'`\n * 2. Pass kind not in `KNOWN_PASS_KINDS` → `'unknown-pass-kind'`\n * 3. `depthFormat` undefined but `renderState` implies depth testing →\n * `'attachment-format-incompatible'`\n *\n * @see plan-strategy §3.2 · requirements AC-02 · charter P5\n */\nexport function validateSpec(\n spec: PipelineSpec,\n):\n | { ok: true }\n | { ok: false; code: PipelineSpecErrorCode; detail: Record<string, unknown>; hint?: string } {\n // Check 1: sampleCount=4 with empty colorFormats is inconsistent —\n // multisample requires a colour target to resolve to.\n if (spec.attachments.sampleCount === 4 && spec.attachments.colorFormats.length === 0) {\n return {\n ok: false,\n code: 'spec-inconsistent',\n detail: { reason: 'sample-count-format-incompatible' },\n hint: 'sampleCount=4 requires at least one colorFormat; shadow-caster (depth-only) passes should use sampleCount=1',\n };\n }\n\n // Check 2: unknown pass kind\n if (!KNOWN_PASS_KINDS.includes(spec.shader.passKind)) {\n return {\n ok: false,\n code: 'unknown-pass-kind',\n detail: { expected: KNOWN_PASS_KINDS, actual: spec.shader.passKind },\n hint: `passKind '${spec.shader.passKind}' is not in KNOWN_PASS_KINDS; register custom pass kinds via ShaderCatalog`,\n };\n }\n\n // Check 3: depth-testing renderState without a depthFormat\n const depthOnly = passKindPolicyTable[spec.shader.passKind]?.shape === 'depth-only';\n const depthRequired = !!spec.renderState?.depthCompare || depthOnly;\n if (!spec.attachments.depthFormat && depthRequired) {\n return {\n ok: false,\n code: 'attachment-format-incompatible',\n detail: {\n reason: 'depth-requirement-without-depth-format',\n expected: 'depthFormat must be set when depth testing or a depth-only pass is requested',\n actual: `depthFormat=${String(spec.attachments.depthFormat)}, depthCompare=${spec.renderState?.depthCompare}`,\n },\n hint: 'set attachments.depthFormat (e.g. depth24plus-stencil8 or depth32float) when renderState specifies depthCompare',\n };\n }\n\n return { ok: true };\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// PipelineCache — Map<string, RenderPipeline> container (D-12)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Pipeline cache — Map from cacheKeyOf(spec) to opaque RenderPipeline handle.\n *\n * Constructed once at createRenderer boot time; shared across all call sites.\n * Consumers call `getOrBuildPipeline(spec, deviceProvider, cache)` — the\n * entrypoint does cache lookup internally; consumers never touch the Map\n * directly.\n *\n * @see plan-strategy D-12 · requirements §3.2\n */\nexport type PipelineCache = Map<string, unknown>;\n\n// ══════════════════════════════════════════════════════════════════════════════\n// getOrBuildPipeline — single entrypoint (D-12)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Device factory interface consumed by {@link getOrBuildPipeline}.\n *\n * Slim abstraction: only `createRenderPipeline` is needed; the entrypoint\n * does not depend on the full `RhiDevice` interface so it can be tested\n * with a mock.\n */\nexport interface PipelineDeviceProvider {\n createRenderPipeline(\n descriptor: Record<string, unknown>,\n ): { ok: true; value: unknown } | { ok: false; error: unknown };\n}\n\n/**\n * Single entrypoint for obtaining a render pipeline from a spec.\n *\n * Cache-hit path: key = cacheKeyOf(spec), returns cached handle immediately.\n * Cache-miss path: validates spec → builds descriptor → calls device.createRenderPipeline\n * → caches result → returns handle.\n * Build failure: throws PipelineSpecError (charter P3 fail-fast, no silent fallback).\n *\n * Pure function: same (spec, deviceProvider, cache) always produces the same result.\n * Boot-time call site: createRenderer wires the real device; record-stage call site\n * uses ctx.runtime.device (same entrypoint, same signature).\n *\n * @param spec - immutable 4-axis pipeline specification\n * @param deviceProvider - factory with createRenderPipeline method\n * @param cache - the PipelineCache (shared across boot + record stage)\n * @returns a RenderPipeline handle (opaque, typed as unknown for M1)\n * @throws PipelineSpecError on validation failure or build failure\n * @see plan-strategy D-12 · requirements AC-03 · charter F1\n */\nexport function getOrBuildPipeline(\n spec: PipelineSpec,\n deviceProvider: PipelineDeviceProvider,\n cache: PipelineCache,\n modules?: {\n vertex: unknown;\n fragment: unknown;\n vertexEntryPoint?: string;\n fragmentEntryPoint?: string;\n layout?: unknown;\n },\n): unknown {\n const key = cacheKeyOf(spec);\n\n // Cache hit — return immediately.\n const cached = cache.get(key);\n if (cached !== undefined) return cached;\n\n // Cache miss — validate, build, cache, return.\n const validation = validateSpec(spec);\n if (!validation.ok) {\n throw new PipelineSpecError({\n code: validation.code,\n detail: validation.detail,\n ...(validation.hint !== undefined ? { hint: validation.hint } : {}),\n });\n }\n\n const descriptor = buildPipelineDescriptor(\n spec,\n modules ?? { vertex: undefined, fragment: undefined },\n );\n const result = deviceProvider.createRenderPipeline(descriptor);\n\n if (!result.ok) {\n throw new PipelineSpecError({\n code: 'pipeline-build-failed',\n detail: { cause: result.error },\n hint: 'device.createRenderPipeline failed for spec; inspect gpuMessage on the error detail',\n });\n }\n\n cache.set(key, result.value);\n return result.value;\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// SPEC_CONST_TABLE — 12 boot-time pre-warm variants (M1-T5)\n// ══════════════════════════════════════════════════════════════════════════════\n\nconst PROCEDURAL_ATTR_LAYOUT: VertexAttributeMap = {\n position: new Float32Array(0),\n normal: new Float32Array(0),\n uv: new Float32Array(0),\n tangent: new Float32Array(0),\n};\n\nconst HDR_FORMAT: GPUTextureFormat = 'rgba16float';\nconst DEPTH_DS: GPUTextureFormat = 'depth24plus-stencil8';\n\n/**\n * Default LDR view format used when callers ask for the SPEC_CONST table\n * without an explicit swap-chain format. Kept for the backward-compatible\n * `SPEC_CONST_TABLE` export consumed by unit tests that exercise the\n * spec/cache-keying layer in isolation. Runtime callers always pass the\n * format selected by `selectSwapChainFormat` (Channel 2 BGRA / Channel 3\n * RGBA / dawn-node RGBA — see bug-20260615 fix-up note in `createRenderer`).\n */\nconst DEFAULT_LDR_FORMAT: GPUTextureFormat = 'bgra8unorm-srgb';\n\nconst TRI_GEOMETRY = {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: PROCEDURAL_ATTR_LAYOUT,\n};\n\n// feat-city-glb multi-UV tiling: the built-in standard PBR shader now declares\n// UV sets @location(6..12), so naga reflects uvSetCount=8 for it and the URP\n// record path threads `shaderUvSetCount: 8` into every standard-pbr spec\n// (createRenderer.ts buildPipelineContext / getMaterialShaderPipeline).\n// The boot-time prewarm must match on both axes: the PSO vertex layout includes\n// all declared UV slots, and the cacheKey carries `:uvsc8`. For single-UV\n// meshes deriveVertexBufferLayout clamp-to-last aliases every missing set onto\n// the last mesh set (48-byte stride unchanged), so existing geometry remains\n// byte-stable.\n// unlit stays on TRI_GEOMETRY (its shader declares only @location(0..3)).\nconst TRI_GEOMETRY_PBR = {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: PROCEDURAL_ATTR_LAYOUT,\n shaderUvSetCount: 8,\n};\n\n// M6 fix-up: URP-variant key string for the standard PBR shader. Mirrors the\n// boot-time variantSet computed at createRenderer.ts step 1b when\n// `isHdrpActive=false` and `storageBufferCapable=true` (the URP default\n// surface). The URP record path requests this exact string at every\n// `getMaterialShaderPipeline` call site, so seeding the table with these\n// variants keeps the URP cache lookup hot from frame 1 instead of\n// skip-drawing the first ~1 frames while the async compile resolves.\nconst URP_PBR_VARIANT_SET = 'CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true';\n\n/**\n * Build the boot-time pre-warm table: 15 standard PipelineSpec variants.\n *\n * feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (AC-12): the\n * four `forgeax::default-sprite` entries (LDR S1 + LDR S4 + HDR S1 + HDR S4)\n * are gone — sprite PSO lands lazily through the generic\n * per-MaterialShader pipeline cache. Pre-feat count was 19; post-feat 15.\n *\n * Matrix:\n * - 8 base material variants — {unlit, standard-pbr} x {LDR, HDR} x {S1, S4}\n * - 4 URP-variant standard-pbr — standard-pbr (variantSet=URP_PBR_VARIANT_SET)\n * x {LDR, HDR} x {S1, S4}; URP record path requests these specs by\n * `getMaterialShaderPipeline` keying off `cacheKeyOf` so the boot-time\n * prewarm seeds `materialShaderPipelineCache` and avoids a 1-frame\n * async-compile skip-draw (M6 fix-up; see render-system-record.ts §URP)\n * - 3 fullscreen-post — tonemap (LDR S1) + skybox (HDR S1, HDR S4)\n *\n * Total: 15. The URP variant is PBR-only because:\n * - unlit URP record path passes `variantSet=undefined` (the no-variant\n * boot-default entries already cover it; createRenderer.ts §unlitRsp)\n * - sprite goes through `getMaterialShaderPipeline('forgeax::sprite', ...)`\n * lazily at first transparent-LDR-split draw — no boot-time pre-warm.\n * - HDRP variant (`variantSet=''` or compound `=true` form) is registered\n * lazily when the clustered Standard profile activates, not at boot — adding clustered\n * prewarm here would build PSOs against the URP layout (the boot-time\n * `pbrModule` is the URP variant when `isHdrpActive=false`)\n *\n * `ldrViewFormat` parameterises the LDR color attachment format. Callers\n * pass the runtime-resolved swap-chain view format (Channel 2 typically\n * `bgra8unorm-srgb`; Channel 3 wgpu-wasm and dawn-node typically\n * `rgba8unorm-srgb`). Hard-coding `bgra8unorm-srgb` at module load made\n * the pre-warmed PSOs incompatible with the actual RenderPass color\n * attachment on Channel 3 / dawn-node, producing whole-commandBuffer\n * invalid errors on every frame (bug-20260615 fix-up — see\n * `createRenderer` boot-time pre-warm site).\n *\n * Fullscreen passes (fxaa / bloom x 3 / SSAO x 2) are lazy-build — they\n * use the same getOrBuildPipeline entrypoint but are not in this table.\n *\n * @see plan-strategy D-4 · research R-D4 · requirements AC-16\n * @see bug-20260612-webgpu-canvas-format-prefer-bgra-shipped (same trap shape)\n */\nexport function buildSpecConstTable(\n ldrViewFormat: GPUTextureFormat,\n): readonly Readonly<PipelineSpec>[] {\n const TRI_ATTACHMENTS_LDR_S1 = {\n colorFormats: [ldrViewFormat],\n depthFormat: DEPTH_DS,\n sampleCount: 1 as const,\n };\n\n const TRI_ATTACHMENTS_LDR_S4 = {\n colorFormats: [ldrViewFormat],\n depthFormat: DEPTH_DS,\n sampleCount: 4 as const,\n };\n\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (AC-12 / D-7):\n // SPRITE_ATTACHMENTS_LDR_S1 / S4 (the dedicated non-srgb storage-format\n // attachments the sprite spec entries consumed) were deleted alongside the\n // four `forgeax::default-sprite` SPEC_CONST entries. The bgra8unorm storage\n // format itself is still enforced at the LDR sprite sub-pass attachment\n // level (the WebGPU pipeline `colorFormats` derive from the actual render\n // pass attachment view, which is built off `pipelineState.format` =\n // swap-chain storage format — see `render-system-record.ts` LDR split\n // beginRenderPass call). The triggering source migrated from the\n // spec-table id to `material.transparent` (derived by the extract stage\n // from `passes[0].renderState.blend !== undefined`, the\n // post-feat-20260626-collapse SSOT; w7 onwards).\n\n const TRI_ATTACHMENTS_HDR_S1 = {\n colorFormats: [HDR_FORMAT],\n depthFormat: DEPTH_DS,\n sampleCount: 1 as const,\n };\n\n const TRI_ATTACHMENTS_HDR_S4 = {\n colorFormats: [HDR_FORMAT],\n depthFormat: DEPTH_DS,\n sampleCount: 4 as const,\n };\n\n return [\n // unlit LDR S1\n {\n shader: { id: 'forgeax::default-unlit', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_LDR_S1,\n geometry: TRI_GEOMETRY,\n renderState: undefined,\n },\n // unlit LDR S4\n {\n shader: { id: 'forgeax::default-unlit', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_LDR_S4,\n geometry: TRI_GEOMETRY,\n renderState: undefined,\n },\n // unlit HDR S1\n {\n shader: { id: 'forgeax::default-unlit', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_HDR_S1,\n geometry: TRI_GEOMETRY,\n renderState: undefined,\n },\n // unlit HDR S4\n {\n shader: { id: 'forgeax::default-unlit', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_HDR_S4,\n geometry: TRI_GEOMETRY,\n renderState: undefined,\n },\n // standard LDR S1\n {\n shader: { id: 'forgeax::default-standard-pbr', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_LDR_S1,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard LDR S4\n {\n shader: { id: 'forgeax::default-standard-pbr', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_LDR_S4,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard HDR S1\n {\n shader: { id: 'forgeax::default-standard-pbr', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_HDR_S1,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard HDR S4\n {\n shader: { id: 'forgeax::default-standard-pbr', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_HDR_S4,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n\n // ── M6 fix-up: URP-variant standard-pbr prewarm ─────────────────────────\n // URP record path (`getMaterialShaderPipeline`) requests\n // `variantSet=URP_PBR_VARIANT_SET` for standard-shading entities; pre-M6\n // the silent `selectStandardFallbackPipeline` shim served the no-variant\n // boot prewarm during the 1-frame async-compile warmup. With M6's\n // explicit-failure surface, those URP requests must hit the boot prewarm\n // by their own variantSet — these 4 entries close that gap.\n\n // standard PBR URP LDR S1\n {\n shader: {\n id: 'forgeax::default-standard-pbr',\n passKind: 'forward',\n variantSet: URP_PBR_VARIANT_SET,\n },\n attachments: TRI_ATTACHMENTS_LDR_S1,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard PBR URP LDR S4\n {\n shader: {\n id: 'forgeax::default-standard-pbr',\n passKind: 'forward',\n variantSet: URP_PBR_VARIANT_SET,\n },\n attachments: TRI_ATTACHMENTS_LDR_S4,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard PBR URP HDR S1\n {\n shader: {\n id: 'forgeax::default-standard-pbr',\n passKind: 'forward',\n variantSet: URP_PBR_VARIANT_SET,\n },\n attachments: TRI_ATTACHMENTS_HDR_S1,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard PBR URP HDR S4\n {\n shader: {\n id: 'forgeax::default-standard-pbr',\n passKind: 'forward',\n variantSet: URP_PBR_VARIANT_SET,\n },\n attachments: TRI_ATTACHMENTS_HDR_S4,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (AC-12 / D-7):\n // the four `forgeax::default-sprite` boot-time pre-warm entries (LDR S1\n // + LDR S4 + HDR S1 + HDR S4) are gone. Sprite PSO lands lazily through\n // the generic per-MaterialShader pipeline cache keyed on\n // `forgeax::sprite` + premultiplied-alpha renderState; SPEC_CONST_TABLE\n // shrinks from 19 to 15 entries (-4 boot-time PSOs).\n\n // ── M2-T4: fullscreen-post boot-time pre-warm (tonemap + skybox) ──────────\n //\n // Tonemap (LDR S1): fullscreen triangle writes to swap-chain LDR view format\n // (parameterised — `ldrViewFormat`; see buildSpecConstTable jsdoc + bug-20260615).\n // Skybox (HDR S1 + S4): fullscreen triangle writes to rgba16float; MSAA variant\n // has sampleCount=4. Both use empty vertexLayout (fullscreen triangle, no\n // attributes) and cullMode='none' (forward cull for fullscreen-quad passthrough).\n //\n // Shadow-probe / fxaa / bloom 4-stage / SSAO 2-stage are lazy-build — not in\n // SPEC_CONST_TABLE (R-D4 decision: only entries that are always-present on\n // every boot).\n\n // tonemap LDR S1 (writes to runtime-resolved swap-chain LDR view format)\n {\n shader: { id: 'forgeax::post::tonemap', passKind: 'post-process', variantSet: undefined },\n attachments: {\n colorFormats: [ldrViewFormat],\n depthFormat: undefined,\n sampleCount: 1 as const,\n },\n geometry: {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: {},\n },\n renderState: {\n cullMode: 'none',\n },\n },\n\n // skybox HDR S1 (writes to rgba16float, no depth)\n {\n shader: { id: 'forgeax::skybox::cube', passKind: 'skybox', variantSet: undefined },\n attachments: {\n colorFormats: [HDR_FORMAT],\n depthFormat: undefined,\n sampleCount: 1 as const,\n },\n geometry: {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: {},\n },\n renderState: {\n cullMode: 'none',\n },\n },\n\n // skybox HDR S4 (MSAA variant)\n {\n shader: { id: 'forgeax::skybox::cube', passKind: 'skybox', variantSet: undefined },\n attachments: {\n colorFormats: [HDR_FORMAT],\n depthFormat: undefined,\n sampleCount: 4 as const,\n },\n geometry: {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: {},\n },\n renderState: {\n cullMode: 'none',\n },\n },\n ];\n}\n\n/**\n * Derive the material-only pre-warm table for a native linear-LDR target.\n *\n * The regular SPEC_CONST table targets the swap-chain view, while the\n * tonemap=none path records geometry directly into the graph-owned\n * `rgba16float` target. Keep that second attachment matrix derived from the\n * same material specs so the first frame does not depend on an asynchronous\n * lazy PSO build.\n */\nexport function buildLinearLdrMaterialSpecTable(\n ldrViewFormat: GPUTextureFormat,\n): readonly Readonly<PipelineSpec>[] {\n return buildSpecConstTable(ldrViewFormat)\n .filter(\n (spec) =>\n spec.shader.passKind === 'forward' && spec.attachments.colorFormats[0] === ldrViewFormat,\n )\n .map((spec) => ({\n ...spec,\n attachments: {\n ...spec.attachments,\n colorFormats: [HDR_FORMAT],\n },\n }));\n}\n\n/**\n * Backward-compatible SPEC_CONST_TABLE — the table built with the default\n * LDR view format (`bgra8unorm-srgb`). Unit tests that exercise the\n * spec/cache-keying layer in isolation import this directly. Runtime\n * callers MUST call `buildSpecConstTable(swapChainFormats.view)` instead\n * so the pre-warmed PSO color format matches the actual RenderPass color\n * attachment on every backend (bug-20260615 fix-up).\n */\nexport const SPEC_CONST_TABLE: readonly Readonly<PipelineSpec>[] =\n buildSpecConstTable(DEFAULT_LDR_FORMAT);\n","import { mat3 } from '@forgeax/engine-math';\nimport { type BindGroup, type Buffer, RhiError, type RhiQueue } from '@forgeax/engine-rhi';\nimport type { DispatchEntry } from '../render-system-extract';\nimport {\n TRANSPARENT_SORT_MODE_LAYER_Y,\n TRANSPARENT_SORT_MODE_LAYER_Z,\n type TransparentSortConfig,\n} from '../systems/transparent-sort-config';\nimport type { ValidatedRenderable } from './frame-snapshot';\n\n/**\n * Stride between per-renderable `entity_world` mat4 slots inside the\n * shared `pipelineState.meshStorageBuffer`. The 256-byte alignment is\n * required because the storage buffer is bound with\n * `hasDynamicOffset: true` and WebGPU spec\n * `minStorageBufferOffsetAlignment` defaults to 256.\n */\nexport const MESH_PER_ENTITY_STRIDE = 256;\n\n// The storage-buffer Mesh struct also carries the temporal previous transform\n// and reactive metadata when STORAGE_BUFFER_AVAILABLE is true:\n// mat4 (64 B) + mat3 (48 B) + previous mat4 (64 B) + vec4 (16 B) = 192 B.\n// The BindGroup entry's `size` must cover the complete reflected struct, not\n// only the first world transform and normal matrix.\nexport const MESH_SSBO_BYTES = 192;\n\n// bug-20260610: WebGL2 fallback shader declares `array<Mesh, 128>` as a\n// uniform buffer; binding must cover the full array size. The storage\n// variant binds a single 112-B slot via dynamic offset, but the uniform\n// variant requires the whole 14336-B range visible to the shader.\nexport const MESH_UBO_FULL_ARRAY_BYTES = 112 * 128;\n\n// bug-20260723-webgl2-instancing-uniform-range: the WebGL2 fallback shader\n// declares `array<InstanceData, 128>` in the instances bind group. Even when\n// a draw carries fewer transforms, the buffer binding must expose the full\n// array range or wgpu rejects the draw at submit time with a late\n// min-binding-size mismatch.\nexport const INSTANCE_UBO_FULL_ARRAY_BYTES = 80 * 128;\n\nexport const MAX_UNIFORM_INSTANCES = 128;\n\n/** The storage-backed InstanceData layout is current + previous mat4. */\nexport const INSTANCE_STORAGE_STRIDE_FLOATS = 32;\n\n/**\n * Project the ECS transform snapshot into the storage-backed InstanceData\n * layout. The extract contract carries one current mat4 per instance; until\n * the ECS snapshot owns a previous-instance column, current is the honest\n * previous value as well. Uniform-backed variants keep the compact 16-float\n * payload and do not use this projection.\n */\nexport function packInstanceStorageBuffer(transforms: Float32Array): Float32Array {\n const count = Math.floor(transforms.length / 16);\n const out = new Float32Array(count * INSTANCE_STORAGE_STRIDE_FLOATS);\n for (let i = 0; i < count; i++) {\n const sourceBase = i * 16;\n const targetBase = i * INSTANCE_STORAGE_STRIDE_FLOATS;\n for (let k = 0; k < 16; k++) {\n const value = transforms[sourceBase + k] ?? 0;\n out[targetBase + k] = value;\n out[targetBase + 16 + k] = value;\n }\n }\n return out;\n}\n\n/**\n * M3 / w12: extracts the underlying GPU resource object from a bind\n * group entry descriptor. Returns the raw object reference (Buffer,\n * TextureView, or Sampler) usable as a WeakMap chain key.\n */\nexport function extractEntryResourceHandle(entry: {\n resource: { kind: string; value: unknown };\n}): object {\n const v = entry.resource.value;\n if (typeof v === 'object' && v !== null && 'buffer' in (v as Record<string, unknown>)) {\n return (v as { buffer: object }).buffer;\n }\n return v as object;\n}\n\n/**\n * feat-20260622-handle-to-id-allocator-elimination M2 / w7: walks a nested\n * WeakMap chain to find or create a BindGroup leaf. Each handle in the\n * `handles` array is a chain node; the final leaf is a Map<string, BindGroup>\n * keyed by `variant` (D-2). Chain keys are always object references, never\n * numeric ids — GC reclaims entries for dead handles automatically.\n *\n * On cache hit returns the cached BindGroup. On miss calls `factory`,\n * bumps `bindGroupCounts.createBindGroup`, stores the result at the leaf,\n * and returns it. Hit/miss accounting is observable via `bindGroupCounts`\n * (D-8: the skin probe reads `counts.createBindGroup` delta).\n */\nexport function getOrCreateFromChain(\n root: WeakMap<object, unknown>,\n handles: readonly object[],\n variant: string,\n factory: () => BindGroup,\n counts: { createBindGroup: number; keys: string[] },\n): BindGroup {\n let node = root;\n for (let i = 0; i < handles.length - 1; i++) {\n // biome-ignore lint/style/noNonNullAssertion: handles length guards the index\n const h = handles[i]!;\n let next = node.get(h) as WeakMap<object, unknown> | undefined;\n if (next === undefined) {\n next = new WeakMap();\n node.set(h, next);\n }\n node = next;\n }\n // biome-ignore lint/style/noNonNullAssertion: known non-empty at call sites\n const last = handles[handles.length - 1]!;\n let leaf = node.get(last) as Map<string, BindGroup> | undefined;\n if (leaf === undefined) {\n leaf = new Map();\n node.set(last, leaf);\n }\n const hit = leaf.get(variant);\n if (hit !== undefined) return hit;\n const bg = factory();\n counts.createBindGroup += 1;\n counts.keys.push(variant);\n leaf.set(variant, bg);\n return bg;\n}\n\n/**\n * feat-20260622-handle-to-id-allocator-elimination M2 / w8: per-entity bind\n * group lookup-or-create helper (D-2). Two-step lookup: outer Map.get(outerKey)\n * finds or lazily creates an inner WeakMap chain, then delegates to\n * `getOrCreateFromChain` for the chain walk. outerKey is `string | number`\n * to cover both per-entity (number entityKey) and material-shared\n * (string shaderId) caches (D-1 / OQ-1).\n */\nexport function getOrCreatePerEntity(\n outerMap: Map<string | number, WeakMap<object, unknown>>,\n outerKey: string | number,\n handles: readonly object[],\n variant: string,\n factory: () => BindGroup,\n counts: { createBindGroup: number; keys: string[] },\n): BindGroup {\n let inner = outerMap.get(outerKey) as WeakMap<object, unknown> | undefined;\n if (inner === undefined) {\n inner = new WeakMap();\n outerMap.set(outerKey, inner);\n }\n return getOrCreateFromChain(inner, handles, variant, factory, counts);\n}\n\n/**\n * feat-20260622-handle-to-id-allocator-elimination M2 / w8: evicts per-entity\n * cache entries whose entityKey is not in the validated set. Works on\n * Map<entityKey, WeakMap<handle, BindGroup>> by iterating the outer Map keys\n * and deleting entries for which validatedEntityKeys.has(ek) is false.\n * No string parsing, no Number / Number.isNaN — the entityKey is already a\n * number (D-1 / RD4).\n *\n * @internal — exported for unit test access (AC-08)\n */\nexport function cleanPerEntityCache(\n cache: Map<number, WeakMap<object, unknown>>,\n validatedEntityKeys: Set<number>,\n): void {\n for (const ek of cache.keys()) {\n if (!validatedEntityKeys.has(ek)) {\n cache.delete(ek);\n }\n }\n}\n\n/**\n * feat-20260608-mesh-ssbo-dynamic-grow-l1-lift-1024-entity-cap M3 / T-M3-04:\n * record-stage entry-point hook to the closure-scoped mesh-SSBO grow\n * controller (createRenderer.ts). Called once per frame, after\n * `validatedOrdered` has been finalised and BEFORE the first per-entity\n * `queue.writeBuffer`. Returns Result-like (never throws — D-5):\n *\n * - `{ ok: true }` — slotCount already covers `neededSlots` (idempotent\n * short-circuit), or the controller successfully grew\n * in this call. Caller proceeds with the frame.\n * - `{ ok: false, code, degradedToSlotCount }` — controller hit ceiling /\n * capacity and ALREADY fired the structured error\n * via errorRegistry. Caller truncates the draw\n * list to the largest complete entity prefix that\n * fits within `degradedToSlotCount` slots (graceful\n * degradation per plan-strategy D-2): renders the\n * subset that fits, discards overflow, no black\n * frame.\n *\n * This helper does NOT re-fire on `ok:false` — the controller is the single\n * fire site (createRenderer.ts grow factory), so callers see exactly one\n * structured error per ceiling event (charter P3 explicit failure: no\n * double-fire).\n *\n * Dev-mode visibility: when grow actually grew (slotCount transition) AND\n * `import.meta.env?.DEV` is truthy, a single `console.info('[mesh-ssbo] ...')`\n * line reports the before / after / requested counts. The optional-chain\n * keeps non-vite envs (dawn-node smoke, plain tsup tests) silent —\n * `import.meta.env` is undefined there, the chain short-circuits to\n * undefined, the if-guard is falsy (AC-11 + plan-strategy §2.D-3).\n *\n * Bind-group cache invalidation is automatic: on grow, the controller\n * mutates `meshSsboState.mesh.buffer` / `.material.buffer` in place\n * (wrapper-object identity preserved, inner buffer replaced — research §F8).\n * Downstream the fresh inner buffer object is a new WeakMap chain key, so\n * `getOrCreateFromChain` misses and rebuilds the BindGroup on the next frame\n * (AC-07; T-M3-03 (a) test).\n *\n * @internal — exported for unit-test access (`mesh-ssbo-grow.test.ts`\n * T-M3-01 / T-M3-02 / T-M3-03 cover idempotency, ceiling, dev info).\n */\nexport function ensureMeshSsboCapacity(\n internals: {\n readonly growMeshSsbo?:\n | ((neededSlots: number) =>\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly code: 'mesh-ssbo-ceiling-reached' | 'mesh-ssbo-capacity-exceeded';\n readonly degradedToSlotCount: number;\n })\n | undefined;\n readonly meshSsboState?: { readonly slotCount: number } | undefined;\n },\n neededSlots: number,\n):\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly code: 'mesh-ssbo-ceiling-reached' | 'mesh-ssbo-capacity-exceeded';\n readonly degradedToSlotCount: number;\n } {\n // Empty scene / no controller wired (legacy / test fixture path).\n if (neededSlots <= 0) return { ok: true };\n const grow = internals.growMeshSsbo;\n if (grow === undefined) return { ok: true };\n // Idempotent guard — current slotCount already covers neededSlots.\n // The controller's own internal guard catches this too, but bailing here\n // skips the spy / tracing overhead and matches the AC-09 contract that\n // grow runs at most once per frame transition.\n const before = internals.meshSsboState?.slotCount ?? 0;\n if (before > 0 && before >= neededSlots) return { ok: true };\n const result = grow(neededSlots);\n // Note: ok:false has already fired the structured error inside the\n // controller (createRenderer.ts grow factory). Do NOT double-fire here.\n if (!result.ok) return result;\n // Dev-mode visibility — only on a real slotCount transition (skip\n // no-op idempotent paths above; ceiling path returned early on ok:false).\n const after = internals.meshSsboState?.slotCount ?? before;\n if (after !== before) {\n // Module-local binding read (NOT `recordModule.devModeProbe`) so vitest\n // ESM-readonly export forced us to expose the probe as a settable holder\n // (`setMeshSsboDevModeProbeForTests`) instead of a `vi.spyOn` target.\n if (meshSsboDevModeProbe()) {\n // biome-ignore lint/suspicious/noConsole: AC-11 mandates a `[mesh-ssbo]` info line in dev mode (vite build dead-strips this branch via the `import.meta.env.DEV` constant fold; tsup / esbuild prod sets NODE_ENV=production).\n console.info(\n '[mesh-ssbo] grew slotCount: %d -> %d (requested=%d)',\n before,\n after,\n neededSlots,\n );\n }\n }\n return result;\n}\n\n/**\n * Test seam: a closure-local function pointer ensureMeshSsboCapacity reads\n * for the dev-mode gate. Defaults to `isMeshSsboDevMode`; tests swap it out\n * via `setMeshSsboDevModeProbeForTests` because vitest 4.x export bindings\n * are non-writable (ESM spec) and `import.meta.env.DEV` is build-time-frozen\n * by the vite transform — neither `vi.spyOn(recordModule, 'isMeshSsboDevMode')`\n * nor `vi.stubEnv('DEV', false)` toggles it at runtime.\n */\nlet meshSsboDevModeProbe: () => boolean = isMeshSsboDevMode;\n\n/**\n * @internal — test-only injection seam for `ensureMeshSsboCapacity`'s\n * dev-mode gate. Pass `undefined` to restore the production probe\n * (`isMeshSsboDevMode`). Production code paths NEVER call this.\n */\nexport function setMeshSsboDevModeProbeForTests(probe: (() => boolean) | undefined): void {\n meshSsboDevModeProbe = probe ?? isMeshSsboDevMode;\n}\n\n/**\n * Dev-mode probe for `ensureMeshSsboCapacity`'s console.info gate\n * (plan-strategy §2.D-3 + AC-11). True when the build is in dev mode:\n * - `import.meta.env?.DEV` is truthy (vite dev / vitest), OR\n * - `process.env.NODE_ENV !== 'production'` (esbuild / tsup / dawn-node).\n * Optional-chain keeps it safe in non-vite ESM envs that never inject\n * `import.meta.env` (the chain short-circuits to undefined → falsy).\n *\n * Vite's `import.meta.env.DEV` is constant-folded at build time, so the\n * production bundle dead-code-strips the entire branch even though the\n * test fall-through reads `process.env.NODE_ENV`.\n *\n * @internal — exported as a function (not a const) so unit tests can\n * `vi.spyOn(...).mockReturnValue(false)` to exercise the dev=false path\n * (vitest 4.x cannot toggle `import.meta.env.DEV` at runtime — it is\n * compile-time-frozen by the vite transform).\n */\nexport function isMeshSsboDevMode(): boolean {\n const importMetaDev = (import.meta as { env?: { DEV?: unknown } }).env?.DEV;\n if (importMetaDev) return true;\n // Fallback for tsup / esbuild / dawn-node where import.meta.env is absent:\n // NODE_ENV !== 'production' counts as dev. NODE_ENV unset (undefined)\n // also counts as dev so test envs without explicit NODE_ENV log too —\n // production builds always set NODE_ENV='production'. We read process via\n // globalThis to keep this file @types/node-free (rest of the package is\n // browser-typed; engine-runtime ships ESM into both browser + dawn-node).\n const proc = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n if (proc !== undefined && proc.env?.NODE_ENV === 'production') return false;\n if (proc === undefined) return false;\n return true;\n}\n\n/**\n * Module-scoped reusable scratch for batched mesh-SSBO uploads (O2).\n * Grows monotonically; never shrinks. One allocation per render session\n * instead of one per entity per frame.\n *\n * @internal\n */\nlet _meshSsboScratch = new Uint8Array(0);\n\n/**\n * feat-20260704 M3/w21: per-renderable `entity_world` upload (batched). All N\n * mat4+normalMatrix slots are assembled into a single contiguous scratch\n * buffer, then flushed as one `writeBuffer` call instead of N individual\n * calls. Extracted verbatim from `recordFrame` (frame.ts) — the module-scoped\n * `_meshSsboScratch` let and its only reassignment site now co-locate in this\n * file so the two mesh-SSBO module lets live together (AC-06).\n *\n * feat-20260518 M3 / w14 (AC-08): each 256-byte slot carries a 16-float mat4\n * at [0..64B) and a 48-byte mat3 normalMatrix at [64..112B) (3 vec4 columns;\n * padding at indices 19/23/27 stays 0). The mat3 =\n * transpose(invert(mat3(worldFromLocal))) for correct normal transform under\n * non-uniform scale.\n *\n * feat-20260622-chunk-gpu-instancing-sprite-tilemap M1 / w4-record-swap (D-1):\n * fold-bucket heads write identity into their slot; the fold path assembles\n * per-instance world matrices into the @group(3) instances buffer instead\n * (sprite/unlit shaders ignore normals; AC-01/AC-02).\n *\n * @internal\n */\nexport function uploadMeshSsboBatch(\n queue: RhiQueue,\n meshStorageBuffer: { readonly buffer: Buffer },\n validatedOrdered: readonly ValidatedRenderable[],\n foldDispatchPlan: FoldDispatchPlan | null,\n): void {\n const slotCount = validatedOrdered.length;\n const neededBytes = slotCount * MESH_PER_ENTITY_STRIDE;\n // Grow the module-scoped scratch monotonically; zero the used range.\n if (_meshSsboScratch.length < neededBytes) {\n _meshSsboScratch = new Uint8Array(neededBytes);\n } else {\n _meshSsboScratch.fill(0, 0, neededBytes);\n }\n const normalMatrixScratch = mat3.create();\n for (let i = 0; i < slotCount; i++) {\n const entry = validatedOrdered[i];\n if (entry === undefined) continue;\n // Float32Array view into this entity's 256-byte slot (current world,\n // normal, previous world, and reactive metadata use 45 floats; the\n // remaining padding stays zero). Byte offset i*256 is always\n // 4-byte aligned since MESH_PER_ENTITY_STRIDE=256 is divisible by 4.\n const slot = new Float32Array(_meshSsboScratch.buffer, i * MESH_PER_ENTITY_STRIDE, 48);\n const isFoldHead = foldDispatchPlan?.headBuckets.has(i) === true;\n if (isFoldHead) {\n // identity mat4\n slot[0] = 1;\n slot[5] = 1;\n slot[10] = 1;\n slot[15] = 1;\n // identity mat3 normal (cols at slot offsets 16/20/24)\n slot[16] = 1;\n slot[20] = 1;\n slot[24] = 1;\n // Fold heads use the instance storage path; keep the mesh temporal\n // fields deterministic for shader variants that still read the slot.\n slot[28] = 1;\n slot[33] = 1;\n slot[38] = 1;\n slot[43] = 1;\n slot[44] = 1;\n } else {\n const worldFromLocal = entry.source.transform.world;\n for (let k = 0; k < 16; k++) slot[k] = worldFromLocal[k] ?? 0;\n const normal = mat3.normalMatrix(normalMatrixScratch, worldFromLocal);\n slot[16] = normal[0] ?? 0;\n slot[17] = normal[1] ?? 0;\n slot[18] = normal[2] ?? 0;\n slot[20] = normal[3] ?? 0;\n slot[21] = normal[4] ?? 0;\n slot[22] = normal[5] ?? 0;\n slot[24] = normal[6] ?? 0;\n slot[25] = normal[7] ?? 0;\n slot[26] = normal[8] ?? 0;\n const previousWorld = entry.source.temporal?.previousTransform.world ?? worldFromLocal;\n for (let k = 0; k < 16; k++) slot[28 + k] = previousWorld[k] ?? 0;\n const reactiveMaterial = entry.source.materials.some(\n (material) =>\n material.transparent === true ||\n material.materialShaderId === 'forgeax::sprite' ||\n material.materialShaderId === 'forgeax::sprite-lit' ||\n (material.materialShaderId !== undefined &&\n !material.materialShaderId.startsWith('forgeax::')),\n );\n slot[44] = entry.source.temporal?.reactive === true || reactiveMaterial ? 1 : 0;\n }\n }\n if (neededBytes > 0) {\n const meshUpload = queue.writeBuffer(\n meshStorageBuffer.buffer,\n 0,\n _meshSsboScratch,\n 0,\n neededBytes,\n );\n if (!meshUpload.ok) throw meshUpload.error;\n }\n}\n\n/**\n * Per-bucket descriptor produced by {@link foldDispatchBuckets}.\n *\n * One bucket = one fold-eligible run of consecutive DispatchEntry whose\n * `(layer, sortKey, materialHandle)` triple is equal. Singleton buckets\n * (bucketSize=1) appear when the mode bypasses fold (D-5 mode 2/3) or\n * when consecutive entries differ in one of the three keys.\n *\n * Fields:\n * - `entries` — original DispatchEntry slice for this bucket (preserves\n * the input ordering); the consumer uses these to look up per-entity\n * material BG handles, mesh handles (which are bucket-uniform by\n * construction since materialHandle key is included), etc.\n * - `bucketSize` — `entries.length`. Surfaced as a top-level field so\n * the consumer can pass it directly as `instanceCount` to\n * `drawIndexed`.\n * - `transforms` — assembled Float32Array of bucketSize world mat4s,\n * stride=16 floats per instance, column-major. Suitable for direct\n * `device.queue.writeBuffer` into an instance buffer used at @group(3).\n * - `materialHandle` / `layer` / `sortKey` — the three-tuple key for this\n * bucket. `sortKey` is mode-dependent: posZ (world[14]) for mode 0\n * (LAYER_Z), posY (world[13]) for mode 1 (LAYER_Y). Consumed by the\n * dispatch loop for bind-group selection / sort-stability invariants.\n */\nexport interface FoldBucket {\n readonly entries: readonly DispatchEntry[];\n readonly bucketSize: number;\n readonly transforms: Float32Array;\n readonly materialHandle: number;\n readonly layer: number;\n readonly sortKey: number;\n}\n\n/**\n * Minimal renderable shape consumed by the helper. The real\n * `RenderableSnapshot` carries many more fields; the helper only reads\n * `transform.world` (a Float32Array of 16 column-major floats) and\n * `material.transparent` (the LDR-split-sub-pass fold gate, see PR #502\n * fix + feat-20260625 R2 fix-up: geometry-pass entities — non-transparent\n * materials — MUST stay singleton because the sprite-pass dispatch path\n * that consumes `headBuckets` does not run for them; folding them would\n * overwrite their mesh-SSBO slot with identity and collapse 3D geometry\n * to origin).\n *\n * Production callers pass `RenderableSnapshot[]` straight through —\n * `RenderableSnapshot.material.transparent` is `boolean | undefined`\n * (derived by the extract stage from `passes[0].renderState.blend !==\n * undefined`, the post-feat-20260626-collapse SSOT; see\n * `MaterialSnapshot.transparent`), structurally compatible with this\n * minimal shape. The gate read inside the helper uses `=== true` /\n * `!== true` so both `false` and `undefined` enter the singleton branch.\n *\n * feat-20260625-refactor-sprite-as-transparent-mesh R2 fix-up: gate\n * migrated from `shadingModel === 'sprite'` (the union member was\n * removed in M3 / w15) to `transparent === true` (the new SSOT for\n * \"routes through the LDR split sub-pass\" — same predicate the\n * `splitLdrSprite` filter at render-system-record.ts:4826/5612 uses).\n */\nexport interface FoldRenderableLike {\n readonly transform: { readonly world: Float32Array };\n readonly material: { readonly transparent?: boolean | undefined };\n}\n\n/**\n * Linear-scan fold operator (plan-strategy D-1).\n *\n * Walks `orderedEntries` (must be transparent-sort-ordered when mode=0;\n * the helper trusts the input ordering and only checks adjacent equality\n * — non-consecutive entries with equal keys are NOT merged, preserving\n * stable-sort semantics).\n *\n * @param orderedEntries — DispatchEntry[] in transparent-sort order. Empty\n * array yields zero buckets (defensive empty-bucket suppression).\n * @param mode — current `TransparentSortConfig.mode`. Modes 0 (LAYER_Z)\n * and 1 (LAYER_Y) enable fold using the appropriate sort-axis coordinate\n * (posZ / posY respectively). Modes 2 and 3 produce singleton buckets\n * per entry (D-5 bypass).\n * @param renderables — parallel snapshot array indexed by\n * `DispatchEntry.renderableIndex`. The helper reads `transform.world`\n * to (a) extract the sort-axis coordinate for the bucket key (posZ\n * world[14] for mode 0, posY world[13] for mode 1), and (b) copy 16\n * floats per entry into the assembled transforms buffer. Out-of-range /\n * missing renderables defensively contribute a zero mat4 slot.\n * @returns Array of FoldBucket descriptors in input order.\n */\nexport function foldDispatchBuckets(\n orderedEntries: readonly DispatchEntry[],\n mode: TransparentSortConfig['mode'],\n renderables: readonly FoldRenderableLike[],\n): readonly FoldBucket[] {\n if (orderedEntries.length === 0) return [];\n\n // Bypass branch (D-5): modes 2 (LAYER_YZ) and 3 (DISTANCE) cannot fold\n // — their sort keys are composite foot-Y formulas or per-entity camera\n // distances, not reducible to a single world-mat4 coordinate read.\n // Each entry produces its own singleton bucket; the dispatch consumer\n // treats bucketSize=1 identically to per-entity drawIndexed (charter P3\n // silent fallback — no error fired).\n //\n // Mode 1 (LAYER_Y) falls through to the fold branch below and uses posY\n // (world[13]) as the sort-axis bucket key.\n if (mode !== TRANSPARENT_SORT_MODE_LAYER_Z && mode !== TRANSPARENT_SORT_MODE_LAYER_Y) {\n const out: FoldBucket[] = [];\n for (let i = 0; i < orderedEntries.length; i++) {\n const e = orderedEntries[i];\n if (e === undefined) continue;\n out.push(makeSingletonBucket(e, renderables, mode));\n }\n return out;\n }\n\n // Fold branch (mode 0 = LAYER_Z, mode 1 = LAYER_Y): linear scan, collect\n // runs with equal (layer, sortKey, materialHandle). sortKey is posZ for\n // mode 0, posY for mode 1 — see readSortKey().\n //\n // Transparent-pass-only gate (PR #502 fix + feat-20260625 R2 fix-up):\n // the only dispatch site that consumes `headBuckets` to emit one\n // instanced drawIndexed per bucket is the transparent-pass loop in\n // `render-system-record.ts` (~line 5500; routed via `splitLdrSprite`\n // filter on `material.transparent === true`). The geometry-pass loop\n // (~line 4660) iterates `validatedOrdered` and emits per-entity\n // drawIndexed unchanged; it does NOT branch on `headBuckets`. So when\n // a non-transparent entry (geometry-pass: unlit / standard-PBR / skin)\n // is folded into a multi-entry bucket, the mesh-SSBO upload loop\n // (~line 2710) still overwrites its mesh slot with identity (because\n // `headBuckets.has(i)` is true), but the geometry-pass then reads\n // identity and renders the 3D geometry at the origin — collapsing the\n // frame to black (hello-room CI regression).\n //\n // Concept-count fix: encode \"fold is transparent-sub-pass-only\" at the\n // head selection point — the gate is the single bucket-key invariant\n // that makes both dispatch sites correct without coupling identity-\n // overwrite logic to a separate check (avoiding the D-9 shared-exit\n // violation that selecting fix-location B would produce).\n //\n // Non-transparent entries (`transparent !== true`) always produce\n // singleton buckets (bucketSize=1), which `buildFoldDispatchPlan`\n // filters out (`if (bucket.bucketSize <= 1) continue`), so they never\n // enter `headBuckets` / `skipIndices` — the mesh-SSBO upload,\n // transparent-pass, and geometry-pass loops all see them as byte-\n // identical to the pre-fold per-entity path.\n //\n // feat-20260625 R2 fix-up: pre-feat the gate was `shadingModel ===\n // 'sprite'`; M3 / w15 narrowed the shadingModel union to\n // `'unlit' | undefined` (the `'sprite'` discriminator was the design\n // ablation target), so the gate now reads `material.transparent` —\n // the new SSOT for \"routes through the LDR split sub-pass\" mirrored\n // on `computeSplitLdrSprite` + the `splitLdrSprite` skip filter.\n const buckets: FoldBucket[] = [];\n let runStart = 0;\n while (runStart < orderedEntries.length) {\n const head = orderedEntries[runStart];\n if (head === undefined) {\n runStart += 1;\n continue;\n }\n // Transparent-pass-only gate (feat-20260625 R2 fix-up): non-transparent\n // heads emit a singleton bucket and advance the cursor by 1 — no run\n // extension. `RenderableSnapshot.material.transparent` is the SSOT\n // carrier (extract stage derives it from the first pass's\n // `renderState.blend !== undefined`, post-feat-20260626-collapse;\n // see `MaterialSnapshot.transparent`).\n const headTransparent = renderables[head.renderableIndex]?.material.transparent;\n if (headTransparent !== true) {\n buckets.push(makeSingletonBucket(head, renderables, mode));\n runStart += 1;\n continue;\n }\n const headSortKey = readSortKey(mode, head.renderableIndex, renderables);\n let runEnd = runStart + 1;\n while (runEnd < orderedEntries.length) {\n const cand = orderedEntries[runEnd];\n if (cand === undefined) break;\n if (cand.layer !== head.layer) break;\n if (cand.materialHandle !== head.materialHandle) break;\n // Defensive: cand transparent must also be true to join the run.\n // Same materialHandle implies same transparent flag in production\n // (material asset identity), but the check costs O(1) per cand and\n // makes the bucket invariant locally readable.\n const candTransparent = renderables[cand.renderableIndex]?.material.transparent;\n if (candTransparent !== true) break;\n const candSortKey = readSortKey(mode, cand.renderableIndex, renderables);\n if (candSortKey !== headSortKey) break;\n runEnd += 1;\n }\n\n const run = orderedEntries.slice(runStart, runEnd);\n const transforms = assembleTransforms(run, renderables);\n buckets.push({\n entries: run,\n bucketSize: run.length,\n transforms,\n materialHandle: head.materialHandle,\n layer: head.layer,\n sortKey: headSortKey,\n });\n runStart = runEnd;\n }\n return buckets;\n}\n\nfunction makeSingletonBucket(\n entry: DispatchEntry,\n renderables: readonly FoldRenderableLike[],\n mode: TransparentSortConfig['mode'],\n): FoldBucket {\n const transforms = new Float32Array(16);\n const w = renderables[entry.renderableIndex]?.transform.world;\n if (w !== undefined) transforms.set(w);\n const sortKey = readSortKey(mode, entry.renderableIndex, renderables);\n return {\n entries: [entry],\n bucketSize: 1,\n transforms,\n materialHandle: entry.materialHandle,\n layer: entry.layer,\n sortKey,\n };\n}\n\nfunction assembleTransforms(\n run: readonly DispatchEntry[],\n renderables: readonly FoldRenderableLike[],\n): Float32Array {\n const out = new Float32Array(run.length * 16);\n for (let i = 0; i < run.length; i++) {\n const e = run[i];\n if (e === undefined) continue;\n const w = renderables[e.renderableIndex]?.transform.world;\n if (w !== undefined) out.set(w, i * 16);\n }\n return out;\n}\n\nfunction readSortKey(\n mode: TransparentSortConfig['mode'],\n renderableIndex: number,\n renderables: readonly FoldRenderableLike[],\n): number {\n const w = renderables[renderableIndex]?.transform.world;\n if (w === undefined) return 0;\n // mode 0 (LAYER_Z): sort-axis is Z, column 3 row 2 = world[14].\n // mode 1 (LAYER_Y): sort-axis is Y, column 3 row 1 = world[13].\n return ((mode === TRANSPARENT_SORT_MODE_LAYER_Z ? w[14] : w[13]) ?? 0) as number;\n}\n\n/**\n * Per-validatedOrdered-index fold metadata consumed by the record-stage\n * dispatch loops. Built from {@link foldDispatchBuckets} output by\n * {@link buildFoldDispatchPlan}; see plan-strategy §3.2 sequence diagram.\n *\n * Field semantics (consumer contract, w4-record-swap):\n * - `headBuckets[i]` is non-null when validatedOrdered index `i` is the\n * **bucket head** of a non-singleton (bucketSize > 1) fold bucket. The\n * dispatch loop overrides @group(3) instances BG to a transient buffer\n * holding `bucket.transforms` and emits `drawIndexed(idxCount,\n * bucket.bucketSize)` instead of per-entity drawIndexed.\n * - `skipIndices.has(i)` is true when index `i` is a non-head member of\n * a non-singleton fold bucket; the dispatch loop emits `continue`.\n * - Singleton buckets (bucketSize === 1) leave both arrays empty for\n * that index — dispatch falls through to the existing per-entity path\n * byte-identically (mode-bypass / non-foldable head / fold-disabled).\n *\n * Note: the maps are keyed on `validatedOrderedIndex`, NOT\n * `renderableIndex`. The dispatch loops iterate `validatedOrdered` by\n * positional index `i`, and that index drives mesh SSBO slot offset\n * (`i * MESH_PER_ENTITY_STRIDE`), material UBO slot, and per-entity bind\n * group cache keys, all of which the swap must coordinate with.\n */\nexport interface FoldDispatchPlan {\n readonly headBuckets: ReadonlyMap<number, FoldBucket>;\n readonly skipIndices: ReadonlySet<number>;\n readonly foldedBucketCount: number;\n}\n\n/**\n * Build the per-validatedOrdered-index fold metadata from a\n * {@link foldDispatchBuckets} output.\n *\n * @param buckets — output of {@link foldDispatchBuckets}; ordered by\n * transparent-sort scan order.\n * @param renderableIndexToValidatedIndex — map from `DispatchEntry.renderableIndex`\n * to the validated-ordered index `i` (the loop counter the dispatch\n * loops use). Caller builds this once per frame from `validatedOrdered`.\n * @returns FoldDispatchPlan keyed by validated-ordered index.\n *\n * Empty / all-singleton input yields empty maps + `foldedBucketCount=0`,\n * which the dispatch loops treat as \"no fold this frame\" — byte-identical\n * to pre-feat behavior.\n */\nexport function buildFoldDispatchPlan(\n buckets: readonly FoldBucket[],\n renderableIndexToValidatedIndex: ReadonlyMap<number, number>,\n): FoldDispatchPlan {\n const headBuckets = new Map<number, FoldBucket>();\n const skipIndices = new Set<number>();\n let foldedBucketCount = 0;\n for (const bucket of buckets) {\n if (bucket.bucketSize <= 1) continue;\n const headEntry = bucket.entries[0];\n if (headEntry === undefined) continue;\n const headValidatedIdx = renderableIndexToValidatedIndex.get(headEntry.renderableIndex);\n if (headValidatedIdx === undefined) continue;\n headBuckets.set(headValidatedIdx, bucket);\n foldedBucketCount += 1;\n for (let i = 1; i < bucket.entries.length; i++) {\n const memberEntry = bucket.entries[i];\n if (memberEntry === undefined) continue;\n const memberValidatedIdx = renderableIndexToValidatedIndex.get(memberEntry.renderableIndex);\n if (memberValidatedIdx === undefined) continue;\n skipIndices.add(memberValidatedIdx);\n }\n }\n return { headBuckets, skipIndices, foldedBucketCount };\n}\n\n/**\n * WebGL2 uniform-fallback per-bucket instance-count ceiling\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M2 / D-2 +\n * research N-1).\n *\n * 128 instances * 64 B/mat4 stride = 8192 B, comfortably below the WebGL2\n * minimum 16384 B UBO size, leaving headroom for the per-frame material\n * UBO slice. Locked at the type level via `RhiInstancingExceedsUniformCapDetail.limit`\n * (literal 128) — a future cap change would be a major evolution, not a\n * runtime knob.\n */\nexport const FOLD_UNIFORM_INSTANCE_CAP = 128;\n\n/**\n * Minimal `RhiCapabilities` shape consumed by the cap-fallback helper.\n *\n * The real `RhiDevice.caps` carries many feature flags; the helper only\n * reads `storageBuffer` (the WebGL2 / WebGPU split signal — true on\n * WebGPU + dawn / wgpu native paths, false on the WebGL2 uniform-only\n * fallback path). Mirrors the field name on the production `RhiCaps`\n * type so the dispatch site can pass `runtime.device.caps` straight in.\n */\nexport interface FoldCapsLike {\n readonly storageBuffer: boolean;\n}\n\n/**\n * Decision POD returned by {@link evaluateFoldBucketUniformCap}.\n *\n * Fields:\n * - `fallback` — `true` when the bucket must NOT fold and the dispatch\n * site must route it through the per-entity drawIndexed exit (the\n * same exit the mode-gate bypass uses, plan-strategy D-9 \"shared\n * fallback exit\"). `false` when the bucket can fold normally.\n * - `error` — the structured RhiError to fire alongside the fallback.\n * Always populated when `fallback === true`; always `undefined` when\n * `fallback === false` (charter proposition 4: explicit failure on\n * the failure path; silent success on the success path).\n *\n * Caller contract: when `fallback === true`, fire the error via the\n * runtime error registry AND draw the bucket's entries individually\n * (each as a 1-instance drawIndexed). Skipping the fallback while still\n * firing the error would leave the frame visually wrong (uniform buffer\n * write would clip at 128 entries).\n */\nexport interface FoldBucketCapDecision {\n readonly fallback: boolean;\n readonly error: RhiError | undefined;\n}\n\n/**\n * Decide whether a fold bucket fits the WebGL2 uniform-fallback per-bucket\n * instance-count ceiling, returning the structured RhiError + fallback\n * intent the dispatch site needs to act on\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M2 / w11 +\n * plan-strategy D-2 + D-9 + AC-05).\n *\n * Decision matrix:\n *\n * | caps.storageBuffer | bucketSize | fallback | error |\n * |:--|:--|:--|:--|\n * | `true` | every | `false` | `undefined` (WebGPU has no per-binding instance cap inside the storage buffer's `maxStorageBufferBindingSize`; the byte-cap path emits `'limit-exceeded'` separately) |\n * | `false` | `<= 128` | `false` | `undefined` (fits inside the WebGL2 minimum 16384 B UBO with headroom) |\n * | `false` | `> 128` | `true` | `RhiError({ code: 'instancing-exceeds-uniform-cap', detail: { requested, limit: 128, scope } })` |\n *\n * Singleton buckets (`bucketSize === 1`) always pass — they are the\n * mode-gate bypass output and never need the cap check (the cap is\n * about *folded* bucket arity, not about per-entity per-frame work).\n *\n * @param bucket — the FoldBucket whose `bucketSize` is the sole input\n * (instance count = bucketSize); other fields are not consulted.\n * @param caps — the runtime's RHI capability flags\n * (`runtime.device.caps`); only `storageBuffer` is read.\n * @param scope — closed `'sprite' | 'tilemap-chunk'` discriminator the\n * dispatch site picks based on the call site (sprite-pass primary\n * sprite entry vs tilemap-chunk-derived entry). Surfaced verbatim on\n * the error's `.detail.scope` so AI users can branch their recovery\n * on which dispatch site overflowed.\n * @returns a {@link FoldBucketCapDecision} POD; never throws.\n */\nexport function evaluateFoldBucketUniformCap(\n bucket: FoldBucket,\n caps: FoldCapsLike,\n scope: 'sprite' | 'tilemap-chunk',\n): FoldBucketCapDecision {\n if (caps.storageBuffer) return { fallback: false, error: undefined };\n if (bucket.bucketSize <= FOLD_UNIFORM_INSTANCE_CAP) {\n return { fallback: false, error: undefined };\n }\n const error = new RhiError({\n code: 'instancing-exceeds-uniform-cap',\n expected: `bucket instance count <= ${FOLD_UNIFORM_INSTANCE_CAP} (uniform fallback cap)`,\n hint: `reduce the bucket size (smaller layer/material groupings), switch to a WebGPU-capable backend (storage buffers lift the cap), or accept the per-cell drawIndexed fallback for ${scope}`,\n detail: {\n requested: bucket.bucketSize,\n limit: FOLD_UNIFORM_INSTANCE_CAP,\n scope,\n },\n });\n return { fallback: true, error };\n}\n\n/**\n * Closed metric key for the AC-06 fold counter\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M3 / D-3).\n *\n * Semantics — count of instanced `drawIndexed` calls the fold operator\n * emits this frame; one increment per non-singleton head bucket retained\n * after the M2 / w11 cap-fallback filter. NOT entity count, NOT pre-\n * filter bucket count — cap-overrun buckets that the dispatch site\n * routed through the per-entity fallback exit do not count.\n *\n * Naming follows the EngineMetrics dot-namespace convention\n * (`<feature>.<event>`); `render.instancing.*` covers both sprite and\n * tilemap-chunk dispatch sites without scope ambiguity (research F-5,\n * plan-strategy §8.2). The owning host evidence reads\n * `ownerMetrics.snapshot()['render.instancing.foldedDraws']`.\n */\nexport const FOLDED_DRAWS_METRIC_KEY = 'render.instancing.foldedDraws';\n\n/**\n * Minimal `EngineMetrics` shape consumed by {@link incrementFoldedDrawsMetric}.\n *\n * The real `EngineMetrics` carries `snapshot()` + `reset()` too; the\n * helper only writes, so the consumed surface narrows to a single\n * method. Lets the unit test inject a `vi.fn()` mock without faking the\n * read APIs.\n */\nexport interface FoldMetricsLike {\n increment(name: string): void;\n}\n\n/**\n * Bump the AC-06 `render.instancing.foldedDraws` counter once per fold-\n * eligible head bucket in `plan` (M3 / w13, plan-strategy D-3).\n *\n * Single counter-write site for the metric — the record-stage consumer\n * calls this once per `recordFrame` after the cap-fallback filter\n * (M2 / w11) so cap-overrun buckets do not contribute (their members\n * fall through to per-entity drawIndexed, which is not an instanced\n * draw). `plan.foldedBucketCount` is the SSOT for \"how many instanced\n * drawIndexed will this frame emit\"; passing the same plan to this\n * helper keeps the metric and the actual dispatch in lockstep.\n *\n * Mode-bypass plans (D-5: mode != 0 yields singleton-only buckets which\n * `buildFoldDispatchPlan` filters out) carry `foldedBucketCount === 0`\n * and produce no increments — per-entity drawIndexed is not folded so\n * the metric correctly stays at 0.\n *\n * @param plan — output of {@link buildFoldDispatchPlan} after possible\n * cap-fallback filtering by the record-stage consumer.\n * @param metrics — the owner-provided EngineMetrics counter; only\n * `increment(name)` is called. Empty `plan.foldedBucketCount === 0`\n * produces zero calls (no metric churn for fold-disabled frames).\n */\nexport function incrementFoldedDrawsMetric(plan: FoldDispatchPlan, metrics: FoldMetricsLike): void {\n for (let i = 0; i < plan.foldedBucketCount; i++) {\n metrics.increment(FOLDED_DRAWS_METRIC_KEY);\n }\n}\n","// @forgeax/engine-runtime — SSAO per-runtime persistent GPU buffers.\n//\n// feat-20260612-hdrp-ssao M1 / w4.\n//\n// Owner of 3 SSAO GPU resources, lazily allocated per RenderSystemRuntime,\n// following the getOrCreateHdrpBuffers WeakMap pattern (research F12):\n// (1) kernel UBO — 64 padded vec4 samples (1024 B), label hdrp-ssao-kernel\n// (2) noise texture — 4x4 rgba32float, label hdrp-ssao-noise, NEAREST/REPEAT\n// (3) uniform UBO — 3 mat4 + vec4 intensityPad (256 B aligned),\n// label hdrp-ssao-uniform\n//\n// plan-strategy D-1: uniform carries view + projection + inverseProjection.\n// plan-strategy D-C: intensity, radius, and bias are carried at offset 192\n// (the existing vec4 slot), so the lighting shader can mix(1.0, ssao*ao,\n// intensity) without a new UBO.\n// The kernel uses a uniform buffer on every backend. 1024 B is below the\n// WebGL2 minimum fragment UBO size, so SSAO does not need a storage-buffer\n// capability gate.\n\nimport type { Buffer, Sampler, Texture, TextureView } from '@forgeax/engine-rhi';\nimport { GPU_TEXTURE_USAGE_COPY_DST, GPU_TEXTURE_USAGE_TEXTURE_BINDING } from './gpu-texture-usage';\nimport { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from './gpu-usage';\nimport type { RenderSystemRuntime } from './record/render-context';\n\n// Deterministic host-side SSAO data is owned by the buffer allocator because\n// these values have no consumer outside the resources they initialize.\nexport const SSAO_KERNEL_SAMPLE_COUNT = 64;\nconst NOISE_SIZE = 16;\n\nfunction mulberry32(seed: number): () => number {\n let state = seed | 0;\n return () => {\n state = (state + 0x6d2b79f5) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + t * (b - a);\n}\n\nexport function generateSsaoKernel(seed: number = 0): readonly Float32Array[] {\n const rand = mulberry32(seed);\n const kernel: Float32Array[] = [];\n for (let i = 0; i < SSAO_KERNEL_SAMPLE_COUNT; i++) {\n let x = rand() * 2 - 1;\n let y = rand() * 2 - 1;\n let z = rand();\n const len = Math.sqrt(x * x + y * y + z * z);\n x /= len;\n y /= len;\n z /= len;\n const r = rand();\n x *= r;\n y *= r;\n z *= r;\n const scale = lerp(0.1, 1.0, (i / SSAO_KERNEL_SAMPLE_COUNT) ** 2);\n const sample = new Float32Array(3);\n sample[0] = x * scale;\n sample[1] = y * scale;\n sample[2] = z * scale;\n kernel.push(sample);\n }\n return kernel;\n}\n\nexport function generateSsaoNoise(seed: number = 0): Float32Array {\n const rand = mulberry32(seed);\n const noise = new Float32Array(NOISE_SIZE * 3);\n for (let i = 0; i < NOISE_SIZE; i++) {\n noise[i * 3 + 0] = rand() * 2 - 1;\n noise[i * 3 + 1] = rand() * 2 - 1;\n noise[i * 3 + 2] = 0;\n }\n return noise;\n}\n\n// Each vec3<f32> in a WGSL array is 16B (12B payload + 4B padding).\n// 64 samples * 16 B/sample = 1024 B.\nconst BYTES_PER_KERNEL_ELEMENT = 16;\n\n// SSAO uniform layout (plan-strategy §D-1 + §D-C, M7 round-2):\n// bytes [0..63] view mat4x4<f32>\n// bytes [64..127] projection mat4x4<f32>\n// bytes [128..191] inverseProjection mat4x4<f32>\n// bytes [192..207] intensityPad vec4<f32> // x = intensity, y = radius, z = bias, w = pad\n// bytes [208..255] padding // align to 256B WebGPU UBO offset\n//\n// The total is rounded to 256B so the same UBO can host an additional\n// shader-side scalar binding at the tail without re-allocation.\nconst UNIFORM_INTENSITY_OFFSET_BYTES = 192;\nconst UNIFORM_BYTES = 256;\nexport const SSAO_UNIFORM_INTENSITY_OFFSET = UNIFORM_INTENSITY_OFFSET_BYTES;\nexport const SSAO_UNIFORM_BYTES = UNIFORM_BYTES;\n\n// ── 1x1 white fallback texture (plan-strategy §D-B) ───────────────────────\n//\n// Single-PSO invariant: the HDRP unified BGL always declares a binding 7\n// texture_2d<f32>. When SSAO is disabled (or its resources are not yet\n// allocated), the bind group binds this 1x1 r8unorm texture filled with\n// 0xFF. r8unorm normalizes 255 -> 1.0, so the lighting shader reads\n// `ssaoFactor = 1.0`, and `mix(1.0, ssao*ao, intensity) = ao` collapses\n// back to the round-1 baseline (ambient = baked-AO only). No shader\n// recompile across enable/disable.\n\ninterface SsaoFallbackResources {\n readonly texture: Texture;\n readonly view: TextureView;\n readonly sampler: Sampler;\n}\n\nconst fallbackCache = new WeakMap<RenderSystemRuntime, SsaoFallbackResources>();\n\n/**\n * Lazily allocate the 1x1 r8unorm white fallback texture + a sampler for\n * SSAO disabled / resource-missing path. Cached per RenderSystemRuntime so\n * subsequent calls reuse the same resources (charter P5 one-owner).\n *\n * Returns `null` if `device.createTexture` / `createTextureView` /\n * `createSampler` / `queue.writeTexture` fails; the caller (createBindGroup)\n * propagates the structured RhiError that landed on `runtime.errorRegistry`.\n */\nexport function getOrCreateSsaoFallbackTexture(\n runtime: RenderSystemRuntime,\n): SsaoFallbackResources | null {\n const cached = fallbackCache.get(runtime);\n if (cached !== undefined) return cached;\n\n const device = runtime.device;\n const texRes = device.createTexture({\n label: 'hdrp-ssao-fallback-white',\n size: { width: 1, height: 1, depthOrArrayLayers: 1 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'r8unorm',\n usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,\n textureBindingViewDimension: undefined,\n });\n if (!texRes.ok) {\n runtime.errorRegistry.fire(texRes.error);\n return null;\n }\n\n // r8unorm: a single byte 0xFF normalizes to 1.0 (white => AO = 1.0).\n const whitePixel = new Uint8Array([255]);\n const writeRes = device.queue.writeTexture(\n {\n texture: texRes.value,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: 0 },\n },\n whitePixel,\n { offset: 0, bytesPerRow: 256, rowsPerImage: 1 },\n { width: 1, height: 1, depthOrArrayLayers: 1 },\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n return null;\n }\n\n const viewRes = device.createTextureView(texRes.value, {\n label: 'hdrp-ssao-fallback-white-view',\n format: 'r8unorm',\n dimension: '2d',\n aspect: 'all',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!viewRes.ok) {\n runtime.errorRegistry.fire(viewRes.error);\n return null;\n }\n\n const samplerRes = device.createSampler({\n label: 'hdrp-ssao-fallback-sampler',\n magFilter: 'linear',\n minFilter: 'linear',\n mipmapFilter: 'linear',\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n addressModeW: 'clamp-to-edge',\n });\n if (!samplerRes.ok) {\n runtime.errorRegistry.fire(samplerRes.error);\n return null;\n }\n\n const resources: SsaoFallbackResources = {\n texture: texRes.value,\n view: viewRes.value,\n sampler: samplerRes.value,\n };\n fallbackCache.set(runtime, resources);\n return resources;\n}\n\n/**\n * SSAO GPU resources owned by this module (plan-strategy D-1, D-4).\n *\n * Fields are readonly per charter P5: one resource, one owner.\n */\nexport interface SsaoBuffers {\n /** 64 padded vec4 uniform buffer for hemisphere samples. */\n readonly kernelBuffer: Buffer;\n readonly kernelBytes: number;\n /** 4x4 rgba32float noise texture for per-pixel TBN rotation. */\n readonly noiseTexture: Texture;\n /** SSAO uniform UBO: view (mat4) + projection (mat4) + inverseProjection (mat4). */\n readonly uniformBuffer: Buffer;\n readonly uniformBytes: number;\n}\n\nconst cache = new WeakMap<RenderSystemRuntime, SsaoBuffers>();\n\n/**\n * Lazily allocate the 3 SSAO GPU resources for `runtime`. Returns the\n * same `SsaoBuffers` object on subsequent calls (per-RenderSystem\n * stable identity, WeakMap).\n *\n * On `device.createBuffer` / `device.createTexture` failure, fires a\n * structured error on the runtime's error registry and returns `null`.\n *\n * @returns SsaoBuffers on success, null if an allocation fails.\n */\nexport function getOrCreateSsaoBuffers(runtime: RenderSystemRuntime): SsaoBuffers | null {\n const cached = cache.get(runtime);\n if (cached !== undefined) return cached;\n\n const device = runtime.device;\n\n // (1) Kernel UBO — 64 padded vec4 samples (1024 B).\n const kernelSamples = generateSsaoKernel();\n const kernelData = new Float32Array(SSAO_KERNEL_SAMPLE_COUNT * 4); // 4 floats per padded vec3\n for (let i = 0; i < SSAO_KERNEL_SAMPLE_COUNT; i++) {\n const s = kernelSamples[i];\n if (s === undefined) continue;\n kernelData[i * 4 + 0] = s[0] ?? 0;\n kernelData[i * 4 + 1] = s[1] ?? 0;\n kernelData[i * 4 + 2] = s[2] ?? 0;\n // kernelData[i * 4 + 3] = 0 (padding for std140 vec3 alignment)\n }\n\n const kernelBufferRes = device.createBuffer({\n label: 'hdrp-ssao-kernel',\n size: SSAO_KERNEL_SAMPLE_COUNT * BYTES_PER_KERNEL_ELEMENT,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!kernelBufferRes.ok) {\n runtime.errorRegistry.fire(kernelBufferRes.error);\n return null;\n }\n\n // Upload kernel data to the buffer.\n const kernelWriteRes = device.queue.writeBuffer(kernelBufferRes.value, 0, kernelData);\n if (!kernelWriteRes.ok) {\n runtime.errorRegistry.fire(kernelWriteRes.error);\n return null;\n }\n\n // (2) Noise texture — 4x4 rgba32float, NEAREST/REPEAT.\n const noiseData = generateSsaoNoise();\n // Pad to rgba32float: 16 texels * 4 floats = 64 floats.\n const noiseRgba = new Float32Array(16 * 4);\n for (let i = 0; i < 16; i++) {\n noiseRgba[i * 4 + 0] = noiseData[i * 3 + 0] ?? 0;\n noiseRgba[i * 4 + 1] = noiseData[i * 3 + 1] ?? 0;\n noiseRgba[i * 4 + 2] = 0;\n noiseRgba[i * 4 + 3] = 1; // alpha = 1 for rgba32float\n }\n\n const noiseTexRes = device.createTexture({\n label: 'hdrp-ssao-noise',\n size: { width: 4, height: 4, depthOrArrayLayers: 1 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'rgba32float',\n usage: GPU_TEXTURE_USAGE_COPY_DST | GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n textureBindingViewDimension: undefined,\n });\n if (!noiseTexRes.ok) {\n runtime.errorRegistry.fire(noiseTexRes.error);\n return null;\n }\n\n // Direct CPU-to-GPU upload via writeTexture (no alignment requirement\n // unlike copyBufferToTexture; WebGPU spec §19.2). 4x4 rgba32float texture\n // = 16 texels * 4 floats * 4 bytes/float = 256 bytes.\n // The forgeax Texture brand wraps a raw GPUTexture; cast through unknown\n // follows the createRenderer.ts fallback-pixel pattern (line 4330).\n const noiseCopyRes = device.queue.writeTexture(\n {\n texture: noiseTexRes.value,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: 0 },\n },\n noiseRgba,\n { offset: 0, bytesPerRow: 4 * 4 * 4, rowsPerImage: 4 },\n { width: 4, height: 4, depthOrArrayLayers: 1 },\n );\n if (!noiseCopyRes.ok) {\n runtime.errorRegistry.fire(noiseCopyRes.error);\n return null;\n }\n\n // (3) SSAO uniform UBO — 3 mat4 (192 B).\n const uniformBufRes = device.createBuffer({\n label: 'hdrp-ssao-uniform',\n size: UNIFORM_BYTES,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!uniformBufRes.ok) {\n runtime.errorRegistry.fire(uniformBufRes.error);\n return null;\n }\n\n const buffers: SsaoBuffers = {\n kernelBuffer: kernelBufferRes.value,\n kernelBytes: SSAO_KERNEL_SAMPLE_COUNT * BYTES_PER_KERNEL_ELEMENT,\n noiseTexture: noiseTexRes.value,\n uniformBuffer: uniformBufRes.value,\n uniformBytes: UNIFORM_BYTES,\n };\n\n cache.set(runtime, buffers);\n return buffers;\n}\n","// @forgeax/engine-runtime - HDRP per-runtime persistent GPU buffers.\n//\n// feat-20260608-cluster-lighting Round-2 fix-up [w18-fix-r2] (F-1 / F-2):\n//\n// The HDRP cluster-forward path needs four persistent GPU buffers (light_data\n// SSBO, cluster_grid SSBO, light_index_list SSBO, cluster_uniform UBO) on BGL\n// slots 3..6 (plan D-1). Round-1 declared them only as graph resources -- no\n// underlying RHI buffers existed, so the graph fail-fast'd on dangling-read\n// every frame and the binner output was discarded.\n//\n// This module owns the lazy, per-runtime allocation of those buffers via a\n// WeakMap keyed on RenderSystemRuntime. The HDRP buildGraph reaches in via\n// `getOrCreateHdrpBuffers(runtime)`; subsequent calls in the same frame return\n// the cached pair so `device.queue.writeBuffer` lands on the same handles as\n// the (eventual) bind-group layout consumer (charter P5: one resource, one\n// owner; AC-13: 4 RHI buffers actually exist on slot 3..6 layout).\n//\n// Storage usage flags come from the render package's dependency-free buffer\n// usage owner; this module stays decoupled from renderer bootstrap.\n//\n// Sizes:\n// - light_data : 256 x 64 B = 16 384 B\n// - cluster_grid : maxGridCells x 8 B = 64 x 64 x 64 x 8 B = 2 097 152 B max\n// (plan D-grid: x,y,z each in [1..64]; maxCells=262144;\n// stride 2 u32 = 8B; we allocate at the install-time\n// grid passed via DEFAULT_CLUSTER_GRID 16x9x24=3456 cells).\n// - light_index_list : 65536 u32 = 262 144 B\n// - cluster_uniform : = 32 B (2 vec4 std140)\n//\n// AC-14: cluster_uniform is allocated once with the install-time grid; runtime\n// grid changes do NOT trigger PSO rebuild because grid lives in the UBO not in\n// shader specialization. (Shader-side draw is M-future; this AC is satisfied\n// by the buffer being a UBO with field-level updates.)\n\nimport {\n type BindGroup,\n type BindGroupLayout,\n type BindGroupLayoutDescriptor,\n type Buffer,\n RhiError,\n type Sampler,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport { GPU_SHADER_STAGE_COMPUTE } from './gpu-stage';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_STORAGE,\n GPU_BUFFER_USAGE_UNIFORM,\n} from './gpu-usage';\nimport { BYTES_PER_LIGHT_SLOT } from './light-buffer-layout';\nimport {\n CLUSTER_GRID_STRIDE_U32,\n DEFAULT_CLUSTER_GRID,\n LIGHT_INDEX_LIST_CAPACITY,\n MAX_LIGHTS,\n} from './pipeline/standard-profile';\nimport { createHdrpBindGroupLayoutDescriptor } from './pipeline-spec';\nimport { MESH_PER_ENTITY_STRIDE, MESH_UBO_FULL_ARRAY_BYTES } from './record/mesh-ssbo';\nimport type { RenderSystemRuntime } from './record/render-context';\nimport { getOrCreateSsaoFallbackTexture } from './ssao-buffers';\n\nexport { getOrCreateSsaoFallbackTexture } from './ssao-buffers';\n\n/**\n * WebGL2 HDRP downlevel light-list capacity. 128 x 64 B = 8 KiB, below the\n * WebGL2 minimum uniform-buffer binding size of 16 KiB. The storage path\n * keeps the full MAX_LIGHTS budget; the uniform path uses the same LightSlot\n * POD and only changes the transport.\n */\nexport const HDRP_UNIFORM_LIGHT_CAPACITY = 128;\n\n/** Bind-group layout used only by the WebGPU cluster membership producer. */\nexport function createHdrpClusterMembershipBindGroupLayoutDescriptor(): BindGroupLayoutDescriptor {\n return {\n label: 'hdrp-cluster-membership-bgl',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_COMPUTE,\n buffer: { type: 'read-only-storage', hasDynamicOffset: false },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_COMPUTE,\n buffer: { type: 'storage', hasDynamicOffset: false },\n },\n {\n binding: 2,\n visibility: GPU_SHADER_STAGE_COMPUTE,\n buffer: { type: 'uniform', hasDynamicOffset: false },\n },\n {\n binding: 3,\n visibility: GPU_SHADER_STAGE_COMPUTE,\n buffer: { type: 'read-only-storage', hasDynamicOffset: false },\n },\n ],\n };\n}\n\n/**\n * The persistent HDRP GPU buffers (plan D-1, BGL slot 3..6) plus the unified\n * BGL layout for group(2) (plan D-6, feat-20260609-hdrp-cluster-fragment-ggx M3).\n *\n * AC-11: light_data stride = `BYTES_PER_LIGHT_SLOT` = 64 (double-sided lock with\n * WGSL hdrp-cluster-forward.wgsl LightSlot).\n * AC-13: 4 distinct RHI Buffer handles, ready for slot-3..6 BGL binding.\n * AC-14: clusterUniform is a uniform buffer (not storage); runtime grid change\n * is a writeBuffer field update, not a PSO rebuild.\n * AC-06: unifiedBindGroupLayout is the 7-entry group(2) BGL (mesh SSBO +\n * cluster 4 buffer).\n */\nexport interface HdrpBuffers {\n /** Whether bindings 3..5 carry storage buffers or uniform-buffer fallback data. */\n readonly storageBuffer: boolean;\n /** light_data -- 256 x 64 B on storage, 128 x 64 B on uniform fallback. */\n readonly lightDataBuffer: Buffer;\n readonly lightDataBytes: number;\n /** cluster_grid SSBO -- gridX*gridY*gridZ * 2 u32, BGL slot 4. */\n readonly clusterGridBuffer: Buffer;\n readonly clusterGridBytes: number;\n /** light_index_list SSBO -- 65536 u32 = 256 KiB, BGL slot 5. */\n readonly lightIndexListBuffer: Buffer;\n readonly lightIndexListBytes: number;\n /** cluster_uniform UBO -- 32 B (2 vec4 std140), BGL slot 6. */\n readonly clusterUniformBuffer: Buffer;\n readonly clusterUniformBytes: number;\n /** CPU-produced light AABBs consumed by the optional WebGPU membership pass. */\n readonly lightBoundsBuffer: Buffer;\n readonly lightBoundsBytes: number;\n /** The grid the buffers were sized for; cluster_grid is sized by gridX*gridY*gridZ. */\n readonly grid: { readonly x: number; readonly y: number; readonly z: number };\n /** Unified BGL layout for group(2). */\n readonly unifiedBindGroupLayout: BindGroupLayout;\n}\n\nconst cache = new WeakMap<RenderSystemRuntime, HdrpBuffers>();\n\n/**\n * Lazily allocate the 4 persistent HDRP buffers for `runtime`. Returns the same\n * `HdrpBuffers` object on subsequent calls (per-RenderSystem stable identity).\n *\n * On `device.createBuffer` failure, fires a structured RhiError on the runtime's\n * error registry and returns `null`; HDRP buildGraph treats null as a hard\n * pipeline disable (charter P3 explicit failure).\n *\n * `grid` defaults to `DEFAULT_CLUSTER_GRID` when undefined (matches the M5\n * record-stage default). The buffers are sized at the *first* call's grid; a\n * later install with a different grid keeps the existing allocation as long as\n * it has enough capacity (gridX*gridY*gridZ <= cached.grid product). Different\n * grids that exceed capacity are not currently re-allocated -- M-future.\n */\nexport function getOrCreateHdrpBuffers(\n runtime: RenderSystemRuntime,\n grid: { x: number; y: number; z: number } = DEFAULT_CLUSTER_GRID,\n): HdrpBuffers | null {\n const cached = cache.get(runtime);\n if (cached !== undefined) return cached;\n\n const device = runtime.device;\n const storageBuffer = runtime.device.caps?.storageBuffer === true;\n const clusterUniformBytes = 32;\n const lightDataBytes =\n (storageBuffer ? MAX_LIGHTS : HDRP_UNIFORM_LIGHT_CAPACITY) * BYTES_PER_LIGHT_SLOT;\n const clusterCells = grid.x * grid.y * grid.z;\n const clusterGridBytes = storageBuffer\n ? clusterCells * CLUSTER_GRID_STRIDE_U32 * 4\n : clusterUniformBytes;\n const lightIndexListBytes = storageBuffer ? LIGHT_INDEX_LIST_CAPACITY * 4 : clusterUniformBytes;\n const lightBoundsBytes = MAX_LIGHTS * 6 * 4;\n\n const lightData = device.createBuffer({\n label: 'hdrp-light-data',\n size: lightDataBytes,\n usage:\n (storageBuffer ? GPU_BUFFER_USAGE_STORAGE : GPU_BUFFER_USAGE_UNIFORM) |\n GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!lightData.ok) {\n runtime.errorRegistry.fire(lightData.error);\n return null;\n }\n const clusterGrid = device.createBuffer({\n label: 'hdrp-cluster-grid',\n size: clusterGridBytes,\n usage:\n (storageBuffer ? GPU_BUFFER_USAGE_STORAGE : GPU_BUFFER_USAGE_UNIFORM) |\n GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!clusterGrid.ok) {\n runtime.errorRegistry.fire(clusterGrid.error);\n return null;\n }\n const lightIndexList = device.createBuffer({\n label: 'hdrp-light-index-list',\n size: lightIndexListBytes,\n usage:\n (storageBuffer ? GPU_BUFFER_USAGE_STORAGE : GPU_BUFFER_USAGE_UNIFORM) |\n GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!lightIndexList.ok) {\n runtime.errorRegistry.fire(lightIndexList.error);\n return null;\n }\n const clusterUniform = device.createBuffer({\n label: 'hdrp-cluster-uniform',\n size: clusterUniformBytes,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!clusterUniform.ok) {\n runtime.errorRegistry.fire(clusterUniform.error);\n return null;\n }\n const lightBounds = device.createBuffer({\n label: 'hdrp-light-bounds',\n size: lightBoundsBytes,\n usage:\n (storageBuffer ? GPU_BUFFER_USAGE_STORAGE : GPU_BUFFER_USAGE_UNIFORM) |\n GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!lightBounds.ok) {\n runtime.errorRegistry.fire(lightBounds.error);\n return null;\n }\n\n // Create the unified 7-entry BGL layout for group(2)\n // (plan D-6, feat-20260609-hdrp-cluster-fragment-ggx M3).\n // The HDRP BGL descriptor is owned by pipeline-spec and shared with the\n // pipeline dispatcher and its byte-identical tests.\n const storageBufferCap = runtime.device.caps?.storageBuffer === true;\n const unifiedBglRes = device.createBindGroupLayout(\n createHdrpBindGroupLayoutDescriptor(storageBufferCap),\n );\n if (!unifiedBglRes.ok) {\n runtime.errorRegistry.fire(unifiedBglRes.error);\n return null;\n }\n const buffers: HdrpBuffers = {\n storageBuffer,\n lightDataBuffer: lightData.value,\n lightDataBytes,\n clusterGridBuffer: clusterGrid.value,\n clusterGridBytes,\n lightIndexListBuffer: lightIndexList.value,\n lightIndexListBytes,\n clusterUniformBuffer: clusterUniform.value,\n clusterUniformBytes,\n lightBoundsBuffer: lightBounds.value,\n lightBoundsBytes,\n grid: { x: grid.x, y: grid.y, z: grid.z },\n unifiedBindGroupLayout: unifiedBglRes.value,\n };\n cache.set(runtime, buffers);\n return buffers;\n}\n\n/**\n * Build the 8-float cluster_uniform std140 payload.\n *\n * [0] gridX u32 (cast in shader)\n * [1] gridY u32\n * [2] gridZ u32\n * [3] lightCount u32 (vec4 alignment; capped by the active transport)\n * [4] near f32\n * [5] far f32\n * [6] logFarOverNear f32\n * [7] ssaoIntensity f32 (scope-amend-webgl2-ubo: folded from removed\n * dedicated @binding(9) UBO; lighting shader\n * reads `cluster_uniform.near_far_log.w`)\n *\n * Matches `__tests__/hdrp-bgl-slots.test.ts CLUSTER_UNIFORM_LAYOUT`.\n *\n * Note: u32 values written into a Float32Array view are bit-pattern correct\n * because writeBuffer copies raw bytes; the WGSL `var<uniform>` declares the\n * field as u32 / f32 per its position so the device reinterprets correctly.\n * Use a Uint32Array view for the integer slots to keep the bit pattern intact.\n */\nexport function packClusterUniform(\n grid: { x: number; y: number; z: number },\n near: number,\n far: number,\n ssaoIntensity: number = 0,\n lightCount: number = 0,\n lightCapacity: number = HDRP_UNIFORM_LIGHT_CAPACITY,\n): ArrayBuffer {\n const buf = new ArrayBuffer(32);\n const u32 = new Uint32Array(buf);\n const f32 = new Float32Array(buf);\n u32[0] = grid.x >>> 0;\n u32[1] = grid.y >>> 0;\n u32[2] = grid.z >>> 0;\n u32[3] = Math.min(Math.max(lightCount, 0), lightCapacity) >>> 0;\n f32[4] = near;\n f32[5] = far;\n // logFarOverNear: log(far/near) used by the shader for log-z slice mapping.\n // Guard against near=0 / far<=near (returns 0; downstream uses fallback).\n f32[6] = near > 0 && far > near ? Math.log(far / near) : 0;\n // f32[7] = SSAO intensity (default 0 = disabled-equivalent: mix(1.0, x, 0) = 1).\n f32[7] = ssaoIntensity;\n return buf;\n}\n\n/**\n * Consumers pass the same mesh storage buffer + stride that URP uses, so the\n * dynamic offset (`i * MESH_PER_ENTITY_STRIDE`) at `setBindGroup(2, ...)`\n * stays valid across both pipelines.\n */\n/**\n * Build the unified group(2) BindGroup for HDRP — binding 0 = mesh SSBO\n * (dynamic offset, same buffer URP binds), bindings 3..6 = the cluster\n * buffers from `getOrCreateHdrpBuffers`.\n *\n * feat-20260609-hdrp-cluster-fragment-ggx M4 / w19. Called per-frame from the\n * recordFrame HDRP block after binner+writeBuffer; the resulting BindGroup\n * lands on `passCtx.hdrpClusterBindGroup` and recordMainPass binds it at\n * group(2) when `frameState.isHdrpActive`.\n *\n * Returns `null` on `device.createBindGroup` failure (a structured RhiError\n * is fired on `runtime.errorRegistry`); recordMainPass gracefully falls back\n * to the URP mesh bindGroup when null.\n *\n * Plan D-1 / D-4: the mesh SSBO buffer + stride mirror the URP path, so the\n * single dynamic offset issued at `setBindGroup(2, ...)` covers binding 0 of\n * the unified BGL just as it covers binding 0 of the URP mesh BGL.\n */\n/**\n * SSAO bind-group input (plan-strategy §D-B, M7;\n * scope-amend-webgl2-ubo: dedicated @binding(9) intensity UBO removed).\n *\n * The HDRP unified BGL always declares 7 entries (cluster 5 + ssao 2); the\n * caller supplies one of two shapes depending on `config.ssao?.enabled`:\n *\n * { enabled: true, ssaoBlurredView }\n * -> binding 7 = real ssaoBlurred view\n * -> binding 8 = real ssao sampler (lazy-allocated alongside fallback)\n *\n * { enabled: false }\n * -> binding 7 = 1x1 white fallback texture (AO = 1.0)\n * -> binding 8 = fallback sampler\n *\n * Intensity flows via `cluster_uniform.near_far_log.w` (binding 6); the host\n * writes intensity=0 when SSAO is disabled so the lighting blend\n * `mix(1.0, ssao*ao, 0) = 1.0` collapses to the round-1 baseline. The\n * \"always-7-entries\" invariant lets every PBR PSO use the same pipeline\n * layout regardless of SSAO state — toggling the runtime config never\n * triggers shader recompile (charter P4 one consistent abstraction).\n *\n * `ssaoBuffers` is no longer carried in the enabled variant: the SSAO\n * compute-side UBO continues to live on the SSAO compute pipeline's own\n * group(0) BGL, decoupled from the lighting-stage group(2).\n */\nexport type SsaoBindOptions =\n | {\n readonly enabled: true;\n readonly ssaoBlurredView: TextureView;\n }\n | { readonly enabled: false };\n\nexport function createHdrpUnifiedBindGroup(\n runtime: RenderSystemRuntime,\n hdrpBuffers: HdrpBuffers,\n meshStorageBuffer: Buffer,\n ssaoOptions: SsaoBindOptions = { enabled: false },\n): BindGroup | null {\n const fallback = getOrCreateSsaoFallbackTexture(runtime);\n if (fallback === null) return null;\n\n const ssaoTexView: TextureView = ssaoOptions.enabled\n ? ssaoOptions.ssaoBlurredView\n : fallback.view;\n const ssaoSampler: Sampler = fallback.sampler;\n\n const result = runtime.device.createBindGroup({\n label: 'hdrp-unified-bg-group2',\n layout: hdrpBuffers.unifiedBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: meshStorageBuffer,\n offset: 0,\n size: hdrpBuffers.storageBuffer ? MESH_PER_ENTITY_STRIDE : MESH_UBO_FULL_ARRAY_BYTES,\n },\n },\n },\n {\n binding: 3,\n resource: {\n kind: 'buffer',\n value: { buffer: hdrpBuffers.lightDataBuffer },\n },\n },\n {\n binding: 4,\n resource: {\n kind: 'buffer',\n value: { buffer: hdrpBuffers.clusterGridBuffer },\n },\n },\n {\n binding: 5,\n resource: {\n kind: 'buffer',\n value: { buffer: hdrpBuffers.lightIndexListBuffer },\n },\n },\n {\n binding: 6,\n resource: {\n kind: 'buffer',\n value: { buffer: hdrpBuffers.clusterUniformBuffer },\n },\n },\n {\n binding: 7,\n resource: { kind: 'textureView', value: ssaoTexView },\n },\n {\n binding: 8,\n resource: { kind: 'sampler', value: ssaoSampler },\n },\n ],\n });\n if (!result.ok) {\n runtime.errorRegistry.fire(result.error);\n return null;\n }\n return result.value;\n}\n\n/**\n * Build the compute-only bind group for ordered cluster membership output.\n * Its group is intentionally separate from the fragment group: the same\n * light-index buffer is read-only in the fragment pipeline but read-write in\n * the producer pipeline, which WebGPU represents with different binding\n * types.\n */\nexport function createHdrpClusterMembershipBindGroup(\n runtime: RenderSystemRuntime,\n hdrpBuffers: HdrpBuffers,\n layout: BindGroupLayout,\n): BindGroup | null {\n const result = runtime.device.createBindGroup({\n label: 'hdrp-cluster-membership-bg',\n layout,\n entries: [\n {\n binding: 0,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.clusterGridBuffer } },\n },\n {\n binding: 1,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.lightIndexListBuffer } },\n },\n {\n binding: 2,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.clusterUniformBuffer } },\n },\n {\n binding: 3,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.lightBoundsBuffer } },\n },\n ],\n });\n if (!result.ok) {\n runtime.errorRegistry.fire(result.error);\n return null;\n }\n return result.value;\n}\n\n/** Sentinel error class re-export for tests asserting the error path. */\nexport { RhiError as HdrpBufferAllocError };\n","// @forgeax/engine-runtime - ShadowAtlas (cube_array depth atlas for point-light shadows).\n//\n// feat-20260612-point-light-shadows-urp-hdrp M3 / T-M3-1 (plan-strategy §D-1).\n//\n// Lazy-allocated `texture_depth_cube_array` (depth32float) + per-face 2D\n// TextureView cache. One layer per shadow-casting PointLight (cap = 4 enforced\n// by the PointLightShadow ECS component cardinality). Total texel footprint at\n// the 512x512 default = 4 layers x 6 faces x 512 x 512 x 4 B = 24 MiB.\n//\n// Why a separate module (vs inlining into createRenderer / pipelineState):\n// - zero-shadow scene path stays allocation-free (AC-09): we never call\n// `device.createTexture` on the cube_array unless `ensure(...)` is invoked\n// from the extract / record path on a frame that has at least one\n// PointLightShadow snapshot.\n// - face-view cache is keyed (layer, face) and built lazily during the\n// per-light shadow caster pass; the cache is invalidated together with the\n// atlas when `dispose()` runs (renderer teardown or layers re-allocation).\n// - the helper descriptors live in `@forgeax/engine-rhi`\n// (`cubeArrayDepthDescriptor` / `cubeArrayDepthFaceView` /\n// `comparisonSamplerDescriptor`) per T-M0-3; this file is the runtime-side\n// owner of the GPU resources they describe.\n//\n// Lifecycle:\n// 1. `new ShadowAtlas(device, { faceSize, layers })` — construct the\n// manager; no GPU work yet.\n// 2. `atlas.ensure()` — first call allocates the cube_array texture +\n// cube_array sampling view + comparison sampler (idempotent thereafter).\n// 3. `atlas.faceView(layer, face)` — lazy 2D depth view used as a render-\n// pass attachment for the corresponding cube face. Cached per (layer,\n// face).\n// 4. `atlas.dispose()` — releases the GPU resources and clears caches.\n// `ensure()` after `dispose()` re-allocates from scratch.\n\nimport {\n comparisonSamplerDescriptor,\n cubeArrayDepthDescriptor,\n cubeArrayDepthFaceView,\n type RhiDevice,\n type Sampler,\n type Texture,\n type TextureView,\n} from '@forgeax/engine-rhi';\n\nimport {\n PointShadowAtlasBoundsViolationError,\n PointShadowAtlasUninitializedError,\n} from './errors/render';\nimport { GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING } from './gpu-texture-usage';\n\n/**\n * Construction options for {@link ShadowAtlas}.\n */\nexport interface ShadowAtlasOptions {\n /** Per-face square size in pixels. Default 512 (PointLightShadow.mapSize default). */\n readonly faceSize?: number;\n /** Number of cube layers. Default 4 (= PointLightShadow cardinality cap). */\n readonly layers?: number;\n}\n\n/** Default per-face square size in pixels. Mirrors PointLightShadow.mapSize default. */\nexport const SHADOW_ATLAS_DEFAULT_FACE_SIZE = 512;\n/** Default cube layer count. Mirrors PointLightShadow cardinality cap. */\nexport const SHADOW_ATLAS_DEFAULT_LAYERS = 4;\n\n/**\n * Cube-array depth atlas for point-light shadows.\n *\n * Shape: `texture_depth_cube_array` (depth32float) with `layers = 4` and per-\n * face size `faceSize x faceSize`. The cube_array sampling view feeds\n * `@group(0) @binding(5)` in URP shaders; the per-face 2D view feeds the\n * shadow-caster render pass attachment for one (layer, face) at a time\n * (WebGPU forbids cube views as render-pass attachments).\n *\n * Construction performs no GPU work. The first `ensure()` call allocates the\n * texture + view + sampler. `dispose()` releases everything; later `ensure()`\n * calls re-allocate.\n *\n * @example Lazy allocation in the extract / record path:\n * ```\n * if (lights.pointShadow.length > 0) {\n * atlas.ensure();\n * for (const ps of lights.pointShadow) {\n * for (let face = 0; face < 6; face++) {\n * const view = atlas.faceView(ps.shadowAtlasLayer, face);\n * // ... begin shadow caster pass with `view` as the depth attachment\n * }\n * }\n * }\n * ```\n */\nexport class ShadowAtlas {\n /** Backing cube_array depth texture. `null` until `ensure()` has run. */\n private texture: Texture | null = null;\n /**\n * Whole-atlas cube_array sampling view used by URP shaders that bind the\n * atlas at `@group(0) @binding(5)`. `null` until `ensure()` has run.\n */\n private cubeArrayView: TextureView | null = null;\n /** Comparison sampler for `texture_depth_cube_array`. */\n private compareSampler: Sampler | null = null;\n /** Per-face 2D depth view cache, keyed by `layer * 6 + face`. */\n private readonly faceViews = new Map<number, TextureView>();\n /** Per-face label cache (debug aid). Reused on re-creation. */\n private readonly device: RhiDevice;\n /** Per-face square size in pixels. */\n readonly faceSize: number;\n /** Cube layer count. */\n readonly layers: number;\n\n constructor(device: RhiDevice, options: ShadowAtlasOptions = {}) {\n this.device = device;\n this.faceSize = options.faceSize ?? SHADOW_ATLAS_DEFAULT_FACE_SIZE;\n this.layers = options.layers ?? SHADOW_ATLAS_DEFAULT_LAYERS;\n }\n\n /**\n * Returns `true` once the atlas texture is allocated. Used by the extract /\n * record path to gate \"no PointLightShadow → no allocation\" (AC-09) — the\n * caller calls {@link ensure} on a frame that has at least one snapshot;\n * before that, `isAllocated()` stays `false` and tests can assert no GPU\n * resources were created.\n */\n isAllocated(): boolean {\n return this.texture !== null;\n }\n\n /**\n * Lazy-allocate the atlas texture + cube_array sampling view + comparison\n * sampler. Idempotent: subsequent calls are zero-cost no-ops once the\n * resources exist.\n *\n * Throws (via the RHI error registry) on allocation failure. This is the\n * only path that touches the GPU — keeping it inside one method makes the\n * \"zero-shadow scene = zero allocation\" gate easy to enforce: the renderer\n * never calls this method on a frame with no PointLightShadow entities.\n */\n ensure(): void {\n if (this.texture !== null) return;\n const usage = GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING;\n const texDesc = cubeArrayDepthDescriptor(this.faceSize, this.layers, usage);\n const texRes = this.device.createTexture(texDesc);\n if (!texRes.ok) throw texRes.error;\n this.texture = texRes.value;\n\n const viewRes = this.device.createTextureView(this.texture, {\n label: 'shadow-atlas-cube-array-view',\n dimension: 'cube-array',\n aspect: 'depth-only',\n baseArrayLayer: 0,\n arrayLayerCount: 6 * this.layers,\n baseMipLevel: 0,\n mipLevelCount: 1,\n });\n if (!viewRes.ok) {\n this.device.destroyTexture(this.texture);\n this.texture = null;\n throw viewRes.error;\n }\n this.cubeArrayView = viewRes.value;\n\n const sampRes = this.device.createSampler(comparisonSamplerDescriptor());\n if (!sampRes.ok) {\n this.device.destroyTexture(this.texture);\n this.texture = null;\n this.cubeArrayView = null;\n throw sampRes.error;\n }\n this.compareSampler = sampRes.value;\n }\n\n /**\n * Whole-atlas cube_array sampling view (`texture_depth_cube_array`). Returns\n * `null` if the atlas is not yet allocated; the caller should gate on a\n * non-null pointShadow array before calling {@link ensure} + this getter.\n */\n getAtlasView(): TextureView | null {\n return this.cubeArrayView;\n }\n\n /**\n * Comparison sampler (`compare: 'less'`) for cube_array depth sampling.\n * Returns `null` if the atlas is not yet allocated.\n */\n getComparisonSampler(): Sampler | null {\n return this.compareSampler;\n }\n\n /**\n * Backing texture handle. Returns `null` if the atlas is not yet allocated.\n */\n getTexture(): Texture | null {\n return this.texture;\n }\n\n /**\n * Lazy 2D depth view selecting `(layer, face)` (the caller passes\n * `shadowAtlasLayer` from the snapshot and a face index 0..5). Used as the\n * depth attachment of the shadow-caster render pass for one cube face.\n *\n * Caches per `(layer, face)` so the per-frame shadow loop pays zero\n * `createTextureView` cost after the first allocation. Cache is cleared on\n * {@link dispose}.\n *\n * @throws PointShadowAtlasUninitializedError if the atlas is not yet\n * allocated (caller must call {@link ensure} first).\n * @throws PointShadowAtlasBoundsViolationError if `layer` or `face` is out\n * of range.\n * @throws RhiError if the underlying `createTextureView` fails.\n */\n faceView(layer: number, face: number): TextureView {\n if (this.texture === null) {\n throw new PointShadowAtlasUninitializedError();\n }\n if (layer < 0 || layer >= this.layers) {\n throw new PointShadowAtlasBoundsViolationError('layer', layer, this.layers);\n }\n if (face < 0 || face >= 6) {\n throw new PointShadowAtlasBoundsViolationError('face', face, 6);\n }\n const key = layer * 6 + face;\n const cached = this.faceViews.get(key);\n if (cached !== undefined) return cached;\n const desc = cubeArrayDepthFaceView(layer, face);\n const r = this.device.createTextureView(this.texture, desc);\n if (!r.ok) throw r.error;\n this.faceViews.set(key, r.value);\n return r.value;\n }\n\n /**\n * Release the GPU resources and clear the per-face view cache. Idempotent;\n * subsequent calls are zero-cost. After dispose, `isAllocated()` returns\n * `false` and the next `ensure()` re-allocates from scratch.\n */\n dispose(): void {\n this.faceViews.clear();\n if (this.texture !== null) {\n this.device.destroyTexture(this.texture);\n this.texture = null;\n }\n this.cubeArrayView = null;\n this.compareSampler = null;\n }\n}\n","// @forgeax/engine-runtime - fullscreen post-process error model\n// (feat-20260604-resource-owning-render-graph-and-fullscreen-postpr M2 / w12;\n// feat-20260609-learn-render-4-5-framebuffers-demo-offscreen-rt-an M1 / T-2\n// added 'fullscreen-input-not-found').\n//\n// Closed 7-member PostProcessErrorCode union + PostProcessError discriminated-union class.\n// - 'post-process-already-registered' (programmer error) -> fullscreen effect registration THROWS a\n// PostProcessError, mirroring ShaderCatalog.installMaterialArtifact's Map.has -> throw\n// fail-fast (research Finding M2-4). A second register under the same id is a coding\n// mistake that must surface immediately.\n// - 'post-process-not-found' (runtime path) -> the typed fullscreen plan returns Result.err with\n// this code when the supplied id resolves to no registered post-process (stale / wrong\n// id). AI users branch on `err.code === 'post-process-not-found'` by property access.\n// - 'fullscreen-input-not-found' (runtime path, feat-20260609 M1 / D-2) -> the\n// dispatchFullscreenPass generic branch THROWS this when reads[0] references a\n// graph resource key that the per-pass resolve context cannot resolve (typo /\n// an unregistered colorTarget / mis-ordered color-target declaration vs the typed fullscreen pass).\n// - 'ssao-radius-non-positive' (runtime path, feat-20260612-hdrp-ssao M2 / w10) ->\n// SSAO radius parameter <= 0; fires when config.ssao.radius value is non-positive.\n// - 'ssao-bias-negative' (runtime path, feat-20260612-hdrp-ssao M2 / w10) ->\n// SSAO bias parameter < 0; fires when config.ssao.bias value is negative.\n//\n// D-1: a NEW independent union rather than folding into RuntimeErrorCode /\n// RuntimeErrorCode's members are render / skin / shadow domain; a separate union\n// keeps the post-process error surface cohesive and additively evolvable.\n//\n// Also per D-4: the fullscreen effect channel is parallel to installMaterialArtifact;\n// material shader errors carry 4-BGL / 12-float-vertex / depth / triangle-list semantics,\n// while post-process errors carry 0-vertex-buffer / no-depth / input-texture-BGL semantics.\n// Mixing the two error spaces would confuse AI users who branch on code for diagnostics.\n//\n// PostProcessError is exposed as a discriminated union (variant per code, AppError pattern)\n// so `if (err.code === 'X')` simultaneously narrows `err.detail` to the per-code payload.\n//\n// Related: requirements M2 AC-08 + AC-19; plan-strategy D-4 / D-9; charter P3 / P4;\n// feat-20260609 M1 plan-decisions D-2 (L-1 lock to scheme B - new closed-set member).\n\n/**\n * Closed union of fullscreen post-process error codes.\n *\n * Exactly 7 members; AI users perform exhaustive `switch (err.code)` without a default\n * and TS guards completeness (AC-08).\n *\n * | code | channel | trigger |\n * |:--|:--|:--|\n * | `'post-process-already-registered'` | throw | a second fullscreen effect registration under an already-registered `id` |\n * | `'post-process-not-found'` | throw / `Result.err` | a typed fullscreen plan whose `shader` id resolves to no registered post-process |\n * | `'fullscreen-input-not-found'` | throw | a typed fullscreen plan whose `reads` key is not a graph-declared color target, or a depth key missing TEXTURE_BINDING (D-4) |\n * | `'ssao-radius-non-positive'` | throw | SSAO `radius <= 0` |\n * | `'ssao-bias-negative'` | throw | SSAO `bias < 0` |\n * | `'params-size-mismatch'` | throw | a fullscreen effect declaration with `params.byteSize < 16` or `defaultValue.length !== byteSize` (feat-20260621 M-A4 / D-4) |\n * | `'params-update-size-mismatch'` | throw | per-frame data-driven write where `PostProcessParams.data` byteLength !== registered `params.byteSize` (feat-20260621 M-A4 / D-4) |\n */\nexport type PostProcessErrorCode = keyof typeof POST_PROCESS_POLICY;\n\n/**\n * Detail for `'post-process-already-registered'`: the post-process id that was already taken.\n * AI consumers read `.detail.id` by property access (charter P4), no message parsing.\n */\nexport interface PostProcessPreviouslyRegisteredDetail {\n readonly id: string;\n}\n\n/**\n * Detail for `'post-process-not-found'`: the post-process id that resolved to no\n * registered entry. Read via `.detail.id` after the code guard.\n */\nexport interface PostProcessNotFoundDetail {\n readonly id: string;\n}\n\n/**\n * Detail for `'fullscreen-input-not-found'`: the graph resource key that the\n * per-pass resolve context could not resolve, plus the pass name that referenced\n * it. Both fields are read via property access after `if (err.code === 'fullscreen-input-not-found')`\n * (charter P4); the AI user immediately knows WHICH key to declare and WHICH\n * pass needs wiring.\n */\nexport interface FullscreenInputNotFoundDetail {\n /** The reads[0] key that resolved to undefined (e.g. 'offscreenColor' / 'hdrColor'). */\n readonly readsKey: string;\n /** The name assigned to the typed fullscreen pass (e.g. 'pp' / 'post'). */\n readonly passName: string;\n}\n\n/**\n * Detail for `'ssao-radius-non-positive'`: the SSAO radius parameter was zero or negative.\n * AI consumers read `.detail.paramName` / `.detail.value` by property access (charter P4).\n */\nexport interface SsaoRadiusNonPositiveDetail {\n readonly paramName: string;\n readonly value: number;\n}\n\n/**\n * Detail for `'ssao-bias-negative'`: the SSAO bias parameter was negative.\n * AI consumers read `.detail.paramName` / `.detail.value` by property access.\n */\nexport interface SsaoBiasNegativeDetail {\n readonly paramName: string;\n readonly value: number;\n}\n\n/**\n * Detail for `'params-size-mismatch'`: the register call's byteSize / defaultValue.length\n * is invalid. Carries `byteSize` (the declared size) and `actualLength` (defaultValue.length).\n * AI consumers read `.detail.byteSize` / `.detail.actualLength` after the code guard.\n */\nexport interface PostProcessParamsSizeMismatchDetail {\n readonly byteSize: number;\n readonly actualLength: number;\n}\n\n/**\n * Detail for `'params-update-size-mismatch'`: the per-frame data-driven write\n * (PostProcessParams.data) had a byteLength that did not equal the registered\n * `params.byteSize`. Carries `byteSize` (registered) + `actualLength` (the\n * supplied data byteLength). AI consumers read `.detail.byteSize` /\n * `.detail.actualLength` after the code guard.\n *\n * NOTE (feat-20260621 M-A2): this code is wired here so dispatchFullscreenPass\n * can fail-fast on a mismatched per-frame write; the full error-model\n * formalization (expected/hint refinement, JSDoc member count, public\n * PostProcessError union variant) is finished in M-A4.\n */\nexport interface PostProcessParamsUpdateSizeMismatchDetail {\n readonly byteSize: number;\n readonly actualLength: number;\n}\n\n/**\n * Conditional resolver from `PostProcessErrorCode` to its detail payload type. Used by the\n * constructor signature so `new PostProcessError({ code: 'X', detail })` narrows the\n * `detail` parameter to the variant payload at compile time.\n */\nexport type PostProcessErrorDetailFor<C extends PostProcessErrorCode> =\n C extends 'post-process-already-registered'\n ? PostProcessPreviouslyRegisteredDetail\n : C extends 'post-process-not-found'\n ? PostProcessNotFoundDetail\n : C extends 'fullscreen-input-not-found'\n ? FullscreenInputNotFoundDetail\n : C extends 'ssao-radius-non-positive'\n ? SsaoRadiusNonPositiveDetail\n : C extends 'ssao-bias-negative'\n ? SsaoBiasNegativeDetail\n : C extends 'params-size-mismatch'\n ? PostProcessParamsSizeMismatchDetail\n : C extends 'params-update-size-mismatch'\n ? PostProcessParamsUpdateSizeMismatchDetail\n : never;\n\n/**\n * Tagged union of `.detail` payloads. The variants are unique by structural fields\n * (`{ id }` for the two id-by-string variants vs `{ readsKey, passName }` for the\n * graph-resource-miss variant); the code discriminator narrows the intent across\n * the two id-shaped variants.\n */\nexport type PostProcessErrorDetail = PostProcessErrorDetailFor<PostProcessErrorCode>;\n\nconst POST_PROCESS_POLICY = {\n 'post-process-already-registered': {\n expected: 'each post-process id is registered at most once',\n hint: (detail) =>\n `post-process id '${(detail as PostProcessPreviouslyRegisteredDetail).id}' is already ` +\n 'registered; same-id re-register is forbidden. Pick a distinct id ' +\n '(engine builtins use the forgeax:: prefix; user passes use <package>::<id>).',\n },\n 'post-process-not-found': {\n expected: 'typed fullscreen plan references a registered post-process id',\n hint: (detail) =>\n `no post-process is registered for id '${(detail as PostProcessNotFoundDetail).id}'. ` +\n `Register '${(detail as PostProcessNotFoundDetail).id}' with the feature host ({source, reads?}), ` +\n 'then reference it from a typed fullscreen RenderFeaturePlan.',\n },\n 'fullscreen-input-not-found': {\n expected: 'reads key must be a graph-declared colorTarget with TEXTURE_BINDING',\n hint: (detail) => {\n const d = detail as FullscreenInputNotFoundDetail;\n return (\n `fullscreen pass '${d.passName}' references reads key '${d.readsKey}' but that key is not ` +\n `declared as a graph color target, or the target is not sampleable as a texture. ` +\n `First declare graph color target '${d.readsKey}' with its format and size ` +\n `(or check spelling) before the typed fullscreen pass '${d.passName}' reads it. ` +\n `If '${d.readsKey}' is a depth target, ensure it has TEXTURE_BINDING usage (0x04) ` +\n `and is declared via graph.addColorTarget. Consider switching pipeline if your pipeline does not expose a sampleable depth target.`\n );\n },\n },\n 'ssao-radius-non-positive': {\n expected: 'SSAO radius must be > 0',\n hint: (detail) => {\n const d = detail as SsaoRadiusNonPositiveDetail;\n return (\n `SSAO parameter '${d.paramName}' is ${d.value}, must be greater than 0. ` +\n `Set config.ssao.${d.paramName} to a positive value (default 0.5) or disable SSAO with config.ssao.enabled = false.`\n );\n },\n },\n 'ssao-bias-negative': {\n expected: 'SSAO bias must be >= 0',\n hint: (detail) => {\n const d = detail as SsaoBiasNegativeDetail;\n return (\n `SSAO parameter '${d.paramName}' is ${d.value}, must be >= 0. ` +\n `Set config.ssao.${d.paramName} to a non-negative value (default 0.025) or disable SSAO.`\n );\n },\n },\n 'params-size-mismatch': {\n expected: 'params.byteSize >= 16 and defaultValue.length === byteSize',\n hint: (detail) => {\n const d = detail as PostProcessParamsSizeMismatchDetail;\n return (\n `params.byteSize is ${d.byteSize} but defaultValue.length is ${d.actualLength}. ` +\n 'The UBO byteSize must be >= 16 B and defaultValue.length must equal byteSize. ' +\n 'Pass a defaultValue Uint8Array whose .length matches byteSize exactly.'\n );\n },\n },\n 'params-update-size-mismatch': {\n expected: 'PostProcessParams.data byteLength === registered params.byteSize',\n hint: (detail) => {\n const d = detail as PostProcessParamsUpdateSizeMismatchDetail;\n return (\n `PostProcessParams.data byteLength is ${d.actualLength} but the registered ` +\n `params.byteSize is ${d.byteSize}. The per-frame data-driven write must match ` +\n 'the registered byteSize exactly; check the PostProcessParams.data you assign each frame.'\n );\n },\n },\n} satisfies Record<\n string,\n {\n readonly expected: string;\n readonly hint: (detail: unknown) => string;\n }\n>;\n\nclass PostProcessErrorClass<C extends PostProcessErrorCode> extends Error {\n readonly code: C;\n readonly expected: string;\n readonly hint: string;\n readonly detail: PostProcessErrorDetailFor<C>;\n\n constructor(args: { code: C; detail: PostProcessErrorDetailFor<C> }) {\n const policy = POST_PROCESS_POLICY[args.code];\n const hint = policy.hint(args.detail);\n super(`post-process: ${args.code} (${hint})`);\n this.name = 'PostProcessError';\n this.code = args.code;\n this.expected = policy.expected;\n this.hint = hint;\n this.detail = args.detail;\n }\n}\n\n/**\n * Variant intersection: a `PostProcessErrorClass` instance whose `code` literal narrows to\n * `C` and whose `detail` narrows to `PostProcessErrorDetailFor<C>`, so `if (err.code === 'X')`\n * simultaneously narrows `err.detail` (charter P3 + P4 discriminated union).\n */\ntype PostProcessErrorVariant<C extends PostProcessErrorCode> = PostProcessErrorClass<C> & {\n readonly code: C;\n readonly detail: PostProcessErrorDetailFor<C>;\n};\n\ninterface PostProcessErrorConstructor {\n new <C extends PostProcessErrorCode>(args: {\n code: C;\n detail: PostProcessErrorDetailFor<C>;\n }): PostProcessErrorVariant<C>;\n readonly prototype: PostProcessErrorClass<PostProcessErrorCode>;\n}\n\n/**\n * Public PostProcessError type - mapped from the authoritative code union.\n *\n * ```ts\n * function recover(err: PostProcessError): string {\n * switch (err.code) {\n * case 'post-process-already-registered': return `id taken: ${err.detail.id}`;\n * case 'post-process-not-found': return `bad id: ${err.detail.id}`;\n * case 'fullscreen-input-not-found': return `bad reads key: ${err.detail.readsKey} on pass ${err.detail.passName}`;\n * }\n * }\n * ```\n */\nexport type PostProcessError = {\n [C in PostProcessErrorCode]: PostProcessErrorVariant<C>;\n}[PostProcessErrorCode];\n\n/**\n * PostProcessError constructor - `new PostProcessError({ code, detail })`.\n *\n * The generic `C` is inferred from the literal `code` argument, which narrows `detail` to\n * the per-code payload (`PostProcessErrorDetailFor<C>`) and narrows the return type to the\n * corresponding `PostProcessErrorVariant<C>` so the call site walks the discriminated union\n * without manual cast (AppError pattern; TS class declarations cannot directly express\n * `<C> ... PostProcessErrorVariant<C>` polymorphism, hence the typed-cast affordance).\n */\nexport const PostProcessError: PostProcessErrorConstructor = PostProcessErrorClass;\n","// @forgeax/engine-render - SSAO parameter authority.\n\nimport { err, ok, type Result } from '@forgeax/engine-types';\nimport { PostProcessError } from './post-process-errors';\n\nexport const SSAO_DEFAULT_RADIUS = 0.5;\nexport const SSAO_DEFAULT_BIAS = 0.025;\nexport const SSAO_DEFAULT_INTENSITY = 1.0;\n\nexport interface SsaoParameterConfig {\n readonly radius?: number | undefined;\n readonly bias?: number | undefined;\n readonly intensity?: number | undefined;\n}\n\nexport interface ResolvedSsaoParameters {\n readonly radius: number;\n readonly bias: number;\n readonly intensity: number;\n}\n\n/**\n * Apply the public defaults without deciding whether the values are valid.\n * The record stage uses this only after the graph build has validated the\n * active HDRP configuration, or for the disabled/default fallback payload.\n */\nexport function getSsaoParameters(config: SsaoParameterConfig | undefined): ResolvedSsaoParameters {\n return {\n radius: config?.radius ?? SSAO_DEFAULT_RADIUS,\n bias: config?.bias ?? SSAO_DEFAULT_BIAS,\n intensity: config?.intensity ?? SSAO_DEFAULT_INTENSITY,\n };\n}\n\n/**\n * Resolve and validate the SSAO configuration used by both graph routes.\n * Invalid values remain structured PostProcessErrors instead of becoming\n * NaNs or silently falling back to shader literals.\n */\nexport function resolveSsaoParameters(\n config: SsaoParameterConfig | undefined,\n): Result<ResolvedSsaoParameters, PostProcessError> {\n const resolved = getSsaoParameters(config);\n if (resolved.radius <= 0) {\n return err(\n new PostProcessError({\n code: 'ssao-radius-non-positive',\n detail: { paramName: 'radius', value: resolved.radius },\n }),\n );\n }\n if (resolved.bias < 0) {\n return err(\n new PostProcessError({\n code: 'ssao-bias-negative',\n detail: { paramName: 'bias', value: resolved.bias },\n }),\n );\n }\n return ok(resolved);\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: helpers.\n// Extracted from render-system-record.ts (feat-20260704 M3/w17, pure move).\n\nimport { resolveAssetHandle } from '@forgeax/engine-assets-runtime';\nimport type { World } from '@forgeax/engine-ecs';\nimport { type Mat4, mat4 } from '@forgeax/engine-math';\nimport type { EquirectAsset } from '@forgeax/engine-types';\nimport { toShared } from '@forgeax/engine-types';\nimport { EquirectProjectionFailedError } from '../errors/render';\nimport { isStandardPbrMaterialShader } from '../pbr-pipeline';\nimport type { CameraSnapshot } from '../render-contract';\nimport type { MaterialSnapshot, SkyboxSnapshot, SkylightSnapshot } from '../render-system-extract';\nimport type { RenderFrameState } from './frame-snapshot';\nimport type { RenderSystemInternals } from './render-context';\n\n/** Convert pass-owned shader definitions into the manifest's canonical variant key. */\nexport function variantSetFromDefines(\n defines: Readonly<Record<string, string>> | undefined,\n): string | undefined {\n if (defines === undefined) return undefined;\n const entries = Object.entries(defines);\n if (entries.length === 0) return undefined;\n return entries\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([name, value]) => `${name}=${value}`)\n .join('+');\n}\n\n/**\n * Select the equirect source for the shared lazy projection.\n *\n * Skylight uses handle 0 as a real \"solid-color ambient\" sentinel, so nullish\n * coalescing cannot distinguish \"no equirect\" from a valid snapshot. Prefer a\n * non-zero Skylight handle and fall back to SkyboxBackground otherwise.\n */\nexport function selectLazyEquirectHandle(\n skylight: Pick<SkylightSnapshot, 'equirectHandle'> | undefined,\n skybox: Pick<SkyboxSnapshot, 'equirectHandle'> | undefined,\n): number {\n const skylightHandle = skylight?.equirectHandle ?? 0;\n return skylightHandle !== 0 ? skylightHandle : (skybox?.equirectHandle ?? 0);\n}\n\n/**\n * feat-20260608-multi-light-warn-once M3: warn-once latch for directional\n * N>1 overrun. Fires console.warn at most once per RenderSystem lifetime.\n * Extracted as a pure helper so the warn-once logic is directly testable\n * without a full recordFrame argument list (AC-05 (c)).\n */\nexport function warnMultiLightDirectional(\n frameState: Pick<RenderFrameState, 'warnedMultiLightDirectional'>,\n directionalCount: number,\n envOverride?: { env?: { NODE_ENV?: string } },\n): void {\n if (!frameState.warnedMultiLightDirectional && directionalCount > 1) {\n frameState.warnedMultiLightDirectional = true;\n const env =\n envOverride ?? (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n if (env?.env?.NODE_ENV !== 'production') {\n console.warn(\n '[forgeax] render-system-multi-light directional: at most 1 entity (got N=' +\n directionalCount +\n '). First entity used; rest dropped.',\n {\n code: 'render-system-multi-light',\n expected: 'at most 1 directional',\n detail: { type: 'directional', got: directionalCount },\n },\n );\n }\n }\n}\n\n/**\n * feat-20260608-multi-light-warn-once M3: warn-once latch for point light\n * N>4 overrun (first-slice cap). Fires at most once per RenderSystem\n * lifetime.\n */\nexport function warnMultiLightPoint(\n frameState: Pick<RenderFrameState, 'warnedMultiLightPoint'>,\n pointCount: number,\n envOverride?: { env?: { NODE_ENV?: string } },\n): void {\n if (!frameState.warnedMultiLightPoint && pointCount > 4) {\n frameState.warnedMultiLightPoint = true;\n const env =\n envOverride ?? (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n if (env?.env?.NODE_ENV !== 'production') {\n console.warn(\n '[forgeax] render-system-multi-light point: at most 4 entities (got N=' +\n pointCount +\n '). First 4 used; rest dropped.',\n {\n code: 'render-system-multi-light',\n expected: 'at most 4 point',\n detail: { type: 'point', got: pointCount },\n },\n );\n }\n }\n}\n\n/**\n * feat-20260608-multi-light-warn-once M3: warn-once latch for spot light\n * N>4 overrun (first-slice cap). Fires at most once per RenderSystem\n * lifetime.\n */\nexport function warnMultiLightSpot(\n frameState: Pick<RenderFrameState, 'warnedMultiLightSpot'>,\n spotCount: number,\n envOverride?: { env?: { NODE_ENV?: string } },\n): void {\n if (!frameState.warnedMultiLightSpot && spotCount > 4) {\n frameState.warnedMultiLightSpot = true;\n const env =\n envOverride ?? (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n if (env?.env?.NODE_ENV !== 'production') {\n console.warn(\n '[forgeax] render-system-multi-light spot: at most 4 entities (got N=' +\n spotCount +\n '). First 4 used; rest dropped.',\n {\n code: 'render-system-multi-light',\n expected: 'at most 4 spot',\n detail: { type: 'spot', got: spotCount },\n },\n );\n }\n }\n}\n\n/**\n * feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w19:\n * once-warn for >1 Skylight entity (first archetype hit wins). Fires at most\n * once per RenderSystem lifetime and names the WINNING entity handle so the\n * scene author can tell which Skylight is used and that the rest are ignored\n * (F-8: warn carries conflicting entity info; charter P3 explicit failure with\n * a warn-once signal floor, no per-frame flooding).\n */\nexport function warnMultiSkylight(\n frameState: Pick<RenderFrameState, 'warnedMultiSkylight'>,\n skylightCount: number,\n winningEntityHandle: number,\n): void {\n if (!frameState.warnedMultiSkylight && skylightCount > 1) {\n frameState.warnedMultiSkylight = true;\n console.warn(\n `[forgeax] Skylight: ${skylightCount} Skylight entities found; using entity ` +\n `${winningEntityHandle} (first by archetype order) for IBL ambient. The other ` +\n `${skylightCount - 1} Skylight ${skylightCount - 1 === 1 ? 'entity is' : 'entities are'} ignored. ` +\n `Keep a single Skylight per scene, or reorder so the intended one is first.`,\n );\n }\n}\n\n/**\n * feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w19:\n * once-warn for >1 SkyboxBackground entity (mirrors warnMultiSkylight). Names\n * the winning entity handle; fires once per RenderSystem lifetime.\n */\nexport function warnMultiSkybox(\n frameState: Pick<RenderFrameState, 'warnedMultiSkybox'>,\n skyboxCount: number,\n winningEntityHandle: number,\n): void {\n if (!frameState.warnedMultiSkybox && skyboxCount > 1) {\n frameState.warnedMultiSkybox = true;\n console.warn(\n `[forgeax] SkyboxBackground: ${skyboxCount} SkyboxBackground entities found; using ` +\n `entity ${winningEntityHandle} (first by archetype order). The other ` +\n `${skyboxCount - 1} ${skyboxCount - 1 === 1 ? 'entity is' : 'entities are'} ignored. ` +\n `Keep a single SkyboxBackground per scene.`,\n );\n }\n}\n\n/**\n * feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w18:\n * lazy equirect-to-cubemap projection trigger. Driven once per frame from\n * `recordFrame` for the active equirect handle (Skylight's, or the\n * SkyboxBackground's when no Skylight cubemap is present -- both reuse one\n * handle). Implements the plan-strategy D-4 state machine:\n *\n * undefined (no entry) -> resolve POD + fire-and-forget projection; the\n * store selects rgba8 output on WebGL2\n * (the store writes status:'pending'\n * synchronously, so this launches once)\n * pending -> in flight; bind white fallback (no fire)\n * ready -> bound by recordMainPass's IBL cache check\n * failed -> fire EquirectProjectionFailedError ONCE\n * per handle (R-2/AC-09 no retry)\n * Fire-and-forget: `_uploadCubemapFromEquirect` is invoked WITHOUT await so the\n * record stay synchronous; the store mutates its own status map and (on\n * success) the per-device IblPipelineCache, which recordMainPass reads on a\n * later frame. The structured error from a fire-and-forget failure is reported\n * via the explicit `status === 'failed'` arm here (read on the next frame), not\n * by awaiting the promise (which would block record).\n */\nexport function driveLazyEquirectProjection(\n internals: RenderSystemInternals,\n world: World,\n frameState: Pick<RenderFrameState, 'firedEquirectProjectionFailedHandles'>,\n equirectHandle: number,\n): void {\n const store = internals.gpuStore;\n const handle = toShared<'EquirectAsset'>(equirectHandle);\n const status = store.getCubemapStatus(handle);\n\n if (status === 'failed') {\n // Fire the structured error exactly once per failed source (the store\n // records failed permanently and never retries; R-2 / AC-09).\n if (!frameState.firedEquirectProjectionFailedHandles.has(equirectHandle)) {\n frameState.firedEquirectProjectionFailedHandles.add(equirectHandle);\n internals.errorRegistry.fire(new EquirectProjectionFailedError(equirectHandle));\n }\n return;\n }\n\n // 'pending' and 'ready' are both handled downstream (white fallback while\n // pending; real IBL once ready). Only the first sight ('undefined') launches.\n if (status !== undefined) return;\n\n // First sight: resolve the equirect POD and fire-and-forget the projection.\n const podRes = resolveAssetHandle<EquirectAsset>(world, handle);\n if (!podRes.ok || podRes.value.kind !== 'equirect') {\n // The handle does not resolve to a live equirect POD (stale / wrong kind).\n // Launch nothing; the store stays empty and the white fallback holds. The\n // skybox / IBL degradation paths surface the missing resource per their own\n // gates -- this trigger only drives a valid equirect source.\n return;\n }\n // Fire-and-forget: do NOT await. The store writes status:'pending'\n // synchronously (before its first await), so a re-entry next frame\n // short-circuits and this launches exactly once.\n void store._uploadCubemapFromEquirect(world, handle, podRes.value);\n}\n\n/**\n * Returns true when a MaterialSnapshot uses a builtin standard/PBR shader\n * that will render black with zero lights.\n *\n * The default mid-grey fallback (materialShaderId === undefined) is excluded\n * — it routes through defaultMaterialSnapshot and never triggers the\n * zero-light warning. Custom shaders are also excluded: their lighting\n * contract is authored by the shader and cannot be inferred from this\n * generic diagnostic.\n *\n * @internal — exported so AC-02 zero-light-warning test can anchor to\n * the production implementation rather than a test-local copy.\n */\nexport function isLitMaterialSnapshot(material: MaterialSnapshot): boolean {\n return isStandardPbrMaterialShader(material.materialShaderId);\n}\n\nexport function computeViewMatrix(camera: CameraSnapshot): Mat4 {\n // feat-20260601 D-3: view = invert(camera world mat4). The camera's resolved\n // world mat4 (propagateTransforms output) is read straight off the snapshot;\n // no recompose from decomposed TRS.\n const cameraFromWorld = mat4.create();\n mat4.invert(cameraFromWorld, camera.world);\n return cameraFromWorld;\n}\n\nexport function computeProjectionMatrix(camera: CameraSnapshot): Mat4 {\n // feat-20260613 M6 / w20: branch on projection variant. The view UBO\n // record path needs the right matrix shape so the main pass renders\n // correctly under both perspective and orthographic cameras (mirrors\n // the CSM extract fix in render-system-extract.ts).\n const proj = mat4.create();\n if (camera.projection === 'orthographic') {\n mat4.orthographic(\n proj,\n camera.orthoLeft,\n camera.orthoRight,\n camera.orthoBottom,\n camera.orthoTop,\n camera.near,\n camera.far,\n );\n } else {\n mat4.perspective(proj, camera.fov, camera.aspect, camera.near, camera.far);\n }\n return proj;\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: view-ubo.\n// feat-20260704 M3/w18: the View UBO + CSM/spot-shadow matrix pack assembly\n// extracted verbatim from `recordFrame` (frame.ts). Builds the 240-float View\n// UBO payload (worldViewProj, directional light, camera pos, per-cascade\n// lightViewProj matrices, split planes, shadow bias, folded spot lightViewProj\n// lanes) and flushes it in one queue.writeBuffer round-trip. Kept as a\n// standalone function so recordFrame stays an orchestration skeleton (D-2).\n\nimport { mat4 } from '@forgeax/engine-math';\nimport type { Buffer, RhiQueue } from '@forgeax/engine-rhi';\nimport type { FogFrame } from '../extract/environment';\nimport type { PointsLinesStyle } from '../points-lines/snapshot';\nimport type { CameraSnapshot } from '../render-contract';\nimport type {\n DirectionalLightSnapshot,\n ExtractedLights,\n SpotLightSnapshot,\n} from '../render-system-extract';\nimport type { TemporalView as LegacyTemporalView } from '../temporal/temporal-view';\nimport type { TemporalView } from '../temporal/view';\nimport { clampPcfKernelSize } from './frame-snapshot';\nimport { computeProjectionMatrix, computeViewMatrix } from './helpers';\n\nexport const VIEW_UNIFORM_BYTES = 960;\nexport const POINTS_LINES_VIEW_BYTES = 160;\nexport const POINTS_LINES_VIEW_SLOT_STRIDE = 256;\nexport const POINTS_LINES_VIEW_SLOT_COUNT = 1024;\nexport const POINTS_LINES_VIEW_BUFFER_SIZE =\n POINTS_LINES_VIEW_SLOT_STRIDE * POINTS_LINES_VIEW_SLOT_COUNT;\nexport const VIEW_UNIFORM_SLOT_STRIDE = 1024;\nexport const POINT_SHADOW_VIEW_SLOT_COUNT = 24;\nexport const VIEW_UNIFORM_BUFFER_SIZE =\n VIEW_UNIFORM_SLOT_STRIDE * (1 + POINT_SHADOW_VIEW_SLOT_COUNT);\n\nexport function pointShadowViewOffset(layer: number, face: number): number {\n return VIEW_UNIFORM_SLOT_STRIDE * (1 + layer * 6 + face);\n}\n\nexport function writePointsLinesViewUbo(\n queue: RhiQueue,\n buffer: Buffer,\n camera: CameraSnapshot,\n width: number,\n height: number,\n model?: ArrayLike<number>,\n style?: PointsLinesStyle,\n byteOffset = 0,\n): void {\n const projection = computeProjectionMatrix(camera);\n const view = computeViewMatrix(camera);\n const worldViewProj = mat4.create();\n mat4.multiply(worldViewProj, projection, view);\n const payload = new Float32Array(40);\n payload.set(worldViewProj);\n if (model === undefined) {\n payload[16] = 1;\n payload[21] = 1;\n payload[26] = 1;\n payload[31] = 1;\n } else {\n for (let index = 0; index < 16; index += 1) {\n payload[16 + index] = model[index] ?? 0;\n }\n }\n payload[32] = width;\n payload[33] = height;\n if (style?.kind === 'points') {\n payload[36] = style.sizePx;\n payload[38] = style.shape === 'circle' ? 1 : 0;\n } else if (style?.kind === 'lines') {\n payload[36] = style.widthPx;\n payload[37] = 1;\n } else {\n payload[36] = 1;\n }\n const uploaded = queue.writeBuffer(buffer, byteOffset, payload);\n if (!uploaded.ok) throw uploaded.error;\n}\n\n/**\n * feat-20260704 M3/w18: assemble + upload the per-frame View UBO payload.\n *\n * feat-20260518 M3 / w14 (AC-07 / AC-09): builds the full view UBO payload.\n * Single queue.writeBuffer covers the whole payload (one round-trip per frame,\n * charter P5 consistent abstraction). Outgoing-direction convention\n * (DirectionalLight @semantics outgoing): the host uploads light.direction\n * verbatim; the shader negates it internally via\n * `let l = normalize(-view.lightDir)` to get the L vector for BRDF (single\n * SSOT, no double-negation).\n *\n * feat-20260520-directional-light-shadow-mapping M1b / w7 + feat-20260613-csm\n * M4 / w16+w25: viewPayload is 240 floats. Layout matches common.wgsl View\n * struct byte-for-byte:\n * [ 0..15] worldViewProj, [16..18] lightDir, [20..22] lightColor,\n * [24..26] cameraPos, [28..43] lightViewProj0 (was lightSpaceMatrix),\n * [44..59] inverseViewProj, [60..75] lightViewProj1,\n * [76..91] lightViewProj2, [92..107] lightViewProj3,\n * [108]/[112]/[116]/[120] splitPlanes (vec4 stride),\n * [124] cascadeCount, [125] cascadeBlend,\n * [126] depthBias, [127] normalBias, [128] pcfKernelSize (feat-20260621\n * M3 / m3-t2-t3), [129..131] align pad,\n * [132..195] spotLightViewProj array<mat4x4<f32>, 4> (feat-20260625 w25:\n * folded from standalone binding 9 to fix WebGL2 fragment uniform-buffer\n * overflow; lane N = spot with shadowAtlasTile === N, 16 f32 / lane,\n * 16 B-aligned at byte 528 = float 132).\n *\n * @internal\n */\nexport function writeViewUbo(\n queue: RhiQueue,\n viewUniformBuffer: Buffer,\n camera: CameraSnapshot,\n light: DirectionalLightSnapshot,\n lights: ExtractedLights,\n spotShadowSnapshots: readonly SpotLightSnapshot[],\n fogOrTemporal?: FogFrame | TemporalView | LegacyTemporalView,\n temporal?: TemporalView,\n): void {\n const isTemporal =\n fogOrTemporal !== undefined &&\n ('currentJitterUv' in fogOrTemporal || 'currentUnjitteredViewProjection' in fogOrTemporal);\n const fog = isTemporal ? undefined : fogOrTemporal;\n const resolvedTemporal = temporal ?? (isTemporal ? fogOrTemporal : undefined);\n // Compose worldViewProj once per frame (view * proj).\n const projMatrix = computeProjectionMatrix(camera);\n const viewMatrix = computeViewMatrix(camera);\n const unjitteredViewProjection = mat4.create();\n mat4.multiply(unjitteredViewProjection, projMatrix, viewMatrix);\n const jitteredProjection = mat4.create();\n if (resolvedTemporal?.currentJitterUv !== undefined) {\n const jitter = mat4.identity(mat4.create());\n jitter[12] = resolvedTemporal.currentJitterUv[0] * 2;\n jitter[13] = resolvedTemporal.currentJitterUv[1] * -2;\n mat4.multiply(jitteredProjection, jitter, projMatrix);\n } else {\n for (let i = 0; i < 16; i += 1) jitteredProjection[i] = projMatrix[i] ?? 0;\n }\n const mainProjection = mat4.create();\n mat4.multiply(mainProjection, jitteredProjection, viewMatrix);\n\n const VIEW_PAYLOAD_FLOATS = 240;\n const viewPayload = new Float32Array(VIEW_PAYLOAD_FLOATS);\n for (let i = 0; i < 16; i++) viewPayload[i] = mainProjection[i] ?? 0;\n viewPayload[16] = (light.direction[0] ?? 0) * light.intensity;\n viewPayload[17] = (light.direction[1] ?? -1) * light.intensity;\n viewPayload[18] = (light.direction[2] ?? 0) * light.intensity;\n viewPayload[20] = light.color[0] ?? 0;\n viewPayload[21] = light.color[1] ?? 0;\n viewPayload[22] = light.color[2] ?? 0;\n viewPayload[24] = camera.position[0] ?? 0;\n viewPayload[25] = camera.position[1] ?? 0;\n viewPayload[26] = camera.position[2] ?? 0;\n // lightViewProj[0] at [28..43] (replaces lightSpaceMatrix).\n if (lights.lightViewProj !== undefined && lights.lightViewProj[0] !== undefined) {\n for (let i = 0; i < 16; i++) viewPayload[28 + i] = lights.lightViewProj[0][i] ?? 0;\n }\n // inverseViewProj at [44..59] — unchanged position.\n // Host pre-computes mat4.invert so the skybox fragment shader avoids\n // per-pixel matrix inversion (charter P4 consistent abstraction).\n const inverseViewProj = mat4.create();\n mat4.invert(inverseViewProj, mainProjection);\n for (let i = 0; i < 16; i++) viewPayload[44 + i] = inverseViewProj[i] ?? 0;\n // lightViewProj[1..3] at [60..107].\n if (lights.lightViewProj !== undefined) {\n for (let c = 1; c <= 3; c++) {\n const base = 60 + (c - 1) * 16;\n const lvp = lights.lightViewProj[c];\n if (lvp !== undefined) {\n for (let i = 0; i < 16; i++) viewPayload[base + i] = lvp[i] ?? 0;\n }\n }\n }\n\n // Temporal ABI tail: current and last-successful unjittered projections\n // stay separate from the jittered main projection and never advance on a\n // failed submission. The fixed 240-float payload already reserves these\n // 36 slots at byte offsets 784..920.\n const previous = resolvedTemporal?.previousUnjitteredViewProjection;\n for (let i = 0; i < 16; i += 1) {\n viewPayload[196 + i] = unjitteredViewProjection[i] ?? 0;\n // No previous successful frame exists on first frame/reset. Keep this\n // lane zeroed instead of copying current state into a history slot.\n viewPayload[212 + i] = previous?.[i] ?? 0;\n }\n viewPayload[228] = camera.near;\n viewPayload[229] = camera.far;\n viewPayload[230] = camera.projection === 'orthographic' ? 1 : 0;\n // splitPlanes at [108], [112], [116], [120] (vec4 stride = 4 floats).\n if (lights.splitPlanes !== undefined) {\n for (let s = 0; s < 4; s++) {\n viewPayload[108 + s * 4] = lights.splitPlanes[s] ?? 0;\n }\n }\n // cascadeCount / cascadeBlend at [124..125].\n viewPayload[124] = lights.cascadeCount ?? 0;\n viewPayload[125] = lights.cascadeBlend ?? 0;\n // feat-20260621-merge-directionallightshadow-into-directionallight M3 /\n // m3-t2: shadow bias + PCF kernel width from the merged DirectionalLight\n // land in the formerly-free tail pad at floats [126/127/128] (bytes\n // 504/508/512). VIEW_PAYLOAD_FLOATS / VIEW_UBO_BYTES are unchanged --\n // the WGSL View struct (common.wgsl) appends matching f32 at the same\n // slots; the host tail pad shrinks 88 B -> 64 B, rest stays zero.\n // pcfKernelSize is host-clamped to the nearest valid odd kernel {1,3,5}\n // (cap 5, matching lighting-directional.wgsl MAX_PCF_HALF=2 from the\n // merged 5.3-production-shadow-demos AC-14 variant-free loop) so the\n // per-iteration radius clip has a fixed, legal bound; undefined\n // (no cast-shadow / no shadow fields) defaults to 3.\n viewPayload[126] = lights.depthBias ?? 0.005;\n viewPayload[127] = lights.normalBias ?? 0.05;\n viewPayload[128] = clampPcfKernelSize(lights.pcfKernelSize);\n\n // feat-20260625-spot-light-shadow-mapping w25 (scope-amend webkit-fallback):\n // spotLightViewProj array<mat4x4<f32>, 4> at floats [132..195] (byte 528,\n // 16 B-aligned after pcfKernelSize). Lane N = the spot with\n // `shadowAtlasTile === N` (cap = 4); the perspective matrix was already\n // computed by the extract stage (SpotLightSnapshot.lightViewProj) — record\n // never recomputes it (Derive). Lanes for non-shadow / clipped spots (tile\n // < 0 or lightViewProj undefined) stay zeroed; the WGSL sample path gates\n // on `SpotLight.shadowAtlasTile >= 0` so zeroed lanes are never read.\n // Folded from the former standalone binding 9 UBO to keep the WebGL2\n // fallback fragment uniform-buffer count <= 11 (GLES 3.0).\n {\n const SPOT_LVP_BASE_FLOAT = 132;\n const SPOT_LVP_LANE_COUNT = 4;\n const SPOT_LVP_FLOATS_PER_LANE = 16;\n const spotSnaps = spotShadowSnapshots;\n for (let i = 0; i < spotSnaps.length; i++) {\n const ss = spotSnaps[i];\n if (ss === undefined) continue;\n const tile = ss.shadowAtlasTile;\n if (tile < 0 || tile >= SPOT_LVP_LANE_COUNT) continue;\n const lvp = ss.lightViewProj;\n if (lvp === undefined) continue;\n const base = SPOT_LVP_BASE_FLOAT + tile * SPOT_LVP_FLOATS_PER_LANE;\n for (let f = 0; f < SPOT_LVP_FLOATS_PER_LANE; f++) {\n viewPayload[base + f] = lvp[f] ?? 0;\n }\n }\n }\n\n // Fog is a resource-owner semantic carried by the shared View ABI. Keep the\n // disabled payload zeroed and write only the selected frame facts so both\n // direct and clustered lanes consume the same owner projection.\n if (fog !== undefined) {\n viewPayload[232] = fog.color[0] ?? 0;\n viewPayload[233] = fog.color[1] ?? 0;\n viewPayload[234] = fog.color[2] ?? 0;\n viewPayload[235] = fog.density;\n viewPayload[236] = fog.heightFalloff;\n viewPayload[237] = fog.maxOpacity;\n }\n\n const viewUploadResult = queue.writeBuffer(viewUniformBuffer, 0, viewPayload);\n if (!viewUploadResult.ok) throw viewUploadResult.error;\n\n for (const snapshot of lights.pointShadow ?? []) {\n if (snapshot.shadowAtlasLayer < 0 || snapshot.shadowAtlasLayer >= 4) continue;\n for (let face = 0; face < 6; face += 1) {\n const facePayload = viewPayload.slice();\n const matrix = snapshot.shadowMatrices.subarray(face * 16, (face + 1) * 16);\n facePayload.set(matrix, 28);\n const uploaded = queue.writeBuffer(\n viewUniformBuffer,\n pointShadowViewOffset(snapshot.shadowAtlasLayer, face),\n facePayload,\n );\n if (!uploaded.ok) throw uploaded.error;\n }\n }\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: per-frame lighting.\n// feat-20260704 M5/w31: further-split from frame.ts (AC-05 <=1500 lines/file).\n// Pure leaf helpers invoked once each from recordFrame; behavior verbatim.\n\nimport { mat4, type Vec3, vec3 } from '@forgeax/engine-math';\nimport {\n type BindGroup,\n type BindGroupLayout,\n RhiError,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport { toShared } from '@forgeax/engine-types';\nimport { bin, type ClusterBinProfilePhase, type ClusterBinProfileRunner } from '../cluster-binner';\nimport {\n HdrpIndexListOverflowError,\n HdrpLightBudgetExceededError,\n PointShadowAtlasBoundsViolationError,\n PointShadowAtlasUninitializedError,\n} from '../errors/render';\nimport {\n createHdrpClusterMembershipBindGroup,\n createHdrpUnifiedBindGroup,\n getOrCreateHdrpBuffers,\n HDRP_UNIFORM_LIGHT_CAPACITY,\n packClusterUniform,\n} from '../hdrp-buffers';\nimport {\n LIGHT_ARRAY_HEADER_BYTES,\n LIGHT_ARRAY_MAX_SLOTS,\n POINT_LIGHT_STD430_BYTES,\n packLightArrayHeader,\n packLightSlot,\n packPointLight,\n packSpotLight,\n SPOT_LIGHT_STD430_BYTES,\n} from '../light-buffer-layout';\nimport { DEFAULT_CLUSTER_GRID, LIGHT_INDEX_LIST_CAPACITY } from '../pipeline/standard-profile';\nimport type { CameraSnapshot, RenderHdrpClusterPhase } from '../render-contract';\nimport type {\n DirectionalLightSnapshot,\n ExtractedLights,\n RenderableSnapshot,\n SkyboxSnapshot,\n SkylightSnapshot,\n} from '../render-system-extract';\nimport { ShadowAtlas } from '../shadow-atlas';\nimport { getOrCreateSsaoBuffers } from '../ssao-buffers';\nimport { getSsaoParameters } from '../ssao-config';\nimport type { BindGroupCounts, RenderFrameState } from './frame-snapshot';\nimport {\n computeProjectionMatrix,\n computeViewMatrix,\n isLitMaterialSnapshot,\n warnMultiLightDirectional,\n warnMultiLightPoint,\n warnMultiLightSpot,\n} from './helpers';\nimport { getOrCreateFromChain, MESH_SSBO_BYTES, MESH_UBO_FULL_ARRAY_BYTES } from './mesh-ssbo';\nimport type { PipelineState, RecordProfileRunner, RenderSystemInternals } from './render-context';\nimport { POINTS_LINES_VIEW_BYTES, VIEW_UNIFORM_BYTES } from './view-ubo';\n\nfunction runHdrpClusterProfilePhase<T>(\n runner: RecordProfileRunner | undefined,\n phase: RenderHdrpClusterPhase,\n action: () => T,\n): T {\n return runner === undefined ? action() : runner(phase, action);\n}\n\n/**\n * feat-20260704 M3/w18: per-frame bind-group cache resolution, extracted\n * verbatim from `recordFrame`. Walks the handle-identity WeakMap caches\n * (feat-20260531 M2 + feat-20260622 M3) to resolve or lazily create the view\n * (@group 0), mesh (@group 2), and — when HDRP is active — HDRP-unified cluster\n * bind groups. Returns all three (null when `hasValidated` is false, the Case E\n * clear-pass-only path). No new mutable state: `bindGroupCounts` accounting +\n * cache maps are threaded through explicitly.\n *\n * @internal\n */\nexport function buildPerFrameBindGroups(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n pipelineState: PipelineState,\n hasValidated: boolean,\n bindGroupCounts: BindGroupCounts,\n graphTargets?: {\n readonly directionalShadow?: TextureView | undefined;\n readonly spotShadow?: TextureView | undefined;\n },\n includeView = true,\n): {\n viewBindGroup: BindGroup | null;\n meshBindGroup: BindGroup | null;\n hdrpClusterBindGroup: BindGroup | null;\n hdrpClusterMembershipBindGroup: BindGroup | null;\n} {\n // View main (#1) chain = b0(viewUniformBuffer), b1(pointLightsBuffer),\n // b2(spotLightsBuffer), b3(graph shadowDepth view or\n // shadowFallbackTextureView), b4(shadowSampler), b5(atlas view), b6\n // (shadowParams); variant 'view-main'.\n // Mesh (#2) chain = inner b0 buffer (meshStorageBuffer.buffer); variant 'mesh'.\n let viewBindGroup: BindGroup | null = null;\n let meshBindGroup: BindGroup | null = null;\n // feat-20260609-hdrp-cluster-fragment-ggx M4 / w19: HDRP unified group(2)\n // BindGroup. Non-null when `frameState.isHdrpActive` AND HDRP buffer\n // allocation succeeded; consumed by recordMainPass at `setBindGroup(2, ...)`.\n let hdrpClusterBindGroup: BindGroup | null = null;\n const hdrpClusterMembershipBindGroup: BindGroup | null = frameState.isHdrpActive\n ? frameState.hdrpClusterMembershipBindGroup\n : null;\n if (hasValidated) {\n // Shadow atlas view comes from the typed graph target.\n // Graph owns the texture lifecycle; record-stage reads the resolved\n // view each frame (D-2 SSOT). When the graph has not allocated the\n // target (castShadow:false or shadowMapSize=0),\n // `getColorTargetView` returns undefined and we fall through to the\n // 1x1 fallback view that keeps the BGL satisfied.\n if (includeView) {\n const shadowSampler = pipelineState.perPassResources.shadowSampler;\n if (shadowSampler === null) {\n return {\n viewBindGroup: null,\n meshBindGroup: null,\n hdrpClusterBindGroup: null,\n hdrpClusterMembershipBindGroup,\n };\n }\n const graphShadowView = graphTargets?.directionalShadow;\n const b3View =\n graphShadowView !== undefined ? graphShadowView : pipelineState.shadowFallbackTextureView;\n // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1: bind the real\n // ShadowAtlas cube_array view when point shadows are active in this\n // frame; otherwise the 1x1x6 fallback (cleared to 1.0 = fully lit).\n const pointShadowAtlas = frameState.pointShadowAtlas;\n const atlasViewMaybe = pointShadowAtlas?.isAllocated()\n ? pointShadowAtlas.getAtlasView()\n : null;\n const b5View =\n atlasViewMaybe !== null ? atlasViewMaybe : pipelineState.shadowAtlasFallbackTextureView;\n // feat-20260625-spot-light-shadow-mapping M2 / w21 (D-1 fragment side +\n // D-5): bind the real `spotShadowDepth` 2D atlas view (graph-owned) when\n // spot shadows run this frame; otherwise the 1x1 depth fallback cleared to\n // 1.0 (fully lit) — same `texture_depth_2d` shape as binding 3, so it\n // satisfies the BGL without a dedicated spot fallback allocation. binding\n // 9 always binds the real spotLightViewProj UBO (zeroed lanes are safe via\n // the shadowAtlasTile >= 0 shader gate).\n const graphSpotShadowView = graphTargets?.spotShadow;\n const b8View =\n graphSpotShadowView !== undefined\n ? graphSpotShadowView\n : pipelineState.shadowFallbackTextureView;\n viewBindGroup = getOrCreateFromChain(\n frameState.viewBindGroupCache,\n [\n pipelineState.viewUniformBuffer,\n pipelineState.pointLightsBuffer,\n pipelineState.spotLightsBuffer,\n b3View,\n shadowSampler,\n b5View,\n pipelineState.shadowParamsBuffer,\n b8View,\n pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,\n ],\n 'view-main',\n () => {\n const viewBindGroupResult = internals.device.createBindGroup({\n label: 'pbr-view-bg',\n layout: pipelineState.viewBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.viewUniformBuffer, size: VIEW_UNIFORM_BYTES },\n },\n },\n {\n binding: 1,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.pointLightsBuffer },\n },\n },\n {\n binding: 2,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.spotLightsBuffer },\n },\n },\n {\n binding: 3,\n resource: {\n kind: 'textureView',\n value: b3View,\n },\n },\n {\n binding: 4,\n resource: {\n kind: 'sampler',\n value: shadowSampler,\n },\n },\n // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1:\n // cube_array shadow atlas view (real ShadowAtlas when point\n // shadows are active; else 1x1x6 fallback).\n {\n binding: 5,\n resource: {\n kind: 'textureView',\n value: b5View,\n },\n },\n // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1:\n // shadowParams UBO (`array<vec4<f32>, 4>` = 64 B). Lane N\n // stores `(near, far, 1/(far-near), 0)` for the point light\n // with shadowAtlasLayer === N. Updated per frame from\n // `pointShadowSnapshots` below.\n {\n binding: 6,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.shadowParamsBuffer },\n },\n },\n // feat-20260613-csm-cascaded-shadow-maps M5 / w28 (rebased to\n // binding 7 on 2026-06-13 to make room for point-shadow 5/6):\n // forward shaders declare binding 7 in common.wgsl (shared\n // view BGL) but never reference it; only shadow_caster.wgsl\n // reads it. Host writes a stable singleton buffer so every\n // forward bind group entry stays populated.\n {\n binding: 7,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.shadowCasterCascadeBuffer },\n },\n },\n // feat-20260625-spot-light-shadow-mapping M3 / w21 (D-5):\n // spot shadow 2D atlas (real spotShadowDepth view when spot\n // shadows run this frame, else the 1x1 depth fallback). Always-on.\n {\n binding: 8,\n resource: {\n kind: 'textureView',\n value: b8View,\n },\n },\n {\n binding: 10,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,\n size: POINTS_LINES_VIEW_BYTES,\n },\n },\n },\n // feat-20260625-spot-light-shadow-mapping w25: the per-spot\n // fragment-read lightViewProj matrices fold into the View UBO\n // (binding 0, `view.spotLightViewProj`) — no standalone binding 9\n // (WebGL2 fragment uniform-buffer budget). binding 10 is the\n // dedicated vertex-only Points/Lines viewport UBO.\n ],\n });\n if (!viewBindGroupResult.ok) throw viewBindGroupResult.error;\n return viewBindGroupResult.value;\n },\n bindGroupCounts,\n );\n }\n\n // M3 / w10 (D-3 hard constraint): use the inner `.buffer` as the\n // WeakMap chain key so the cache tracks the underlying GPU buffer\n // identity. The wrapper object's identity is stable across grow\n // events; using the wrapper would defeat AC-07 cache invalidation.\n meshBindGroup = getOrCreateFromChain(\n frameState.meshBindGroupCache,\n [pipelineState.meshStorageBuffer.buffer],\n 'mesh',\n () => {\n // bug-20260610: WebGL2 fallback path needs the binding to cover the\n // whole `array<Mesh, 128>` uniform buffer (14336 B) instead of a\n // single dynamic-offset slot (112 B). `caps.storageBuffer === false`\n // is the same proxy createRenderer uses to pick the uniform variant.\n const meshBindSize = internals.device.caps.storageBuffer\n ? MESH_SSBO_BYTES\n : MESH_UBO_FULL_ARRAY_BYTES;\n const meshBindGroupResult = internals.device.createBindGroup({\n label: 'pbr-mesh-bg',\n layout: pipelineState.meshBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.meshStorageBuffer.buffer,\n offset: 0,\n size: meshBindSize,\n },\n },\n },\n ],\n });\n if (!meshBindGroupResult.ok) throw meshBindGroupResult.error;\n return meshBindGroupResult.value;\n },\n bindGroupCounts,\n );\n\n // feat-20260609-hdrp-cluster-fragment-ggx M4 / w19: when HDRP is active,\n // build the unified group(2) BindGroup that carries the mesh SSBO at\n // binding 0 + the 4 cluster buffers at bindings 3..6. The bindGroup\n // shares the mesh SSBO with URP's `meshBindGroup` (same `meshStorageBuffer.buffer`\n // + same per-entity stride), so the dynamic offset issued at\n // `setBindGroup(2, ...)` covers binding 0 of either layout. Cached\n // alongside `meshBindGroupCache` keyed on the mesh SSBO + cluster\n // buffer identities; cache invalidates on a buffer-grow event the same\n // way the mesh path does (handle id rotation).\n if (frameState.isHdrpActive) {\n const hdrpBuffers = getOrCreateHdrpBuffers(\n internals,\n frameState.installedPipelineConfig?.clusterGrid,\n );\n if (hdrpBuffers !== null) {\n // D-3: buffer dimension uses the inner `.buffer` (same constraint\n // as the mesh path) so a grow event rotates the chain key.\n hdrpClusterBindGroup = getOrCreateFromChain(\n frameState.meshBindGroupCache,\n [\n pipelineState.meshStorageBuffer.buffer,\n hdrpBuffers.lightDataBuffer,\n hdrpBuffers.clusterGridBuffer,\n hdrpBuffers.lightIndexListBuffer,\n hdrpBuffers.clusterUniformBuffer,\n ],\n 'hdrp-unified',\n () => {\n const bg = createHdrpUnifiedBindGroup(\n internals,\n hdrpBuffers,\n pipelineState.meshStorageBuffer.buffer,\n );\n if (bg === null) {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'HDRP unified BindGroup creation succeeds when HDRP is active',\n hint: 'inspect prior errorRegistry events for createBindGroup failure detail',\n });\n }\n return bg;\n },\n bindGroupCounts,\n );\n }\n }\n }\n return { viewBindGroup, meshBindGroup, hdrpClusterBindGroup, hdrpClusterMembershipBindGroup };\n}\n\n/**\n * feat-20260704 M3/w18: per-frame lighting preparation, extracted verbatim from\n * `recordFrame`. (1) URP-only multi-light warn-once (directional / point / spot\n * over `LIGHT_ARRAY_MAX_SLOTS`; HDRP gated off — 256 SSBO lights). (2) pin the\n * point + spot shadow snapshot lists onto frameState for the URP shadow caster\n * pass closures + lazy-allocate the point-shadow cube_array atlas on first\n * non-empty frame (AC-09 zero-shadow zero-alloc). (3) destructure ExtractedLights\n * into the directional-fallback `light` (zero-intensity Case C default), point /\n * spot arrays, and totalLightCount.\n *\n * @internal\n */\nexport function prepareFrameLighting(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n lights: ExtractedLights,\n): {\n light: DirectionalLightSnapshot;\n pointLights: ExtractedLights['point'];\n spotLights: ExtractedLights['spot'];\n totalLightCount: number;\n} {\n if (lights.directionalCount > 1) {\n warnMultiLightDirectional(frameState, lights.directionalCount);\n }\n // feat-20260621-merge-directionallightshadow-into-directionallight M3 / m3-t2:\n // the AC-04/AC-22 \"shadow disabled by missing component\" once-warn is gone.\n // After merging DirectionalLightShadow into DirectionalLight there is no\n // orphan-shadow / missing-companion configuration to warn about -- castShadow\n // defaults true on the single component, so the warn condition can never\n // arise. The error class + RuntimeErrorCode member have been removed in M4 (m4-t2).\n\n // feat-20260608-cluster-lighting M6 / w23 (F-4 fix): URP-only multi-light\n // warn. HDRP supports 256 punctual lights via SSBO; the 4-slot first-slice\n // cap is irrelevant under HDRP, so gate on `!isHdrpActive` to silence noise.\n // Sibling tweak-20260608-rhi-hdr-renderable-caps-and-warn-once (#320)\n // extracted the warn into warnMultiLight{Point,Spot} helpers (warn-once\n // dedup); we keep the helpers and add the HDRP gate on top.\n if (!frameState.isHdrpActive) {\n if (lights.point.length > LIGHT_ARRAY_MAX_SLOTS) {\n warnMultiLightPoint(frameState, lights.point.length);\n }\n if (lights.spot.length > LIGHT_ARRAY_MAX_SLOTS) {\n warnMultiLightSpot(frameState, lights.spot.length);\n }\n }\n\n // feat-20260612-point-light-shadows-urp-hdrp M3 / T-M3-2 (plan-strategy §D-1):\n // project lights.pointShadow onto frameState so the URP point shadow caster\n // pass can read the snapshot list during graph execute. Lazy-allocate the\n // cube_array atlas on first non-empty frame; zero-shadow scenes never\n // touch the GPU here (AC-09). The snapshot list is stable for the\n // duration of recordFrame; its count is part of the typed topology key.\n frameState.pointShadowSnapshots = lights.pointShadow;\n // feat-20260625-spot-light-shadow-mapping M2 / w9 (D-2): pin the spot\n // snapshots for the spotShadowDepth caster pass closure. The spot atlas is\n // a graph-owned typed target, not a runtime ShadowAtlas, so graph compilation\n // owns the depth texture lifetime.\n frameState.spotShadowSnapshots = lights.spot;\n if (lights.pointShadow.length > 0) {\n if (frameState.pointShadowAtlas === null) {\n const firstSnap = lights.pointShadow[0];\n const faceSize = firstSnap?.mapSize ?? 512;\n frameState.pointShadowAtlas = new ShadowAtlas(internals.device, {\n faceSize,\n layers: 4,\n });\n }\n try {\n frameState.pointShadowAtlas.ensure();\n } catch (e) {\n if (\n e instanceof PointShadowAtlasUninitializedError ||\n e instanceof PointShadowAtlasBoundsViolationError\n ) {\n internals.errorRegistry.fire(e);\n } else {\n throw e;\n }\n }\n }\n\n // ExtractedLights three-arm consumption (R-10 preparation; M2 / w16):\n //\n // - lights.directional : feeds the View UBO at slot [16..23]\n // (lightDir + lightColor; existing path).\n // - lights.point[] : packed into pointLightsBuffer (std430).\n // - lights.spot[] : packed into spotLightsBuffer (std430).\n //\n // Each variant carries the discriminant `kind` so the record-time packing\n // call sites can run exhaustive switch (charter P2 + AC-03).\n const directionalLight: DirectionalLightSnapshot | undefined = lights.directional;\n const pointLights = lights.point;\n const spotLights = lights.spot;\n\n // Case C: 0 DirectionalLight = legitimate scene; the View UBO falls\n // back to a zero-intensity directional payload so the shader's\n // `view.lightDir * view.lightColor` term contributes nothing\n // (physically-correct black under standard, untouched under unlit).\n const light: DirectionalLightSnapshot = directionalLight ?? {\n kind: 'directional' as const,\n direction: vec3.create(0, -1, 0),\n color: vec3.create(0, 0, 0),\n intensity: 0,\n };\n\n const totalLightCount =\n (directionalLight !== undefined ? 1 : 0) + pointLights.length + spotLights.length;\n\n return { light, pointLights, spotLights, totalLightCount };\n}\n\n/**\n * feat-20260704 M3/w18: per-frame full rewrite of the PointLight + SpotLight\n * std430 storage buffers, extracted verbatim from `recordFrame`.\n *\n * feat-20260519-light-casters-point-spot-pbr M3 / w20 (D-S1 + D-S2 + D-S6):\n * header (16 B count u32 + 12 B pad) at offset 0 + first-slice cap N=4 slots\n * packed sequentially. The N>4 fail-fast upstream ensures the counts are <= 4\n * when the listener registry consumed the structured error; the slice keeps\n * the buffer write bounded even if downstream listeners ignore the RhiError\n * (charter P9 graceful degradation: surplus entities dropped, frame records).\n *\n * @internal\n */\nexport function writePointSpotLightBuffers(\n internals: RenderSystemInternals,\n pipelineState: PipelineState,\n lights: ExtractedLights,\n): void {\n const pointSlots =\n lights.point.length <= LIGHT_ARRAY_MAX_SLOTS\n ? lights.point\n : lights.point.slice(0, LIGHT_ARRAY_MAX_SLOTS);\n const pointHeader = packLightArrayHeader(pointSlots.length);\n const pointHeaderUpload = internals.device.queue.writeBuffer(\n pipelineState.pointLightsBuffer,\n 0,\n new Uint8Array(pointHeader),\n );\n if (!pointHeaderUpload.ok) throw pointHeaderUpload.error;\n for (let i = 0; i < pointSlots.length; i++) {\n const slot = pointSlots[i];\n if (slot === undefined) continue;\n const packed = packPointLight(slot);\n const offset = LIGHT_ARRAY_HEADER_BYTES + i * POINT_LIGHT_STD430_BYTES;\n const writeRes = internals.device.queue.writeBuffer(\n pipelineState.pointLightsBuffer,\n offset,\n packed,\n );\n if (!writeRes.ok) throw writeRes.error;\n }\n const spotSlots =\n lights.spot.length <= LIGHT_ARRAY_MAX_SLOTS\n ? lights.spot\n : lights.spot.slice(0, LIGHT_ARRAY_MAX_SLOTS);\n const spotHeader = packLightArrayHeader(spotSlots.length);\n const spotHeaderUpload = internals.device.queue.writeBuffer(\n pipelineState.spotLightsBuffer,\n 0,\n new Uint8Array(spotHeader),\n );\n if (!spotHeaderUpload.ok) throw spotHeaderUpload.error;\n for (let i = 0; i < spotSlots.length; i++) {\n const slot = spotSlots[i];\n if (slot === undefined) continue;\n const packed = packSpotLight(slot);\n const offset = LIGHT_ARRAY_HEADER_BYTES + i * SPOT_LIGHT_STD430_BYTES;\n const writeRes = internals.device.queue.writeBuffer(\n pipelineState.spotLightsBuffer,\n offset,\n packed,\n );\n if (!writeRes.ok) throw writeRes.error;\n }\n}\n\n/**\n * feat-20260704 M3/w18: write the point-shadow params UBO (bound at viewBg\n * binding 6), extracted verbatim from `recordFrame`.\n *\n * feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1: 4 lanes x vec4<f32>;\n * lane[shadowAtlasLayer] = (near, far, 1/(far-near), 0). Lanes for non-shadow\n * slots stay zero (the WGSL sample path is gated by PointLight.shadowAtlasLayer\n * >= 0). Always writes the full 64 B so stale non-zero lanes from a previous\n * frame's allocation cannot poison the current frame.\n *\n * @internal\n */\nexport function writeShadowParamsBuffer(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n pipelineState: PipelineState,\n): void {\n const SHADOW_PARAMS_LANE_COUNT = 4;\n const SHADOW_PARAMS_FLOATS_PER_LANE = 4;\n const shadowParamsArr = new Float32Array(\n SHADOW_PARAMS_LANE_COUNT * SHADOW_PARAMS_FLOATS_PER_LANE,\n );\n for (let i = 0; i < frameState.pointShadowSnapshots.length; i++) {\n const ps = frameState.pointShadowSnapshots[i];\n if (ps === undefined) continue;\n const layer = ps.shadowAtlasLayer;\n if (layer < 0 || layer >= SHADOW_PARAMS_LANE_COUNT) continue;\n const base = layer * SHADOW_PARAMS_FLOATS_PER_LANE;\n const near = ps.nearPlane;\n const far = ps.farPlane;\n const invSpan = far > near ? 1 / (far - near) : 0;\n shadowParamsArr[base] = near;\n shadowParamsArr[base + 1] = far;\n shadowParamsArr[base + 2] = invSpan;\n shadowParamsArr[base + 3] = 0;\n }\n const shadowParamsWriteRes = internals.device.queue.writeBuffer(\n pipelineState.shadowParamsBuffer,\n 0,\n shadowParamsArr,\n );\n if (!shadowParamsWriteRes.ok) {\n internals.errorRegistry.fire(shadowParamsWriteRes.error);\n }\n}\n\n/**\n * feat-20260704 M3/w18: zero-light standard-material once-warn, extracted\n * verbatim from `recordFrame`.\n *\n * feat-20260520-skylight-ibl-cubemap M4 / t27 (AC-10): fires once per\n * RenderSystem lifetime when the 0-light three-condition conjunction holds — no\n * Skylight, 0 direct light (totalLightCount === 0), AND at least one builtin\n * standard/PBR material (which renders black with no light). Custom shaders\n * own their lighting contract and cannot be classified by this generic\n * diagnostic. Suppressed under NODE_ENV=production.\n *\n * @internal\n */\nexport function warnZeroLightStandard(\n frameState: RenderFrameState,\n renderables: readonly RenderableSnapshot[],\n skylight: SkylightSnapshot | undefined,\n totalLightCount: number,\n): void {\n const hasStandardMaterial = renderables.some((r) => isLitMaterialSnapshot(r.material));\n if (\n skylight === undefined &&\n totalLightCount === 0 &&\n hasStandardMaterial &&\n !frameState.warnedZeroLightStandard\n ) {\n frameState.warnedZeroLightStandard = true;\n const env = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n if (env?.env?.NODE_ENV !== 'production') {\n console.warn(\n '[forgeax] standard material renders black with 0 lights of every type (no Skylight, and directional + point + spot all empty); spawn at least one light (Skylight, DirectionalLight, PointLight, or SpotLight) or switch material to an unlit shader (Materials.unlit(...)). See AGENTS.md section Breaking changes 2026-05-19.',\n );\n }\n }\n}\n\n/**\n * feat-20260704 M3/w18: HDRP per-frame CPU cluster binning + light-data /\n * cluster-grid / light-index-list / cluster-uniform / SSAO uniform buffer\n * uploads. Extracted verbatim from `recordFrame`. Runs only when the HDRP\n * pipeline is active. A zero-punctual frame explicitly clears the persistent\n * cluster buffers so stale membership cannot leak across frames; direct and\n * non-clustered paths remain untouched.\n *\n * feat-20260608-cluster-lighting M5 / w21 + M6 / w23 + r2 fix-up: fail-soft\n * semantics preserved verbatim — index-list-overflow and light-budget-exceeded\n * fire once per frame (via `frameState.hdrpOncePerFrameFired`) and continue\n * rendering.\n *\n * @internal\n */\nexport function writeHdrpClusterAndSsaoBuffers(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n camera: CameraSnapshot,\n pointLights: ExtractedLights['point'],\n spotLights: ExtractedLights['spot'],\n profilePhase?: RecordProfileRunner,\n useGpuMembership = false,\n membershipBindGroupLayout: BindGroupLayout | null = null,\n): void {\n const hdrpLightCount = pointLights.length + spotLights.length;\n if (!frameState.isHdrpActive) return;\n if (hdrpLightCount === 0) {\n const grid = frameState.installedPipelineConfig?.clusterGrid ?? DEFAULT_CLUSTER_GRID;\n const hdrpBuffers = getOrCreateHdrpBuffers(internals, grid);\n if (hdrpBuffers === null) return;\n const lightCapacity = hdrpBuffers.storageBuffer ? 256 : HDRP_UNIFORM_LIGHT_CAPACITY;\n const clusterSsaoConfig = frameState.installedPipelineConfig?.ssao;\n const clusterSsaoIntensity =\n clusterSsaoConfig !== undefined && clusterSsaoConfig.enabled === true\n ? (clusterSsaoConfig.intensity ?? 1.0)\n : 0;\n const clusterUniformPayload = packClusterUniform(\n grid,\n camera.near,\n camera.far,\n clusterSsaoIntensity,\n 0,\n lightCapacity,\n );\n const clusterUniformUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.clusterUniformBuffer,\n 0,\n new Uint8Array(clusterUniformPayload),\n );\n if (!clusterUniformUpload.ok) internals.errorRegistry.fire(clusterUniformUpload.error);\n const clusterGridClear = internals.device.queue.writeBuffer(\n hdrpBuffers.clusterGridBuffer,\n 0,\n new Uint8Array(hdrpBuffers.clusterGridBytes),\n );\n if (!clusterGridClear.ok) internals.errorRegistry.fire(clusterGridClear.error);\n const lightIndexListClear = internals.device.queue.writeBuffer(\n hdrpBuffers.lightIndexListBuffer,\n 0,\n new Uint8Array(hdrpBuffers.lightIndexListBytes),\n );\n if (!lightIndexListClear.ok) internals.errorRegistry.fire(lightIndexListClear.error);\n return;\n }\n const HDRP_LIGHT_BUDGET = 256;\n let effectivePointLights = pointLights;\n let effectiveSpotLights = spotLights;\n if (hdrpLightCount > HDRP_LIGHT_BUDGET) {\n if (!frameState.hdrpOncePerFrameFired.has('hdrp-light-budget-exceeded')) {\n frameState.hdrpOncePerFrameFired.add('hdrp-light-budget-exceeded');\n internals.errorRegistry.fire(\n new HdrpLightBudgetExceededError(hdrpLightCount, HDRP_LIGHT_BUDGET),\n );\n }\n if (pointLights.length >= HDRP_LIGHT_BUDGET) {\n effectivePointLights = pointLights.slice(0, HDRP_LIGHT_BUDGET);\n effectiveSpotLights = [];\n } else {\n effectivePointLights = pointLights;\n effectiveSpotLights = spotLights.slice(0, HDRP_LIGHT_BUDGET - pointLights.length);\n }\n }\n const effectiveLightCount = effectivePointLights.length + effectiveSpotLights.length;\n const configuredClusterGrid =\n frameState.installedPipelineConfig?.clusterGrid ?? DEFAULT_CLUSTER_GRID;\n let gpuMembership = useGpuMembership && membershipBindGroupLayout !== null;\n if (\n gpuMembership &&\n membershipBindGroupLayout !== null &&\n frameState.hdrpClusterMembershipBindGroup === null\n ) {\n const hdrpBuffers = getOrCreateHdrpBuffers(internals, configuredClusterGrid);\n if (hdrpBuffers !== null) {\n frameState.hdrpClusterMembershipBindGroup = createHdrpClusterMembershipBindGroup(\n internals,\n hdrpBuffers,\n membershipBindGroupLayout,\n );\n }\n gpuMembership = frameState.hdrpClusterMembershipBindGroup !== null;\n }\n\n const { clusterGrid, gridX, gridY, gridZ, clusterGridBuf, lightIndexListBuf, lightIndexCount } =\n runHdrpClusterProfilePhase(profilePhase, 'record/scene-state/hdrp-cluster/binner', () => {\n const binnerProfile: ClusterBinProfileRunner | undefined =\n profilePhase === undefined\n ? undefined\n : <T>(phase: ClusterBinProfilePhase, action: () => T): T =>\n runHdrpClusterProfilePhase(\n profilePhase,\n `record/scene-state/hdrp-cluster/binner/${phase}` as RenderHdrpClusterPhase,\n action,\n );\n const {\n hdrpLights,\n clusterGrid,\n gridX,\n gridY,\n gridZ,\n clusterGridBuf,\n lightIndexListBuf,\n projMatrix,\n viewMatrix,\n } = runHdrpClusterProfilePhase(\n profilePhase,\n 'record/scene-state/hdrp-cluster/binner/input-preparation',\n () => {\n const hdrpLights: Array<{ position: Vec3; range: number }> = [];\n for (const pl of effectivePointLights) {\n const range =\n Number.isFinite(pl.invRangeSquared) && pl.invRangeSquared > 0\n ? Math.sqrt(1 / pl.invRangeSquared)\n : 1000;\n hdrpLights.push({ position: pl.position, range });\n }\n for (const sl of effectiveSpotLights) {\n const range =\n Number.isFinite(sl.invRangeSquared) && sl.invRangeSquared > 0\n ? Math.sqrt(1 / sl.invRangeSquared)\n : 1000;\n hdrpLights.push({ position: sl.position, range });\n }\n\n const clusterGrid =\n frameState.installedPipelineConfig?.clusterGrid ?? DEFAULT_CLUSTER_GRID;\n const gridX = clusterGrid.x;\n const gridY = clusterGrid.y;\n const gridZ = clusterGrid.z;\n const clusterCount = gridX * gridY * gridZ;\n\n const projMatrix = computeProjectionMatrix(camera);\n const viewMatrix = computeViewMatrix(camera);\n\n const clusterGridBuf =\n frameState.hdrpClusterGridScratch === null ||\n frameState.hdrpClusterGridScratch.length < clusterCount * 2\n ? new Uint32Array(clusterCount * 2)\n : frameState.hdrpClusterGridScratch;\n frameState.hdrpClusterGridScratch = clusterGridBuf;\n const lightIndexListBuf =\n frameState.hdrpLightIndexListScratch === null ||\n frameState.hdrpLightIndexListScratch.length < LIGHT_INDEX_LIST_CAPACITY\n ? new Uint32Array(LIGHT_INDEX_LIST_CAPACITY)\n : frameState.hdrpLightIndexListScratch;\n frameState.hdrpLightIndexListScratch = lightIndexListBuf;\n\n return {\n hdrpLights,\n clusterGrid,\n gridX,\n gridY,\n gridZ,\n clusterGridBuf,\n lightIndexListBuf,\n projMatrix,\n viewMatrix,\n };\n },\n );\n\n const binResult = runHdrpClusterProfilePhase(\n profilePhase,\n 'record/scene-state/hdrp-cluster/binner/bin-core',\n () =>\n bin(\n hdrpLights,\n viewMatrix,\n projMatrix,\n { x: gridX, y: gridY, z: gridZ },\n camera.near,\n camera.far,\n clusterGridBuf,\n lightIndexListBuf,\n LIGHT_INDEX_LIST_CAPACITY,\n frameState.hdrpClusterBinScratch,\n binnerProfile,\n { writeMembership: !gpuMembership },\n ),\n );\n\n if (!binResult.ok && !frameState.hdrpOncePerFrameFired.has('hdrp-index-list-overflow')) {\n frameState.hdrpOncePerFrameFired.add('hdrp-index-list-overflow');\n const detail = binResult.error.detail;\n internals.errorRegistry.fire(\n new HdrpIndexListOverflowError(detail.actual, detail.capacity),\n );\n }\n\n // Falsify injection point: FORGEAX_HDRP_FALSIFY_CLUSTER_GRID_ZERO\n // zeroes the cluster_grid buffer so every fragment culls every light.\n // Used by hello-hdrp-lighting smoke FALSIFY=cluster-grid-zero to\n // prove the smoke has discriminability (must FAIL vs baseline).\n // Read process via globalThis to keep this file @types/node-free.\n const envFalsify = (globalThis as { process?: { env?: Record<string, string | undefined> } })\n .process?.env;\n if (envFalsify?.FORGEAX_HDRP_FALSIFY_CLUSTER_GRID_ZERO) {\n clusterGridBuf.fill(0);\n }\n\n return {\n clusterGrid,\n gridX,\n gridY,\n gridZ,\n clusterGridBuf,\n lightIndexListBuf,\n lightIndexCount: binResult.ok ? binResult.value : 0,\n };\n });\n\n const hdrpPayload = runHdrpClusterProfilePhase(\n profilePhase,\n 'record/scene-state/hdrp-cluster/payload-packing',\n () => {\n const hdrpBuffers = getOrCreateHdrpBuffers(internals, clusterGrid);\n if (hdrpBuffers === null) return null;\n\n const lightCapacity = hdrpBuffers.storageBuffer ? 256 : HDRP_UNIFORM_LIGHT_CAPACITY;\n const lightDataPayload = new Float32Array(lightCapacity * 16);\n let slotIdx = 0;\n for (const pl of effectivePointLights) {\n if (slotIdx >= lightCapacity) break;\n // feat-20260612-point-light-shadows-urp-hdrp M4 / T-M4-4\n // (plan-strategy §D-8): thread the optional shadow info through\n // packLightSlot. PointLightSnapshot.shadowAtlasLayer is set by\n // extract's join pass when the entity carries PointLightShadow;\n // sentinel -1 means no shadow (unshadowed evalPoint path).\n const layer = pl.shadowAtlasLayer;\n const packed =\n layer !== undefined &&\n layer >= 0 &&\n pl.shadowNear !== undefined &&\n pl.shadowFar !== undefined\n ? packLightSlot(pl, {\n shadowAtlasLayer: layer,\n near: pl.shadowNear,\n far: pl.shadowFar,\n })\n : packLightSlot(pl);\n lightDataPayload.set(packed, slotIdx * 16);\n slotIdx += 1;\n }\n for (const sl of effectiveSpotLights) {\n if (slotIdx >= lightCapacity) break;\n const packed = packLightSlot(sl);\n lightDataPayload.set(packed, slotIdx * 16);\n slotIdx += 1;\n }\n\n // scope-amend-webgl2-ubo: SSAO intensity is folded into the\n // cluster_uniform .w lane (formerly pad), removing the dedicated\n // @binding(9) UBO that pushed fragment-stage UBO count past\n // WebGL2's max_uniform_buffers_per_shader_stage=11. Disabled-SSAO\n // path writes 0 so `mix(1.0, ssao*ao, 0.0) = 1.0` in the lighting\n // shader (no PSO recompile across enable/disable).\n const clusterSsaoConfig = frameState.installedPipelineConfig?.ssao;\n const clusterSsaoIntensity =\n clusterSsaoConfig !== undefined && clusterSsaoConfig.enabled === true\n ? (clusterSsaoConfig.intensity ?? 1.0)\n : 0;\n const clusterUniformPayload = packClusterUniform(\n { x: gridX, y: gridY, z: gridZ },\n camera.near,\n camera.far,\n clusterSsaoIntensity,\n Math.min(effectivePointLights.length + effectiveSpotLights.length, lightCapacity),\n lightCapacity,\n );\n\n return {\n hdrpBuffers,\n lightDataUploadPayload: lightDataPayload.subarray(0, slotIdx * 16),\n clusterUniformPayload: new Uint8Array(clusterUniformPayload),\n };\n },\n );\n\n runHdrpClusterProfilePhase(profilePhase, 'record/scene-state/hdrp-cluster/buffer-upload', () => {\n if (hdrpPayload !== null) {\n const { hdrpBuffers, lightDataUploadPayload, clusterUniformPayload } = hdrpPayload;\n const lightDataUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.lightDataBuffer,\n 0,\n lightDataUploadPayload,\n );\n if (!lightDataUpload.ok) internals.errorRegistry.fire(lightDataUpload.error);\n\n if (hdrpBuffers.storageBuffer) {\n if (gpuMembership) {\n const lightBoundsUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.lightBoundsBuffer,\n 0,\n frameState.hdrpClusterBinScratch.lightBounds.subarray(0, effectiveLightCount * 6),\n );\n if (!lightBoundsUpload.ok) internals.errorRegistry.fire(lightBoundsUpload.error);\n }\n const clusterGridUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.clusterGridBuffer,\n 0,\n clusterGridBuf.subarray(0, gridX * gridY * gridZ * 2),\n );\n if (!clusterGridUpload.ok) internals.errorRegistry.fire(clusterGridUpload.error);\n\n if (!gpuMembership && lightIndexCount > 0) {\n const lightIndexListUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.lightIndexListBuffer,\n 0,\n lightIndexListBuf.subarray(0, lightIndexCount),\n );\n if (!lightIndexListUpload.ok) internals.errorRegistry.fire(lightIndexListUpload.error);\n }\n }\n\n const clusterUniformUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.clusterUniformBuffer,\n 0,\n clusterUniformPayload,\n );\n if (!clusterUniformUpload.ok) internals.errorRegistry.fire(clusterUniformUpload.error);\n }\n\n // ── feat-20260612-hdrp-ssao M1 / w6 + M7 / w33 ───────────────\n // Per-frame SSAO uniform write (plan-strategy D-1 + D-C):\n // view + projection + inverseProjection at offsets 0/64/128 +\n // intensityPad (vec4 — x=intensity, y=radius, z=bias) at offset 192;\n // total 256 B (matches host SSAO_UNIFORM_BYTES + WGSL struct).\n // Single writeBuffer covers all four fields so one queue entry\n // updates the entire UBO.\n // Separate from View UBO (592 B invariant); does not affect\n // material PSO bytecode.\n //\n // Writes when HDRP is active; config.ssao?.enabled guard comes in\n // M4 / w19 after the config.ssao type narrowing is added.\n {\n const ssaoBufs = getOrCreateSsaoBuffers(internals);\n if (ssaoBufs !== null) {\n const sProj = computeProjectionMatrix(camera);\n const sView = computeViewMatrix(camera);\n // inverseProjection = inverse(projection): NDC -> view-space.\n const invProjOnly = mat4.create();\n mat4.invert(invProjOnly, sProj);\n\n // Float32Array of 64 (256 B): 3 mat4 (48) + intensityPad vec4 (4)\n // + 12 trailing padding floats. We only fill the declared region.\n const ssaoUniformPayload = new Float32Array(64);\n ssaoUniformPayload.set(sView, 0);\n ssaoUniformPayload.set(sProj, 16);\n ssaoUniformPayload.set(invProjOnly, 32);\n // intensityPad carries the same resolved values as the graph SSAO\n // calc pass; this early write keeps the shared UBO valid before the\n // typed fullscreen pass executes.\n const ssaoConfig = frameState.installedPipelineConfig?.ssao;\n const parameters = getSsaoParameters(\n ssaoConfig !== undefined && ssaoConfig.enabled === true ? ssaoConfig : undefined,\n );\n ssaoUniformPayload[48] = parameters.intensity;\n ssaoUniformPayload[49] = parameters.radius;\n ssaoUniformPayload[50] = parameters.bias;\n\n const ssaoUniformRes = internals.device.queue.writeBuffer(\n ssaoBufs.uniformBuffer,\n 0,\n ssaoUniformPayload,\n );\n if (!ssaoUniformRes.ok) internals.errorRegistry.fire(ssaoUniformRes.error);\n }\n }\n });\n}\n\n/**\n * feat-20260704 M3/w18: resolve `tonemapActive` + `skyboxActive` for this\n * frame, extracted verbatim from `recordFrame`.\n *\n * feat-20260519-tonemap-reinhard-mvp: tonemap is active when the camera carries\n * `tonemap !== 'none'` (routes geometry into the HDR offscreen target + a\n * fullscreen tonemap pass). feat-20260531-skybox-env-background M2 / w9: skybox\n * is active only when a SkyboxBackground entity is present AND tonemap is active\n * (hdrColor is only allocated on the tonemap path). M3 / w20: once-warn when\n * tonemap is 'none' but a skybox exists (config issue, not resource-timing —\n * no structured error). M3 / w18: skybox degrades to clear-colour for a frame\n * while its cubemap view is not yet resident (lazy equirect projection pending\n * / failed; the lazy trigger owns the fire-once-on-failed error).\n *\n * @internal\n */\nexport function resolveSkyboxActive(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n camera: CameraSnapshot,\n skybox: SkyboxSnapshot | undefined,\n): { tonemapActive: boolean; skyboxActive: boolean } {\n const tonemapActive = camera.tonemap !== 'none';\n let skyboxActive = skybox !== undefined && tonemapActive;\n // feat-20260531-skybox-env-background M3 / w20: once-warn when camera\n // tonemap is 'none' but a SkyboxBackground entity exists. The skybox\n // pass requires the HDR render target allocated by the tonemap path;\n // without it the skybox is skipped for this frame. This is a config\n // issue, not a resource-timing issue -- don't fire a structured error\n // (plan-strategy D-2 NOTE, charter P3 non-silent).\n if (skybox !== undefined && !tonemapActive && !frameState.warnedSkyboxTonemapNone) {\n frameState.warnedSkyboxTonemapNone = true;\n console.warn(\n '[forgeax] SkyboxBackground: skybox requires tonemap active (camera.tonemap !== \"none\") to write HDR target. The skybox pass will be skipped for this frame.',\n );\n }\n // feat-20260531-skybox-env-background M3 / w18: degradation when cubemap\n // GPU view is not ready. getCubemapGpuView returns undefined if the\n // equirect-to-cube upload has not completed yet.\n if (skybox !== undefined && tonemapActive) {\n const cubemapView = internals.gpuStore.getCubemapGpuView(\n toShared<'EquirectAsset'>(skybox.equirectHandle),\n );\n if (cubemapView === undefined) {\n // The skybox reuses the Skylight's equirect handle; the cubemap\n // projection is driven lazily by the single trigger in `driveLazy\n // EquirectProjection` above (it owns the fire-and-forget launch AND the\n // fire-once-on-failed structured error). While the projection is\n // pending or has failed the cube view is not resident, so the skybox\n // pass degrades to the clear-colour background for this frame\n // (charter P3: it activates once the shared projection flips to\n // 'ready'). No error is fired here -- 'pending' is a normal transition\n // (firing per frame would flood the channel), and 'failed' is reported\n // once by the lazy trigger. (feat-20260630 M3 / w18.)\n skyboxActive = false;\n }\n }\n return { tonemapActive, skyboxActive };\n}\n","// IblPipelineCache.ts -- DeviceScope-generation cache for IBL precompute.\n//\n// Plan-strategy D-1/D-7: cache for 4 GPU passes (equirect->cube /\n// irradiance / prefilter / BRDF LUT). M2 provides the cache skeleton;\n// M3 (t18/t20) wires real shader math from ibl.wgsl.\n//\n// The cache is keyed by the renderer-owned DeviceScope generation. Raw device\n// handles are inputs to pipeline creation, never cache or lifecycle owners.\n//\n// Public surface (M3):\n// - getOrCreateIblCache(scope): get or initialize the generation cache\n// - iblCacheSize(): introspection hook\n// - hasIblCache(scope): introspection hook\n// - setIblWgslSource(source): set the ibl.wgsl WGSL source string\n// - createIblShaderModules(device, factory): create shader modules from ibl.wgsl\n// - createIblPipelines(scope, device, factory, modules): create 4 render pipelines\n// - runIblPrecompute(opts): execute 4 GPU precompute passes (M3 t20)\n//\n// M3 t20: pipeline slots are filled with real render pipelines loaded from\n// ibl.wgsl, replacing the M2 stub undefined slots. The 4 GPU passes are\n// executed in the standard order (equirect->cube -> irradiance -> prefilter\n// -> BRDF LUT), with counters set post-execution per AC-04/05/06.\n\n// ─── RHI-owned handles ───────────────────────────────────────────────────────\n\nimport {\n type BindGroup,\n type BindGroupLayout,\n type Buffer,\n type CommandBuffer,\n err,\n ok,\n type RenderPipeline,\n type Result,\n type RhiCommandEncoder,\n type RhiDevice,\n type RhiError,\n type RhiRenderPassEncoder,\n type Sampler,\n type ShaderModule,\n type Texture,\n type TextureFormat,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport type { DeviceScope } from '../device/device-scope';\nimport { GPU_SHADER_STAGE_FRAGMENT, GPU_SHADER_STAGE_VERTEX } from '../gpu-stage';\nimport {\n GPU_TEXTURE_USAGE_COPY_DST,\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\n\n/**\n * Shader module factory (async, injected via configureGpuDevice).\n * Mirrors `MipmapShaderModuleFactory` from mipmap-generator.\n */\n/**\n * IBL is assembled by the renderer's device owner, so it consumes the full\n * opaque RHI device rather than a structurally-compatible raw/shim split.\n * Keeping the owner as RhiDevice makes the backend boundary explicit: raw\n * GPU handles can only exist inside an RHI implementation or a test readback.\n */\nexport type IblRhiOwner = RhiDevice;\n\nexport type IblShaderModuleFactory = (\n device: IblRhiOwner,\n desc: { code: string; label?: string },\n) => Promise<Result<ShaderModule, RhiError>>;\n\nexport interface IblPipelineSet {\n readonly equirectToCubePipeline: RenderPipeline;\n readonly irradiancePipeline: RenderPipeline;\n readonly prefilterPipeline: RenderPipeline;\n readonly brdfLutPipeline: RenderPipeline;\n}\n\nexport interface IblPipelineError {\n readonly code: 'ibl-pipeline-create-failed' | 'ibl-shader-module-missing';\n readonly expected: string;\n readonly hint: string;\n readonly detail: { readonly stage: string; readonly rhiCode?: RhiError['code'] };\n}\n\n/**\n * Per-DeviceScope-generation IBL pipeline cache instance.\n *\n * M3.5 (round-2 t52): the 4 pipeline slots are mutable so createIblPipelines\n * can fill them after construction. The 4 textures + their views are also\n * cached here so runIblPrecompute targets are stable across calls\n * (idempotent).\n */\nexport interface IblPipelineCache {\n /** Color format shared by all precompute outputs for this device. */\n outputFormat?: TextureFormat;\n /** Equirectangular-to-cubemap pipeline. */\n equirectToCubePipeline?: RenderPipeline;\n /** Diffuse irradiance convolution pipeline. */\n irradiancePipeline?: RenderPipeline;\n /** Specular prefilter pipeline. */\n prefilterPipeline?: RenderPipeline;\n /** BRDF integration LUT pipeline. */\n brdfLutPipeline?: RenderPipeline;\n\n /** Face uniforms BGL (shared across equirect/irradiance/prefilter, D-9). */\n faceUniformsBgl?: BindGroupLayout;\n /** group(1) BGL for the equirect-to-cube pass (texture_2d + sampler). */\n equirectGroup1Bgl?: BindGroupLayout;\n /** group(1) BGL for irradiance + prefilter (texture_cube + sampler). */\n cubeGroup1Bgl?: BindGroupLayout;\n /** group(0) BGL for prefilter (face + prefilter uniforms). */\n prefilterGroup0Bgl?: BindGroupLayout;\n\n /** Irradiance cubemap texture (32x32; outputFormat, cube). */\n irradianceTexture?: Texture;\n /** Irradiance cubemap view (dimension:cube). */\n irradianceView?: TextureView;\n /** Per-face 2D views for irradiance (render-attachment use). */\n irradianceFaceViews?: ReadonlyArray<TextureView>;\n /** Specular prefilter cubemap (128x128, 5 mip levels). */\n prefilterTexture?: Texture;\n /** Prefilter cubemap view (dimension:cube, all mips). */\n prefilterView?: TextureView;\n /** Per-face 2D views per mip for prefilter (5 mips x 6 faces). */\n prefilterFaceViewsByMip?: ReadonlyArray<ReadonlyArray<TextureView>>;\n /** BRDF LUT (256x256; outputFormat). */\n brdfLutTexture?: Texture;\n /** BRDF LUT view. */\n brdfLutView?: TextureView;\n\n /** Counter: times irradiance pass has executed. AC-04: == 1 after first cook. */\n irradianceBakeCount: number;\n /** Counter: times prefilter pass has executed. AC-05: == 1 after first cook. */\n prefilterBakeCount: number;\n /** Counter: times BRDF LUT pass has executed. AC-06: == 1 after first cook. */\n brdfLutBakeCount: number;\n}\n\n/**\n * Cache ownership follows the renderer's DeviceScope generation. A cache is\n * never recovered by looking up an opaque device handle, so every pipeline and\n * side texture is born under the same lifecycle owner as the rest of the\n * renderer resources.\n */\nconst scopeCaches: WeakMap<DeviceScope, IblPipelineCache> = new WeakMap();\n\n/**\n * Get or create the current-generation IBL pipeline cache.\n */\nexport function getOrCreateIblCache(scope: DeviceScope): IblPipelineCache {\n const existing = scopeCaches.get(scope);\n if (existing !== undefined) return existing;\n\n const cache: IblPipelineCache = {\n irradianceBakeCount: 0,\n prefilterBakeCount: 0,\n brdfLutBakeCount: 0,\n };\n scopeCaches.set(scope, cache);\n return cache;\n}\n\n/**\n * Check whether a DeviceScope generation has an active cache entry.\n */\nexport function hasIblCache(scope: DeviceScope): boolean {\n return scopeCaches.has(scope);\n}\n\n// ─── M3.5 composed ibl-* shader source registry ─────────────────────────────\n//\n// 4 composed WGSL strings -- one per render pipeline. Each string is the\n// output of @forgeax/engine-naga composeShader after merging ibl_shared +\n// the per-pass module. Built by ShaderCatalog / vite-plugin-shader at\n// build-time so the runtime cache never reaches into engine-naga\n// (AGENTS.md grep gate forbids).\n\nexport interface IblComposedShaders {\n /** ibl-equirect-to-cube composed (cubemap_vs + equirectToCube_fs). */\n readonly equirectToCube: string;\n /** ibl-irradiance composed (cubemap_vs + irradianceConvolve_fs). */\n readonly irradiance: string;\n /** ibl-prefilter composed (cubemap_vs + prefilterEnv_fs). */\n readonly prefilter: string;\n /** ibl-brdf-lut composed (fullscreen_vs + brdfLutBake_fs). */\n readonly brdfLut: string;\n}\n\nlet iblComposedShadersCache: IblComposedShaders | undefined;\n\n/**\n * Inject the composed ibl-* shader sources used by createIblPipelines.\n * Called once by the engine bootstrap (createRenderer step \"shader-load\")\n * with the 4 composed entries from ShaderCatalog.\n */\nexport function setIblComposedShaders(sources: IblComposedShaders): void {\n iblComposedShadersCache = sources;\n}\n\n// ─── Standard cube vertices for cubemap face rendering ───────────────────────\n// 36 vertices (6 faces * 2 triangles * 3 vertices), vec3<f32> format.\n// Unit cube [-1, 1]^3 centered at origin.\nexport const CUBEMAP_FACE_VERTICES = new Float32Array([\n // +X face (+1, 0, 0)\n 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,\n // -X face (-1, 0, 0)\n -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,\n 1.0,\n // +Y face (0, +1, 0)\n -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,\n // -Y face (0, -1, 0)\n -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0,\n 1.0,\n // +Z face (0, 0, +1)\n -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,\n // -Z face (0, 0, -1)\n 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0,\n -1.0,\n]);\n\n// 6 capture view-projection matrices (right-handed, from origin).\n// Projection Y is negated for WebGPU top-left framebuffer origin.\n// Target directions: +X, -X, +Y, -Y, +Z, -Z.\n// Up vectors: -Y for X/Z faces, +Z for +Y, -Z for -Y.\nexport const CAPTURE_VIEW_PROJS = buildCaptureViewProjs();\n\nfunction buildCaptureViewProjs(): Float32Array[] {\n const targets: [number, number, number][] = [\n [1, 0, 0],\n [-1, 0, 0],\n [0, 1, 0],\n [0, -1, 0],\n [0, 0, 1],\n [0, 0, -1],\n ];\n const ups: [number, number, number][] = [\n [0, -1, 0],\n [0, -1, 0],\n [0, 0, 1],\n [0, 0, -1],\n [0, -1, 0],\n [0, -1, 0],\n ];\n\n const proj = cubemapCaptureProjection(Math.PI / 2, 0.1, 10.0);\n\n return targets.map((_t, i) => {\n const t = _t;\n const u = ups[i] ?? [0, -1, 0];\n const view = lookAtMatrix([0, 0, 0], t, u);\n return mulMat4(proj, view);\n });\n}\n\nfunction cubemapCaptureProjection(fovy: number, near: number, far: number): Float32Array {\n const f = 1.0 / Math.tan(fovy / 2);\n const nf = 1.0 / (near - far);\n // biome-ignore format: manual column-major mat4\n return new Float32Array([\n f, 0, 0, 0,\n 0, -f, 0, 0,\n 0, 0, (far + near) * nf, -1,\n 0, 0, 2 * far * near * nf, 0,\n ]);\n}\n\nfunction lookAtMatrix(\n eye: readonly number[],\n target: readonly number[],\n up: readonly number[],\n): Float32Array {\n const [ex, ey0, ez] = [eye[0] ?? 0, eye[1] ?? 0, eye[2] ?? 0];\n const [tx, ty, tz] = [target[0] ?? 0, target[1] ?? 0, target[2] ?? 0];\n const [upx, upy, upz] = [up[0] ?? 0, up[1] ?? 0, up[2] ?? 0];\n let fx = ex - tx,\n fy = ey0 - ty,\n fz = ez - tz;\n const fLen = Math.sqrt(fx * fx + fy * fy + fz * fz);\n fx /= fLen;\n fy /= fLen;\n fz /= fLen;\n\n let rx = upy * fz - upz * fy;\n let ry = upz * fx - upx * fz;\n let rz = upx * fy - upy * fx;\n const rLen = Math.sqrt(rx * rx + ry * ry + rz * rz);\n rx /= rLen;\n ry /= rLen;\n rz /= rLen;\n\n const ux = fy * rz - fz * ry;\n const uy = fz * rx - fx * rz;\n const uz = fx * ry - fy * rx;\n\n return new Float32Array([\n rx,\n ux,\n fx,\n 0,\n ry,\n uy,\n fy,\n 0,\n rz,\n uz,\n fz,\n 0,\n -(rx * ex + ry * ey0 + rz * ez),\n -(ux * ex + uy * ey0 + uz * ez),\n -(fx * ex + fy * ey0 + fz * ez),\n 1,\n ]);\n}\n\n// Column-major matrix product `r = a * b` where each Float32Array stores\n// 4 contiguous column vectors of 4 floats (WGSL `mat4x4<f32>` uniform\n// layout). For column-major storage `flat[c*4 + row] = M[col=c, row]`, so:\n// (a * b)[col=c, row=r] = sum_k a[col=k, row=r] * b[col=c, row=k]\n// flat_out[c*4 + r] = sum_k a[k*4 + r] * b[c*4 + k]\n//\n// The prior row-major iteration silently transposed the result, producing\n// `b * a` in WGSL's view -- IBL equirect-to-cube vertices then projected\n// to clip with w=0 / w=-1, every face fell outside the [-1,1] frustum, no\n// fragments drew, and every downstream IBL texture (irradiance / prefilter)\n// inherited the clearValue=(0,0,0,1). Demo 3x3 sphere matrix rendered\n// pure black because `ambient = kD * 0 + specular * 0 = 0` and there are\n// no direct lights in the IBL demo scene.\nfunction mulMat4(a: Float32Array, b: Float32Array): Float32Array {\n const r = new Float32Array(16);\n for (let c = 0; c < 4; c++) {\n for (let row = 0; row < 4; row++) {\n let sum = 0;\n for (let k = 0; k < 4; k++) {\n sum += (a[k * 4 + row] ?? 0) * (b[c * 4 + k] ?? 0);\n }\n r[c * 4 + row] = sum;\n }\n }\n return r;\n}\n\n// ─── M3.5 t52: createIblPipelines (4 independent GPURenderPipelines) ─────────\n\n// IBL output texture sizes (plan D-10 SSOT, mirrored in ibl-brdf-lut.wgsl).\nexport const IRRADIANCE_SIZE = 32;\nexport const PREFILTER_SIZE = 128;\nexport const PREFILTER_MIP_LEVELS = 5;\nexport const BRDF_LUT_SIZE = 256;\n\n/**\n * Create 4 independent GPURenderPipelines + their shared / per-pass bind\n * group layouts. Pipeline slots are stored on the per-device cache and\n * survive across calls (D-1 startup-once cook).\n *\n * D-9: faceUniforms BGL (@group(0) for equirect/irradiance/prefilter) is\n * a single instance reused across 3 pipelines (binary-compatible).\n * group(1) is per-pipeline: texture_2d for equirect, texture_cube for\n * irradiance + prefilter, none for brdf-lut.\n */\nexport async function createIblPipelines(\n scope: DeviceScope,\n device: IblRhiOwner,\n factory: IblShaderModuleFactory,\n cubeOutputFormat: TextureFormat = 'rgba16float',\n): Promise<Result<IblPipelineSet, RhiError | IblPipelineError>> {\n const cache = getOrCreateIblCache(scope);\n if (\n cache.equirectToCubePipeline !== undefined &&\n cache.irradiancePipeline !== undefined &&\n cache.prefilterPipeline !== undefined &&\n cache.brdfLutPipeline !== undefined\n ) {\n return ok({\n equirectToCubePipeline: cache.equirectToCubePipeline,\n irradiancePipeline: cache.irradiancePipeline,\n prefilterPipeline: cache.prefilterPipeline,\n brdfLutPipeline: cache.brdfLutPipeline,\n });\n }\n // Keep the output format on the per-device cache so the four pipelines and\n // their lazily-created side textures cannot drift. WebGL2 may need the\n // renderable rgba8 fallback even when the source equirect remains float.\n const outputFormat = cubeOutputFormat;\n cache.outputFormat = outputFormat;\n\n const composed = iblComposedShadersCache;\n // Mock-device path: factory returns synthetic modules. Both production\n // (composed) and unit-test (placeholder code) paths converge here.\n const fallbackCode = '@vertex fn vs() -> @builtin(position) vec4<f32> { return vec4<f32>(0.0); }';\n const src = composed ?? {\n equirectToCube: fallbackCode,\n irradiance: fallbackCode,\n prefilter: fallbackCode,\n brdfLut: fallbackCode,\n };\n\n const modules = await Promise.all([\n factory(device, { code: src.equirectToCube, label: 'ibl-equirect-to-cube' }),\n factory(device, { code: src.irradiance, label: 'ibl-irradiance' }),\n factory(device, { code: src.prefilter, label: 'ibl-prefilter' }),\n factory(device, { code: src.brdfLut, label: 'ibl-brdf-lut' }),\n ]);\n for (const m of modules) {\n if (!m.ok) return err(m.error);\n }\n const shaderModules = modules.flatMap((module) => (module.ok ? [module.value] : []));\n if (shaderModules.length !== 4) {\n return err(iblPipelineError('shader-modules', 'ibl-shader-module-missing'));\n }\n const [mEq, mIr, mPr, mBr] = shaderModules;\n if (mEq === undefined || mIr === undefined || mPr === undefined || mBr === undefined) {\n return err(iblPipelineError('shader-modules', 'ibl-shader-module-missing'));\n }\n\n // D-9: faceUniforms BGL shared across 3 pipelines (equirect / irradiance /\n // prefilter). The prefilter additionally needs binding(1) for prefUniforms;\n // we keep a separate BGL for the prefilter group(0) to honour the WGSL\n // declaration in ibl-prefilter.wgsl.\n const faceBgl = device.createBindGroupLayout({\n label: 'ibl-face-uniforms-bgl',\n entries: [{ binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } }],\n });\n if (!faceBgl.ok) return err(faceBgl.error);\n cache.faceUniformsBgl = faceBgl.value;\n\n const prefilterGroup0 = device.createBindGroupLayout({\n label: 'ibl-prefilter-group0-bgl',\n entries: [\n { binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } },\n { binding: 1, visibility: GPU_SHADER_STAGE_FRAGMENT, buffer: { type: 'uniform' } },\n ],\n });\n if (!prefilterGroup0.ok) return err(prefilterGroup0.error);\n cache.prefilterGroup0Bgl = prefilterGroup0.value;\n\n const equirectGroup1 = device.createBindGroupLayout({\n label: 'ibl-equirect-group1-bgl',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n ],\n });\n if (!equirectGroup1.ok) return err(equirectGroup1.error);\n cache.equirectGroup1Bgl = equirectGroup1.value;\n\n const cubeGroup1 = device.createBindGroupLayout({\n label: 'ibl-cube-group1-bgl',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: 'cube' },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n ],\n });\n if (!cubeGroup1.ok) return err(cubeGroup1.error);\n cache.cubeGroup1Bgl = cubeGroup1.value;\n\n // Pipeline layouts.\n const equirectLayout = device.createPipelineLayout({\n label: 'ibl-equirect-pipeline-layout',\n bindGroupLayouts: [faceBgl.value, equirectGroup1.value],\n });\n if (!equirectLayout.ok) return err(equirectLayout.error);\n const irradianceLayout = device.createPipelineLayout({\n label: 'ibl-irradiance-pipeline-layout',\n bindGroupLayouts: [faceBgl.value, cubeGroup1.value],\n });\n if (!irradianceLayout.ok) return err(irradianceLayout.error);\n const prefilterLayout = device.createPipelineLayout({\n label: 'ibl-prefilter-pipeline-layout',\n bindGroupLayouts: [prefilterGroup0.value, cubeGroup1.value],\n });\n if (!prefilterLayout.ok) return err(prefilterLayout.error);\n const brdfLutLayout = device.createPipelineLayout({\n label: 'ibl-brdf-lut-pipeline-layout',\n bindGroupLayouts: [],\n });\n if (!brdfLutLayout.ok) return err(brdfLutLayout.error);\n\n const vertexLayout3F = {\n arrayStride: 12,\n attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' as const }],\n };\n\n const pipeEquirect = device.createRenderPipeline({\n label: 'ibl-equirect-to-cube-pipeline',\n layout: equirectLayout.value,\n vertex: { module: mEq, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },\n fragment: {\n module: mEq,\n entryPoint: 'equirectToCube_fs',\n targets: [{ format: cubeOutputFormat }],\n },\n primitive: { topology: 'triangle-list', cullMode: 'none' },\n });\n if (!pipeEquirect.ok) return err(pipeEquirect.error);\n cache.equirectToCubePipeline = pipeEquirect.value;\n\n const pipeIrradiance = device.createRenderPipeline({\n label: 'ibl-irradiance-pipeline',\n layout: irradianceLayout.value,\n vertex: { module: mIr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },\n fragment: {\n module: mIr,\n entryPoint: 'irradianceConvolve_fs',\n targets: [{ format: cubeOutputFormat }],\n },\n primitive: { topology: 'triangle-list', cullMode: 'none' },\n });\n if (!pipeIrradiance.ok) return err(pipeIrradiance.error);\n cache.irradiancePipeline = pipeIrradiance.value;\n\n const pipePrefilter = device.createRenderPipeline({\n label: 'ibl-prefilter-pipeline',\n layout: prefilterLayout.value,\n vertex: { module: mPr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },\n fragment: {\n module: mPr,\n entryPoint: 'prefilterEnv_fs',\n targets: [{ format: cubeOutputFormat }],\n },\n primitive: { topology: 'triangle-list', cullMode: 'none' },\n });\n if (!pipePrefilter.ok) return err(pipePrefilter.error);\n cache.prefilterPipeline = pipePrefilter.value;\n\n const pipeBrdfLut = device.createRenderPipeline({\n label: 'ibl-brdf-lut-pipeline',\n layout: brdfLutLayout.value,\n vertex: { module: mBr, entryPoint: 'fullscreen_vs', buffers: [] },\n fragment: {\n module: mBr,\n entryPoint: 'brdfLutBake_fs',\n targets: [{ format: cubeOutputFormat }],\n },\n primitive: { topology: 'triangle-list', cullMode: 'none' },\n });\n if (!pipeBrdfLut.ok) return err(pipeBrdfLut.error);\n cache.brdfLutPipeline = pipeBrdfLut.value;\n\n return ok({\n equirectToCubePipeline: pipeEquirect.value,\n irradiancePipeline: pipeIrradiance.value,\n prefilterPipeline: pipePrefilter.value,\n brdfLutPipeline: pipeBrdfLut.value,\n });\n}\n\nfunction iblPipelineError(\n stage: string,\n code: IblPipelineError['code'],\n cause?: RhiError,\n): IblPipelineError {\n return {\n code,\n expected: `${stage} completed through the RHI Result contract`,\n hint: `inspect the ${stage} RHI error before retrying IBL pipeline creation`,\n detail: { stage, ...(cause === undefined ? {} : { rhiCode: cause.code }) },\n };\n}\n\n// ─── M3.5 t53: runIblPrecompute (4-pass dispatch + queue.submit) ─────────────\n\n/**\n * Options consumed by runIblPrecompute. The caller (the internal\n * GpuResidencyCache equirect-to-cubemap projection) provides the equirect input\n * + cubemap target GPU resources; the face-uniform / prefilter-uniform buffers\n * come from the t55 helpers.\n */\nexport interface RunIblPrecomputeOptions {\n readonly scope: DeviceScope;\n readonly device: IblRhiOwner;\n readonly equirectGpuTex: Texture;\n readonly equirectView: TextureView;\n readonly cubeGpuTex: Texture;\n readonly cubeView: TextureView;\n readonly cubeFaceViews: ReadonlyArray<TextureView>;\n readonly faceUniformsBuffer: Buffer;\n readonly prefilterUniformsBuffer: Buffer;\n readonly cubeVertexBuffer: Buffer;\n}\n\nexport interface IblPrecomputeError {\n readonly code: 'ibl-precompute-not-dispatched';\n readonly expected: string;\n readonly hint: string;\n readonly detail?: { readonly stage: string; readonly rhiCode?: RhiError['code'] };\n}\n\n/**\n * Execute the 4 IBL precompute passes (equirect-to-cube / irradiance /\n * prefilter / brdf-lut) in a single CommandEncoder and submit.\n *\n * Counter invariant (AC-20, plan D-7 / N-3): the\n * `irradiance/prefilter/brdfLut BakeCount` counters are incremented\n * AFTER queue.submit returns. If submit throws or returns Result.err, the\n * counters stay at 0 -- this is the prime safety guard against the\n * round-1 \"counter += 1 as dispatch proxy\" anti-pattern.\n *\n * Returns Result.err with code='ibl-precompute-not-dispatched' when the\n * underlying device lacks queue.submit or one of the 4 pipelines was not\n * created (createIblPipelines must run first).\n */\nexport function runIblPrecompute(\n opts: RunIblPrecomputeOptions,\n): Result<{ submitted: boolean }, IblPrecomputeError> {\n const { device, scope } = opts;\n const cache = getOrCreateIblCache(scope);\n const outputFormat = cache.outputFormat ?? 'rgba16float';\n\n if (\n cache.equirectToCubePipeline === undefined ||\n cache.irradiancePipeline === undefined ||\n cache.prefilterPipeline === undefined ||\n cache.brdfLutPipeline === undefined\n ) {\n return err({\n code: 'ibl-precompute-not-dispatched',\n expected: '4 IBL pipelines created via createIblPipelines',\n hint: 'check IblPipelineCache.createIblPipelines was called before runIblPrecompute; counters must not increment before queue.submit',\n detail: { stage: 'pipeline-cache' },\n });\n }\n\n // Allocate side textures (irradiance / prefilter / brdf-lut) lazily.\n // M5-amend Bug 1: dawn readback (t51 + reference baker) copies the\n // side textures back to a buffer via copyTextureToBuffer, which\n // requires the TextureUsage::CopySrc bit on the source. Without it\n // Dawn fails-fast \"usage doesn't include CopySrc\".\n\n if (cache.irradianceTexture === undefined) {\n const textureResult = device.createTexture({\n label: 'ibl-irradiance-cube',\n size: { width: IRRADIANCE_SIZE, height: IRRADIANCE_SIZE, depthOrArrayLayers: 6 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: outputFormat,\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC,\n viewFormats: [],\n textureBindingViewDimension: undefined,\n });\n if (!textureResult.ok) return err(badAlloc('irradiance-texture', textureResult.error));\n cache.irradianceTexture = textureResult.value;\n const cubeViewResult = device.createTextureView(textureResult.value, {\n label: 'ibl-irradiance-cube-view',\n dimension: 'cube',\n arrayLayerCount: 6,\n });\n if (!cubeViewResult.ok) return err(badAlloc('irradiance-view', cubeViewResult.error));\n cache.irradianceView = cubeViewResult.value;\n const faceViews: TextureView[] = [];\n for (let f = 0; f < 6; f++) {\n const viewResult = device.createTextureView(textureResult.value, {\n label: `ibl-irradiance-face-${f}`,\n dimension: '2d',\n baseArrayLayer: f,\n arrayLayerCount: 1,\n });\n if (!viewResult.ok) return err(badAlloc('irradiance-face-view', viewResult.error));\n faceViews.push(viewResult.value);\n }\n cache.irradianceFaceViews = faceViews;\n }\n\n if (cache.prefilterTexture === undefined) {\n const textureResult = device.createTexture({\n label: 'ibl-prefilter-cube',\n size: { width: PREFILTER_SIZE, height: PREFILTER_SIZE, depthOrArrayLayers: 6 },\n mipLevelCount: PREFILTER_MIP_LEVELS,\n sampleCount: 1,\n dimension: '2d',\n format: outputFormat,\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC,\n viewFormats: [],\n textureBindingViewDimension: undefined,\n });\n if (!textureResult.ok) return err(badAlloc('prefilter-texture', textureResult.error));\n cache.prefilterTexture = textureResult.value;\n const cubeViewResult = device.createTextureView(textureResult.value, {\n label: 'ibl-prefilter-cube-view',\n dimension: 'cube',\n arrayLayerCount: 6,\n baseMipLevel: 0,\n mipLevelCount: PREFILTER_MIP_LEVELS,\n });\n if (!cubeViewResult.ok) return err(badAlloc('prefilter-view', cubeViewResult.error));\n cache.prefilterView = cubeViewResult.value;\n const mipViews: TextureView[][] = [];\n for (let m = 0; m < PREFILTER_MIP_LEVELS; m++) {\n const faces: TextureView[] = [];\n for (let f = 0; f < 6; f++) {\n const viewResult = device.createTextureView(textureResult.value, {\n label: `ibl-prefilter-mip${m}-face${f}`,\n dimension: '2d',\n baseMipLevel: m,\n mipLevelCount: 1,\n baseArrayLayer: f,\n arrayLayerCount: 1,\n });\n if (!viewResult.ok) return err(badAlloc('prefilter-face-view', viewResult.error));\n faces.push(viewResult.value);\n }\n mipViews.push(faces);\n }\n cache.prefilterFaceViewsByMip = mipViews;\n }\n\n if (cache.brdfLutTexture === undefined) {\n const textureResult = device.createTexture({\n label: 'ibl-brdf-lut',\n size: { width: BRDF_LUT_SIZE, height: BRDF_LUT_SIZE, depthOrArrayLayers: 1 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: outputFormat,\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC,\n viewFormats: [],\n textureBindingViewDimension: undefined,\n });\n if (!textureResult.ok) return err(badAlloc('brdf-lut-texture', textureResult.error));\n cache.brdfLutTexture = textureResult.value;\n const viewResult = device.createTextureView(textureResult.value, {\n label: 'ibl-brdf-lut-view',\n dimension: '2d',\n });\n if (!viewResult.ok) return err(badAlloc('brdf-lut-view', viewResult.error));\n cache.brdfLutView = viewResult.value;\n }\n\n // Shared sampler (filtering, linear-linear).\n // U=repeat because equirect wraps horizontally (atan2 seam at ±π);\n // V=clamp because equirect poles are clamped vertically.\n const samplerResult = device.createSampler({\n label: 'ibl-precompute-sampler',\n magFilter: 'linear',\n minFilter: 'linear',\n mipmapFilter: 'linear',\n addressModeU: 'repeat',\n addressModeV: 'clamp-to-edge',\n addressModeW: 'clamp-to-edge',\n });\n if (!samplerResult.ok) return err(badAlloc('sampler', samplerResult.error));\n const sampler: Sampler = samplerResult.value;\n\n const encoderResult = device.createCommandEncoder({ label: 'ibl-precompute-encoder' });\n if (!encoderResult.ok) return err(badAlloc('encoder', encoderResult.error));\n const encoder: RhiCommandEncoder = encoderResult.value;\n\n const faceUniformsBgl = cache.faceUniformsBgl;\n const equirectGroup1Bgl = cache.equirectGroup1Bgl;\n const cubeGroup1Bgl = cache.cubeGroup1Bgl;\n const prefilterGroup0Bgl = cache.prefilterGroup0Bgl;\n const equirectPipeline = cache.equirectToCubePipeline;\n const irradiancePipeline = cache.irradiancePipeline;\n const prefilterPipeline = cache.prefilterPipeline;\n const brdfLutPipeline = cache.brdfLutPipeline;\n const irrFaceViews = cache.irradianceFaceViews;\n const prefMipViews = cache.prefilterFaceViewsByMip;\n const brdfLutView = cache.brdfLutView;\n if (\n faceUniformsBgl === undefined ||\n equirectGroup1Bgl === undefined ||\n cubeGroup1Bgl === undefined ||\n prefilterGroup0Bgl === undefined ||\n equirectPipeline === undefined ||\n irradiancePipeline === undefined ||\n prefilterPipeline === undefined ||\n brdfLutPipeline === undefined ||\n irrFaceViews === undefined ||\n prefMipViews === undefined ||\n brdfLutView === undefined\n ) {\n return err(badAlloc('ibl-cache-resources'));\n }\n\n // Bind group: equirect group(1).\n const equirectBgResult = device.createBindGroup({\n label: 'ibl-equirect-bg',\n layout: equirectGroup1Bgl,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: opts.equirectView } },\n { binding: 1, resource: { kind: 'sampler', value: sampler } },\n ],\n });\n if (!equirectBgResult.ok) return err(badAlloc('equirect-bg', equirectBgResult.error));\n const equirectBg: BindGroup = equirectBgResult.value;\n\n // Bind group: cube group(1) for irradiance + prefilter.\n const cubeBgResult = device.createBindGroup({\n label: 'ibl-cube-bg',\n layout: cubeGroup1Bgl,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: opts.cubeView } },\n { binding: 1, resource: { kind: 'sampler', value: sampler } },\n ],\n });\n if (!cubeBgResult.ok) return err(badAlloc('cube-bg', cubeBgResult.error));\n const cubeBg: BindGroup = cubeBgResult.value;\n\n // (a) equirect-to-cube: 6 face draws.\n const cubeFaceViews = opts.cubeFaceViews;\n for (let face = 0; face < 6; face++) {\n const cubeFaceView = cubeFaceViews[face];\n if (cubeFaceView === undefined) return err(badAlloc('cube-face-view'));\n const pass: RhiRenderPassEncoder = encoder.beginRenderPass({\n label: 'ibl-equirect-to-cube',\n colorAttachments: [\n {\n view: cubeFaceView,\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n });\n // Face uniform: dynamic offset = face * 256.\n const faceBgResult = device.createBindGroup({\n label: `ibl-face-bg-${face}`,\n layout: faceUniformsBgl,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: opts.faceUniformsBuffer,\n offset: face * 256,\n size: 64,\n },\n },\n },\n ],\n });\n if (!faceBgResult.ok) return err(badAlloc('face-bg', faceBgResult.error));\n pass.setPipeline(equirectPipeline);\n pass.setBindGroup(0, faceBgResult.value);\n pass.setBindGroup(1, equirectBg);\n pass.setVertexBuffer(0, opts.cubeVertexBuffer);\n pass.draw(6, 1, face * 6, 0);\n pass.end();\n }\n\n // (b) irradiance convolve: 6 face draws.\n for (let face = 0; face < 6; face++) {\n const irrFaceView = irrFaceViews[face];\n if (irrFaceView === undefined) return err(badAlloc('irradiance-face-view'));\n const pass: RhiRenderPassEncoder = encoder.beginRenderPass({\n label: 'ibl-irradiance',\n colorAttachments: [\n {\n view: irrFaceView,\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n });\n const faceBgResult = device.createBindGroup({\n label: `ibl-irr-face-bg-${face}`,\n layout: faceUniformsBgl,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: opts.faceUniformsBuffer,\n offset: face * 256,\n size: 64,\n },\n },\n },\n ],\n });\n if (!faceBgResult.ok) return err(badAlloc('irr-face-bg', faceBgResult.error));\n pass.setPipeline(irradiancePipeline);\n pass.setBindGroup(0, faceBgResult.value);\n pass.setBindGroup(1, cubeBg);\n pass.setVertexBuffer(0, opts.cubeVertexBuffer);\n pass.draw(6, 1, face * 6, 0);\n pass.end();\n }\n\n // (c) prefilter env: 5 mips x 6 faces = 30 sub-passes.\n for (let mip = 0; mip < PREFILTER_MIP_LEVELS; mip++) {\n const mipFaceViews = prefMipViews[mip];\n if (mipFaceViews === undefined) return err(badAlloc('prefilter-mip-views'));\n for (let face = 0; face < 6; face++) {\n const subIdx = mip * 6 + face;\n const mipFaceView = mipFaceViews[face];\n if (mipFaceView === undefined) return err(badAlloc('prefilter-face-view'));\n const pass: RhiRenderPassEncoder = encoder.beginRenderPass({\n label: 'ibl-prefilter',\n colorAttachments: [\n {\n view: mipFaceView,\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n });\n const bgResult = device.createBindGroup({\n label: `ibl-pref-bg-${subIdx}`,\n layout: prefilterGroup0Bgl,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: opts.faceUniformsBuffer,\n offset: face * 256,\n size: 64,\n },\n },\n },\n {\n binding: 1,\n resource: {\n kind: 'buffer',\n value: {\n buffer: opts.prefilterUniformsBuffer,\n offset: subIdx * 256,\n size: 16,\n },\n },\n },\n ],\n });\n if (!bgResult.ok) return err(badAlloc('pref-bg', bgResult.error));\n pass.setPipeline(prefilterPipeline);\n pass.setBindGroup(0, bgResult.value);\n pass.setBindGroup(1, cubeBg);\n pass.setVertexBuffer(0, opts.cubeVertexBuffer);\n pass.draw(6, 1, face * 6, 0);\n pass.end();\n }\n }\n\n // (d) brdf-lut: fullscreen triangle.\n {\n const pass: RhiRenderPassEncoder = encoder.beginRenderPass({\n label: 'ibl-brdf-lut',\n colorAttachments: [\n {\n view: brdfLutView,\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n });\n pass.setPipeline(brdfLutPipeline);\n pass.draw(3, 1, 0, 0);\n pass.end();\n }\n\n // Finish + submit. Counter increments are STRICTLY after submit; if\n // submit throws or fails, counters stay at 0 (AC-20 critical invariant).\n const finishRes = encoder.finish();\n if (!finishRes.ok) return err(badAlloc('finish', finishRes.error));\n const cmdBuffer: CommandBuffer = finishRes.value;\n const submitRes = device.queue.submit([cmdBuffer]);\n if (!submitRes.ok) return err(badAlloc('queue.submit', submitRes.error));\n\n // POST-SUBMIT counter increments (AC-20).\n cache.irradianceBakeCount += 1;\n cache.prefilterBakeCount += 1;\n cache.brdfLutBakeCount += 1;\n\n return ok({ submitted: true });\n}\n\n// Local helper -- structured error payload shared across allocation paths.\nfunction badAlloc(stage: string, cause?: RhiError): IblPrecomputeError {\n return {\n code: 'ibl-precompute-not-dispatched',\n expected: `${stage} allocated successfully`,\n hint: `check the RHI Result for ${stage}; counters must not increment before queue.submit`,\n ...(cause === undefined ? {} : { detail: { stage, rhiCode: cause.code } }),\n };\n}\n","import type { PointsLinesExpandedGeometry } from './expansion-cache';\nimport type { PointsLinesRetainedSnapshot } from './snapshot';\n\nexport const POINTS_LINES_MATERIAL_SHADER_ID = 'forgeax::points-lines';\n\nexport type PointsLinesLane = 'direct' | 'clustered' | 'cpu-webgl2';\nexport type PointsLinesBackend = 'webgpu' | 'wgpu-webgl2' | 'null';\n\nexport interface PointsLinesLaneContract {\n readonly lane: PointsLinesLane;\n readonly backend: PointsLinesBackend;\n readonly authoring: 'shared';\n readonly evidence: 'runtime' | 'structural-only';\n readonly material: {\n readonly source: 'MaterialAsset';\n readonly shaderId: typeof POINTS_LINES_MATERIAL_SHADER_ID;\n readonly shadingModel: 'unlit';\n readonly clusteredLighting: false;\n readonly lit: false;\n };\n readonly graph: {\n readonly additionalAttachments: 0;\n readonly additionalPasses: 0;\n };\n readonly shadowDrawCount: 0;\n readonly capabilities: {\n readonly compute: false;\n readonly storage: false;\n readonly indirect: false;\n };\n}\n\nexport interface PointsLinesRecordPlan {\n readonly lane: PointsLinesLane;\n readonly backend: PointsLinesBackend;\n readonly materialShaderId: typeof POINTS_LINES_MATERIAL_SHADER_ID;\n readonly component: 'Points' | 'Lines';\n readonly meshGeneration: number;\n readonly materialGeneration: number;\n readonly vertexCount: number;\n readonly indexCount: number;\n readonly drawCount: 0 | 1;\n readonly shadowDrawCount: 0;\n readonly conservativeMarginPx: number;\n readonly graph: PointsLinesLaneContract['graph'];\n}\n\n/**\n * Describes the shared lane boundary without selecting a backend in authoring.\n * Every lane uses CPU-uploaded triangle expansion; capability flags therefore\n * stay false, including on WebGPU, and the graph remains the existing pass.\n */\nexport function createPointsLinesLaneContract(\n lane: PointsLinesLane,\n backend: PointsLinesBackend,\n): PointsLinesLaneContract {\n return {\n lane,\n backend,\n authoring: 'shared',\n evidence: backend === 'null' ? 'structural-only' : 'runtime',\n material: {\n source: 'MaterialAsset',\n shaderId: POINTS_LINES_MATERIAL_SHADER_ID,\n shadingModel: 'unlit',\n clusteredLighting: false,\n lit: false,\n },\n graph: { additionalAttachments: 0, additionalPasses: 0 },\n shadowDrawCount: 0,\n capabilities: { compute: false, storage: false, indirect: false },\n };\n}\n\n/**\n * Turns one retained expansion into the bounded draw facts consumed by the\n * existing record pass. The shader expands one quad per point or segment,\n * so the limits are exactly four vertices and six indices per primitive.\n */\nexport function createPointsLinesRecordPlan(\n snapshot: PointsLinesRetainedSnapshot,\n geometry: PointsLinesExpandedGeometry,\n contract: PointsLinesLaneContract,\n): PointsLinesRecordPlan {\n const primitiveCount = geometry.pointCount + geometry.segmentCount;\n const visible = snapshot.visible && primitiveCount > 0;\n const conservativeMarginPx =\n snapshot.style?.kind === 'points'\n ? snapshot.style.sizePx * 0.5\n : (snapshot.style?.widthPx ?? 0) * 0.5;\n return {\n lane: contract.lane,\n backend: contract.backend,\n materialShaderId: POINTS_LINES_MATERIAL_SHADER_ID,\n component: geometry.component,\n meshGeneration: snapshot.meshGeneration,\n materialGeneration: snapshot.materialGeneration,\n vertexCount: primitiveCount * 4,\n indexCount: primitiveCount * 6,\n drawCount: visible ? 1 : 0,\n shadowDrawCount: 0,\n conservativeMarginPx,\n graph: contract.graph,\n };\n}\n\nexport interface PointsLinesLaneAdapter {\n readonly contract: PointsLinesLaneContract;\n createRecordPlan(\n snapshot: PointsLinesRetainedSnapshot,\n geometry: PointsLinesExpandedGeometry,\n ): PointsLinesRecordPlan;\n}\n\nexport function createPointsLinesLaneAdapter(\n lane: PointsLinesLane,\n backend: PointsLinesBackend,\n): PointsLinesLaneAdapter {\n const contract = createPointsLinesLaneContract(lane, backend);\n return {\n contract,\n createRecordPlan: (snapshot, geometry) =>\n createPointsLinesRecordPlan(snapshot, geometry, contract),\n };\n}\n","// @forgeax/engine-runtime / gpu-resource\n//\n// feat-20260612-rhi-destroy-renderer-dispose-gpu-lifecycle / M2 / w7 + w8.\n//\n// Runtime-side wrappers around RHI Buffer / Texture opaque handles that\n// expose an explicit `.destroy()` lifecycle and an `isDestroyed` flag.\n//\n// Design rationale (charter + plan-strategy + architecture-principles):\n//\n// - SSOT (architecture-principles §1): the lifecycle bookkeeping (the\n// \"is this handle destroyed yet?\" fact) lives once in the RHI shim\n// layer (rhi-webgpu device.ts: BUFFER_META_MAP / TEXTURE_META_MAP;\n// rhi-wgpu device.ts: same shape over the wgpu wasm boundary). The\n// runtime wrapper does NOT keep its own destroyed: Set; it forwards\n// to `device.destroyBuffer(handle)` / `device.destroyTexture(handle)`\n// and lets the RHI shim be the authority. The local `destroyed`\n// boolean is a derived view (architecture-principles §2 Derive,\n// Don't Duplicate) for the synchronous `isDestroyed` getter --\n// flipped on the success branch of the forward, never on the err\n// branch (so a second destroy preserves the prior `true`).\n//\n// - Concept compression (charter F1 / AGENTS.md design axiom): a\n// single union `type GpuResource = GpuBuffer | GpuTexture` covers\n// both buffer and texture lifecycles so AI-user-facing code that\n// just wants \"a GPU resource I need to dispose\" reaches one\n// symbol. Parallel classes (not a runtime-tagged generic\n// `GpuResource<'buffer' | 'texture'>`) so the shape mirrors the\n// RHI opaque-handle taxonomy verbatim and TS narrowing on\n// instanceof / `'data' in r` keeps each branch typed end-to-end\n// (plan-strategy D-2).\n//\n// - v1 single-owner immortal (requirements §Constraints 8): no refcount,\n// no shared ownership, no move semantics. The wrapper holds the\n// handle once; whoever constructed it disposes it. A future\n// refcount layer (if needed) wraps GpuResource externally without\n// re-entering this file.\n//\n// - Plain boolean isDestroyed (plan-strategy D-5): no typed-state\n// narrowing (i.e. no `Live<GpuBuffer>` / `Destroyed<GpuBuffer>`\n// compile-time partition). The check happens at runtime via the\n// getter; the RHI fail-fast on second destroy is the structural\n// guard. Keeps the public type surface flat (charter F1: one\n// symbol, not three states).\n//\n// - RHI stays spec-aligned and opaque-handle-only (requirements\n// §Constraints 3): GpuResource is a runtime concept; the RHI package\n// exports no wrapper class.\n//\n// Failure paths (forwarded verbatim from RhiDevice):\n// - second `.destroy()` on the same wrapper -> `Result.err({ code:\n// 'destroy-after-destroy', ... })` (RHI errors.ts §RhiErrorCode;\n// introduced in feat-20260612 M1 / w1).\n\nimport type { Buffer, Result, RhiDevice, RhiError, Texture } from '@forgeax/engine-rhi';\n\n/**\n * Runtime wrapper around an RHI `Buffer` opaque handle that exposes\n * an explicit `.destroy()` lifecycle.\n *\n * Holds the device by reference (no clone); the device's own lifetime\n * outlives the buffer. After `.destroy()` returns ok, `isDestroyed`\n * flips to true; a second `.destroy()` returns err code\n * `'destroy-after-destroy'` forwarded from `device.destroyBuffer(...)`.\n *\n * @example\n * import { GpuBuffer } from './gpu-resource';\n * const created = device.createBuffer({ size: 64, usage: GPUBufferUsage.STORAGE });\n * if (!created.ok) return;\n * const gpuBuf = new GpuBuffer(device, created.value);\n * // ... use gpuBuf.handle in RHI calls ...\n * const r = gpuBuf.destroy();\n * if (!r.ok) {\n * // r.error.code is one of the RhiErrorCode union members,\n * // typically 'destroy-after-destroy' on a stale handle.\n * }\n */\nexport class GpuBuffer {\n readonly device: RhiDevice;\n readonly handle: Buffer;\n // SSOT note: the canonical destroyed: boolean lives on the RHI shim's\n // BUFFER_META_MAP. This local flag is a derived view written only on\n // the success branch of `device.destroyBuffer(...)`; charter §F1.\n private destroyed = false;\n\n constructor(device: RhiDevice, handle: Buffer) {\n this.device = device;\n this.handle = handle;\n }\n\n get isDestroyed(): boolean {\n return this.destroyed;\n }\n\n /**\n * Destroy the underlying GPU buffer. Forwards to\n * `device.destroyBuffer(handle)`; on ok flips `isDestroyed` to true,\n * on err leaves the flag unchanged so a downstream second destroy\n * still surfaces the underlying RHI fail-fast.\n */\n destroy(): Result<void, RhiError> {\n const r = this.device.destroyBuffer(this.handle);\n if (r.ok) {\n this.destroyed = true;\n }\n return r;\n }\n}\n\n/**\n * Runtime wrapper around an RHI `Texture` opaque handle that exposes\n * an explicit `.destroy()` lifecycle. Mirrors `GpuBuffer` exactly --\n * the only difference is the underlying RHI surface\n * (`device.destroyTexture` instead of `device.destroyBuffer`) and the\n * handle brand. Same SSOT rationale: the destroyed bookkeeping lives\n * on the RHI shim's TEXTURE_META_MAP; the local flag is a derived view.\n *\n * @example\n * import { GpuTexture } from './gpu-resource';\n * const r = device.createTexture({ size: [w, h, 1], format: 'rgba8unorm', usage: ... });\n * if (!r.ok) return;\n * const gpuTex = new GpuTexture(device, r.value);\n * // ... use gpuTex.handle in RHI calls ...\n * gpuTex.destroy();\n */\nexport class GpuTexture {\n readonly device: RhiDevice;\n readonly handle: Texture;\n private destroyed = false;\n\n constructor(device: RhiDevice, handle: Texture) {\n this.device = device;\n this.handle = handle;\n }\n\n get isDestroyed(): boolean {\n return this.destroyed;\n }\n\n /**\n * Destroy the underlying GPU texture. Forwards to\n * `device.destroyTexture(handle)`; ok branch sets `isDestroyed=true`.\n */\n destroy(): Result<void, RhiError> {\n const r = this.device.destroyTexture(this.handle);\n if (r.ok) {\n this.destroyed = true;\n }\n return r;\n }\n}\n\n/**\n * Union of runtime-managed GPU resources requiring explicit\n * `.destroy()`. AI-user-facing code that needs to dispose \"a GPU\n * resource\" types its parameter as `GpuResource` and lets TS narrow\n * via `instanceof GpuBuffer / GpuTexture` if branch-specific access\n * is required. Charter F1 single-entry indexability.\n */\nexport type GpuResource = GpuBuffer | GpuTexture;\n","// skylight-bind-group.ts -- Skylight resources merged into @group(1) PBR\n// material BGL (binding 7..13) + fallback identity resource bundle. The\n// complete Standard material group appends transmission entries.\n//\n// Plan-strategy D-5 (round-4 REVISED): the round-2 stand-alone @group(4)\n// Skylight BindGroupLayout collided with WebGPU's default maxBindGroups=4\n// limit, blocking pbr-pl pipeline-layout creation in chrome-beta. Round-4\n// rewrites the contract: Skylight 7 entries are **appended** to the\n// existing PBR material BindGroupLayout at bindings 7..13; pipeline layout\n// stays at 4 slots `[view, material, mesh, instances]`; unlit pipeline is\n// untouched (it uses its own material BGL).\n//\n// Surface (M2 round-4 / t40 amend):\n// - mergeSkylightIntoMaterialBgl(materialBglEntries): given the existing\n// 7 PBR material BindGroupLayout entries (binding 0..6), returns the\n// merged 14-entry array with Skylight resources at binding 7..13\n// [irrTex, irrSampler, prefTex, prefSampler, brdfTex, brdfSampler,\n// uniform { intensity: f32 }]. The merge is a pure function -- caller\n// (createRenderer) is responsible for passing the result to\n// `device.createBindGroupLayout`.\n// - assembleMaterialWithSkylightEntries(materialEntries, skylightResources):\n// given the existing material BindGroupEntry values + a skylight\n// resource bundle (active or fallback), returns the merged material\n// array with the engine-owned transmission pair at the end, suitable for\n// `device.createBindGroup`. Charter P5 minimal\n// surface: this helper does NOT allocate samplers/textures itself.\n// - createSkylightFallback(device, queue): allocate a 1x1 white\n// irradiance/prefilter cube pair + a 1x1 BRDF approximation + intensity=0 uniform\n// buffer + a shared linear/clamp sampler. Returns the resource bundle\n// so createRenderer can wire it into PipelineState.skylightFallback;\n// no stand-alone bindGroup is created (that was the round-2 shape).\n//\n// All resources write into PipelineState.skylightFallback so the M4\n// recordFrame branch (Skylight present vs absent) selects active vs\n// fallback resources when assembling the PBR material BindGroup\n// (charter P4 consistent abstraction -- one BG layout, one assembly path).\n// The irradiance texture uses the canonical irradianceEOverPi payload semantic;\n// sampling applies the single E/pi normalization at the shader callsite.\n\nimport type {\n BindGroupEntry,\n Buffer,\n Result,\n RhiError,\n Sampler,\n SamplerDescriptor,\n Texture,\n TextureDescriptor,\n TextureView,\n TextureViewDescriptor,\n} from '@forgeax/engine-rhi';\nimport { GPU_SHADER_STAGE_FRAGMENT } from '../gpu-stage';\nimport {\n GPU_TEXTURE_USAGE_COPY_DST,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\nimport { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';\n\n// The rhi shim enforces bytesPerRow % 256 === 0 uniformly (see\n// fallback-white texture upload in createRenderer.ts). Pad each 1x1 face\n// upload to a 256-byte row stride.\nexport const FALLBACK_BYTES_PER_ROW = 256;\n\n// Local alias for the @webgpu/types BindGroupLayoutEntry shape. Used at\n// object-literal push sites below to dodge the AC-08 (j) `as GPU<Type>`\n// grep gate (charter proposition 5 red line for shim leaks); the underlying\n// type is identical to GPUBindGroupLayoutEntry, so byte-level behavior is\n// unchanged. engine-rhi does not yet re-export a BindGroupLayoutEntry alias\n// (the public surface is BindGroupLayoutDescriptor which Picks `entries`);\n// once it does this alias collapses into a direct import.\ntype BglEntry = GPUBindGroupLayoutEntry;\n\n// ─── Device shim shapes ──────────────────────────────────────────────────────\n//\n// We accept a structural subset of RhiDevice so unit tests can pass a\n// mocked device without standing up the full RHI surface. The createRenderer\n// production path passes a real RhiDevice; both satisfy the interface.\n\n/**\n * Minimal RhiDevice subset used by the skylight fallback helper.\n * Mirrors RhiDevice for the methods touched by this module (charter P4\n * narrowest surface -- avoids dragging the full RhiDevice in for tests).\n */\nexport interface SkylightDevice {\n createSampler(desc: SamplerDescriptor): Result<Sampler, RhiError>;\n createTexture(desc: TextureDescriptor): Result<Texture, RhiError>;\n createTextureView(tex: Texture, desc: TextureViewDescriptor): Result<TextureView, RhiError>;\n createBuffer(desc: {\n label?: string | undefined;\n size: number;\n usage: number;\n mappedAtCreation?: boolean | undefined;\n }): Result<Buffer, RhiError>;\n}\n\n/**\n * Minimal queue subset used for fallback resource upload (zero-pixel\n * texture seed + intensity=0 uniform seed).\n */\nexport interface SkylightQueue {\n writeTexture(\n destination: {\n texture: Texture;\n mipLevel?: number;\n origin?: { x: number; y: number; z: number };\n },\n data: ArrayBufferView,\n dataLayout: { offset: number; bytesPerRow: number; rowsPerImage: number },\n size: { width: number; height: number; depthOrArrayLayers: number },\n ): Result<void, RhiError> | unknown;\n writeBuffer(\n buffer: Buffer,\n bufferOffset: number,\n data: ArrayBufferView,\n ): Result<void, RhiError> | unknown;\n}\n\n// ─── Public types ───────────────────────────────────────────────────────────\n\n/**\n * Skylight bind group resources (cube + cube + 2D LUT + intensity uniform).\n * The active set comes from the IblPipelineCache precompute path; the\n * fallback set is the 1x1 zero identity bundle below.\n */\nexport interface SkylightBindGroupResources {\n readonly irradianceView: TextureView;\n readonly irradianceSampler: Sampler;\n readonly prefilterView: TextureView;\n readonly prefilterSampler: Sampler;\n readonly brdfLutView: TextureView;\n readonly brdfLutSampler: Sampler;\n readonly intensityBuffer: Buffer;\n}\n\n/**\n * Fallback resource bundle attached to `PipelineState.skylightFallback`.\n * The M4 round-4 recordFrame branch reads this bundle when\n * `skylightCount === 0` and feeds it through\n * `assembleMaterialWithSkylightEntries` so the PBR material BindGroup\n * binds the same 14-entry layout shape with zero data + intensity=0.\n *\n * No stand-alone `bindGroup` field: the round-2 stand-alone Skylight BG\n * is gone (D-5 round-4); the fallback resources flow into the PBR\n * material BG at binding 7..13.\n */\nexport interface SkylightFallback {\n readonly irradianceTexture: Texture;\n readonly irradianceView: TextureView;\n readonly prefilterTexture: Texture;\n readonly prefilterView: TextureView;\n readonly brdfLutTexture: Texture;\n readonly brdfLutView: TextureView;\n readonly sampler: Sampler;\n readonly intensityBuffer: Buffer;\n}\n\n// ─── Pure merger: BindGroupLayout entries (D-5 round-4) ─────────────────────\n\n/**\n * Append the 7 Skylight BindGroupLayout entries after the existing PBR\n * user-region entries. Pure function -- the\n * caller passes the result to `device.createBindGroupLayout`. Charter P4\n * consistent abstraction: one BGL holds material + Skylight together,\n * no second `@group(4)` allocated.\n *\n * Throws if the input is too short to contain the material UBO plus one\n * sampler/texture pair (defensive guard; mirrors charter P3 explicit failure).\n */\nexport function mergeSkylightIntoMaterialBgl(\n materialBglEntries: readonly GPUBindGroupLayoutEntry[],\n): GPUBindGroupLayoutEntry[] {\n if (materialBglEntries.length < 7) {\n throw new Error(\n `mergeSkylightIntoMaterialBgl: expected at least 7 material BGL entries (PBR layout), got ${materialBglEntries.length}`,\n );\n }\n const merged: GPUBindGroupLayoutEntry[] = [...materialBglEntries];\n const skylightBindingStart = materialBglEntries.length;\n // binding 7: irradianceMap (texture_cube)\n merged.push({\n binding: skylightBindingStart,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: 'cube' },\n } as BglEntry);\n // binding 8: irradianceSampler\n merged.push({\n binding: skylightBindingStart + 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n } as BglEntry);\n // binding 9: prefilterMap (texture_cube)\n merged.push({\n binding: skylightBindingStart + 2,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: 'cube' },\n } as BglEntry);\n // binding 10: prefilterSampler\n merged.push({\n binding: skylightBindingStart + 3,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n } as BglEntry);\n // binding 11: brdfLut (texture_2d)\n merged.push({\n binding: skylightBindingStart + 4,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n } as BglEntry);\n // binding 12: brdfLutSampler\n merged.push({\n binding: skylightBindingStart + 5,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n } as BglEntry);\n // binding 13: uniform { intensity: f32 }\n merged.push({\n binding: skylightBindingStart + 6,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n } as BglEntry);\n return merged;\n}\n\n// ─── Pure merger: BindGroupEntry values (assembly site) ─────────────────────\n\n/**\n * Append the 7 Skylight BindGroupEntry resources (binding 7..13) onto the\n * existing PBR material BindGroupEntry values (binding 0..6). The caller\n * passes the result to `device.createBindGroup` as part of the merged\n * material BG.\n *\n * The skylight argument may be the fallback identity bundle (rendered\n * with ambient=0) or the active IblPipelineCache output bundle. Same\n * call site, same layout shape -- charter P4 + F1 (AI users do not need\n * a `if (hasSkylight)` branch when writing demos).\n */\n/** Engine-owned material transmission injection resources. */\nexport interface TransmissionBindGroupResources {\n readonly sampler: Sampler;\n readonly backdropView?: TextureView | null;\n}\n\n// Lightmap (emissive + occlusion sampler/texture pair x 2) and transmission\n// injection starts are computed from the assembled list length on each push —\n// no hardcoded binding literals.\n\nexport function assembleMaterialWithSkylightEntries(\n materialEntries: readonly BindGroupEntry[],\n skylight: SkylightBindGroupResources,\n transmission?: TransmissionBindGroupResources | undefined,\n): BindGroupEntry[] {\n // IBL injection start = end of the user-region. The user-region IS\n // `materialEntries` (UBO binding 0 + N sampler/texture pairs), so its length\n // is the injection start — was a hardcoded 7, now per-shader (a 4-texture\n // parallax material's user-region is 9 entries, so IBL lands at 9). This\n // mirrors the BGL-side `appendInjection(userRegion, 'ibl')` (D-1 / D-8),\n // which likewise reads `bgl.length`.\n const iblStart = materialEntries.length;\n const result: BindGroupEntry[] = [\n ...materialEntries,\n {\n binding: iblStart,\n resource: { kind: 'textureView', value: skylight.irradianceView },\n },\n {\n binding: iblStart + 1,\n resource: { kind: 'sampler', value: skylight.irradianceSampler },\n },\n {\n binding: iblStart + 2,\n resource: { kind: 'textureView', value: skylight.prefilterView },\n },\n {\n binding: iblStart + 3,\n resource: { kind: 'sampler', value: skylight.prefilterSampler },\n },\n {\n binding: iblStart + 4,\n resource: { kind: 'textureView', value: skylight.brdfLutView },\n },\n {\n binding: iblStart + 5,\n resource: { kind: 'sampler', value: skylight.brdfLutSampler },\n },\n {\n binding: iblStart + 6,\n resource: { kind: 'buffer', value: { buffer: skylight.intensityBuffer } },\n },\n ];\n // Transmission injection is always present after IBL. Non-transmission\n // variants bind the existing Skylight resources as layout-only placeholders;\n // they are not a functional fallback and are never sampled by those shaders.\n const transmissionSampler = transmission?.sampler ?? skylight.irradianceSampler;\n const transmissionView = transmission?.backdropView ?? skylight.brdfLutView;\n const transmissionStart = result.length;\n result.push(\n {\n binding: transmissionStart,\n resource: { kind: 'sampler', value: transmissionSampler },\n },\n {\n binding: transmissionStart + 1,\n resource: { kind: 'textureView', value: transmissionView },\n },\n );\n return result;\n}\n\n// ─── Fallback constructor (createRenderer wires this into pipelineState) ────\n\n/**\n * Allocate the fallback Skylight resource bundle: 1x1 WHITE rgba16float\n * irradiance/prefilter texture_cube pair + 1x1 rg16float BRDF approximation\n * `[1, 0]` + a 16-byte uniform buffer + a single\n * linear / clamp-to-edge sampler reused across all three texture slots.\n *\n * Two regimes share this bundle (the per-frame Skylight uniform selects):\n * - No Skylight entity: render-system-record writes intensity=0, so\n * ambient = whiteIrradiance * kD * albedo * color * 0 == 0\n * -- physically black, no `if (hasSkylight)` shader branch (D-5 round-4).\n * - Skylight with NO cubemap (downstream integration #4): record writes the\n * user's intensity + color, so the WHITE irradiance gives an instant\n * solid-color ambient and a neutral white specular reflection with no\n * async precompute. The 1x1 BRDF approximation is intentionally roughness\n * independent; a real cubemap swaps in the prefiltered IBL views and LUT.\n *\n * No stand-alone BindGroupLayout / BindGroup is created here -- those\n * roles moved into the PBR material BGL factory (D-5 round-4). The\n * caller (createRenderer) feeds the resource handles below through\n * `assembleMaterialWithSkylightEntries` when composing the per-frame\n * material BindGroup.\n */\nexport function createSkylightFallback(\n device: SkylightDevice,\n queue: SkylightQueue,\n): SkylightFallback {\n // One sampler shared across the three texture slots. The PBR material\n // BindGroup still declares 3 separate sampler bindings (D-5 round-4\n // ordering at binding 8/10/12), so we pass the same handle three times\n // in assembleMaterialWithSkylightEntries; WebGPU spec permits sampler\n // reuse across BindGroupEntry slots.\n const samplerResult = device.createSampler({\n label: 'skylight-fallback-sampler',\n magFilter: 'linear',\n minFilter: 'linear',\n mipmapFilter: 'linear',\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n addressModeW: 'clamp-to-edge',\n });\n if (!samplerResult.ok) throw samplerResult.error;\n const sampler = samplerResult.value;\n\n // 1x1 all-zero rgba16float cube (irradiance fallback). depthOrArrayLayers=6\n // gives the texture cube semantics (D-5 fallback shape; testable via\n // createTexture descriptor capture in unit tests).\n const irradianceTexResult = device.createTexture({\n label: 'skylight-fallback-irradiance-cube',\n size: { width: 1, height: 1, depthOrArrayLayers: 6 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'rgba16float',\n usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,\n viewFormats: [],\n textureBindingViewDimension: 'cube',\n });\n if (!irradianceTexResult.ok) throw irradianceTexResult.error;\n const irradianceTexture = irradianceTexResult.value;\n\n // 1x1 white rgba16float cube (prefilter fallback). A Skylight without an\n // equirect is still a white environment, so its specular input must not be\n // black just because the full prefilter bake is unavailable.\n const prefilterTexResult = device.createTexture({\n label: 'skylight-fallback-prefilter-cube',\n size: { width: 1, height: 1, depthOrArrayLayers: 6 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'rgba16float',\n usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,\n viewFormats: [],\n textureBindingViewDimension: 'cube',\n });\n if (!prefilterTexResult.ok) throw prefilterTexResult.error;\n const prefilterTexture = prefilterTexResult.value;\n\n // 1x1 rg16float BRDF approximation (A=1, B=0). This keeps the split-sum\n // specular response non-zero for the white-environment fallback; a real IBL\n // bake replaces it with the roughness/NdotV-dependent LUT.\n const brdfLutTexResult = device.createTexture({\n label: 'skylight-fallback-brdf-lut',\n size: { width: 1, height: 1, depthOrArrayLayers: 1 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'rg16float',\n usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,\n viewFormats: [],\n textureBindingViewDimension: undefined,\n });\n if (!brdfLutTexResult.ok) throw brdfLutTexResult.error;\n const brdfLutTexture = brdfLutTexResult.value;\n\n // 1x1 rgba16float = 8 bytes per pixel; 1x1 rg16float = 4 bytes per pixel.\n // The shim requires bytesPerRow % 256 === 0, so we pad each row to 256 bytes\n // (matches the fallback-white pattern in createRenderer.ts). Destination\n // stays 1x1; only the row stride is padded.\n //\n // A Skylight with no cubemap represents a flat white environment. Both\n // irradiance and prefilter are therefore white (half-float 1.0 = 0x3c00),\n // while the BRDF fallback approximates `A=1, B=0`. Crucially this does NOT\n // light scenes that lack a Skylight: the per-frame Skylight uniform writes\n // intensity 0 when no Skylight entity exists (render-system-record).\n const whitePixel = new Uint8Array(FALLBACK_BYTES_PER_ROW);\n {\n const dv = new DataView(whitePixel.buffer);\n // RGBA half-float 1.0 = 0x3c00 (little-endian) at byte offsets 0,2,4,6.\n dv.setUint16(0, 0x3c00, true);\n dv.setUint16(2, 0x3c00, true);\n dv.setUint16(4, 0x3c00, true);\n dv.setUint16(6, 0x3c00, true);\n }\n const brdfApproxPixel = new Uint8Array(FALLBACK_BYTES_PER_ROW);\n new DataView(brdfApproxPixel.buffer).setUint16(0, 0x3c00, true);\n for (const face of [0, 1, 2, 3, 4, 5]) {\n queue.writeTexture(\n {\n texture: irradianceTexture,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: face },\n },\n whitePixel,\n { offset: 0, bytesPerRow: FALLBACK_BYTES_PER_ROW, rowsPerImage: 1 },\n { width: 1, height: 1, depthOrArrayLayers: 1 },\n );\n queue.writeTexture(\n {\n texture: prefilterTexture,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: face },\n },\n whitePixel,\n { offset: 0, bytesPerRow: FALLBACK_BYTES_PER_ROW, rowsPerImage: 1 },\n { width: 1, height: 1, depthOrArrayLayers: 1 },\n );\n }\n queue.writeTexture(\n {\n texture: brdfLutTexture,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: 0 },\n },\n brdfApproxPixel,\n { offset: 0, bytesPerRow: FALLBACK_BYTES_PER_ROW, rowsPerImage: 1 },\n { width: 1, height: 1, depthOrArrayLayers: 1 },\n );\n\n // Cube views over the depthOrArrayLayers=6 textures so the @group(1)\n // @binding(7,9) texture_cube bindings can sample them.\n const irradianceViewResult = device.createTextureView(irradianceTexture, {\n label: 'skylight-fallback-irradiance-cube-view',\n dimension: 'cube',\n arrayLayerCount: 6,\n });\n if (!irradianceViewResult.ok) throw irradianceViewResult.error;\n const irradianceView = irradianceViewResult.value;\n\n const prefilterViewResult = device.createTextureView(prefilterTexture, {\n label: 'skylight-fallback-prefilter-cube-view',\n dimension: 'cube',\n arrayLayerCount: 6,\n });\n if (!prefilterViewResult.ok) throw prefilterViewResult.error;\n const prefilterView = prefilterViewResult.value;\n\n const brdfLutViewResult = device.createTextureView(brdfLutTexture, {\n label: 'skylight-fallback-brdf-lut-view',\n dimension: '2d',\n });\n if (!brdfLutViewResult.ok) throw brdfLutViewResult.error;\n const brdfLutView = brdfLutViewResult.value;\n\n // intensity=0 uniform. The WGSL struct is two vec4-aligned lanes:\n // [intensity, colorR, colorG, colorB] + [rotation quaternion].\n const intensityBufResult = device.createBuffer({\n label: 'skylight-fallback-intensity',\n size: 32,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n });\n if (!intensityBufResult.ok) throw intensityBufResult.error;\n const intensityBuffer = intensityBufResult.value;\n queue.writeBuffer(intensityBuffer, 0, new Float32Array([0, 0, 0, 0, 0, 0, 0, 1]));\n\n return {\n irradianceTexture,\n irradianceView,\n prefilterTexture,\n prefilterView,\n brdfLutTexture,\n brdfLutView,\n sampler,\n intensityBuffer,\n };\n}\n","// @forgeax/engine-runtime - RenderData projection layer\n// (feat-20260601-device/gpu-residency-extraction M2 / w5).\n//\n// The middle of the three GPU-asset layers: AssetRegistry catalogues CPU asset\n// POD; `deriveRenderData*` PROJECTS a POD into the GPU descriptor a resource\n// build needs; GpuResidencyCache owns device-side resource life/death. These\n// projections are PURE -- they know the asset `kind` but never touch a device\n// (AC-07). The store consumes the descriptor and does the createTexture /\n// createBuffer / writeX work.\n//\n// Coverage is exactly the three GPU-resource kinds (mesh / texture / equirect,\n// the latter projected to a cubemap). Asset kinds with no GPU residency are\n// never projected -- the\n// `ensureResident` miss switch dispatches per-kind with no default, so a fourth\n// GPU-resource kind would surface as a `tsc -b` exhaustiveness error at the\n// switch rather than a silent fallthrough (AC-06).\n\nimport { numMipLevels } from '@forgeax/engine-assets-runtime';\nimport {\n bytesPerRow as blockBytesPerRow,\n blockParamsForFormat,\n isCompressedFormat,\n} from '@forgeax/engine-codec';\nimport {\n deriveVertexLayoutProjection,\n type VertexLayoutProjection,\n} from '@forgeax/engine-geometry';\nimport { err, ok, type Result } from '@forgeax/engine-rhi';\nimport {\n ASSET_ERROR_HINTS,\n type AssetError,\n type MeshAsset,\n type Submesh,\n type TextureAsset,\n} from '@forgeax/engine-types';\nimport {\n GPU_TEXTURE_USAGE_COPY_DST,\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from './gpu-texture-usage';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_INDEX,\n GPU_BUFFER_USAGE_VERTEX,\n} from './gpu-usage';\n\n// AssetError without importing AssetRegistry: build the 4-field surface\n// (.code / .expected / .hint) directly against the @forgeax/engine-types SSOT\n// (charter P5 producer / consumer split; mirrors the store's RuntimeAssetError).\nclass ProjectionAssetError extends Error implements AssetError {\n readonly code: AssetError['code'];\n readonly expected: string;\n readonly hint: string;\n constructor(fields: { code: AssetError['code']; expected: string; hint: string }) {\n super(`[AssetError ${fields.code}] expected: ${fields.expected}; hint: ${fields.hint}`);\n this.name = 'AssetError';\n this.code = fields.code;\n this.expected = fields.expected;\n this.hint = fields.hint;\n }\n}\n\nfunction projectionError(fields: {\n code: AssetError['code'];\n expected: string;\n hint: string;\n}): AssetError {\n return new ProjectionAssetError(fields);\n}\n\n/** Descriptor for a mesh's GPU vertex + index buffers (projected from POD). */\nexport interface MeshRenderData {\n readonly vertexByteLength: number;\n /** Geometry-owned immutable layout facts used by all GPU consumers. */\n readonly layoutProjection: VertexLayoutProjection;\n /** Index byte length padded up to a 4-byte multiple (writeBuffer alignment). */\n readonly indexByteLength: number;\n readonly indexCount: number;\n readonly indexFormat: 'uint16' | 'uint32';\n readonly vertexUsage: number;\n readonly indexUsage: number;\n /**\n * Submeshes from the source MeshAsset, projected verbatim to the GPU store\n * so the record stage can iterate per-submesh draw calls (feat-20260608 M4 / w16).\n * Mirrors MeshAsset.submeshes (readonly Submesh[]) 1:1.\n */\n readonly submeshes: readonly Submesh[];\n}\n\n/** Descriptor for a 2D texture's GPU resource (projected from POD). */\nexport interface TextureRenderData {\n /** Logical width retained for existing projection consumers. */\n readonly width: number;\n /** Logical height retained for existing projection consumers. */\n readonly height: number;\n /** Authored content extent; TextureAsset remains the logical asset SSOT. */\n readonly logicalExtent: TextureExtent;\n /** GPU allocation extent, derived from format + logicalExtent. */\n readonly physicalExtent: TextureExtent;\n /** Maps logical UVs away from block padding. */\n readonly uvScale: readonly [number, number];\n readonly format: GPUTextureFormat;\n readonly mipLevelCount: number;\n readonly usage: number;\n /**\n * Row pitch for the BASE mip (level 0) the store passes to `writeTexture`.\n * Uncompressed: `width * 4` (RGBA8). Block-compressed: the block-padded\n * `ceil(width / blockW) * bytesPerBlock` (feat-20260707 M5 / w35, AC-08).\n * The per-mip layout for a multi-level compressed upload comes from\n * {@link deriveMipUploadLayout}.\n */\n readonly bytesPerRow: number;\n /** True iff `format` is a block-compressed format (drives the store's upload arm). */\n readonly compressed: boolean;\n}\n\nexport interface TextureExtent {\n readonly width: number;\n readonly height: number;\n}\n\n/**\n * The sole logical-content to physical-storage projection for a texture.\n * Block sizes come from codec's format table; no physical dimensions are\n * authored or serialized with TextureAsset.\n */\nexport function deriveTextureExtent(\n format: GPUTextureFormat,\n width: number,\n height: number,\n): {\n readonly logicalExtent: TextureExtent;\n readonly physicalExtent: TextureExtent;\n readonly uvScale: readonly [number, number];\n} {\n const params = blockParamsForFormat(format);\n const physicalWidth = params === null ? width : Math.ceil(width / params.blockW) * params.blockW;\n const physicalHeight =\n params === null ? height : Math.ceil(height / params.blockH) * params.blockH;\n return {\n logicalExtent: { width, height },\n physicalExtent: { width: physicalWidth, height: physicalHeight },\n uvScale: [width / physicalWidth, height / physicalHeight],\n };\n}\n\n/** One mip level's GPU-upload layout (feat-20260707 M5 / w35, AC-08). */\nexport interface MipUploadLevel {\n /** Mip level index (0 = base / largest). */\n readonly level: number;\n /** Logical pixel width of this level (`baseWidth >> level`, min 1). */\n readonly width: number;\n /** Logical pixel height of this level (`baseHeight >> level`, min 1). */\n readonly height: number;\n /** Block-aligned storage dimensions for this logical mip. */\n readonly physicalWidth: number;\n readonly physicalHeight: number;\n /** Logical `writeTexture` copy width; full-subresource copies may end mid-block. */\n readonly copyWidth: number;\n /** Logical `writeTexture` copy height; full-subresource copies may end mid-block. */\n readonly copyHeight: number;\n /** Bytes per compressed row: `ceil(width / blockW) * bytesPerBlock`. */\n readonly bytesPerRow: number;\n /** Block rows: `ceil(height / blockH)` (the writeTexture `rowsPerImage`). */\n readonly rowsPerImage: number;\n /** Byte offset of this level in the mip-major payload (sum of prior levels). */\n readonly byteOffset: number;\n /** Byte length of this level (`bytesPerRow * rowsPerImage`). */\n readonly byteLength: number;\n}\n\n/**\n * Derive the per-mip GPU-upload layout for a block-compressed texture\n * (feat-20260707 M5 / w35, AC-08). Each level pads the pixel width up to a full\n * block (`ceil(width / blockW) * bytesPerBlock`) and counts block rows\n * (`ceil(height / blockH)`); `byteOffset` accumulates the prior levels' byte\n * lengths (mip-major layout). The GPU samples only the valid texel region, so a\n * non-4-multiple size or a 1x1 / 2x2 mip tail pads up to a block without image\n * corruption (t5). Block math is sourced from the codec block table (SSOT --\n * Derive, Don't Duplicate); TextureAsset carries no block fields (F-6).\n *\n * `format` must be a block-compressed format; callers branch on the projection's\n * `compressed` flag first (the uncompressed path uses the linear `width * 4`\n * pitch). Level dimensions floor-halve per mip, clamped to a 1-pixel minimum.\n */\nexport function deriveMipUploadLayout(\n format: GPUTextureFormat,\n baseWidth: number,\n baseHeight: number,\n mipLevelCount: number,\n): readonly MipUploadLevel[] {\n const params = blockParamsForFormat(format);\n if (params === null) return [];\n const levels: MipUploadLevel[] = [];\n let byteOffset = 0;\n for (let level = 0; level < mipLevelCount; level++) {\n const width = Math.max(1, baseWidth >> level);\n const height = Math.max(1, baseHeight >> level);\n const blockCols = Math.ceil(width / params.blockW);\n const blockRows = Math.ceil(height / params.blockH);\n const rowBytes = blockCols * params.bytesPerBlock;\n const byteLength = rowBytes * blockRows;\n levels.push({\n level,\n width,\n height,\n physicalWidth: blockCols * params.blockW,\n physicalHeight: blockRows * params.blockH,\n copyWidth: blockCols * params.blockW,\n copyHeight: blockRows * params.blockH,\n bytesPerRow: rowBytes,\n rowsPerImage: blockRows,\n byteOffset,\n byteLength,\n });\n byteOffset += byteLength;\n }\n return levels;\n}\n\n/** Descriptor for a cubemap built from an equirect source (projected from POD). */\nexport interface CubeRenderData {\n /** Square cube face edge length (== source equirect height). */\n readonly cubeFaceSize: number;\n /** Filterable output format the IBL pipeline BGL expects. */\n readonly outputFormat: 'rgba16float';\n /** True when the source is rgba32float and the store must pack to rgba16float. */\n readonly needsHalfConversion: boolean;\n readonly cubeUsage: number;\n}\n\n/**\n * Project a `MeshAsset` POD into its GPU vertex / index buffer descriptor.\n * Pure: computes byte lengths, the 4-byte-aligned index size, index format,\n * and the buffer usage flags the store's `createBuffer` calls need.\n */\nexport function deriveRenderDataMesh(mesh: MeshAsset): Result<MeshRenderData, AssetError> {\n // Vertex-only meshes (no `indices`) take the non-indexed draw path. Their\n // index-side fields are zeroed; `indexFormat` keeps a `'uint16'` placeholder\n // (never consumed when no index buffer is built).\n const indices = mesh.indices;\n const indexBytesUnpadded = indices === undefined ? 0 : indices.byteLength;\n const indexByteLength = ((indexBytesUnpadded + 3) >> 2) << 2;\n const layoutProjection = deriveVertexLayoutProjection(mesh.attributes);\n return ok({\n vertexByteLength: mesh.vertices.byteLength,\n layoutProjection,\n indexByteLength,\n indexCount: indices === undefined ? 0 : indices.length,\n indexFormat: indices instanceof Uint32Array ? 'uint32' : 'uint16',\n vertexUsage: GPU_BUFFER_USAGE_VERTEX | GPU_BUFFER_USAGE_COPY_DST,\n indexUsage: GPU_BUFFER_USAGE_INDEX | GPU_BUFFER_USAGE_COPY_DST,\n submeshes: mesh.submeshes,\n });\n}\n\n/**\n * Project a `TextureAsset` POD into its GPU texture descriptor. Pure: derives\n * the mip-level count (when `mipmap`), the row pitch, and the usage flags, and\n * fails fast if the POD's `format` and `colorSpace` are internally\n * inconsistent (a `-srgb` format requires an `srgb` colorSpace and vice versa).\n */\nexport function deriveRenderDataTexture(tex: TextureAsset): Result<TextureRenderData, AssetError> {\n const isSrgbFormat = tex.format.endsWith('-srgb');\n const expectedColorSpace: 'srgb' | 'linear' = isSrgbFormat ? 'srgb' : 'linear';\n if (tex.colorSpace !== expectedColorSpace) {\n return err(\n projectionError({\n code: 'invalid-source-format',\n expected: \"format ends in '-srgb' iff colorSpace is 'srgb' (linear otherwise)\",\n hint: ASSET_ERROR_HINTS['invalid-source-format'],\n }),\n );\n }\n\n const compressed = isCompressedFormat(tex.format);\n // feat-20260707 M5 / w35 (AC-09, D-9): a block-compressed texture cannot have\n // its mips GPU-generated (F-7). An OFFLINE chain baked into `data`\n // (mipLevelCount > 1, e.g. a KTX2 level chain) is the normal compressed path\n // and passes; requesting RUNTIME mip generation (`mipmap:true` with no offline\n // chain) fails fast with a self-recovery hint (fail-fast at the projection\n // layer -- producer self-validate).\n const hasOfflineMipChain = (tex.mipLevelCount ?? 1) > 1;\n if (compressed && tex.mipmap === true && !hasOfflineMipChain) {\n return err(\n projectionError({\n code: 'mipgen-unsupported-compressed-format',\n expected:\n 'a compressed texture requesting mipmap:true must carry an offline mip chain (mipLevelCount > 1)',\n hint: ASSET_ERROR_HINTS['mipgen-unsupported-compressed-format'],\n }),\n );\n }\n\n // Uncompressed: runtime mip-gen count from the pixel size. Compressed: the\n // level count is authored (offline chain) -- honour the POD's mipLevelCount,\n // never re-derive it from the size (a compressed chain may stop early).\n const mipLevelCount = compressed\n ? Math.max(1, tex.mipLevelCount ?? 1)\n : tex.mipmap\n ? numMipLevels(tex)\n : 1;\n\n const uncompressedBytesPerTexel =\n tex.format === 'rgba32float' ? 16 : tex.format === 'rgba16float' ? 8 : 4;\n if (!compressed && tex.data.byteLength < tex.width * tex.height * uncompressedBytesPerTexel) {\n return err(\n projectionError({\n code: 'invalid-source-format',\n expected: 'uncompressed texture data contains at least one complete base mip',\n hint: ASSET_ERROR_HINTS['invalid-source-format'],\n }),\n );\n }\n\n // Compressed rows derive from block format. Uncompressed row pitch derives\n // from the format, not aggregate payload length: imported images may retain\n // trailing decoder bytes and offline mip chains contain more than the base mip.\n const bytesPerRow = compressed\n ? (blockBytesPerRow(tex.format, tex.width) ?? tex.width * 4)\n : tex.width * uncompressedBytesPerTexel;\n\n // Compressed formats are not renderable -- RENDER_ATTACHMENT would fail\n // createTexture validation, and the runtime mipmap blit (which needs it) never\n // runs on a compressed texture anyway (the mip gate above rules out runtime\n // mip-gen). Both paths keep COPY_SRC so a real consumer can validate the\n // uploaded texture through the standard GPU readback contract.\n const usage = compressed\n ? GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST | GPU_TEXTURE_USAGE_COPY_SRC\n : GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC;\n\n return ok({\n width: tex.width,\n height: tex.height,\n ...deriveTextureExtent(tex.format, tex.width, tex.height),\n format: tex.format,\n mipLevelCount,\n usage,\n bytesPerRow,\n compressed,\n });\n}\n\n/**\n * Project an equirectangular HDR `TextureAsset` source into its cubemap\n * descriptor. Pure: validates the source is a linear HDR format, computes the\n * square cube face size (== source height), narrows the output to the filterable\n * `rgba16float` the IBL pipeline expects, and flags whether the store must pack\n * an rgba32float source down to rgba16float. The store keeps the resource build\n * (createTexture / cube + face views / IBL precompute) and the rgba32f->rgba16f\n * byte conversion.\n *\n * feat-20260707 M5 fix: the accepted-format whitelist is `rgba16float |\n * rgba32float` only -- a block-compressed HDR format (`bc6h-rgb-ufloat`) is NOT\n * accepted here. An equirect cube source drives equirect-to-cube / irradiance /\n * prefilter RENDER passes, and a BC6H texture is sample-only, never a color-\n * renderable render target (\"BC6HRGBUfloat is not color renderable\"). The\n * equirect is therefore always delivered uncompressed rgba16float; this\n * fail-fast whitelist is the projection-layer guard that rejects a non-\n * renderable cube source rather than letting it blow up at GPU createTexture.\n */\nexport function deriveRenderDataCubemap(source: TextureAsset): Result<CubeRenderData, AssetError> {\n const isAcceptedHdr = source.format === 'rgba16float' || source.format === 'rgba32float';\n if (!isAcceptedHdr || source.colorSpace !== 'linear') {\n return err(\n projectionError({\n code: 'invalid-source-format',\n expected: \"format 'rgba16float' or 'rgba32float' with colorSpace 'linear'\",\n hint: ASSET_ERROR_HINTS['invalid-source-format'],\n }),\n );\n }\n return ok({\n cubeFaceSize: source.height,\n outputFormat: 'rgba16float',\n needsHalfConversion: source.format === 'rgba32float',\n cubeUsage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC,\n });\n}\n","import type { AssetRegistry, DynamicTextureStore } from '@forgeax/engine-assets-runtime';\nimport type { World } from '@forgeax/engine-ecs';\nimport type { VertexLayoutProjection } from '@forgeax/engine-geometry';\nimport type { Profiler } from '@forgeax/engine-profiler';\nimport type { CompiledRenderGraphInfo } from '@forgeax/engine-render-graph';\nimport type {\n BindGroup,\n BindGroupLayout,\n Buffer,\n ComputePipeline,\n PipelineLayout,\n Result,\n RhiCanvasContext,\n RhiDevice,\n RenderPipeline as RhiRenderPipeline,\n Sampler,\n Texture,\n TextureFormat,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport { err, ok, RhiError } from '@forgeax/engine-rhi';\nimport type { MaterialRuntimeArtifact } from '@forgeax/engine-shader';\nimport type {\n MaterialRenderState,\n ParamSchemaEntry,\n PassKind,\n PrimitiveTopology,\n VertexAttributeMap,\n} from '@forgeax/engine-types';\nimport type { MaterialRenderProjection } from '../assembly/material/assembly';\nimport type { DeviceScope } from '../device/device-scope';\nimport type { MeshGpuHandles } from '../device/gpu-residency';\nimport type { EngineMetrics } from '../engine-metrics';\nimport type { RenderFeatureHost } from '../features/host';\nimport type { RenderFeatureShaderModuleMode } from '../features/types';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\nimport type { SkylightFallback } from '../ibl/skylight-bind-group';\nimport type { BloomInspection } from '../inspection-types';\nimport type { HealthListenerRegistry, RhiErrorListenerRegistry } from '../lifecycle';\nimport type { StandardProfile } from '../pipeline/standard-profile';\nimport type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';\nimport type { PointsLinesInspection } from '../points-lines/inspection';\nimport type { PointsLinesRecordPlan } from '../points-lines/record';\n\nexport interface PointsLinesRecordSubmission {\n readonly plan: PointsLinesRecordPlan;\n readonly vertexBuffer: Buffer;\n readonly indexBuffer: Buffer;\n readonly layoutProjection: VertexLayoutProjection;\n}\n\nimport type {\n RenderDebugOverlay,\n RenderPipelineContext,\n RenderRecordPhase,\n} from '../render-contract';\nimport type {\n DispatchEntry,\n MaterialSnapshot,\n SkyboxSnapshot,\n SkylightSnapshot,\n} from '../render-system-extract';\nimport type { SkinPaletteAllocator } from '../systems/skin-palette-allocator';\nimport type {\n BindGroupCounts,\n BloomFrameReceipts,\n DispatchCounts,\n MaterialBgAssemblyCacheEntry,\n RenderFrameState,\n ValidatedRenderable,\n} from './frame-snapshot';\nimport type { FoldDispatchPlan } from './mesh-ssbo';\n\nexport interface RenderSystemRuntime {\n readonly device: RhiDevice;\n readonly deviceScope: DeviceScope;\n readonly errorRegistry: RhiErrorListenerRegistry;\n readonly debugOverlay?: RenderDebugOverlay | undefined;\n readonly healthRegistry: HealthListenerRegistry;\n readonly getMaterialProjection?: (materialGuid: string) => MaterialRenderProjection | undefined;\n readonly getMaterialArtifact?: (specializationKey: string) => MaterialRuntimeArtifact | undefined;\n readonly getMaterialShaderPipeline?: (\n materialShaderId: string,\n isHdr: boolean,\n renderState?: MaterialRenderState,\n topology?: PrimitiveTopology,\n indexFormat?: 'uint16' | 'uint32',\n variantSet?: string,\n passKind?: PassKind,\n meshAttributes?: VertexAttributeMap,\n sampleCount?: number,\n colorFormatOverride?: GPUTextureFormat,\n shaderUvSetCount?: number,\n depthFormatOverride?: GPUTextureFormat | null,\n vertexLayout?: string,\n vertexLayoutProjection?: VertexLayoutProjection,\n shaderModuleMode?: RenderFeatureShaderModuleMode,\n layoutKindOverride?: 'pbr' | 'pbr-skin',\n ) => RhiRenderPipeline | null;\n readonly getMaterialShaderBindingContract?: (\n materialShaderId: string,\n ) => 'group-0' | 'group-0-resource' | 'view-only' | 'view-and-scene-depth' | 'render-material';\n readonly getParamSchema?: (materialShaderId: string) => readonly ParamSchemaEntry[] | undefined;\n readonly getMaterialBindGroupLayout?: (materialShaderId: string) => BindGroupLayout | undefined;\n readonly metrics: EngineMetrics;\n readonly lookupPostProcess?: (\n id: string,\n ) => import('../fullscreen-post-process-pass').PostProcessShaderEntry | undefined;\n readonly getPostProcessParamsBuffer?: (id: string) => Buffer | undefined;\n readonly getPostProcessPipeline?: (\n id: string,\n bgl: BindGroupLayout,\n colorFormat: GPUTextureFormat,\n ) => RhiRenderPipeline | null;\n readonly clearPostProcessPipelineCache?: (id: string) => void;\n readonly invalidateShaderModule?: (label: string) => void;\n readonly dynamicTextureStore?: DynamicTextureStore | undefined;\n}\n\n/** Renderer-owned bridge from retained Points/Lines facts into main geometry. */\nexport interface PointsLinesRecordOwner {\n prepare(entry: ValidatedRenderable, clustered: boolean): PointsLinesRecordSubmission | undefined;\n beginFrame(): void;\n resetForDeviceLoss(): void;\n inspections(): readonly PointsLinesInspection[];\n}\n\nexport interface PerPassResources {\n depthTexture: Texture | null;\n depthTextureView: TextureView | null;\n depthTextureWidth: number;\n depthTextureHeight: number;\n configured: boolean;\n hdrColorTexture: Texture | null;\n hdrColorView: TextureView | null;\n hdrDepthTexture: Texture | null;\n hdrDepthView: TextureView | null;\n hdrTextureWidth: number;\n hdrTextureHeight: number;\n hdrDepthSampleCount: number;\n readonly fxaaPipeline: RhiRenderPipeline | null;\n readonly fxaaBindGroupLayout: BindGroupLayout | null;\n readonly fxaaSampler: Sampler | null;\n msaaColorTexture: Texture | null;\n msaaColorView: TextureView | null;\n msaaSpriteColorTexture: Texture | null;\n msaaSpriteColorView: TextureView | null;\n msaaDepthTexture: Texture | null;\n msaaDepthView: TextureView | null;\n msaaTextureWidth: number;\n msaaTextureHeight: number;\n hdrColorMsaaTexture: Texture | null;\n hdrColorMsaaView: TextureView | null;\n readonly skyboxPipeline: RhiRenderPipeline | null;\n readonly skyboxPipelineMsaa: RhiRenderPipeline | null;\n readonly skyboxBindGroupLayout: BindGroupLayout | null;\n readonly skyboxSampler: Sampler | null;\n readonly skyboxRotationBuffer: Buffer | null;\n bloomBrightPipeline: RhiRenderPipeline | null;\n bloomBlurHPipeline: RhiRenderPipeline | null;\n bloomBlurVPipeline: RhiRenderPipeline | null;\n bloomCompositePipeline: RhiRenderPipeline | null;\n bloomBrightBindGroupLayout: BindGroupLayout | null;\n bloomBlurBindGroupLayout: BindGroupLayout | null;\n bloomCompositeBindGroupLayout: BindGroupLayout | null;\n bloomSampler: Sampler | null;\n bloomBrightParamsBuffer: Buffer | null;\n bloomBlurHParamsBuffer: Buffer | null;\n bloomBlurVParamsBuffer: Buffer | null;\n bloomCompositeParamsBuffer: Buffer | null;\n ensureBloomResources?: () => void;\n getBloomResources?: () => BloomPersistentBundle | null;\n commitBloomResources?: () => void;\n commitBloomFrameReceipts?: (receipts: BloomFrameReceipts) => void;\n discardBloomResources?: () => void;\n retireBloomResources?: (completion: Promise<unknown>) => void;\n /** Drain candidate, active, and fence-retiring Bloom generations. */\n drainBloomResources?: () => void;\n inspectBloomResources?: (graph?: CompiledRenderGraphInfo) => BloomInspection;\n bloomBrightTexture: Texture | null;\n bloomBrightView: TextureView | null;\n bloomBrightWidth: number;\n bloomBrightHeight: number;\n bloomBlurHTexture: Texture | null;\n bloomBlurHView: TextureView | null;\n bloomBlurHWidth: number;\n bloomBlurHHeight: number;\n bloomBlurVTexture: Texture | null;\n bloomBlurVView: TextureView | null;\n bloomBlurVWidth: number;\n bloomBlurVHeight: number;\n ssaoCalcPipeline: RhiRenderPipeline | null;\n ssaoBlurPipeline: RhiRenderPipeline | null;\n ssaoBgl: BindGroupLayout | null;\n ssaoFilteringSampler: Sampler | null;\n ssaoDepthSampler: Sampler | null;\n ssaoFallbackRawView: TextureView | null;\n shadowTexture: Texture | null;\n shadowMapSize: number;\n shadowCascadeCount: number;\n shadowSampler: Sampler | null;\n shadowLightSpaceMatrix: Float32Array | null;\n shadowCsmLightViewProj: Float32Array | null;\n shadowCsmSelection: {\n readonly viewMatrix: Float32Array;\n readonly splitPlanes: Float32Array;\n } | null;\n}\n\n/** Renderer-private Bloom bundle selected for one record transaction. */\nexport interface BloomPersistentBundle {\n readonly scope: DeviceScope;\n readonly generation: number;\n readonly bloomBrightPipeline: RhiRenderPipeline | null;\n readonly bloomBlurHPipeline: RhiRenderPipeline | null;\n readonly bloomBlurVPipeline: RhiRenderPipeline | null;\n readonly bloomCompositePipeline: RhiRenderPipeline | null;\n readonly bloomBrightBindGroupLayout: BindGroupLayout | null;\n readonly bloomBlurBindGroupLayout: BindGroupLayout | null;\n readonly bloomCompositeBindGroupLayout: BindGroupLayout | null;\n readonly bloomSampler: Sampler | null;\n readonly bloomBrightParamsBuffer: Buffer | null;\n readonly bloomBlurHParamsBuffer: Buffer | null;\n readonly bloomBlurVParamsBuffer: Buffer | null;\n readonly bloomCompositeParamsBuffer: Buffer | null;\n}\n\nexport interface PipelineState {\n readonly meshes: ReadonlyMap<number, MeshGpuHandles>;\n readonly format: TextureFormat;\n readonly colorAttachmentFormat: TextureFormat;\n /** Surface route committed by configureSurface for inspection provenance. */\n readonly surfaceProfile?: 'dual-view' | 'raw-only';\n readonly viewBindGroupLayout: BindGroupLayout;\n readonly materialBindGroupLayout: BindGroupLayout;\n readonly meshBindGroupLayout: BindGroupLayout;\n readonly viewUniformBuffer: Buffer;\n readonly pointsLinesViewBuffer?: Buffer;\n readonly shadowCasterCascadeBuffer: Buffer;\n readonly materialUniformBuffer: { readonly buffer: Buffer; readonly sizeInBytes: number };\n readonly meshStorageBuffer: { readonly buffer: Buffer; readonly sizeInBytes: number };\n readonly pointLightsBuffer: Buffer;\n readonly spotLightsBuffer: Buffer;\n readonly instancesBindGroupLayout: BindGroupLayout;\n readonly identityInstanceBuffer: Buffer;\n readonly defaultSampler: Sampler;\n readonly nearestSampler: Sampler;\n readonly fallbackTextureView: TextureView;\n readonly unlitPipeline: RhiRenderPipeline | null;\n readonly standardPipeline: RhiRenderPipeline | null;\n readonly unlitPipelineMsaa: RhiRenderPipeline | null;\n readonly unlitPipelineHdrMsaa: RhiRenderPipeline | null;\n readonly pbrPipelineLayout: PipelineLayout | null;\n readonly hdrpPbrPipelineLayout: PipelineLayout | null;\n readonly hdrpClusterMembershipPipeline: ComputePipeline | null;\n readonly hdrpClusterMembershipBindGroupLayout: BindGroupLayout | null;\n readonly pbrSkinPipelineLayout: PipelineLayout | null;\n readonly pbrSkinMeshBindGroupLayout: BindGroupLayout | null;\n readonly skinPaletteAllocator: SkinPaletteAllocator | null;\n readonly defaultWhiteTextureView: TextureView;\n readonly defaultNormalTextureView: TextureView;\n readonly unlitPipelineHdr: RhiRenderPipeline | null;\n readonly shadowFallbackTextureView: TextureView;\n readonly shadowAtlasFallbackTextureView: TextureView;\n readonly shadowParamsBuffer: Buffer;\n readonly skylightFallback: SkylightFallback | null;\n readonly perPassResources: PerPassResources;\n}\n\nexport interface RenderSystemInternals extends RenderSystemRuntime {\n readonly canvas: HTMLCanvasElement | OffscreenCanvas;\n readonly standardProfile?: StandardProfile | undefined;\n readonly standardPipeline: RenderFrameState['activePipeline'];\n readonly featureHost?: RenderFeatureHost | undefined;\n readonly shaderModuleFactory?: PipelineBuilderShaderModuleFactory;\n /** Optional handle-first factory for feature-owned generated shader programs. */\n readonly immediateShaderModuleFactory?: PipelineBuilderShaderModuleFactory;\n readonly profiler?: Profiler | undefined;\n readonly context: RhiCanvasContext | null;\n readonly getPipelineState: () => PipelineState | null;\n readonly assets: AssetRegistry;\n readonly gpuStore: import('../device/gpu-residency').GpuResidencyCache;\n readonly growMeshSsbo?:\n | ((neededSlots: number) =>\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly code: 'mesh-ssbo-ceiling-reached' | 'mesh-ssbo-capacity-exceeded';\n readonly degradedToSlotCount: number;\n })\n | undefined;\n readonly meshSsboState?: { readonly slotCount: number } | undefined;\n readonly buildPostProcessPipeline?:\n | ((\n entry: import('../fullscreen-post-process-pass').PostProcessShaderEntry,\n bgl: BindGroupLayout,\n colorFormat: GPUTextureFormat,\n label: string,\n ) => RhiRenderPipeline | null)\n | undefined;\n}\n\nexport interface _StandardForwardSceneView {\n readonly assets: AssetRegistry;\n readonly store: import('../device/gpu-residency').GpuResidencyCache;\n readonly pipelineState: PipelineState;\n readonly bloomResources?: BloomPersistentBundle | null;\n readonly runtime: RenderSystemRuntime;\n readonly validated: readonly ValidatedRenderable[];\n readonly validatedOrdered: readonly ValidatedRenderable[];\n readonly viewBindGroup: BindGroup | null;\n readonly meshBindGroup: BindGroup | null;\n readonly frameState: RenderFrameState;\n readonly dispatchCounts: DispatchCounts;\n readonly bindGroupCounts: BindGroupCounts;\n readonly skylight: SkylightSnapshot | undefined;\n readonly skylightCount: number;\n readonly skybox: SkyboxSnapshot | undefined;\n readonly profilePhase?: <T>(phase: RenderRecordPhase, action: () => T) => T;\n readonly directionalShadowCacheReuse: boolean;\n readonly world: World;\n readonly gpuDrivenEntityKeys: ReadonlySet<number>;\n readonly tonemapActive: boolean;\n readonly geometryColorView: TextureView | null;\n readonly geometryDepthView: TextureView | null;\n readonly geometryDepthKey: string | null;\n readonly skyboxActive: boolean;\n readonly splitLdrSprite: boolean;\n readonly ldrSpritePassView: TextureView | null;\n readonly transparentColorFormat?: GPUTextureFormat;\n readonly dispatch: readonly DispatchEntry[];\n readonly hdrpClusterBindGroup: BindGroup | null;\n readonly hdrpClusterMembershipBindGroup: BindGroup | null;\n readonly foldDispatchPlan: FoldDispatchPlan | null;\n readonly materialSlotIndices: readonly (readonly number[])[];\n readonly materialSlots: readonly MaterialSnapshot[];\n readonly materialSlotOwners: readonly number[];\n readonly materialSlotCount: number;\n readonly pointsLines: PointsLinesRecordOwner | undefined;\n readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;\n materialUboPayloadCache?: {\n readonly materialSlots: readonly MaterialSnapshot[];\n readonly materialSlotCount: number;\n readonly payload: Uint8Array;\n };\n hdrpSsaoBlurredView?: TextureView;\n}\n\nexport type _InternalRenderPipelineContext = RenderPipelineContext & _StandardForwardSceneView;\n\nexport type RecordProfileRunner = <T>(phase: RenderRecordPhase, action: () => T) => T;\n\nexport const STANDARD_PBR_UBO_SIZE = 384;\nexport const MATERIAL_PER_ENTITY_STRIDE = 512;\n\nexport type SwapChainFormatPair = {\n readonly storage: GPUTextureFormat;\n readonly view: GPUTextureFormat;\n readonly fallbackReason?: 'preferred-canvas-format-missing';\n};\n\n/** Internal closed projection of the concrete surface route. */\nexport type SurfaceProfile =\n | {\n readonly kind: 'dual-view';\n readonly storageFormat: GPUTextureFormat;\n readonly viewFormat: GPUTextureFormat;\n readonly viewFormats: readonly [GPUTextureFormat];\n readonly hasDisplayEndpoint: true;\n }\n | {\n readonly kind: 'raw-only';\n readonly storageFormat: GPUTextureFormat;\n readonly viewFormat: GPUTextureFormat;\n readonly viewFormats: readonly [];\n readonly hasDisplayEndpoint: false;\n };\n\nexport interface SurfaceCapabilityFacts {\n /** Concrete wgpu downlevel `SURFACE_VIEW_FORMATS` flag. */\n readonly surfaceViewFormats: boolean;\n readonly rawAttachment: boolean;\n readonly floatRenderAttachment: boolean;\n}\n\nexport function resolveSurfaceProfile(\n storageFormat: GPUTextureFormat,\n viewFormat: GPUTextureFormat,\n facts: SurfaceCapabilityFacts,\n): Result<SurfaceProfile, RhiError> {\n if (facts.surfaceViewFormats) {\n return ok({\n kind: 'dual-view',\n storageFormat,\n viewFormat,\n viewFormats: [viewFormat],\n hasDisplayEndpoint: true,\n });\n }\n if (!facts.rawAttachment || !facts.floatRenderAttachment) {\n return err(\n new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'raw surface attachment and rgba16float render attachment capabilities',\n hint: 'surface profile cannot establish a raw-only linear output route',\n detail: {\n error: {\n code: 'surface-raw-endpoint-failed',\n message: 'raw-only surface capabilities are incomplete',\n },\n },\n }),\n );\n }\n return ok({\n kind: 'raw-only',\n storageFormat,\n viewFormat: storageFormat,\n viewFormats: [],\n hasDisplayEndpoint: false,\n });\n}\n\nexport type SurfaceBackendKind = 'webgpu' | 'wgpu-native' | 'wgpu-webgl2' | 'null';\n\nexport function resolveSurfaceFormatPair(\n _backendKind: SurfaceBackendKind,\n storage: GPUTextureFormat,\n view: GPUTextureFormat,\n): SwapChainFormatPair {\n return { storage, view };\n}\n\nfunction surfaceCapabilityFacts(\n device: RhiDevice,\n storageFormat: GPUTextureFormat,\n): SurfaceCapabilityFacts {\n const internal = device as unknown as { readonly surfaceViewFormats?: boolean };\n return {\n surfaceViewFormats: internal.surfaceViewFormats ?? device.caps?.backendKind !== 'wgpu-webgl2',\n rawAttachment: storageFormat === 'rgba8unorm' || storageFormat === 'bgra8unorm',\n floatRenderAttachment: device.caps?.rgba16floatRenderable ?? true,\n };\n}\n\nexport function configureSurface(\n context: RhiCanvasContext,\n device: RhiDevice,\n format: TextureFormat,\n colorAttachmentFormat: TextureFormat,\n): Result<void, RhiError> {\n const backendKind = device.caps?.backendKind ?? 'webgpu';\n const isWebGl2 = backendKind === 'wgpu-webgl2';\n const surfaceFormats = resolveSurfaceFormatPair(\n backendKind,\n format as GPUTextureFormat,\n colorAttachmentFormat as GPUTextureFormat,\n );\n const profile = resolveSurfaceProfile(\n surfaceFormats.storage,\n surfaceFormats.view,\n surfaceCapabilityFacts(device, surfaceFormats.storage),\n );\n if (!profile.ok) return profile;\n // WebGL2 surface pixels are proven by the compositor fixture, so it has no\n // surface consumer for optional TEXTURE_BINDING/COPY_SRC usage. The concrete\n // wgpu surface derives supported usages from SurfaceCapabilities and rejects\n // unsupported requests; this path requests only the guaranteed attachment\n // usage. Raw-only deliberately has no alternate view.\n const supportsTextureBinding =\n backendKind !== 'wgpu-webgl2' && (device.caps?.storageBuffer ?? true);\n const configured = context.configure({\n device,\n format: surfaceFormats.storage,\n alphaMode: isWebGl2 ? 'opaque' : 'premultiplied',\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n (supportsTextureBinding ? GPU_TEXTURE_USAGE_TEXTURE_BINDING : 0) |\n (isWebGl2 ? 0 : GPU_TEXTURE_USAGE_COPY_SRC),\n viewFormats: [...profile.value.viewFormats],\n });\n if (!configured.ok) return configured;\n if (\n isWebGl2 &&\n (context.presentationProof === undefined ||\n !context.presentationProof.descriptor ||\n !context.presentationProof.acquisition ||\n !context.presentationProof.validation ||\n typeof context.presentationProof.surfaceIdentity !== 'string' ||\n context.presentationProof.surfaceIdentity.length === 0 ||\n context.presentationProof.requested === undefined ||\n context.presentationProof.validated === undefined ||\n JSON.stringify(context.presentationProof.requested) !==\n JSON.stringify(context.presentationProof.validated))\n ) {\n return err(\n new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'WebGL2 surface storage has descriptor, acquisition, and validation proof',\n hint: 'run the concrete presentation probe and retain the last-known-good graph when proof is absent',\n detail: {\n error: {\n code: 'surface-raw-endpoint-failed',\n message: 'surface storage raw endpoint proof is incomplete',\n },\n },\n }),\n );\n }\n return ok(undefined);\n}\n\nexport function selectSwapChainFormat(\n storageBufferCapable: boolean,\n surfaceViewFormats = true,\n): SwapChainFormatPair {\n if (!storageBufferCapable) {\n return {\n storage: 'rgba8unorm',\n view: surfaceViewFormats ? 'rgba8unorm-srgb' : 'rgba8unorm',\n };\n }\n const nav = (\n globalThis as { navigator?: { gpu?: { getPreferredCanvasFormat?: () => GPUTextureFormat } } }\n ).navigator;\n const gpu = nav?.gpu;\n const getPreferred = gpu?.getPreferredCanvasFormat;\n if (gpu !== undefined && typeof getPreferred === 'function') {\n const storage = getPreferred.call(gpu);\n const view =\n storage === 'rgba8unorm'\n ? 'rgba8unorm-srgb'\n : storage === 'bgra8unorm'\n ? 'bgra8unorm-srgb'\n : storage;\n return {\n storage,\n view: surfaceViewFormats ? view : storage,\n };\n }\n return {\n storage: 'rgba8unorm',\n view: surfaceViewFormats ? 'rgba8unorm-srgb' : 'rgba8unorm',\n fallbackReason: 'preferred-canvas-format-missing',\n };\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: main-pass-material.\n// Extracted from render-system-record.ts (feat-20260704 M3/w17, pure move).\n\nimport { resolveAssetHandle } from '@forgeax/engine-assets-runtime';\nimport type { EntityHandle, World } from '@forgeax/engine-ecs';\nimport {\n VIDEO_ELEMENT_PROVIDER_KEY,\n type VideoElementProvider,\n} from '@forgeax/engine-graphics-extras';\nimport {\n type BindGroup,\n type BindGroupEntry,\n type BindGroupLayout,\n type Buffer,\n type RenderPipeline,\n RhiError,\n type Sampler,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport {\n DEFAULT_MSDF_TEXT_PARAM_SCHEMA,\n DEFAULT_SPRITE_PARAM_SCHEMA,\n DEFAULT_STANDARD_PBR_PARAM_SCHEMA,\n DEFAULT_UNLIT_PARAM_SCHEMA,\n} from '@forgeax/engine-shader';\nimport type {\n Handle,\n ImageError,\n MaterialRenderState,\n ParamSchemaEntry,\n PrimitiveTopology,\n SamplerAsset,\n TextureAsset,\n} from '@forgeax/engine-types';\nimport { derive, handleSlot, resolveMaterialTextureCoordinates } from '@forgeax/engine-types';\nimport type { GpuResidencyCache } from '../device/gpu-residency';\nimport { VideoUploadUnsupportedError } from '../errors/render';\nimport {\n assembleMaterialWithSkylightEntries,\n type SkylightBindGroupResources,\n type TransmissionBindGroupResources,\n} from '../ibl/skylight-bind-group';\nimport { isStandardPbrMaterialShader } from '../pbr-pipeline';\nimport { deriveTextureExtent } from '../render-data';\nimport type { MaterialSnapshot } from '../render-system-extract';\nimport type { BindGroupCounts, MaterialBgAssemblyCacheEntry } from './frame-snapshot';\nimport { extractEntryResourceHandle, getOrCreatePerEntity } from './mesh-ssbo';\nimport {\n type PipelineState,\n type RenderSystemRuntime,\n STANDARD_PBR_UBO_SIZE,\n} from './render-context';\n\n// Param schemas are immutable runtime contracts: the shader registry installs\n// them once and material snapshots only retain the same array reference. Keep\n// the expensive pure derivation on that identity so the per-submesh record\n// path does not rebuild the same UBO/texture maps for every visible material\n// on every frame. A WeakMap keeps this optimization bounded by the lifetime of\n// the schema owner and adds no global strong-reference lifetime.\nconst DERIVED_PARAM_SCHEMA_CACHE = new WeakMap<\n readonly ParamSchemaEntry[],\n ReturnType<typeof derive>\n>();\n\nfunction derivedParamSchema(schema: readonly ParamSchemaEntry[]): ReturnType<typeof derive> {\n const cached = DERIVED_PARAM_SCHEMA_CACHE.get(schema);\n if (cached !== undefined) return cached;\n const derived = derive(schema);\n DERIVED_PARAM_SCHEMA_CACHE.set(schema, derived);\n return derived;\n}\n\n// feat-20260601-customizable-render-pipeline-seam M2 / w12: the former\n// `RecordPassContext` (26-field full surface, including the `internals` kitchen-sink and\n// the 0-consumed `skyboxCount` residual) is DELETED. The per-frame shared state injected\n// into the render-graph pass execute closures is now the clean `RenderPipelineContext`\n// (defined in `render-system.ts`): `internals` is gone (replaced by the named\n// `assets` / `store` / `pipelineState` / `runtime` surfaces) so a pipeline author cannot\n// reach the runtime kitchen-sink through the public ctx (AC-08). The graph is\n// `RenderGraph<RenderPipelineContext>` so `execute(ctx)` forwards the object to each\n// closure with no `as` assertion.\n//\n// Encoder ownership (RD-4): `ctx.encoder` is the SHARED frame encoder used by the main /\n// tonemap / FXAA passes (finished + submitted once at frame end); the shadow pass opens\n// its OWN encoder internally + submits independently (the runtime-side manual barrier for\n// the depth write -> sample hazard).\n\n// M1 / w7: ensureLazyTexture DELETED — GPU texture ownership moved to render-graph\n// via addColorTarget + compile(device). The graph allocates transient/persistent\n// render targets during the compile allocation phase; pass execute closures resolve\n// TextureViews through resolve(name). PerPassResources texture slots still hold\n// the last-used views for bindgroup-invalidation self-checks (D-3 physical texture\n// identity), but the graph owns the create/destroy lifecycle.\n\n/**\n * Keep line primitives visible when they share a depth plane with filled\n * geometry. The same topology policy is consumed by the CPU and GPU-driven\n * raster lanes so a mixed mesh does not change appearance when ownership\n * moves between them.\n */\nexport function geometryRenderStateForTopology(\n topology: PrimitiveTopology,\n renderState: MaterialRenderState | undefined,\n): MaterialRenderState | undefined {\n if (topology !== 'line-list' && topology !== 'line-strip') return renderState;\n return {\n ...renderState,\n depthWriteEnabled: false,\n depthCompare: 'less-equal',\n };\n}\n\n/**\n * feat-20260604-learn-render-4.10-anti-aliasing-msaa M2 / w9: pick the static\n * unlit geometry pipeline handle for a (tonemapActive x msaaActive)\n * combination. The four mode axes (LDR/HDR x single/MSAA) map to the 14 static\n * pipeline handles built in createRenderer (7 base + 7 count=4 variants). A\n * pipeline's `multisample.count` must match the colour-attachment sampleCount,\n * so the count=4 variant is required whenever the camera carries\n * `antialias === 'msaa'`. Returns null when the requested pipeline was not\n * built (empty-manifest path / MSAA variant build failure) -- the caller fires\n * a structured `shader-compile-failed` on the null-narrow.\n */\n// feat-20260615-pipeline-spec-ssot M6-T1: the standard-shading fallback\n// selector was deleted. The pre-M6 selector silently substituted the\n// boot-time URP `pipelineState.standardPipeline*` whenever the per-\n// MaterialShader cache returned null and HDRP was inactive -- masking\n// real PipelineSpecError build failures behind a layout-compatible-but-\n// wrong PSO. Charter P3 explicit-failure now governs: a missing cache\n// entry surfaces as null, and the per-submesh\n// `if (smPipelineHandle === null) continue` skip-draw (which already\n// covered the HDRP-active and skin-shader miss-skip paths) is the single\n// uniform recovery shape across URP / HDRP / skin.\n\nexport function selectGeometryPipeline(\n pipelineState: PipelineState,\n tonemapActive: boolean,\n msaaActive: boolean,\n): RenderPipeline | null {\n if (tonemapActive) {\n return msaaActive ? pipelineState.unlitPipelineHdrMsaa : pipelineState.unlitPipelineHdr;\n }\n return msaaActive ? pipelineState.unlitPipelineMsaa : pipelineState.unlitPipeline;\n}\n\n/**\n * feat-city-glb Bug 5 (per-submesh transparency): true when EVERY submesh\n * material of the entity is transparent (blend). Used by the geometry pass to\n * decide whether to skip the whole entity (fully transparent → deferred to the\n * blend sub-pass) vs. draw its opaque submeshes and skip only the transparent\n * ones per-submesh.\n *\n * Falls back to the entity-level `material.transparent` when `materials` is\n * absent (single-material entities / test fixtures), byte-identical to the\n * pre-fix whole-entity gate.\n *\n * @internal\n */\nexport function isEntityFullyTransparent(source: {\n readonly material: MaterialSnapshot;\n readonly materials?: readonly MaterialSnapshot[];\n}): boolean {\n const mats = source.materials;\n if (mats === undefined || mats.length === 0) return source.material.transparent === true;\n for (let j = 0; j < mats.length; j++) {\n if (mats[j]?.transparent !== true) return false;\n }\n return true;\n}\n\n/**\n * feat-city-glb Bug 5: true when the entity has at least one transparent AND at\n * least one opaque submesh — i.e. it must be drawn in BOTH the geometry pass\n * (opaque submeshes) and the blend sub-pass (transparent submeshes). A pure-\n * opaque or pure-transparent entity returns false (handled by the whole-entity\n * fast paths).\n *\n * @internal\n */\nexport function entityHasTransparentSubmesh(source: {\n readonly material: MaterialSnapshot;\n readonly materials?: readonly MaterialSnapshot[];\n}): boolean {\n const mats = source.materials;\n if (mats === undefined) return source.material.transparent === true;\n for (let j = 0; j < mats.length; j++) {\n if (mats[j]?.transparent === true) return true;\n }\n return false;\n}\n\n/**\n * feat-20260601-device/gpu-residency-extraction M1 / D-9: resolve a texture's\n * GPU view through the pull-model residency store. The three steps replace the\n * pre-extraction single-call accessor on the registry:\n * 1. fetch the TextureAsset POD off the registry (CPU; registry keeps PODs)\n * 2. synchronously `ensureResident(handle, pod)` (first access builds the\n * GPU texture + prewarmed mipmap blit; subsequent access is O(1))\n * 3. return the GPU view (or undefined on POD miss / ensureResident err)\n *\n * Returns `undefined` when the POD is absent (handle never registered) or the\n * upload fails (a structured error is fired). Callers then fall back to their\n * existing placeholder view, preserving the pre-extraction fallback semantics.\n */\nfunction isImageError(error: unknown): error is ImageError {\n if (typeof error !== 'object' || error === null) return false;\n const code = (error as { readonly code?: unknown }).code;\n return typeof code === 'string' && code.startsWith('image-');\n}\n\nexport function residentTextureView(\n world: World,\n store: GpuResidencyCache,\n runtime: RenderSystemRuntime,\n handle: Handle<'TextureAsset', 'shared'>,\n worldId: World | number = world,\n): TextureView | undefined {\n const podRes = resolveAssetHandle<TextureAsset>(world, handle);\n if (!podRes.ok) return undefined;\n const residentRes = store.ensureResident(handle, podRes.value, worldId);\n if (!residentRes.ok) {\n // Preserve the concrete asset-capability boundary on the renderer error\n // channel. In particular, WebGL2 texture-dimension refusal must not\n // collapse into the later debug-pink asset-not-registered fallback.\n if (residentRes.error instanceof RhiError || isImageError(residentRes.error)) {\n runtime.errorRegistry.fire(residentRes.error);\n }\n return undefined;\n }\n return store.getTextureGpuView(handle, worldId);\n}\n\nfunction residentSampler(\n world: World,\n store: GpuResidencyCache,\n runtime: RenderSystemRuntime,\n handle: Handle<'SamplerAsset', 'shared'>,\n worldId: World | number = world,\n): Sampler | undefined {\n const podRes = resolveAssetHandle<SamplerAsset>(world, handle);\n if (!podRes.ok) return undefined;\n const residentRes = store.ensureSamplerResident(handle, podRes.value, worldId);\n if (!residentRes.ok) {\n runtime.errorRegistry.fire(residentRes.error);\n return undefined;\n }\n return residentRes.value;\n}\n\n// feat-20260623-world-space-video-asset M4 / w16 (D-3): resolve the\n// current-frame GPU view for a video-sourced texture field through the\n// transient DynamicTextureStore, NOT the static `residentTextureView` /\n// `ensureResident` cache (video never enters that switch; AC-08).\n//\n// Per frame: ask the host-registered VideoElementProvider (World Resource,\n// D-1) for this entity's HTMLVideoElement, upload its current frame via\n// `store.uploadFrame` (copyExternalImageToTexture), and return the resulting\n// view. When the provider is absent / returns no element / the element has no\n// decodable dimensions yet, fall back to a previously-uploaded view and\n// finally to `undefined` (caller binds the default view this frame — charter\n// P3 graceful, no garbage sampling). A failed GPU upload fires the structured\n// RhiError on the engine channel and degrades to the default view.\n//\n// `highPerfAvailable` is the w17 capability probe; the high-perf\n// GPUExternalTexture branch is a reserved hook (OOS-5) — when it ever becomes\n// available the upload would route there. Today it is always false so the\n// general copyExternalImageToTexture path is the only one taken.\ntype DynamicTextureStore = import('@forgeax/engine-assets-runtime').DynamicTextureStore;\n\ntype VideoUploadFailureEpisodes = Map<number, Set<number>>;\n\n// The store is renderer-owned, so this keeps one failure episode per\n// renderer/entity/clip without creating a second video system or leaking\n// state across a replacement renderer.\nconst VIDEO_UPLOAD_FAILURE_EPISODES = new WeakMap<\n DynamicTextureStore,\n VideoUploadFailureEpisodes\n>();\n\nfunction markVideoUploadFailureEpisode(\n store: DynamicTextureStore,\n entityKey: number,\n clip: Handle<'VideoAsset', 'shared'>,\n): boolean {\n let clips = VIDEO_UPLOAD_FAILURE_EPISODES.get(store);\n if (clips === undefined) {\n clips = new Map();\n VIDEO_UPLOAD_FAILURE_EPISODES.set(store, clips);\n }\n let episodes = clips.get(entityKey);\n if (episodes === undefined) {\n episodes = new Set();\n clips.set(entityKey, episodes);\n }\n const clipId = handleSlot(clip);\n if (episodes.has(clipId)) return false;\n episodes.add(clipId);\n return true;\n}\n\nfunction clearVideoUploadFailureEpisode(\n store: DynamicTextureStore,\n entityKey: number,\n clip: Handle<'VideoAsset', 'shared'>,\n): void {\n const clips = VIDEO_UPLOAD_FAILURE_EPISODES.get(store);\n const episodes = clips?.get(entityKey);\n if (episodes === undefined) return;\n episodes.delete(handleSlot(clip));\n if (episodes.size === 0) clips?.delete(entityKey);\n if (clips?.size === 0) VIDEO_UPLOAD_FAILURE_EPISODES.delete(store);\n}\n\nexport function videoTextureView(\n world: World,\n store: DynamicTextureStore | undefined,\n runtime: RenderSystemRuntime,\n entityKey: number,\n clip: Handle<'VideoAsset', 'shared'>,\n highPerfAvailable: boolean,\n): TextureView | undefined {\n if (store === undefined) return undefined;\n const provider = world.hasResource(VIDEO_ELEMENT_PROVIDER_KEY)\n ? world.getResource<VideoElementProvider>(VIDEO_ELEMENT_PROVIDER_KEY)\n : undefined;\n const element = provider?.getElement(entityKey as EntityHandle, clip);\n // AC-10 double-miss: a VideoPlayer entity can reach NEITHER upload path this\n // frame — no host HTMLVideoElement (general copyExternalImageToTexture path)\n // AND no high-perf GPUExternalTexture path. This is the genuine \"this backend\n // exposes no usable video upload path\" case (no provider registered, or the\n // provider yields nothing while the high-perf reserved hook is unavailable —\n // OOS-5 keeps it always false today). Rather than silently binding the\n // default view, fire the structured VideoUploadUnsupportedError on the engine\n // error channel so an AI user can detect the dead path via `.code` / `.hint`\n // (charter P3; AC-10 signal lives on the REAL per-frame upload path, not an\n // orphan system). The default view is still bound this frame so the draw\n // does not crash (graceful degradation), but the failure is no longer silent.\n if (element === undefined && !highPerfAvailable) {\n if (markVideoUploadFailureEpisode(store, entityKey, clip)) {\n runtime.errorRegistry.fire(new VideoUploadUnsupportedError());\n }\n return store.getView(clip);\n }\n // D-2 / w17 high-perf reserved hook: a future GPUExternalTexture import path\n // would key off `highPerfAvailable` here. It is always false today\n // (importExternalTexture absent), so the general copyExternalImageToTexture\n // path below is the sole route end-to-end.\n if (element === undefined) {\n clearVideoUploadFailureEpisode(store, entityKey, clip);\n return store.getView(clip);\n }\n const width = element.videoWidth;\n const height = element.videoHeight;\n // Metadata dimensions can be non-zero before the decoder has produced a\n // current frame. WebGPU rejects copyExternalImageToTexture in that window\n // because the video element has no back resource yet; keep the previous\n // frame/default view until HAVE_CURRENT_DATA (2) is reached.\n if (width <= 0 || height <= 0 || element.readyState < 2) return store.getView(clip);\n const uploaded = store.uploadFrame(clip, element, width, height);\n if (uploaded === undefined) return store.getView(clip);\n if (!uploaded.ok) {\n runtime.errorRegistry.fire(uploaded.error);\n return store.getView(clip);\n }\n clearVideoUploadFailureEpisode(store, entityKey, clip);\n return uploaded.value;\n}\n\n// feat-20260621-learn-render-5-5-parallax M2 / w8 (D-3): the built-in\n// standard-PBR user-region texture field order, used when the shader is not\n// resolvable through getParamSchema (cross-worktree late-register). Mirrors\n// derive(default-standard-pbr).textureFieldNames.\nexport const BUILTIN_USER_REGION_TEXTURE_FIELDS: readonly string[] = [\n 'baseColorTexture',\n 'metallicRoughnessTexture',\n 'normalTexture',\n 'specularTintTexture',\n 'emissiveTexture',\n 'occlusionTexture',\n 'transmissionTexture',\n 'thicknessTexture',\n];\n\nconst LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET = 80;\n// The Standard schema owns five transmission numeric fields between\n// normalScale and the engine-owned coordinate records. Keep this fallback\n// aligned with derive(DEFAULT_STANDARD_PBR_PARAM_SCHEMA): the first record is\n// at byte 128, not the pre-transmission byte 96.\nconst STANDARD_PBR_TEXTURE_SCALE_OFFSET = 128;\nconst MATERIAL_TEXTURE_SCALE_FIELDS = [\n 'baseColorTexture',\n 'metallicRoughnessTexture',\n 'normalTexture',\n 'specularTintTexture',\n 'emissiveTexture',\n 'occlusionTexture',\n 'transmissionTexture',\n 'thicknessTexture',\n] as const;\nconst LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS = [\n 'baseColorTexture',\n 'metallicRoughnessTexture',\n 'normalTexture',\n 'emissiveTexture',\n 'occlusionTexture',\n] as const;\nconst STANDARD_PBR_TEXTURE_COORDINATE_OFFSET = 128;\nconst STANDARD_PBR_TEXTURE_COORDINATE_STRIDE = 8;\nconst DEFAULT_LEGACY_TEXTURE_SCALES = new Float32Array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);\nconst DEFAULT_STANDARD_TEXTURE_COORDINATES = new Float32Array([\n 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,\n 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,\n]);\n\n/** Derives the logical-content UV scale for an uploaded material texture. */\nexport function materialTextureUvScale(\n texture: Pick<TextureAsset, 'width' | 'height' | 'format'> | undefined,\n): readonly [number, number] {\n if (texture === undefined) return [1, 1];\n return deriveTextureExtent(texture.format, texture.width, texture.height).uvScale;\n}\n\nfunction materialTextureForField(\n material: MaterialSnapshot,\n field: string,\n): Handle<'TextureAsset', 'shared'> | undefined {\n if (field === 'emissiveTexture') return material.emissiveTexture;\n if (field === 'occlusionTexture') return material.occlusionTexture;\n return material.textureHandles?.get(field);\n}\n\n/**\n * Appends the engine-owned scale for every built-in material texture binding.\n * Asset dimensions remain logical; this is the sole record-stage projection\n * from a bound texture asset to its shader sampling coordinates.\n */\ntype MaterialUboPayload = ArrayBuffer | Uint8Array | Float32Array;\n\nfunction materialUboFloatView(payload: MaterialUboPayload): Float32Array {\n if (payload instanceof Float32Array) return payload;\n return payload instanceof Uint8Array\n ? new Float32Array(payload.buffer, payload.byteOffset, payload.byteLength / 4)\n : new Float32Array(payload);\n}\n\nexport function applyMaterialTextureUvScales(\n payload: MaterialUboPayload,\n material: MaterialSnapshot,\n world: World,\n): void {\n const f32 = materialUboFloatView(payload);\n const coordinateSchema = materialCoordinateSchema(material);\n if (coordinateSchema !== undefined) {\n const coordinateRecords = derivedParamSchema(coordinateSchema).coordinateRecords;\n for (const record of coordinateRecords) {\n const field = record.parameter;\n const handle = materialTextureForField(material, field);\n const resolvedTexture =\n handle === undefined ? undefined : resolveAssetHandle<TextureAsset>(world, handle);\n const texture = resolvedTexture?.ok === true ? resolvedTexture.value : undefined;\n const [u, v] = materialTextureUvScale(texture);\n const coordinates = resolveMaterialTextureCoordinates(\n material.textureCoordinates?.get(field),\n );\n const offset = record.offset / 4;\n f32[offset] = coordinates.transform.offset[0];\n f32[offset + 1] = coordinates.transform.offset[1];\n f32[offset + 2] = coordinates.transform.scale[0];\n f32[offset + 3] = coordinates.transform.scale[1];\n f32[offset + 4] = coordinates.set;\n f32[offset + 5] = coordinates.transform.rotation;\n f32[offset + 6] = u;\n f32[offset + 7] = v;\n }\n return;\n }\n // Standard PBR has a schema-derived 128-byte authored region before the\n // engine-owned UV records. Sprite, sprite-lit, unlit, and text keep their\n // own legacy tail positions because their WGSL layouts differ.\n const textureScaleOffset = isStandardPbrMaterialShader(material.materialShaderId)\n ? STANDARD_PBR_TEXTURE_SCALE_OFFSET\n : LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET;\n const isStandardPbr = textureScaleOffset === STANDARD_PBR_TEXTURE_SCALE_OFFSET;\n const hasTextureMetadata =\n material.textureCoordinates !== undefined ||\n material.textureHandles !== undefined ||\n material.videoTextureFields !== undefined ||\n material.baseColorTexture !== undefined ||\n material.metallicRoughnessTexture !== undefined ||\n material.normalTexture !== undefined ||\n material.emissiveTexture !== undefined ||\n material.occlusionTexture !== undefined;\n if (!hasTextureMetadata) {\n f32.set(\n isStandardPbr ? DEFAULT_STANDARD_TEXTURE_COORDINATES : DEFAULT_LEGACY_TEXTURE_SCALES,\n textureScaleOffset / 4,\n );\n return;\n }\n const fields = isStandardPbr\n ? MATERIAL_TEXTURE_SCALE_FIELDS\n : LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS;\n for (let index = 0; index < fields.length; index++) {\n const field = fields[index];\n if (field === undefined) continue;\n const handle = materialTextureForField(material, field);\n const resolved =\n handle === undefined ? undefined : resolveAssetHandle<TextureAsset>(world, handle);\n const texture = resolved?.ok === true ? resolved.value : undefined;\n const [u, v] = materialTextureUvScale(texture);\n if (isStandardPbr) {\n const coordinates = material.textureCoordinates?.get(field);\n const transform = coordinates?.transform;\n const offset =\n STANDARD_PBR_TEXTURE_COORDINATE_OFFSET / 4 + index * STANDARD_PBR_TEXTURE_COORDINATE_STRIDE;\n f32[offset] = transform?.offset?.[0] ?? 0;\n f32[offset + 1] = transform?.offset?.[1] ?? 0;\n f32[offset + 2] = transform?.scale?.[0] ?? 1;\n f32[offset + 3] = transform?.scale?.[1] ?? 1;\n f32[offset + 4] = coordinates?.set ?? 0;\n f32[offset + 5] = transform?.rotation ?? 0;\n f32[offset + 6] = u;\n f32[offset + 7] = v;\n } else {\n const offset = textureScaleOffset / 4 + index * 2;\n f32[offset] = u;\n f32[offset + 1] = v;\n }\n }\n}\n\nfunction materialCoordinateSchema(\n material: MaterialSnapshot,\n): readonly ParamSchemaEntry[] | undefined {\n if (\n isStandardPbrMaterialShader(material.materialShaderId) &&\n material.paramSnapshot !== undefined\n ) {\n return DEFAULT_STANDARD_PBR_PARAM_SCHEMA;\n }\n if (material.materialParamSchema !== undefined && material.materialParamSchema.length > 0) {\n return material.materialParamSchema;\n }\n switch (material.materialShaderId) {\n case 'forgeax::default-unlit':\n return DEFAULT_UNLIT_PARAM_SCHEMA;\n case 'forgeax::sprite':\n case 'forgeax::sprite-lit':\n return DEFAULT_SPRITE_PARAM_SCHEMA;\n case 'forgeax::msdf-text':\n return DEFAULT_MSDF_TEXT_PARAM_SCHEMA;\n default:\n return undefined;\n }\n}\n\n/**\n * feat-20260621-learn-render-5-5-parallax M2 / w8 (D-3): ordered user-region\n * texture field names for a material's bind-group assembly, derived from the\n * shader's paramSchema via the `derive()` SSOT (insertion order = sampler/\n * texture pair order in derive().bglEntries). Falls back to the built-in\n * fields only when the schema is unavailable; an explicit empty schema means\n * the authored material has no user-region textures.\n */\nexport function userRegionTextureFieldOrder(\n schema: Parameters<typeof derive>[0] | undefined,\n): readonly string[] {\n if (schema === undefined) return BUILTIN_USER_REGION_TEXTURE_FIELDS;\n const fields = [...derivedParamSchema(schema).textureFieldNames];\n return fields;\n}\n\n/**\n * feat-20260621-learn-render-5-5-parallax M2 / w8: the fallback texture view\n * for a user-region field when no handle is provided (graceful, charter P3).\n * normalTexture decodes to a flat tangent normal; everything else (baseColor,\n * MR, height, ...) uses the 1x1 white default (height white -> zero displacement).\n */\nexport function defaultViewForUserRegionField(\n field: string,\n pipelineState: PipelineState,\n): TextureView {\n if (field === 'normalTexture') return pipelineState.defaultNormalTextureView;\n if (field === 'baseColorTexture') return pipelineState.fallbackTextureView;\n return pipelineState.defaultWhiteTextureView;\n}\n\n/**\n * feat-20260527-sprite-nineslice M4 / w17 (AC-16): once-per-renderable\n * detection of \"Transform.scale below the four 9-slice corner anchors\". Pure\n * helper extracted out of recordFrame so unit tests can drive it without a\n * GPU device — the recordFrame loop calls this with its `transformWorld` /\n * `slices` / `renderableIndex` / `seenIndices` / `metrics` arguments.\n *\n * The scale-vs-anchor formula mirrors plan-strategy §D-3 — the world x scale must\n * accommodate `|slices.x| + |slices.z|`, and `scaleY` must accommodate\n * `|slices.y| + |slices.w|`. Slices ≡ all zero is a no-op (legacy quad\n * path); a breach increments `nineslice.scale-too-small` exactly once per\n * `renderableIndex` per RenderSystem lifetime via the `seenIndices` Set\n * (the same warn-once anchor pattern used for missing-texture sprites).\n *\n * @param transformWorld The entity's resolved Transform.world mat4 (16 floats column-major).\n * @param slices The four anchor distances `[left, top, right, bottom]`\n * (sentinel `bottom < 0` for tile mode is consumed via abs()).\n * @param renderableIndex The entity index into the validated renderables list.\n * @param seenIndices The per-frame-state guard Set; entries are added on increment.\n * @param metrics The owner-provided EngineMetrics counter.\n * @internal — exported for unit-test access (w17).\n */\nexport function detectNineSliceScaleTooSmall(\n transformWorld: Float32Array,\n slices: readonly [number, number, number, number],\n renderableIndex: number,\n seenIndices: Set<number>,\n metrics: { increment(name: string): void },\n): void {\n const anyNonZero = slices[0] !== 0 || slices[1] !== 0 || slices[2] !== 0 || slices[3] !== 0;\n if (!anyNonZero) return;\n const sx = Math.hypot(transformWorld[0] ?? 1, transformWorld[1] ?? 0, transformWorld[2] ?? 0);\n const sy = Math.hypot(transformWorld[4] ?? 0, transformWorld[5] ?? 1, transformWorld[6] ?? 0);\n const horizontalAnchor = Math.abs(slices[0]) + Math.abs(slices[2]);\n const verticalAnchor = Math.abs(slices[1]) + Math.abs(slices[3]);\n if (sx < horizontalAnchor || sy < verticalAnchor) {\n if (!seenIndices.has(renderableIndex)) {\n seenIndices.add(renderableIndex);\n metrics.increment('nineslice.scale-too-small');\n }\n }\n}\n\n/**\n * Build the 384-byte Material UBO payload for a PBR / unlit material entry\n * (feat-20260527-sprite-nineslice M2 / w11; D-7 regression-net helper).\n *\n * Byte-for-byte equivalent to the legacy hard-coded PBR write path; each\n * deviation is caught by `render-system-record-pbr-ubo-stable.test.ts`.\n * The schema-driven paramSnapshot overlay (feat-20260523 M9-T05; AC-14)\n * positions vec4 / f32 slots onto std140 [slot0 vec4, slot1 f32 metallic,\n * slot1 f32 roughness] mirroring the engine-shipped default-standard-pbr\n * Material struct.\n */\nexport function buildPbrMaterialUboPayload(material: MaterialSnapshot): Uint8Array {\n const buf = new Uint8Array(STANDARD_PBR_UBO_SIZE);\n writePbrMaterialUboPayload(buf, material);\n return buf;\n}\n\n/**\n * Write the standard material payload into caller-owned storage.\n *\n * The allocating wrapper above remains the byte-stable test/helper surface,\n * while the frame recorder reuses one scratch slot for all materials. A\n * scene with thousands of submeshes otherwise allocates one 384-byte\n * Uint8Array per material per frame, creating avoidable GC pressure without\n * changing GPU-visible bytes.\n */\nexport function writePbrMaterialUboPayload(\n buf: Uint8Array | Float32Array,\n material: MaterialSnapshot,\n): void {\n if (buf.byteLength < STANDARD_PBR_UBO_SIZE) {\n throw new RangeError(\n `writePbrMaterialUboPayload: expected at least ${STANDARD_PBR_UBO_SIZE} bytes, got ${buf.byteLength}`,\n );\n }\n buf.fill(0);\n const f32 = materialUboFloatView(buf);\n // Layout (issue-1: channelMap split per D-8) -- byte-equivalent to the\n // post-split sidecar paramSchema for default-standard-pbr (12 numeric\n // entries packed std140 into one merged UBO at binding(0)).\n // f32[0..3] baseColor (offset 0, vec4)\n // f32[4] metallic (offset 16)\n // f32[5] roughness (offset 20)\n // f32[6] metallicChannel (offset 24) -- glTF 2.0 default = B = 2\n // f32[7] roughnessChannel (offset 28) -- glTF 2.0 default = G = 1\n // f32[8] aoChannel (offset 32) -- glTF 2.0 default = R = 0\n // f32[9] extraChannel (offset 36) -- reserved = 0\n // (offset 40..47 implicit pad: vec3 align=16)\n // f32[12..14] emissive (offset 48, vec3)\n // f32[15] emissiveIntensity (offset 60)\n // f32[16] occlusionStrength (offset 64)\n // f32[17] alphaCutoff (offset 68)\n // f32[18] clearcoat (offset 72)\n // f32[19] clearcoatRoughness (offset 76)\n // f32[20..22] specularTint (offset 80, vec3)\n // f32[23] normalScale (offset 92)\n // f32[24] transmission (offset 96)\n // f32[25] ior (offset 100)\n // f32[26] thickness (offset 104)\n // f32[28..30] attenuationColor (offset 112, vec3)\n // f32[31] attenuationDistance(offset 124)\n // f32[32..95] engine-owned texture coordinate records (offset 128)\n f32[0] = material.baseColor[0] ?? 0;\n f32[1] = material.baseColor[1] ?? 0;\n f32[2] = material.baseColor[2] ?? 0;\n f32[3] = 1;\n f32[4] = material.metallic;\n f32[5] = material.roughness;\n // channelMap default = (B, G, R, _) per AGENTS.md + glTF 2.0\n // KHR_materials_pbrSpecularGlossiness ARM packing -- now 4 independent\n // f32 selectors; fragment casts each to u32 at the pick site.\n f32[6] = 2; // metallicChannel <- B\n f32[7] = 1; // roughnessChannel <- G\n f32[8] = 0; // aoChannel <- R\n f32[9] = 0; // extraChannel <- reserved\n // emissive vec3 + emissiveIntensity (offset 48..63)\n const em = material.emissive;\n f32[12] = em?.[0] ?? 0;\n f32[13] = em?.[1] ?? 0;\n f32[14] = em?.[2] ?? 0;\n f32[15] = material.emissiveIntensity ?? 0;\n // occlusionStrength (offset 64)\n f32[16] = material.occlusionStrength ?? 1;\n // alphaCutoff (offset 68).\n const alphaCutoff = material.paramSnapshot?.alphaCutoff;\n f32[17] = typeof alphaCutoff === 'number' ? alphaCutoff : 0;\n f32[18] = material.clearcoat ?? 0;\n f32[19] = material.clearcoatRoughness ?? 0.5;\n const specularTint = material.specularTint;\n f32[20] = specularTint?.[0] ?? 1;\n f32[21] = specularTint?.[1] ?? 1;\n f32[22] = specularTint?.[2] ?? 1;\n const snapshotNumber = (name: string, fallback: number): number => {\n const value = material.paramSnapshot?.[name];\n return typeof value === 'number' ? value : fallback;\n };\n const snapshotVec3 = (\n name: string,\n fallback: readonly [number, number, number],\n ): readonly [number, number, number] => {\n const value = material.paramSnapshot?.[name];\n return Array.isArray(value)\n ? [value[0] ?? fallback[0], value[1] ?? fallback[1], value[2] ?? fallback[2]]\n : fallback;\n };\n f32[23] = material.normalScale ?? snapshotNumber('normalScale', 1);\n f32[24] = snapshotNumber('transmission', 0);\n f32[25] = snapshotNumber('ior', 1.5);\n f32[26] = snapshotNumber('thickness', 0);\n const attenuationColor = snapshotVec3('attenuationColor', [1, 1, 1]);\n f32[28] = attenuationColor[0];\n f32[29] = attenuationColor[1];\n f32[30] = attenuationColor[2];\n f32[31] = snapshotNumber('attenuationDistance', 0);\n // Schema-driven paramSnapshot overlay (feat-20260523 M9-T05, AC-14):\n // for user-shaders with a paramSnapshot, project the first vec4/color\n // entry onto slot 0 and the first two f32 entries onto slot 1's first\n // two floats. The default-standard-pbr path lands on the same offsets\n // via the explicit fields above, so the overlay is a no-op for the\n // engine's stock PBR shader (charter P4 + R-H regression fence).\n const paramSnap = material.paramSnapshot;\n if (paramSnap !== undefined) {\n const f32Snap = (name: string): number | undefined => {\n const v = paramSnap[name];\n return typeof v === 'number' ? v : undefined;\n };\n const colorSnap = (name: string): readonly number[] | undefined => {\n const v = paramSnap[name];\n return Array.isArray(v) && v.every((x) => typeof x === 'number')\n ? (v as readonly number[])\n : undefined;\n };\n // Walk schema in declared order, fill positional UBO slots.\n const materialShaderId = material.materialShaderId;\n // Note: schema lookup is the caller's job (it owns the runtime ref);\n // when the helper has no access to runtime, paramSnap is consumed\n // positionally without a schema walk. The inline caller (recordFrame)\n // still performs the schema-driven walk and writes the overlay before\n // queueing this payload, so this helper is only the byte-stable\n // baseline. To preserve byte-for-byte equivalence in the helper-only\n // unit-test path, the overlay pass is skipped when the helper is\n // called without an external schema reference.\n void materialShaderId;\n void f32Snap;\n void colorSnap;\n }\n}\n\n/**\n * Generic std140 UBO writer driven by `derive(paramSchema).uboLayout.entries`\n * (feat-20260625-refactor-sprite-as-transparent-mesh M1 / w3, plan-strategy\n * section 2 D-2).\n *\n * For each numeric entry in the schema, looks up the matching value in\n * `paramSnapshot` and writes it at the std140 offset `derive` computed.\n * Vec / color entries pull from `paramSnapshot[name]` as a `readonly number[]`\n * (writes `min(size/4, value.length)` floats, padding with 0 if shorter for\n * the field's declared width); scalar entries pull a single number.\n *\n * Behaviour:\n * - schema or snapshot `undefined` -> no writes (caller may keep payload\n * baseline).\n * - missing snapshot field -> that field's bytes are left untouched\n * (overlay semantics; same shape the legacy inline overlay had).\n * - field type the writer cannot interpret (texture / sampler / storage_\n * buffer / value-type mismatch) -> skipped silently; `derive` strips\n * non-numeric entries from `uboLayout.entries` so the loop only iterates\n * numeric fields.\n *\n * The writer reads `paramSnapshot` only -- it does NOT call\n * `runtime.assets.get<MaterialAsset>` or cast `firstMaterial`. Gate R-H\n * (plan-strategy section 5.6) bans those paths through\n * `scripts/forgeax/check-render-record-no-material-asset-get.mjs`.\n *\n * standard-pbr remains byte-identical to `buildPbrMaterialUboPayload`: the\n * engine's stock PBR material ships `paramSnapshot: undefined`, so this\n * writer is a no-op on that path; the explicit field writes in the helper\n * above cover every byte. User shaders (sprite-shaped 4 x vec4 or another\n * paramSchema) get their fields written at the offsets declared by derive.\n *\n * @internal export-for-test (consumed inside `recordFrame` + render-system-\n * record.test.ts; not part of the package's public surface).\n */\nexport function applyParamSnapshotToUbo(\n payload: MaterialUboPayload,\n paramSchema: readonly ParamSchemaEntry[] | undefined,\n paramSnapshot:\n | Readonly<Record<string, number | readonly number[] | string | undefined>>\n | undefined,\n): void {\n if (paramSchema === undefined) return;\n if (paramSnapshot === undefined) return;\n const f32 = materialUboFloatView(payload);\n const effectiveSchema =\n Object.hasOwn(paramSnapshot, 'transmission') &&\n Object.hasOwn(paramSnapshot, 'ior') &&\n Object.hasOwn(paramSnapshot, 'thickness')\n ? DEFAULT_STANDARD_PBR_PARAM_SCHEMA\n : paramSchema;\n const { uboLayout } = derivedParamSchema(effectiveSchema);\n for (const entry of uboLayout.entries) {\n const value = paramSnapshot[entry.name];\n if (value === undefined) continue;\n const f32Offset = entry.offset / 4;\n const f32Width = entry.size / 4;\n if (typeof value === 'number') {\n // Scalar f32 / i32 / u32 -- single-slot write. (i32 / u32 still arrive\n // as a JS number; the GPU side reads the four bytes as the declared\n // type, so an f32 write is the correct bit pattern when the caller\n // already produced an integer value.)\n if (f32Width >= 1) f32[f32Offset] = value;\n continue;\n }\n if (Array.isArray(value)) {\n const arr = value as readonly number[];\n const writeCount = Math.min(arr.length, f32Width);\n for (let i = 0; i < writeCount; i++) {\n const v = arr[i];\n if (typeof v === 'number') f32[f32Offset + i] = v;\n }\n }\n // string values (texture GUIDs) belong to texture bindings, not the\n // UBO; derive's uboLayout.entries already strips non-numeric schema\n // entries, so we will not see a uboLayout entry whose snapshot value\n // is a string under normal flow. Skip defensively if we do.\n }\n}\n\n/**\n * feat-20260704 M3/w19: shared per-submesh material bind-group assembly, hoisted\n * from the `buildPerSubmeshMaterialBg` closure inside recordMainPass so both the\n * geometry pass and the LDR blend sub-pass (extracted to separate functions)\n * call the identical layout.\n *\n * feat-city-glb Bug 5 (per-submesh transparency): a transparent PBR submesh\n * binds the identical metallic/roughness/normal/emissive/occlusion +\n * Skylight layout the geometry pass uses (the sub-pass previously bound a\n * sprite-only BG, which cannot render a PBR decal). The per-frame closure state\n * (runtime / pipelineState / world / store / skylightResources / the shared\n * material BG cache + counters) is threaded through `deps`; the caller passes\n * the per-submesh material snapshot + entityKey (video texture routing) and sets\n * the dynamic UBO offset itself.\n *\n * @internal\n */\nexport interface PerSubmeshMaterialBgDeps {\n readonly runtime: RenderSystemRuntime;\n readonly pipelineState: PipelineState;\n readonly world: World;\n readonly store: GpuResidencyCache;\n readonly materialSlice: number;\n readonly videoHighPerfAvailable: boolean;\n readonly skylightResources: SkylightBindGroupResources;\n readonly materialBgShared: Map<string, WeakMap<object, unknown>>;\n /** Cross-frame final BG reuse keyed by the stable source material handle. */\n readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;\n /** Active transmission backdrop; undefined/null means layout placeholder. */\n readonly transmissionBackdropView?: TextureView | null;\n readonly bindGroupCounts: BindGroupCounts;\n}\n\n/** @internal Exported only so buffer-generation invalidation stays regression-tested. */\nexport function isMaterialBgAssemblyCacheHit(\n cached: MaterialBgAssemblyCacheEntry | undefined,\n material: MaterialSnapshot,\n materialBgl: BindGroupLayout,\n materialBuffer: Buffer,\n skylightResources: SkylightBindGroupResources,\n materialResourceEpoch: number,\n transmissionBackdropView?: TextureView | null,\n): cached is MaterialBgAssemblyCacheEntry {\n if (transmissionBackdropView != null) return false;\n return (\n cached?.material === material &&\n cached.materialResourceEpoch === materialResourceEpoch &&\n cached.materialBgl === materialBgl &&\n cached.materialBuffer === materialBuffer &&\n cached.skylightResources.irradianceView === skylightResources.irradianceView &&\n cached.skylightResources.irradianceSampler === skylightResources.irradianceSampler &&\n cached.skylightResources.prefilterView === skylightResources.prefilterView &&\n cached.skylightResources.prefilterSampler === skylightResources.prefilterSampler &&\n cached.skylightResources.brdfLutView === skylightResources.brdfLutView &&\n cached.skylightResources.brdfLutSampler === skylightResources.brdfLutSampler &&\n cached.skylightResources.intensityBuffer === skylightResources.intensityBuffer\n );\n}\n\nexport function buildPerSubmeshMaterialBg(\n deps: PerSubmeshMaterialBgDeps,\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World = deps.world,\n): BindGroup {\n const {\n runtime,\n pipelineState,\n store,\n materialSlice,\n videoHighPerfAvailable,\n skylightResources,\n materialBgShared,\n materialBgAssemblyCache,\n transmissionBackdropView,\n bindGroupCounts,\n } = deps;\n const smMaterialHandle = submeshMaterial.materialHandle;\n const materialCacheKey =\n smMaterialHandle === undefined ? undefined : `${materialWorld.identity}:${smMaterialHandle}`;\n const smHasVideoFields = (submeshMaterial.videoTextureFields?.size ?? 0) > 0;\n const smShaderId = submeshMaterial.materialShaderId;\n const smPerShaderBgl =\n smShaderId !== undefined ? runtime.getMaterialBindGroupLayout?.(smShaderId) : undefined;\n const smMaterialBgl = smPerShaderBgl ?? pipelineState.materialBindGroupLayout;\n const hasActiveTransmissionBackdrop = transmissionBackdropView != null;\n if (smMaterialHandle !== undefined && !smHasVideoFields && !hasActiveTransmissionBackdrop) {\n const cached =\n materialCacheKey === undefined ? undefined : materialBgAssemblyCache.get(materialCacheKey);\n if (\n isMaterialBgAssemblyCacheHit(\n cached,\n submeshMaterial,\n smMaterialBgl,\n pipelineState.materialUniformBuffer.buffer,\n skylightResources,\n store.materialResourceEpoch,\n transmissionBackdropView,\n )\n ) {\n return cached.bindGroup;\n }\n }\n const smSchema =\n submeshMaterial.materialParamSchema ??\n (smShaderId !== undefined ? runtime.getParamSchema?.(smShaderId) : undefined);\n // The shipped PBR shaders always own the eight texture pairs declared by the\n // standard shader artifact. The runtime PBR BGL exposes those pairs directly;\n // emissive and occlusion are not duplicated in an engine injection region.\n // Keep the record projection on the shader-owned layout so IBL starts at\n // binding 17 rather than colliding with transmissionSampler.\n const smUserRegionFields =\n smPerShaderBgl === undefined || isStandardPbrMaterialShader(smShaderId)\n ? BUILTIN_USER_REGION_TEXTURE_FIELDS\n : userRegionTextureFieldOrder(smSchema);\n let materialResourcesResident = true;\n const smSamplerForField = (field: string | undefined): Sampler => {\n const handle = field === undefined ? undefined : submeshMaterial.samplerHandles?.get(field);\n if (handle === undefined) return pipelineState.defaultSampler;\n const sampler = residentSampler(materialWorld, store, runtime, handle);\n if (sampler === undefined) materialResourcesResident = false;\n return sampler ?? pipelineState.defaultSampler;\n };\n const smBaseEntries: BindGroupEntry[] = [\n {\n binding: 0,\n resource: {\n kind: 'buffer' as const,\n value: {\n buffer: pipelineState.materialUniformBuffer.buffer,\n offset: 0,\n size: materialSlice,\n },\n },\n },\n ];\n const smBglPairCount = smUserRegionFields.length;\n for (let fi = 0; fi < smBglPairCount; fi++) {\n const field = smUserRegionFields[fi];\n const samplerBinding = 1 + fi * 2;\n const textureBinding = samplerBinding + 1;\n let smView: TextureView =\n field !== undefined\n ? defaultViewForUserRegionField(field, pipelineState)\n : pipelineState.defaultWhiteTextureView;\n const smVideoClip =\n field !== undefined ? submeshMaterial.videoTextureFields?.get(field) : undefined;\n if (smVideoClip !== undefined) {\n const view = videoTextureView(\n materialWorld,\n runtime.dynamicTextureStore,\n runtime,\n entityKey,\n smVideoClip,\n videoHighPerfAvailable,\n );\n if (view !== undefined) smView = view;\n } else {\n const smHandle =\n field === 'emissiveTexture'\n ? submeshMaterial.emissiveTexture\n : field === 'occlusionTexture'\n ? submeshMaterial.occlusionTexture\n : field !== undefined\n ? submeshMaterial.textureHandles?.get(field)\n : undefined;\n if (smHandle !== undefined) {\n const view = residentTextureView(materialWorld, store, runtime, smHandle);\n if (view !== undefined) smView = view;\n else materialResourcesResident = false;\n }\n }\n smBaseEntries.push(\n {\n binding: samplerBinding,\n resource: { kind: 'sampler' as const, value: smSamplerForField(field) },\n },\n {\n binding: textureBinding,\n resource: { kind: 'textureView' as const, value: smView },\n },\n );\n }\n // The backdrop is a full mip-chain view owned by the pipeline. Reuse the\n // pipeline's existing filtering/clamp sampler for screen-space sampling;\n // the material default sampler intentionally keeps repeat addressing for\n // authored UV textures and is not a backdrop sampler.\n const transmissionSampler =\n transmissionBackdropView != null\n ? skylightResources.prefilterSampler\n : pipelineState.defaultSampler;\n const smMergedEntries = assembleMaterialWithSkylightEntries(smBaseEntries, skylightResources, {\n sampler: transmissionSampler,\n ...(transmissionBackdropView === undefined ? {} : { backdropView: transmissionBackdropView }),\n } satisfies TransmissionBindGroupResources);\n const createBindGroup = (): BindGroup => {\n const result = runtime.device.createBindGroup({\n label: 'pbr-material-skylight-bg',\n layout: smMaterialBgl,\n entries: smMergedEntries,\n });\n if (!result.ok) throw result.error;\n return result.value;\n };\n const smBindGroup = hasActiveTransmissionBackdrop\n ? createBindGroup()\n : getOrCreatePerEntity(\n materialBgShared,\n smShaderId ?? '',\n smMergedEntries.map((e) => extractEntryResourceHandle(e)),\n 'material-shared',\n createBindGroup,\n bindGroupCounts,\n );\n if (\n smMaterialHandle !== undefined &&\n !smHasVideoFields &&\n materialResourcesResident &&\n !hasActiveTransmissionBackdrop\n ) {\n if (materialCacheKey !== undefined) {\n materialBgAssemblyCache.set(materialCacheKey, {\n material: submeshMaterial,\n materialResourceEpoch: store.materialResourceEpoch,\n materialBgl: smMaterialBgl,\n materialBuffer: pipelineState.materialUniformBuffer.buffer,\n skylightResources,\n bindGroup: smBindGroup,\n });\n }\n }\n return smBindGroup;\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: main-pass geometry draws.\n// feat-20260704 M5/w31: further-split from main-pass.ts (AC-05 <=1500 lines/file).\n// recordGeometryDraws + resolveGeometryInstanceBuffer, moved verbatim.\n\nimport type { World } from '@forgeax/engine-ecs';\nimport {\n type BindGroup,\n type Buffer,\n type RenderPipeline,\n RhiError,\n type RhiRenderPassEncoder,\n} from '@forgeax/engine-rhi';\nimport type { PassKind, PrimitiveTopology } from '@forgeax/engine-types';\nimport { GpuBuffer } from '../gpu-resource';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_STORAGE,\n GPU_BUFFER_USAGE_UNIFORM,\n} from '../gpu-usage';\nimport type { InstanceBufferCacheEntry } from '../instance-buffer-cache';\nimport { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';\nimport { SKIN_MATERIAL_SHADER_ID } from '../pbr-pipeline';\nimport { renderStateHash, variantSetFromVertexLayoutProjection } from '../pipeline-spec';\nimport type { PointsLinesRecordPlan } from '../points-lines/record';\nimport { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';\nimport type { RenderRecordPhase } from '../render-contract';\nimport type { MaterialSnapshot } from '../render-system-extract';\nimport { worldEntityKey } from './frame-snapshot';\nimport {\n geometryRenderStateForTopology,\n isEntityFullyTransparent,\n selectGeometryPipeline,\n} from './main-pass-material';\nimport {\n getOrCreateFromChain,\n INSTANCE_UBO_FULL_ARRAY_BYTES,\n MAX_UNIFORM_INSTANCES,\n MESH_PER_ENTITY_STRIDE,\n MESH_SSBO_BYTES,\n MESH_UBO_FULL_ARRAY_BYTES,\n packInstanceStorageBuffer,\n} from './mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { MATERIAL_PER_ENTITY_STRIDE } from './render-context';\nimport { POINTS_LINES_VIEW_SLOT_STRIDE, writePointsLinesViewUbo } from './view-ubo';\n\ntype GeometryInstanceDraw = {\n readonly instanceBuffer: Buffer;\n readonly instanceBindGroup: BindGroup;\n readonly instanceCount: number;\n};\n\ntype GeometryBindingState = {\n pipeline: RenderPipeline | null;\n instancesBuffer: Buffer | null;\n};\n\ntype MaterialPipelineLookup = {\n readonly materialShaderId: string;\n readonly isHdrTarget: boolean;\n readonly renderStateKey: string;\n readonly topology: PrimitiveTopology;\n readonly indexFormat: 'uint16' | 'uint32';\n readonly variantSet: string | undefined;\n readonly passKind: PassKind;\n readonly layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection;\n readonly sampleCount: number;\n readonly colorFormatOverride: GPUTextureFormat | undefined;\n readonly handle: RenderPipeline | null;\n};\n\ntype GeometryRecordProfileSegment = 'material-bind-groups' | 'pipeline-selection' | 'draw-submit';\n\ntype GeometryRenderState = ReturnType<typeof geometryRenderStateForTopology>;\n\n/**\n * Resolve the depth contract for a geometry pass without changing the base\n * material state. Temporal scene-data shares the main pass depth attachment:\n * it is read-only and accepts the equal depth produced by the unjittered\n * temporal projection, while still rejecting fragments behind the visible\n * surface.\n */\nexport function geometryRenderStateForPass(\n base: GeometryRenderState,\n passKind: PassKind,\n): GeometryRenderState {\n if (passKind !== 'temporal') return base;\n return {\n ...base,\n depthWriteEnabled: false,\n depthCompare: 'less-equal' as const,\n };\n}\n\nfunction geometryRecordPhase(\n passKind: PassKind,\n segment: GeometryRecordProfileSegment,\n): RenderRecordPhase {\n const pass = passKind === 'deferred' ? 'g-buffer' : 'forward';\n return `record/graph-execute/${pass}/${segment}` as RenderRecordPhase;\n}\n\nfunction profileGeometrySegment<T>(\n c: _InternalRenderPipelineContext,\n passKind: PassKind,\n segment: GeometryRecordProfileSegment,\n action: () => T,\n): T {\n const profilePhase = c.profilePhase;\n return profilePhase === undefined\n ? action()\n : profilePhase(geometryRecordPhase(passKind, segment), action);\n}\n\nfunction submitSubmeshDraws(\n pass: RhiRenderPassEncoder,\n state: GeometryBindingState,\n pipeline: RenderPipeline,\n instanceDraws: readonly GeometryInstanceDraw[],\n indexed: boolean,\n indexCount: number,\n vertexCount: number,\n indexOffset: number,\n): void {\n if (state.pipeline !== pipeline) {\n pass.setPipeline(pipeline);\n state.pipeline = pipeline;\n }\n for (const instanceDraw of instanceDraws) {\n if (instanceDraw.instanceBuffer !== state.instancesBuffer) {\n pass.setBindGroup(3, instanceDraw.instanceBindGroup);\n state.instancesBuffer = instanceDraw.instanceBuffer;\n }\n if (indexed) {\n pass.drawIndexed(indexCount, instanceDraw.instanceCount, indexOffset, 0, 0);\n } else {\n pass.draw(vertexCount, instanceDraw.instanceCount, 0, 0);\n }\n }\n}\n\n/**\n * Issues a prepared Points/Lines draw into the already-open geometry pass.\n * Pass lifetime, attachments, bind groups, and submission remain owned by the\n * existing main-pass interpreter.\n */\nexport function recordPointsLinesDraw(\n pass: RhiRenderPassEncoder,\n plan: PointsLinesRecordPlan,\n): void {\n if (plan.drawCount === 0) return;\n if (plan.indexCount > 0) {\n pass.drawIndexed(plan.indexCount, 1, 0, 0, 0);\n return;\n }\n pass.draw(plan.vertexCount, 1, 0, 0);\n}\n\n/**\n * feat-20260704 M3/w19: per-entity geometry (main colour) draw loop, extracted\n * verbatim from recordMainPass. Walks `c.validatedOrdered`, selects the\n * per-entity / per-submesh PBR / unlit / skin pipeline, uploads the per-submesh\n * material UBO slices, binds view / material / mesh / instances bind groups, and\n * issues the per-submesh draws into the already-begun geometry `pass`. Fully-\n * transparent entities are skipped here (drawn in the LDR blend sub-pass);\n * mixed meshes draw their opaque submeshes here and skip transparent submeshes.\n * The pass-selector match set, per-entity material-slot start table, MSAA sample\n * count, Standard group(2) bind group, fallback mesh group(2) bind group, and\n * the shared per-submesh material BG builder are threaded in explicitly.\n *\n * @internal\n */\nexport function recordGeometryDraws(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n matchedMaterials: ReadonlyMap<number, ReadonlySet<number>> | null,\n materialSlotIndices: readonly (readonly number[])[],\n sampleCount: number,\n meshGroup2: BindGroup | null,\n meshBindGroup: BindGroup | null,\n resolveMaterialBindGroup: (\n materialSlot: number,\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World,\n ) => BindGroup,\n passKind: PassKind = 'forward',\n): void {\n const {\n runtime,\n pipelineState,\n frameState,\n bindGroupCounts,\n dispatchCounts,\n tonemapActive,\n msaaActive,\n validatedOrdered,\n splitLdrSprite,\n viewBindGroup,\n } = c;\n const colorFormatOverride = c.transparentColorFormat as GPUTextureFormat | undefined;\n // A no-tone frame may still render into the graph-owned rgba16float target\n // (the linear-LDR route). Shader variants must follow the attachment's\n // numeric domain rather than the camera's tone-map switch, otherwise the\n // LDR/OETF fragment entry point is encoded once here and again by the\n // output transform.\n const isHdrTarget = tonemapActive || colorFormatOverride === 'rgba16float';\n let lastVertexBuffer: GpuBuffer | null = null;\n let lastIndexBuffer: GpuBuffer | null = null;\n const bindingState: GeometryBindingState = {\n pipeline: null,\n instancesBuffer: null,\n };\n const identityInstanceBuffer = pipelineState.identityInstanceBuffer;\n const identityInstanceDraws: readonly GeometryInstanceDraw[] = [\n {\n instanceBuffer: identityInstanceBuffer,\n instanceBindGroup: resolveGeometryInstancesBindGroup(c, identityInstanceBuffer),\n instanceCount: 1,\n },\n ];\n const profilePhase = c.profilePhase;\n const materialGroup1DynamicOffsets = new Uint32Array(1);\n const meshGroup2DynamicOffsets = [0];\n const skinGroup2DynamicOffsets = [0, 0];\n let lastStencilReference: number | null = null;\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (D-7):\n // sprite PSO selection no longer maintains a dedicated tag — the\n // generic materialShaderId path covers sprite via the same per-\n // MaterialShader pipeline cache PBR / unlit use. The 4-placeholder\n // BG bindings (D-1 candidate b) still apply via the generic per-\n // submesh BG construction below; sprite's `forgeax::sprite` shader\n // module ships through the same cache key formula.\n // Pipeline identity does not include material parameters or the material\n // asset handle. Keying this cache by material handle therefore misses for\n // every distinct asset even when all assets use the same PSO. The nested\n // table keeps lookup O(1) by shader and immutable render-state identity; the\n // renderer's authoritative cache still owns lifetime/invalidation, while\n // this frame-local table removes the hot call/lookup overhead.\n const materialPipelineLookupCache = new Map<string, Map<string, MaterialPipelineLookup[]>>();\n const resolveMaterialPipeline = (\n materialShaderId: string,\n renderState: MaterialSnapshot['renderState'],\n topology: PrimitiveTopology,\n indexFormat: 'uint16' | 'uint32',\n variantSet: string | undefined,\n colorFormat: GPUTextureFormat | undefined,\n layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection,\n ): RenderPipeline | null => {\n const renderStateKey = renderStateHash(renderState);\n const shaderLookupCache = materialPipelineLookupCache.get(materialShaderId);\n const cachedLookups = shaderLookupCache?.get(renderStateKey);\n if (cachedLookups !== undefined) {\n for (const cached of cachedLookups) {\n if (\n cached.isHdrTarget === isHdrTarget &&\n cached.renderStateKey === renderStateKey &&\n cached.topology === topology &&\n cached.indexFormat === indexFormat &&\n cached.variantSet === variantSet &&\n cached.passKind === passKind &&\n cached.layoutProjection.digest === layoutProjection.digest &&\n cached.sampleCount === sampleCount &&\n cached.colorFormatOverride === colorFormat\n ) {\n return cached.handle;\n }\n }\n }\n const resolvedVariantSetResult =\n variantSet === undefined &&\n (materialShaderId === 'forgeax::sprite' || materialShaderId === 'forgeax::sprite-lit')\n ? ({ ok: true, value: undefined } as const)\n : variantSetFromVertexLayoutProjection(layoutProjection, variantSet);\n if (!resolvedVariantSetResult.ok) {\n runtime.errorRegistry.fire(resolvedVariantSetResult.error);\n return null;\n }\n const resolvedVariantSet = resolvedVariantSetResult.value;\n const resolvePipeline = () =>\n runtime.getMaterialShaderPipeline?.(\n materialShaderId,\n isHdrTarget,\n renderState,\n topology,\n indexFormat,\n resolvedVariantSet,\n passKind,\n undefined,\n sampleCount,\n colorFormat,\n undefined,\n undefined,\n undefined,\n layoutProjection,\n ) ?? null;\n const handle =\n profilePhase === undefined\n ? resolvePipeline()\n : profileGeometrySegment(c, passKind, 'pipeline-selection', resolvePipeline);\n // A null handle is a transient async-build signal (`rhi-not-available`),\n // not a stable pipeline result. Do not memoize it in this frame's lookup:\n // caching the first pending lookup would turn a one-frame shader warm-up\n // into a permanent skip for every later frame in a tight smoke loop. The\n // owning runtime cache remains the SSOT; retrying here is bounded by the\n // existing per-frame draw path and preserves the explicit skip-draw\n // recovery while the pipeline becomes ready.\n if (handle !== null) {\n const nextLookup: MaterialPipelineLookup = {\n materialShaderId,\n isHdrTarget,\n renderStateKey,\n topology,\n indexFormat,\n variantSet,\n passKind,\n layoutProjection,\n sampleCount,\n colorFormatOverride: colorFormat,\n handle,\n };\n if (shaderLookupCache === undefined) {\n materialPipelineLookupCache.set(\n materialShaderId,\n new Map([[renderStateKey, [nextLookup]]]),\n );\n } else if (cachedLookups === undefined) {\n shaderLookupCache.set(renderStateKey, [nextLookup]);\n } else {\n cachedLookups.push(nextLookup);\n }\n }\n return handle;\n };\n\n for (let i = 0; i < validatedOrdered.length; i++) {\n const entry = validatedOrdered[i];\n if (entry === undefined) continue;\n\n // Points/Lines share the Standard geometry pass. Their retained source\n // is prepared once by the renderer owner, while this loop remains the\n // sole pass/draw submission owner and preserves the authored topology.\n const pointsLinesSubmission = c.pointsLines?.prepare(entry, frameState.isHdrpActive);\n if (entry.source.pointsLines !== undefined && pointsLinesSubmission?.plan.drawCount !== 1)\n continue;\n\n if (\n passKind === 'forward' &&\n c.gpuDrivenEntityKeys.has(worldEntityKey(entry.source.worldId, entry.source.entityKey))\n ) {\n continue;\n }\n\n // feat-20260609 M2: skip entities that don't match the pass selector.\n if (matchedMaterials !== null && !matchedMaterials.has(entry.renderableIndex)) continue;\n\n // D-2 generalised feat-20260625 M2 / w7: transparent entities are\n // dispatched in the separate sub-pass (bgra8unorm unorm view,\n // loadOp=load) so they must NOT be drawn here in the geometry pass\n // (bgra8unorm-srgb sRGB view, loadOp=clear). In the HDR path\n // (tonemapActive=true) or when there are no transparent entries,\n // splitLdrSprite=false and this guard is a no-op. Post-w13 the\n // legacy shadingModel arm is gone; transparent is the single SSOT\n // mirrored on `computeSplitLdrSprite`.\n //\n // feat-city-glb Bug 5 (per-submesh transparency): only skip the WHOLE\n // entity here when EVERY submesh is transparent (the sprite / fully-\n // transparent-mesh fast path, byte-identical to the pre-fix behavior for\n // single-material entities). A mixed mesh (opaque road submesh + BLEND\n // decal submesh) is NOT skipped at the entity level; its opaque submeshes\n // draw here and the per-submesh loop below skips the transparent ones\n // (they are drawn in the blend sub-pass instead).\n if (splitLdrSprite && isEntityFullyTransparent(entry.source)) continue;\n\n const pipelineTag: 'unlit' = 'unlit';\n\n // w10: setStencilReference per draw when the dispatch entry carries\n // a stencil reference value (plan-strategy D-3: draw-call dynamic\n // state after setPipeline). Defaults to 0 when no reference is set\n // (WebGPU stencil reference default, semantically a no-op).\n const stencilReference = entry.stencilReference ?? 0;\n if (stencilReference !== lastStencilReference) {\n pass.setStencilReference(stencilReference);\n lastStencilReference = stencilReference;\n }\n\n if (pointsLinesSubmission !== undefined && entry.source.pointsLines !== undefined) {\n const pointsLinesMaterial: MaterialSnapshot = {\n ...entry.source.material,\n materialShaderId: POINTS_LINES_MATERIAL_SHADER_ID,\n materialParamSchema:\n runtime.getParamSchema?.(POINTS_LINES_MATERIAL_SHADER_ID) ??\n entry.source.material.materialParamSchema,\n };\n const materialSlot = materialSlotIndices[i]?.[0] ?? 0;\n const pointsLinesBindGroup = resolveMaterialBindGroup(\n materialSlot,\n pointsLinesMaterial,\n entry.source.entityKey,\n entry.world ?? c.world,\n );\n const pointsLinesPipeline = resolveMaterialPipeline(\n POINTS_LINES_MATERIAL_SHADER_ID,\n {\n ...pointsLinesMaterial.renderState,\n cullMode: 'none',\n },\n 'triangle-list',\n 'uint32',\n undefined,\n colorFormatOverride,\n pointsLinesSubmission.layoutProjection,\n );\n if (pointsLinesPipeline === null) continue;\n if (pipelineState.pointsLinesViewBuffer === undefined) continue;\n writePointsLinesViewUbo(\n runtime.device.queue,\n pipelineState.pointsLinesViewBuffer,\n c.camera,\n c.targetW,\n c.targetH,\n entry.source.transform.world,\n entry.source.pointsLines.style,\n i * POINTS_LINES_VIEW_SLOT_STRIDE,\n );\n pass.setBindGroup(\n 0,\n viewBindGroup as BindGroup,\n new Uint32Array([i * POINTS_LINES_VIEW_SLOT_STRIDE]),\n 0,\n 1,\n );\n pass.setPipeline(pointsLinesPipeline);\n pass.setVertexBuffer(0, pointsLinesSubmission.vertexBuffer);\n pass.setIndexBuffer(pointsLinesSubmission.indexBuffer, 'uint32');\n materialGroup1DynamicOffsets[0] = materialSlot * MATERIAL_PER_ENTITY_STRIDE;\n pass.setBindGroup(1, pointsLinesBindGroup, materialGroup1DynamicOffsets, 0, 1);\n const pointsLinesMeshGroup = meshBindGroup ?? meshGroup2;\n if (pointsLinesMeshGroup === null) continue;\n pass.setBindGroup(2, pointsLinesMeshGroup, meshGroup2DynamicOffsets);\n pass.setBindGroup(\n 3,\n identityInstanceDraws[0]?.instanceBindGroup ??\n resolveGeometryInstancesBindGroup(c, identityInstanceBuffer),\n );\n recordPointsLinesDraw(pass, pointsLinesSubmission.plan);\n pass.setBindGroup(0, viewBindGroup as BindGroup, [0]);\n continue;\n }\n\n if (entry.mesh.vertexBuffer !== lastVertexBuffer) {\n pass.setVertexBuffer(0, entry.mesh.vertexBuffer.handle);\n lastVertexBuffer = entry.mesh.vertexBuffer;\n }\n // feat-20260604 M4 / w11: vertex-only meshes (indexed === false) carry no\n // index buffer; skip setIndexBuffer entirely and dispatch via pass.draw\n // below. Indexed meshes keep the existing setIndexBuffer path unchanged.\n if (entry.mesh.indexed && entry.mesh.indexBuffer !== lastIndexBuffer) {\n if (entry.mesh.indexBuffer !== null) {\n pass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);\n lastIndexBuffer = entry.mesh.indexBuffer;\n }\n }\n\n // Dispatch counter bump — sprite folds into the same 2-bucket\n // surface for now (`pipelineDispatchCounts.{unlit, standard}`\n // mirror the original 2-pipeline scope; sprite-bucket counters\n // can land in a follow-up if AI users need them separately).\n // sprite entries do not bump either counter — the bench (M-4)\n // can read sprite render counts via the transparent bucket\n // length instead.\n if (pipelineTag === 'unlit') dispatchCounts.unlit += 1;\n\n const instanceDraws = resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws);\n if (instanceDraws === null) continue;\n\n // feat-20260611 R2 / M8 / w28 (IS-14): skin entries need a 2-binding\n // group(2) BG matching `pbr-skin-pl` (binding 0 mesh-array UBO +\n // binding 1 palette UBO). Building this here -- not in the\n // `meshBindGroup` factory above -- because the binding-shape\n // (1-entry vs 2-entry) is per-entry, not per-frame. URP / HDRP\n // entries keep using `meshGroup2` (1-entry mesh-array or HDRP\n // unified). The skin-variant cache key includes both buffer\n // identities so a future allocator-driven palette buffer rotation\n // invalidates the BG without manual eviction.\n //\n // PSO-availability gate: only swap to the skin BG when (a) the\n // skin pipeline layout itself was built (charter P3 fail-stop on\n // BGL-build failure), AND (b) the skin PSO cache returns a non-null\n // pipeline for this entry. Without (b), the per-submesh selector\n // below falls back to URP `standardPipeline` (`pbr-pl` layout,\n // 1-entry mesh-array BGL); binding the 2-entry skin BG against\n // that pipeline reproduces the exact `pbr-mesh-array-bgl ... does\n // not match layout pbr-skin-mesh-array-bgl` device error R1\n // captured. Mirrors the uniform null skip-draw pattern (M6-T1).\n let group2BindGroup: BindGroup = meshGroup2 as BindGroup;\n // feat-20260612-skin-palette-per-frame-upload M3 / m3-2: dyn-offset\n // tuple follows the skin group2 offset contract. Defaults to the\n // length-1 non-skin shape; the skin branch below re-computes with the\n // per-entity `entry.source.skin.byteOffset` cursor.\n meshGroup2DynamicOffsets[0] = i * MESH_PER_ENTITY_STRIDE;\n let group2DynamicOffsets: readonly number[] = meshGroup2DynamicOffsets;\n const isSkinEntry = entry.source.skin !== undefined;\n // feat-20260612-skin-palette-per-frame-upload M1 / m1-3 + M6: the\n // record stage reads the GPU buffer reference through\n // `entry.source.skin.buffer` (per-slice carrier set at extract time\n // by allocateSlice). On the storage path every slice carries the\n // same shared buffer pointer, so the BG cache key collapses to one\n // entry per frame (miss=1 + hit=N-1). On the uniform fallback path\n // each slice carries its own per-entity 16320 B UBO, so the BG\n // cache key naturally splits per entity (one BG per buffer pointer)\n // -- there is no shared-buffer assumption to break under\n // 16 KiB UBO cap. Charter P3 explicit failure preserved: skin\n // entries skip when the pipeline layout is missing OR the slice\n // failed to allocate (no buffer field). dynOffset[1] = byteOffset\n // is 0 on the uniform path (entry already covers the full buffer)\n // and walks 0, 1536, 3072, ... on the storage path.\n const skinAllocator = pipelineState.skinPaletteAllocator;\n const skinSlice = entry.source.skin;\n const skinResources =\n isSkinEntry &&\n pipelineState.pbrSkinMeshBindGroupLayout !== null &&\n skinAllocator !== null &&\n skinSlice !== undefined\n ? {\n meshArrayBgl: pipelineState.pbrSkinMeshBindGroupLayout,\n paletteBuffer: skinSlice.buffer,\n paletteBindingWindowBytes: skinAllocator.bindingWindowBytes,\n }\n : null;\n // Probe the skin PSO cache up front so we can decide whether to swap\n // to the 2-binding skin BG. The same probe + selector is repeated in\n // the per-submesh loop below (the loop's variantSet derivation is\n // identical -- skin shader registers a single all-true variant so\n // the canonical empty-key rule applies on HDRP and the URP key is\n // the explicit expanded form, mirroring the standard PBR path).\n const skinVariantSetResult = variantSetFromVertexLayoutProjection(\n entry.mesh.layoutProjection,\n frameState.isHdrpActive\n ? ''\n : 'CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true',\n );\n if (!skinVariantSetResult.ok) runtime.errorRegistry.fire(skinVariantSetResult.error);\n const skinVariantSet = skinVariantSetResult.ok ? skinVariantSetResult.value : undefined;\n const skinPsoProbe =\n skinResources !== null && skinVariantSetResult.ok\n ? (runtime.getMaterialShaderPipeline?.(\n SKIN_MATERIAL_SHADER_ID,\n isHdrTarget,\n entry.source.material.renderState,\n entry.mesh.submeshes[0]?.topology ?? 'triangle-list',\n entry.mesh.indexFormat,\n skinVariantSet,\n passKind,\n undefined, // meshAttributes — skin probe uses first submesh, derive from entry\n sampleCount,\n colorFormatOverride,\n undefined,\n undefined,\n undefined,\n entry.mesh.layoutProjection,\n ) ?? null)\n : null;\n if (skinResources !== null && skinPsoProbe !== null) {\n const meshBindSize = runtime.device.caps.storageBuffer\n ? MESH_SSBO_BYTES\n : MESH_UBO_FULL_ARRAY_BYTES;\n // m3-2 / D-8: skin BG cache miss / hit instrumentation. The chain\n // walk no longer exposes a string key to `.has()`, so we derive\n // hit/miss from the w7 `bindGroupCounts.createBindGroup` accounting:\n // snapshot the counter, run `getOrCreateFromChain`, and compare. A\n // delta of 1 means the factory ran (miss); 0 means a chain hit. This\n // publishes the per-frame counter the m3-1 acceptanceCheck reads\n // (miss=1 + hit=N-1 across N skin entries sharing one allocator\n // buffer + mesh SSBO). Field is optional + opt-in (read via\n // structural cast so prod paths that omit the counter pay nothing).\n const skinStats = (pipelineState as { _skinBgCacheStats?: { miss: number; hit: number } })\n ._skinBgCacheStats;\n const skinMissesBefore = bindGroupCounts.createBindGroup;\n const skinBindGroup: BindGroup = getOrCreateFromChain(\n frameState.meshBindGroupCache,\n [pipelineState.meshStorageBuffer.buffer, skinResources.paletteBuffer],\n 'pbr-skin-mesh',\n () => {\n const result = runtime.device.createBindGroup({\n label: 'pbr-skin-mesh-bg',\n layout: skinResources.meshArrayBgl,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.meshStorageBuffer.buffer,\n offset: 0,\n size: meshBindSize,\n },\n },\n },\n {\n binding: 1,\n resource: {\n kind: 'buffer',\n value: {\n buffer: skinResources.paletteBuffer,\n offset: 0,\n // M6 SSOT: static BG entry size (= MAX_JOINTS * 64 =\n // 16320 B) sourced from the allocator. The per-draw\n // window slides via `group2DynamicOffsets[1]`\n // (= entry.source.skin.byteOffset) so this size\n // stays at the worst case across all skin entries\n // -- one BG covers every skinned draw in the frame\n // (m3-1b miss=1 + hit=N-1 contract). The allocator\n // guarantees `buffer.size >= byteOffset + this size`\n // so dynOffset[1] passes WebGPU validation.\n size: skinResources.paletteBindingWindowBytes,\n },\n },\n },\n ],\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n bindGroupCounts,\n );\n if (skinStats !== undefined) {\n if (bindGroupCounts.createBindGroup > skinMissesBefore) skinStats.miss += 1;\n else skinStats.hit += 1;\n }\n group2BindGroup = skinBindGroup;\n // m3-2: dyn-offset tuple uses the per-entity palette cursor M2 m2-6\n // wrote at the extract stage.\n // Replaces the prior PR #353 hard-coded `0` second slot -- every\n // skin entry now points the palette window at its own slice while\n // sharing the worst-case BG entry size above.\n skinGroup2DynamicOffsets[0] = i * MESH_PER_ENTITY_STRIDE;\n skinGroup2DynamicOffsets[1] = entry.source.skin?.byteOffset ?? 0;\n group2DynamicOffsets = skinGroup2DynamicOffsets;\n } else if (isSkinEntry) {\n // Skin entry but skin PSO not ready (cache miss / async build pending,\n // or skin pipeline layout failed at boot). Skip the draw rather than\n // fall back to URP `pbr-pl` against the 6-attribute skin VBO -- that\n // path produced the layer-3 / layer-4 device errors R1 captured. Once\n // the async PSO compile resolves the cache hits and the next frame\n // routes the skin BG + skin pipeline together. Mirrors the uniform\n // null skip-draw shape (M6-T1, charter P3 explicit failure).\n continue;\n }\n // feat-20260520-2d-sprite-layer-mvp M-3 / w25 (@fallback sprite\n // bucket): sprite entries get a per-entity material BindGroup so\n // each sprite carries its own texture binding at @group(1) @binding(2).\n // Bindings 3..6 (metallicRoughness sampler/texture + normal\n // sampler/texture) bind `pipelineState.defaultSampler` +\n // `pipelineState.defaultWhiteTextureView` placeholders (D-1\n // candidate b — zero new GPU resource; the 1x1 white view was\n // already provisioned for unlit / standard fallback so the sprite\n // path adds 4 binding references, no new resource code).\n //\n // Missing-texture fallback (AC-18 path 4 + R7 isolation): when the\n // sprite texture has no GPU view, the binding uses\n // `defaultWhiteTextureView` as the fallback texture and the\n // material UBO upload above wrote debug-pink colorTint so the\n // sprite is visually distinct. The warn-once + RhiError surface\n // fires inside the upload loop. R7 isolation: this does NOT change\n // the existing unlit / standard bucket missing-texture handling —\n // those keep their silent-white fallback (a future\n // `feat-future-pbr-missing-texture-fallback-explicit` will retrofit).\n // bug-20260610 layer 7d: BG is per-submesh — each iteration of\n // the submesh draw loop below builds (or cache-hits) a BG with\n // matsForRebind[smIdx]'s 5 textureViews (baseColor / MR / normal /\n // emissive / occlusion). Cache key is 14-handle-id only (entityKey\n // dropped) so identical-material submeshes / entities dedup\n // globally. Sprite path is unchanged (single spriteBg, sprite\n // per-submesh OOS-1). The non-sprite branch leaves perSubmeshBg\n // declared but null; the submesh loop reassigns it per iteration\n // and the source-grep gate in skylight-fallback-path.test.ts /\n // systems.unit.test.ts continues to match\n // `setBindGroup\\s*\\(\\s*1\\s*,\\s*perSubmeshBg\\b` on the in-loop call.\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w13 (D-1\n // candidate b): the sprite-specific BG construction is gone — sprite\n // materials reuse the same per-submesh BG path PBR / unlit use. The\n // 7-entry BGL is byte-for-byte shared (binding 0 = Material UBO,\n // 1 = baseColorSampler, 2 = baseColorTexture, 3-6 = filler samplers /\n // textureViews). Sprite's \"no metallic/normal/emissive/occlusion\n // texture\" simply falls through to `defaultWhite` / `defaultNormal`\n // — the same placeholders the unlit path already used. The generic\n // branch below builds the per-submesh BG.\n let perSubmeshBg: BindGroup | null = null;\n // feat-20260608 M4 / w16: per-submesh pipeline selection + draw loop.\n // Each submesh carries its own topology, so pipeline selection is per-submesh.\n // Vertex/index buffers and bind groups are set once (shared across all submeshes).\n // feat-20260608 M5 amend / w16-a: the material UBO bind (group=1)\n // ALSO moves into the loop -- the j-th submesh sees the j-th\n // material slot via dynamic offset (entitySlotStart + j) * 256.\n const matsForRebind = entry.source.materials;\n for (let smIdx = 0; smIdx < entry.mesh.submeshes.length; smIdx++) {\n const sm = entry.mesh.submeshes[smIdx];\n if (sm === undefined) continue;\n const matSlotIdx = sm.materialSlot;\n const submeshMaterial = matsForRebind[matSlotIdx] ?? entry.source.material;\n if (matchedMaterials !== null) {\n const materialHandles = matchedMaterials.get(entry.renderableIndex);\n const materialHandle = submeshMaterial.materialHandle ?? 0;\n if (materialHandles === undefined || !materialHandles.has(materialHandle)) continue;\n }\n // feat-city-glb Bug 5 (per-submesh transparency): in the LDR split, a\n // transparent submesh is drawn in the blend sub-pass (non-sRGB view),\n // NOT here in the sRGB geometry pass. Skip it. Opaque submeshes of the\n // same (mixed) mesh still draw here. Single-material / fully-opaque\n // meshes are unaffected (their submesh materials are not transparent).\n if (splitLdrSprite && submeshMaterial.transparent === true) {\n continue;\n }\n // bug-20260610 layer 7d: per-submesh BG construction. Texture\n // views resolve from `matsForRebind[smIdx]` so the j-th submesh\n // sees its own materials[j] textures (baseColor / MR / normal /\n // emissive / occlusion). Pick slot j when materials.length covers\n // smIdx; otherwise fall back to slot 0 (count-mismatch already\n // filtered by extract; this guard handles the materials.length=1\n // single-material path mapped over multi-submesh meshes safely).\n // This BG drops entityKey: identical-texture-set submeshes\n // (whether on the same entity or different ones) share one BG via\n // the shaderId-outer `materialBgShared` cache. The 14 handle\n // objects form the WeakMap chain and fully discriminate the\n // binding state since sampler/textureView/buffer handle identities\n // are stable across frames.\n //\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w13:\n // sprite materials now use the same per-submesh BG construction\n // (the sprite-specific BG branch above is deleted; sprite per-\n // submesh single-slot is still enforced via materialSlotIndices\n // and the sprite-shaped paramSnapshot fills the PBR-shaped BGL\n // bindings via fallback textures for the 4 unused slots).\n // feat-city-glb Bug 5: per-submesh material BG assembly extracted to\n // the shared `buildPerSubmeshMaterialBg` closure (also called by the\n // LDR blend sub-pass). Resolves the shader's user-region textures\n // (baseColor/MR/normal + a custom Nth texture), emissive/occlusion\n // injection, and Skylight merge; deduped cross-entity via the\n // shaderId-outer `materialBgShared` cache.\n const materialSlot = materialSlotIndices[i]?.[matSlotIdx] ?? materialSlotIndices[i]?.[0] ?? 0;\n perSubmeshBg =\n profilePhase === undefined\n ? resolveMaterialBindGroup(\n materialSlot,\n submeshMaterial,\n entry.source.entityKey,\n entry.world ?? c.world,\n )\n : profileGeometrySegment(c, passKind, 'material-bind-groups', () =>\n resolveMaterialBindGroup(\n materialSlot,\n submeshMaterial,\n entry.source.entityKey,\n entry.world ?? c.world,\n ),\n );\n materialGroup1DynamicOffsets[0] = materialSlot * MATERIAL_PER_ENTITY_STRIDE;\n pass.setBindGroup(1, perSubmeshBg, materialGroup1DynamicOffsets, 0, 1);\n const smTopology = sm.topology;\n const smMaterialShaderId =\n entry.source.skin !== undefined\n ? SKIN_MATERIAL_SHADER_ID\n : submeshMaterial.materialShaderId;\n const isSpriteShader =\n smMaterialShaderId === 'forgeax::sprite' || smMaterialShaderId === 'forgeax::sprite-lit';\n // Preserve the dedicated sprite-pass state when the linear-LDR graph\n // routes a sprite through this generic geometry path. Negative scale\n // flips winding, so back-face culling would erase the quad.\n const basePipelineRenderState = isSpriteShader\n ? {\n ...submeshMaterial.renderState,\n depthWriteEnabled: false,\n depthCompare: 'less-equal' as const,\n cullMode: 'none' as const,\n blend: submeshMaterial.renderState?.blend ?? SPRITE_PREMULTIPLIED_ALPHA_BLEND,\n }\n : geometryRenderStateForTopology(smTopology, submeshMaterial.renderState);\n const pipelineRenderState = geometryRenderStateForPass(basePipelineRenderState, passKind);\n let smPipelineHandle: typeof pipelineState.unlitPipeline;\n if (smMaterialShaderId === undefined || smMaterialShaderId === 'forgeax::default-unlit') {\n const unlitShaderId = smMaterialShaderId ?? 'forgeax::default-unlit';\n const unlitProjectionVariantResult = variantSetFromVertexLayoutProjection(\n entry.mesh.layoutProjection,\n undefined,\n );\n if (!unlitProjectionVariantResult.ok) {\n runtime.errorRegistry.fire(unlitProjectionVariantResult.error);\n continue;\n }\n const unlitHasColor = unlitProjectionVariantResult.value === 'VERTEX_COLOR_AVAILABLE=true';\n const unlitVariantSet = unlitHasColor\n ? ''\n : 'STORAGE_BUFFER_AVAILABLE=true+VERTEX_COLOR_AVAILABLE=false';\n const unlitRsp = resolveMaterialPipeline(\n unlitShaderId,\n pipelineRenderState,\n smTopology,\n entry.mesh.indexFormat,\n unlitVariantSet,\n colorFormatOverride,\n entry.mesh.layoutProjection,\n );\n smPipelineHandle =\n unlitRsp ??\n (colorFormatOverride === undefined\n ? selectGeometryPipeline(pipelineState, isHdrTarget, msaaActive)\n : null);\n } else if (smMaterialShaderId !== undefined) {\n // feat-20260609 M4.5 / w38 (D-11): the variantSet handed to\n // getMaterialShaderPipeline MUST mirror the boot-time\n // `definesKey` rule at createRenderer.ts:2483-2485 (sortedEntries\n // .every(v=>v===true) ? '' : 'A=v+...'). manifest variant.definesKey\n // is `''` for the all-true variant, so HDRP (both axes true) must\n // pass the canonical empty key to hit that variant via\n // findVariantByKey. Passing the expanded form would produce a\n // miss and silently fall back to the registered default WGSL,\n // creating a layout/binding mismatch under HDRP.\n //\n // URP path passes the explicit expanded form because the URP\n // variant's manifest definesKey IS that exact non-empty string\n // (CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true)\n // -- the canonical-empty rule only applies to the all-true case.\n const hasVertexColor = entry.mesh.layoutProjection.attributes.some(\n (attribute) => attribute.key === 'color',\n );\n // The all-true HDRP variant uses the canonical empty key only when\n // every variant axis is true. A plain mesh adds the geometry-owned\n // VERTEX_COLOR_AVAILABLE=false axis, so retain the two capability\n // axes explicitly or the selector would silently choose the URP\n // group(2) layout for an HDRP cluster bind group.\n const capabilityVariantSet = frameState.isHdrpActive\n ? hasVertexColor\n ? ''\n : 'CLUSTER_FORWARD_AVAILABLE=true+STORAGE_BUFFER_AVAILABLE=true'\n : 'CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true';\n // Sprite's base request must retain the boot-selected artifact. Only\n // SpriteInstances uses the explicit empty key for the\n // PER_INSTANCE_REGION=true variant; synthesizing the generic PBR\n // capability axes for a base sprite would invent a lazy module label\n // that has no boot seed and skip the first HDR draw.\n const variantSet = isSpriteShader\n ? smMaterialShaderId === 'forgeax::sprite' && entry.source.spriteInstances !== undefined\n ? ''\n : undefined\n : entry.variantSet === undefined\n ? capabilityVariantSet\n : capabilityVariantSet === ''\n ? entry.variantSet\n : `${capabilityVariantSet}+${entry.variantSet}`;\n const projectionVariantSetResult = isSpriteShader\n ? ({ ok: true, value: variantSet } as const)\n : variantSetFromVertexLayoutProjection(entry.mesh.layoutProjection, variantSet);\n if (!projectionVariantSetResult.ok) {\n runtime.errorRegistry.fire(projectionVariantSetResult.error);\n continue;\n }\n const cachedPipeline = resolveMaterialPipeline(\n smMaterialShaderId,\n pipelineRenderState,\n smTopology,\n entry.mesh.indexFormat,\n projectionVariantSetResult.value,\n colorFormatOverride,\n entry.mesh.layoutProjection,\n );\n // feat-20260615-pipeline-spec-ssot M6-T1: cache miss resolves to\n // null uniformly across URP / HDRP / skin shaders. Charter P3\n // explicit failure: the pre-M6 URP-path silent fallback to the\n // boot-time `pipelineState.standardPipeline*` (M4.5-followup w43)\n // masked real PipelineSpecError build failures behind a\n // layout-compatible-but-wrong PSO. The per-submesh\n // `if (smPipelineHandle === null) continue` skip-draw (which\n // already covered HDRP-active and skin miss paths) is now the\n // single uniform recovery shape -- one frame of skip-draw on\n // first-touch, then the cached PSO flows in once the async\n // build resolves. The pre-loop skin-PSO probe still skips the\n // entire entry on first-submesh probe miss; this site only\n // fires on per-submesh topology variance miss.\n smPipelineHandle = cachedPipeline ?? null;\n } else {\n smPipelineHandle = selectGeometryPipeline(pipelineState, isHdrTarget, msaaActive);\n }\n\n if (smPipelineHandle === null) {\n continue;\n }\n // Standard clustered PBR variants declare the unified cluster/SSAO\n // group(2) layout. Unlit and other URP-layout materials must bind the\n // ordinary mesh group instead; choosing one group for the whole pass\n // makes Dawn reject an otherwise valid unlit pipeline and invalidates\n // the command buffer before it reaches the surface.\n const usesStandardClusterBindings = smMaterialShaderId === 'forgeax::default-standard-pbr';\n if (!isSkinEntry) {\n if (usesStandardClusterBindings) {\n if (meshGroup2 === null) continue;\n group2BindGroup = meshGroup2;\n } else {\n const fallbackGroup = meshBindGroup ?? meshGroup2;\n if (fallbackGroup === null) continue;\n group2BindGroup = fallbackGroup;\n }\n }\n pass.setBindGroup(2, group2BindGroup, group2DynamicOffsets);\n\n if (profilePhase === undefined) {\n submitSubmeshDraws(\n pass,\n bindingState,\n smPipelineHandle,\n instanceDraws,\n entry.mesh.indexed,\n sm.indexCount,\n sm.vertexCount,\n sm.indexOffset,\n );\n } else {\n profileGeometrySegment(c, passKind, 'draw-submit', () =>\n submitSubmeshDraws(\n pass,\n bindingState,\n smPipelineHandle,\n instanceDraws,\n entry.mesh.indexed,\n sm.indexCount,\n sm.vertexCount,\n sm.indexOffset,\n ),\n );\n }\n }\n }\n}\n\n/**\n * Resolve the per-entity @group(3) instance buffers for the geometry pass.\n *\n * @internal\n */\nfunction resolveGeometryInstanceBuffer(\n c: _InternalRenderPipelineContext,\n entry: _InternalRenderPipelineContext['validatedOrdered'][number],\n identityInstanceDraws: readonly GeometryInstanceDraw[],\n): readonly GeometryInstanceDraw[] | null {\n const { runtime, pipelineState, frameState } = c;\n const inst = entry.source.instances;\n if (inst === undefined) return identityInstanceDraws;\n let instanceBuffer: Buffer = pipelineState.identityInstanceBuffer;\n let instanceCount = 1;\n {\n // feat-20260526-pbr-uniform-fallback-no-storage-buffer M3 / w13:\n // caps.storageBuffer===false -> uniform fallback with 128-instance\n // cap (128 * 64B = 8192B < WebGL2 min 16384B UBO limit).\n // caps.storageBuffer===true -> existing storage buffer path unchanged.\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n let instanceBufferUsage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;\n\n if (uniformFallback && inst.instanceCount > MAX_UNIFORM_INSTANCES) {\n const draws: GeometryInstanceDraw[] = [];\n for (let start = 0; start < inst.instanceCount; start += MAX_UNIFORM_INSTANCES) {\n const count = Math.min(MAX_UNIFORM_INSTANCES, inst.instanceCount - start);\n const chunk = inst.transforms.subarray(start * 16, (start + count) * 16);\n const bufRes = runtime.device.createBuffer({\n size: INSTANCE_UBO_FULL_ARRAY_BYTES,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n return null;\n }\n const buffer = new GpuBuffer(runtime.device, bufRes.value);\n frameState.transientInstanceBuffers.push({\n buffer,\n uploadedArchVersion: inst.archVersion,\n uploadedByteLength: chunk.byteLength,\n });\n const writeRes = runtime.device.queue.writeBuffer(buffer.handle, 0, chunk);\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n return null;\n }\n draws.push({\n instanceBuffer: buffer.handle,\n instanceBindGroup: resolveGeometryInstancesBindGroup(c, buffer.handle),\n instanceCount: count,\n });\n }\n return draws;\n }\n if (uniformFallback) {\n instanceBufferUsage = GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;\n }\n\n {\n // Cap-gate (LimitExceededDetail single emit point — feat-20260514\n // M3 / w15 anchor): `requestedBytes <= maxStorageBufferBindingSize`.\n const instancePayload = uniformFallback\n ? inst.transforms\n : packInstanceStorageBuffer(inst.transforms);\n const requestedBytes = instancePayload.byteLength;\n const cap = runtime.device.limits.maxStorageBufferBindingSize;\n if (!uniformFallback && typeof cap === 'number' && cap > 0 && requestedBytes > cap) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'limit-exceeded',\n expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,\n hint: 'reduce instance count to fit within device.limits.maxStorageBufferBindingSize, or split transforms across multiple Instances entries',\n detail: {\n maxStorageBufferBindingSize: cap,\n requestedBytes,\n },\n }),\n );\n return null;\n } else {\n // Look up the cached GPU buffer or create a fresh one when the\n // archetype version bumped or the byte length changed.\n const cached = frameState.instanceBuffers.get(\n worldEntityKey(entry.source.worldId, inst.cacheKey),\n );\n let active: InstanceBufferCacheEntry | null = null;\n if (\n cached !== undefined &&\n cached.uploadedArchVersion === inst.archVersion &&\n cached.uploadedByteLength === requestedBytes\n ) {\n active = cached;\n } else if (requestedBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: uniformFallback ? INSTANCE_UBO_FULL_ARRAY_BYTES : requestedBytes,\n usage: instanceBufferUsage,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n // feat-20260619 M4 / F12: destroy the old cached buffer\n // before replacing it with the new one (D-6).\n if (cached !== undefined && !cached.buffer.isDestroyed) {\n const r = cached.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuffer = new GpuBuffer(runtime.device, bufRes.value);\n active = {\n buffer: newBuffer,\n uploadedArchVersion: inst.archVersion,\n uploadedByteLength: requestedBytes,\n };\n frameState.instanceBuffers.set(\n worldEntityKey(entry.source.worldId, inst.cacheKey),\n active,\n );\n }\n }\n if (active !== null) {\n const writeRes = runtime.device.queue.writeBuffer(\n active.buffer.handle,\n 0,\n instancePayload,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n instanceBuffer = active.buffer.handle;\n instanceCount = Math.max(1, inst.instanceCount);\n }\n }\n }\n // The cache write above is keyed by worldEntityKey(worldId, cacheKey)\n // so separate worlds cannot alias their instance buffers.\n }\n }\n return [\n {\n instanceBuffer,\n instanceBindGroup: resolveGeometryInstancesBindGroup(c, instanceBuffer),\n instanceCount,\n },\n ];\n}\n\nfunction resolveGeometryInstancesBindGroup(\n c: _InternalRenderPipelineContext,\n instanceBuffer: Buffer,\n): BindGroup {\n const { runtime, pipelineState, frameState, bindGroupCounts } = c;\n return getOrCreateFromChain(\n frameState.instancesBgShared,\n [pipelineState.instancesBindGroupLayout, instanceBuffer],\n 'instances',\n () => {\n const result = runtime.device.createBindGroup({\n label: 'pbr-instances-bg',\n layout: pipelineState.instancesBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: { buffer: instanceBuffer },\n },\n },\n ],\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n bindGroupCounts,\n );\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: main-pass sprite draws.\n// feat-20260704 M5/w31: further-split from main-pass.ts (AC-05 <=1500 lines/file).\n// recordSpritePass + sprite entity/transparent/instance-buffer helpers, moved verbatim.\n\nimport type { World } from '@forgeax/engine-ecs';\nimport {\n type BindGroup,\n type BindGroupEntry,\n type Buffer,\n type RenderPipeline,\n RhiError,\n type RhiRenderPassEncoder,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport type { Handle, MaterialRenderState } from '@forgeax/engine-types';\nimport { GpuBuffer } from '../gpu-resource';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_STORAGE,\n GPU_BUFFER_USAGE_UNIFORM,\n} from '../gpu-usage';\nimport {\n assembleMaterialWithSkylightEntries,\n type SkylightBindGroupResources,\n} from '../ibl/skylight-bind-group';\nimport type { InstanceBufferCacheEntry } from '../instance-buffer-cache';\nimport { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';\nimport { SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET } from '../pbr-pipeline';\nimport {\n buildBeginRenderPassDescriptor,\n variantSetFromVertexLayoutProjection,\n} from '../pipeline-spec';\nimport type { MaterialSnapshot, SpriteInstancesSnapshot } from '../render-system-extract';\nimport { worldEntityKey } from './frame-snapshot';\nimport {\n BUILTIN_USER_REGION_TEXTURE_FIELDS,\n defaultViewForUserRegionField,\n entityHasTransparentSubmesh,\n residentTextureView,\n} from './main-pass-material';\nimport {\n extractEntryResourceHandle,\n getOrCreatePerEntity,\n MAX_UNIFORM_INSTANCES,\n MESH_PER_ENTITY_STRIDE,\n packInstanceStorageBuffer,\n} from './mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { MATERIAL_PER_ENTITY_STRIDE, STANDARD_PBR_UBO_SIZE } from './render-context';\n\nexport type { SpriteInstancesSnapshot };\n\n/**\n * Build the sprite material's Standard user-region from the shared field-order\n * owner. The sprite shader uses the same Standard material bind-group layout;\n * keeping this projection derived from the shared list prevents IBL injection\n * from moving ahead of newly added material texture pairs.\n */\nexport function buildSpritePassBaseMaterialEntries(\n pipelineState: _InternalRenderPipelineContext['pipelineState'],\n spriteTexView: TextureView,\n): BindGroupEntry[] {\n const entries: BindGroupEntry[] = [\n {\n binding: 0,\n resource: {\n kind: 'buffer' as const,\n value: {\n buffer: pipelineState.materialUniformBuffer.buffer,\n offset: 0,\n size: STANDARD_PBR_UBO_SIZE,\n },\n },\n },\n ];\n for (const [index, field] of BUILTIN_USER_REGION_TEXTURE_FIELDS.entries()) {\n const view =\n field === 'baseColorTexture'\n ? spriteTexView\n : defaultViewForUserRegionField(field, pipelineState);\n entries.push(\n {\n binding: 1 + index * 2,\n resource: {\n kind: 'sampler' as const,\n value: index === 0 ? pipelineState.nearestSampler : pipelineState.defaultSampler,\n },\n },\n {\n binding: 2 + index * 2,\n resource: { kind: 'textureView' as const, value: view },\n },\n );\n }\n return entries;\n}\n\n/**\n * Build the interleaved sprite instance payload consumed by this record owner.\n * The extract stage validates the two packed arrays before they reach this\n * function, so the record path has one source of count-mismatch errors.\n */\nexport function interleaveSpriteInstanceBuffer(\n transforms: Float32Array,\n regions: Float32Array,\n includePrevious = false,\n): Float32Array {\n const count = transforms.length / 16;\n const stride = includePrevious ? 36 : 20;\n const regionOffset = includePrevious ? 32 : 16;\n const out = new Float32Array(count * stride);\n for (let i = 0; i < count; i++) {\n const dstBase = i * stride;\n const transformBase = i * 16;\n const regionBase = i * 4;\n for (let k = 0; k < 16; k++) out[dstBase + k] = transforms[transformBase + k] ?? 0;\n if (includePrevious) {\n for (let k = 0; k < 16; k++) {\n out[dstBase + 16 + k] = transforms[transformBase + k] ?? 0;\n }\n }\n for (let k = 0; k < 4; k++) {\n out[dstBase + regionOffset + k] = regions[regionBase + k] ?? 0;\n }\n }\n return out;\n}\n\n/**\n * Check whether the existing per-entity sprite buffer still matches the\n * extract snapshot and interleaved byte count.\n */\nexport function spriteInstancesCacheHit(\n entry: InstanceBufferCacheEntry | undefined,\n snapshot: SpriteInstancesSnapshot,\n requestedBytes: number,\n): boolean {\n return (\n entry !== undefined &&\n entry.uploadedArchVersion === snapshot.archVersion &&\n entry.uploadedByteLength === requestedBytes\n );\n}\n\n/**\n * Decide whether the LDR record needs the transparent sprite sub-pass. This\n * remains beside the sprite record owner so the frame stage and draw stage\n * share the same transparent-material rule.\n */\nexport function computeSplitLdrSprite(\n validatedOrdered: readonly (\n | {\n readonly source: {\n readonly material: MaterialSnapshot;\n readonly materials?: readonly MaterialSnapshot[];\n };\n }\n | undefined\n )[],\n tonemapActive: boolean,\n): boolean {\n if (tonemapActive) return false;\n for (const entry of validatedOrdered) {\n if (entry === undefined) continue;\n const materials = entry.source.materials;\n if (materials !== undefined) {\n if (materials.some((material) => material.transparent === true)) return true;\n } else if (entry.source.material.transparent === true) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * feat-20260704 M3/w19: LDR sprite split sub-pass, extracted verbatim from\n * recordMainPass. Runs after the geometry pass when there are sprite / LDR\n * transparent entities and the split path is active (splitLdrSprite && a raw\n * unorm swap-chain view exists). Ends the geometry `pass`, opens a `spritePass`\n * on the resolved transparent-pass view (loadOp=load), draws the sprite / sprite-lit\n * entities (fold-instanced where possible) then the generic per-submesh\n * transparent PBR submeshes, and ends the sprite pass. Returns the updated\n * `geometryPassEnded` flag so the caller skips the unconditional pass.end().\n *\n * @internal\n */\nexport function recordSpritePass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n matchedIndices: Set<number> | null,\n materialSlotIndices: readonly (readonly number[])[],\n sampleCount: number,\n resolveMaterialBindGroup: (\n materialSlot: number,\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World,\n ) => BindGroup,\n skylightResources: SkylightBindGroupResources,\n graphPass?: RhiRenderPassEncoder,\n): boolean {\n const {\n runtime,\n pipelineState,\n encoder,\n msaaActive,\n ldrSpritePassView,\n ldrSpriteColorView,\n geometryDepthView,\n viewBindGroup,\n splitLdrSprite,\n } = c;\n // The split pass is also used by the no-tone linear-LDR route. That route\n // keeps transparent draws in the graph-owned rgba16float attachment, so\n // sprite shaders must use their linear/HDR fragment entry point even though\n // the camera itself has no tone map enabled.\n const spriteIsHdr =\n c.tonemapActive || transparentPassColorFormat(c, pipelineState) === 'rgba16float';\n let geometryPassEnded = false;\n if (splitLdrSprite && (graphPass !== undefined || ldrSpritePassView !== null)) {\n if (graphPass === undefined) {\n pass.end();\n geometryPassEnded = true;\n }\n\n // feat-20260604 M2 / w9 (F-1): under MSAA the sprite sub-pass writes the\n // count=4 transparent-pass view of the SAME multisample texture the\n // geometry pass wrote (loadOp=load preserves geometry under sprites) and\n // resolves the combined result to the single-sample transparent-pass\n // view at this (last) pass end. Depth reuses the shared count=4\n // multisample depth (depthLoadOp=load preserves sprite-vs-mesh occlusion).\n // The single-\n // sample path is byte-for-byte unchanged (writes the swap-chain view).\n const spriteColorView = msaaActive ? ldrSpriteColorView : ldrSpritePassView;\n // sprite-split sub-pass: forward shape with both color and depth loaded\n // (preserves prior content from the main forward pass under the sprites).\n // Stencil ops auto-emitted by the helper because depthFormat carries\n // stencil8.\n const spritePass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n {\n // SSOT for the sprite-pass color format is the resolved transparent\n // attachment. Native linear-LDR frames use graph-owned `ldrColor`\n // (possibly rgba16float); swap-chain fallback frames use their raw\n // storage format. WebGPU requires the attachment format and PSO\n // target to match, so both are resolved by the same helper.\n colorFormats: [transparentPassColorFormat(c) as GPUTextureFormat],\n depthFormat: 'depth24plus-stencil8',\n sampleCount: msaaActive ? 4 : 1,\n },\n {\n colorViews: [spriteColorView],\n depthView: geometryDepthView,\n ...(msaaActive ? { resolveTargets: [ldrSpritePassView] } : {}),\n },\n 'forward',\n { colorLoadOp: 'load', depthLoadOp: 'load' },\n ) as never,\n );\n\n spritePass.setBindGroup(0, viewBindGroup as BindGroup, [0]);\n\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (D-7):\n // sprite PSO resolution migrated from the dedicated boot-time PSO\n // fields (deleted) to the generic per-MaterialShader pipeline cache.\n // feat-20260626-collapse M2 / M2-T2: blend factor pair literal moved\n // to the public `SPRITE_PREMULTIPLIED_ALPHA_BLEND` named constant\n // (re-exported from `@forgeax/engine-runtime`) so each AI user\n // building a transparent material declares the same blend by\n // reference; the previous implicit blend-state factory helper is\n // gone. Cache miss still surfaces as a structured\n // `shader-compile-failed` RhiError mirroring the pre-w14 behaviour.\n //\n // feat-20260608-tilemap-object-layer-rendering M2 / m2-t6 (D-8): sprite\n // pipeline cullMode='none'. H/V flip via negative scale x/y (tilemap\n // per-cell entity TRS form) inverts the triangle winding; cullMode='back'\n // would throw the flipped quad away. The sprite pass runs in the\n // alpha-blend transparent bucket back-to-front already, so cullMode='none'\n // adds no overdraw cost. Pre-feat-20260625 the dedicated spritePipeline\n // hard-coded 'none' (deleted in w14); the generic path must replicate\n // it here or the cullmode-flip dawn smoke goes black on negative-scale.\n const spritePremulBlend: MaterialRenderState = {\n depthWriteEnabled: false,\n depthCompare: 'less-equal',\n cullMode: 'none',\n blend: SPRITE_PREMULTIPLIED_ALPHA_BLEND,\n };\n // bug-20260629: PR #526 added PER_INSTANCE_REGION as a second variant\n // axis on sprite.wgsl. Build BOTH variants here; the per-entity loop\n // picks the right one based on whether the entity carries a\n // SpriteInstances snapshot:\n // - spritePH (PER_INSTANCE_REGION=false): regular per-entity sprites\n // + fold-bucket instanced draws (64-byte mat4 only instance buf);\n // UV region comes from the material UBO `region` slot.\n // - spritePH_withRegion (PER_INSTANCE_REGION=true): SpriteInstances\n // entities with 80-byte interleaved (mat4 64B + region 16B) per\n // instance; UV region comes from `instances[idx].region`.\n //\n // Without spritePH_withRegion the SpriteInstances data was uploaded\n // but the shader read bytes 64-79 as region=0 → black quads.\n //\n // feat-20260624-sprite-lit-shading-model-pure-2d-lighting M1' / t7:\n // sprite-lit walks the same LDR transparent split pass with mirror\n // PSO request shape (only materialShaderId string differs). The\n // sprite-lit PSO is fetched lazily per-entity below since the pass\n // mixes sprite + sprite-lit transparent entities. PSO cache strings\n // are isolated by `materialShaderId` (D-11), no slot collision.\n const spritePH =\n runtime.getMaterialShaderPipeline?.(\n 'forgeax::sprite',\n spriteIsHdr,\n spritePremulBlend,\n 'triangle-list',\n undefined,\n undefined,\n 'forward',\n undefined,\n msaaActive ? 4 : 1,\n // feat-20260625-refactor-sprite-as-transparent-mesh R2 fix-up:\n // the split sub-pass PSO must use the same attachment format as the\n // encoder. Native linear-LDR frames resolve graph-owned `ldrColor`\n // (possibly rgba16float); swap-chain fallback frames resolve their raw\n // storage format. `transparentPassColorFormat` is the single owner for\n // this format so lazy PSO construction cannot fall back to the geometry\n // sRGB view.\n transparentPassColorFormat(c, pipelineState) as GPUTextureFormat,\n ) ?? null;\n const spritePH_withRegion =\n runtime.getMaterialShaderPipeline?.(\n 'forgeax::sprite',\n spriteIsHdr,\n spritePremulBlend,\n 'triangle-list',\n undefined,\n SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET,\n 'forward',\n undefined,\n msaaActive ? 4 : 1,\n transparentPassColorFormat(c) as GPUTextureFormat,\n ) ?? null;\n\n // bug-20260629: spritePH===null check moved OUTSIDE the entity loop so the\n // sprite pass is properly ended before returning. Inside the loop the early\n // `return` left spritePass open → render-pass-not-ended error every frame\n // where the pipeline is still being compiled (frame 0 on first load).\n //\n // feat-city-glb Bug 5: a missing sprite PSO must NOT abort the whole\n // sub-pass — the generic per-submesh PBR transparent loop below does not\n // depend on the sprite shader. Only skip the sprite ENTITIES when spritePH\n // is null (fire the diagnostic once, iff a sprite entity is actually\n // present), then fall through to the PBR loop. A PBR-only transparent\n // scene (e.g. a glTF BLEND decal, no sprites) renders regardless of\n // whether sprite.wgsl is in the manifest.\n let spriteUnavailableReported = false;\n const reportSpriteUnavailable = (): void => {\n if (spriteUnavailableReported) return;\n spriteUnavailableReported = true;\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'shader-compile-failed',\n expected:\n 'manifest entries include sprite.wgsl + the engine triple (pbr + unlit + tonemap)',\n hint: 'verify @forgeax/engine-vite-plugin-shader emits manifest.json with the 4 engine entries (sprite.wgsl is required when spawning sprite materials); check vite plugin engineEntries option',\n }),\n );\n };\n\n // feat-20260624 M1' / t7: parallel sprite-lit PSO request — same\n // arg shape, only materialShaderId differs.\n const spriteLitPH =\n runtime.getMaterialShaderPipeline?.(\n 'forgeax::sprite-lit',\n spriteIsHdr,\n spritePremulBlend,\n 'triangle-list',\n undefined,\n undefined,\n 'forward',\n undefined,\n msaaActive ? 4 : 1,\n transparentPassColorFormat(c) as GPUTextureFormat,\n ) ?? null;\n recordSpriteEntityDraws(\n c,\n spritePass,\n matchedIndices,\n skylightResources,\n spritePH,\n spritePH_withRegion,\n spriteLitPH,\n reportSpriteUnavailable,\n );\n\n // feat-city-glb Bug 5 (per-submesh transparency): generic per-submesh PBR\n // draws in the LDR blend sub-pass. The sprite loop above handles only true\n // sprite / sprite-lit entities (whole-mesh sprite PSO). EVERY non-sprite\n // transparent material — built-in PBR, single- or multi-submesh, incl.\n // glTF alphaMode=BLEND (the crosswalk decal submesh AND the 4.3-blending\n // window quad) — is drawn here with its real shader + per-submesh\n // geometry, reusing the geometry pass's PBR machinery but rendering into\n // the resolved transparent attachment (colorFormatOverride =\n // transparentPassColorFormat(c)).\n // Opaque submeshes of a mixed mesh were already drawn in the geometry pass\n // (per-submesh skip there).\n //\n // Non-skinned, non-instanced (glTF static meshes): group 2 = the shared\n // frame meshBindGroup with the per-entity dynamic offset; group 3 = the\n // identity instance BG (drawIndexed instanceCount=1). Skinned / instanced\n // transparent submeshes are OOS here (no such content) and fall through.\n recordSpriteTransparentPbrDraws(\n c,\n spritePass,\n matchedIndices,\n materialSlotIndices,\n sampleCount,\n resolveMaterialBindGroup,\n );\n\n if (graphPass === undefined) spritePass.end();\n }\n return geometryPassEnded;\n}\n\n/**\n * feat-20260704 M3/w19: generic per-submesh transparent PBR draws in the LDR\n * blend sub-pass, extracted verbatim from the sprite split pass. Every\n * non-sprite transparent material (built-in PBR, single- or multi-submesh, incl.\n * glTF alphaMode=BLEND) draws here with its real shader + per-submesh geometry,\n * reusing the geometry pass's PBR machinery but rendering into the resolved\n * transparent attachment (colorFormatOverride = transparentPassColorFormat(c)). Opaque submeshes of a\n * mixed mesh were already drawn in the geometry pass (per-submesh skip there).\n * Sprites are handled by the sprite loop; skinned / instanced transparent\n * submeshes are OOS here and fall through.\n *\n * @internal\n */\nfunction recordSpriteTransparentPbrDraws(\n c: _InternalRenderPipelineContext,\n spritePass: RhiRenderPassEncoder,\n matchedIndices: Set<number> | null,\n materialSlotIndices: readonly (readonly number[])[],\n sampleCount: number,\n resolveMaterialBindGroup: (\n materialSlot: number,\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World,\n ) => BindGroup,\n): void {\n const { runtime, pipelineState, frameState, bindGroupCounts, validatedOrdered, meshBindGroup } =\n c;\n const isHdrTarget =\n c.tonemapActive || transparentPassColorFormat(c, pipelineState) === 'rgba16float';\n let lastPbrSubPipelineHandle: typeof pipelineState.unlitPipeline = null;\n let lastPbrSubVertexBuffer: GpuBuffer | null = null;\n let lastPbrSubIndexBuffer: GpuBuffer | null = null;\n for (let i = 0; i < validatedOrdered.length; i++) {\n const entry = validatedOrdered[i];\n if (entry === undefined) continue;\n if (matchedIndices !== null && !matchedIndices.has(entry.renderableIndex)) continue;\n // Sprites are handled by the sprite loop above; skip them here.\n const entShaderId = entry.source.material.materialShaderId;\n const entIsSprite = entShaderId === 'forgeax::sprite' || entShaderId === 'forgeax::sprite-lit';\n if (entIsSprite) continue;\n // Only entities that carry at least one transparent submesh reach a draw\n // (single-submesh transparent PBR and mixed opaque+transparent meshes).\n if (!entityHasTransparentSubmesh(entry.source)) continue;\n // Skinned / instanced transparent submeshes are not supported in this\n // sub-pass path (no such content today); skip to avoid mis-binding.\n if (entry.source.skin !== undefined || entry.source.instances !== undefined) continue;\n\n const matsForRebind = entry.source.materials;\n if (entry.mesh.vertexBuffer !== lastPbrSubVertexBuffer) {\n spritePass.setVertexBuffer(0, entry.mesh.vertexBuffer.handle);\n lastPbrSubVertexBuffer = entry.mesh.vertexBuffer;\n }\n if (\n entry.mesh.indexed &&\n entry.mesh.indexBuffer !== null &&\n entry.mesh.indexBuffer !== lastPbrSubIndexBuffer\n ) {\n spritePass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);\n lastPbrSubIndexBuffer = entry.mesh.indexBuffer;\n }\n spritePass.setBindGroup(2, meshBindGroup as BindGroup, [i * MESH_PER_ENTITY_STRIDE]);\n // Identity instance BG (instanceCount=1); reuse the per-entity cache.\n const identityInstBg: BindGroup = getOrCreatePerEntity(\n frameState.instancesBgPerEntity,\n worldEntityKey(entry.source.worldId, entry.source.entityKey),\n [pipelineState.identityInstanceBuffer],\n 'instances',\n () => {\n const result = runtime.device.createBindGroup({\n label: 'pbr-transparent-sub-instances-bg',\n layout: pipelineState.instancesBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.identityInstanceBuffer },\n },\n },\n ],\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n bindGroupCounts,\n );\n spritePass.setBindGroup(3, identityInstBg);\n\n const subVariantSet = frameState.isHdrpActive\n ? ''\n : 'CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true';\n const projectionVariantSetResult = variantSetFromVertexLayoutProjection(\n entry.mesh.layoutProjection,\n subVariantSet,\n );\n if (!projectionVariantSetResult.ok) {\n runtime.errorRegistry.fire(projectionVariantSetResult.error);\n continue;\n }\n const projectionVariantSet = projectionVariantSetResult.value;\n\n for (let smIdx = 0; smIdx < entry.mesh.submeshes.length; smIdx++) {\n const sm = entry.mesh.submeshes[smIdx];\n if (sm === undefined) continue;\n const matSlotIdx = sm.materialSlot;\n const submeshMaterial = matsForRebind[matSlotIdx] ?? entry.source.material;\n // Only transparent submeshes belong in this blend sub-pass; opaque\n // submeshes were drawn in the geometry pass.\n if (submeshMaterial.transparent !== true) continue;\n const smShaderId = submeshMaterial.materialShaderId;\n if (smShaderId === undefined) continue;\n\n // Bind the per-submesh material BG first (mirrors the geometry pass\n // order), then resolve the PSO; a first-frame async-compile miss skips\n // only the draw, not the BG (one transient frame, PSO flows in next).\n const materialSlot = materialSlotIndices[i]?.[matSlotIdx] ?? materialSlotIndices[i]?.[0] ?? 0;\n const subBg = resolveMaterialBindGroup(\n materialSlot,\n submeshMaterial,\n entry.source.entityKey,\n entry.world ?? c.world,\n );\n spritePass.setBindGroup(1, subBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);\n\n const subPipeline =\n runtime.getMaterialShaderPipeline?.(\n smShaderId,\n isHdrTarget,\n submeshMaterial.renderState,\n sm.topology,\n entry.mesh.indexFormat,\n projectionVariantSet,\n 'forward',\n undefined,\n sampleCount,\n // Non-sRGB blend view (same override the sprite path uses).\n transparentPassColorFormat(c) as GPUTextureFormat,\n undefined,\n undefined,\n undefined,\n entry.mesh.layoutProjection,\n ) ?? null;\n if (subPipeline === null) continue;\n\n if (lastPbrSubPipelineHandle !== subPipeline) {\n spritePass.setPipeline(subPipeline);\n lastPbrSubPipelineHandle = subPipeline;\n }\n if (entry.mesh.indexed) {\n spritePass.drawIndexed(sm.indexCount, 1, sm.indexOffset, 0, 0);\n } else {\n spritePass.draw(sm.vertexCount, 1, 0, 0);\n }\n }\n }\n}\n\n/**\n * feat-20260704 M3/w19: per-entity sprite / sprite-lit draw loop for the LDR\n * blend sub-pass, extracted verbatim from the sprite split pass. Selects the\n * sprite vs sprite-lit PSO per entity, resolves the per-entity / fold-bucket\n * instance buffer (fold-instanced drawIndexed where a fold bucket applies and\n * the entity has no explicit Instances), uploads the per-entity sprite material\n * UBO slice, binds view / material / mesh / instances groups, and issues the\n * draw. Non-sprite transparent submeshes are drawn separately\n * (recordSpriteTransparentPbrDraws). The loop-invariant sprite PSO handles + the\n * once-per-frame sprite-unavailable diagnostic are threaded in.\n *\n * @internal\n */\nfunction recordSpriteEntityDraws(\n c: _InternalRenderPipelineContext,\n spritePass: RhiRenderPassEncoder,\n matchedIndices: Set<number> | null,\n skylightResources: SkylightBindGroupResources,\n spritePH: RenderPipeline | null,\n spritePH_withRegion: RenderPipeline | null,\n spriteLitPH: RenderPipeline | null,\n reportSpriteUnavailable: () => void,\n): void {\n const {\n runtime,\n world,\n store,\n pipelineState,\n frameState,\n bindGroupCounts,\n validatedOrdered,\n meshBindGroup,\n foldDispatchPlan,\n materialSlotIndices,\n } = c;\n let lastSpritePipelineHandle: RenderPipeline | null = null;\n let lastSpriteVertexBuffer: GpuBuffer | null = null;\n let lastSpriteIndexBuffer: GpuBuffer | null = null;\n for (let i = 0; i < validatedOrdered.length; i++) {\n const spriteEntry = validatedOrdered[i];\n // feat-20260625 M3 / w13: sub-pass entity filter migrated from\n // `shadingModel === 'sprite'` to `transparent === true` — the\n // shadingModel arm is gone post-feat (plan-strategy D-3).\n if (spriteEntry === undefined || spriteEntry.source.material.transparent !== true) continue;\n // feat-city-glb Bug 5 (per-submesh transparency): this loop is the\n // SPRITE path (whole-mesh sprite / sprite-lit PSO). Non-sprite\n // transparent materials (built-in PBR, incl. glTF alphaMode=BLEND) are\n // drawn per-submesh with their real shader in the dedicated PBR loop\n // below — so skip them here. Previously the 4.3-blending window (a PBR\n // material) was drawn through here with the sprite shader; it now flows\n // through the PBR loop, which is both correct and multi-submesh-capable.\n {\n const sid = spriteEntry.source.material.materialShaderId;\n const isSpriteShader = sid === 'forgeax::sprite' || sid === 'forgeax::sprite-lit';\n if (!isSpriteShader) continue;\n }\n // feat-20260622-chunk-gpu-instancing-sprite-tilemap M1 / w4-record-swap\n // (D-1): fold-bucket non-head member — skip; the bucket head emits one\n // instanced drawIndexed covering all members.\n if (foldDispatchPlan?.skipIndices.has(i) === true) {\n continue;\n }\n const foldHeadBucket = foldDispatchPlan?.headBuckets.get(i);\n\n // feat-20260609 M2: skip entities that don't match the pass selector.\n if (matchedIndices !== null && !matchedIndices.has(spriteEntry.renderableIndex)) {\n continue;\n }\n\n // feat-20260624 M1' / t7: select sprite vs sprite-lit PSO per\n // entity. Both paths share the LDR sub-pass + the same UBO\n // layout; only the shader module + fragment math differ. PSO\n // cache strings are isolated by materialShaderId (D-11) so\n // routing here keeps the cache slots disjoint.\n //\n // bug-20260629: SpriteInstances entities additionally need the\n // PER_INSTANCE_REGION=true variant so the shader reads UV region\n // from the 80B-per-instance interleaved buffer rather than from\n // the material UBO. Only the base sprite path has the per-instance\n // region variant compiled; sprite-lit + non-instances entities\n // keep the PER_INSTANCE_REGION=false variant.\n const entityShaderId = spriteEntry.source.material.materialShaderId;\n const useRegionVariant =\n entityShaderId !== 'forgeax::sprite-lit' && spriteEntry.source.spriteInstances !== undefined;\n const activeSpritePH =\n entityShaderId === 'forgeax::sprite-lit'\n ? spriteLitPH\n : useRegionVariant\n ? spritePH_withRegion\n : spritePH;\n if (activeSpritePH === null) {\n // Variant not yet compiled — for PER_INSTANCE_REGION=true the\n // variant cache fill is async on first use (mirrors the\n // spritePH===null guard above); falling back to the non-region\n // variant would render black quads (region read returns 0).\n // For sprite-lit the manifest may lack sprite-lit.wgsl; either\n // way fail-safe-skip is the closest the renderer can get to\n // \"show nothing visibly wrong\" without ending the sprite pass\n // (which would drop remaining sprite entities for the frame).\n if (entityShaderId === 'forgeax::sprite') {\n reportSpriteUnavailable();\n } else if (entityShaderId === 'forgeax::sprite-lit') {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'shader-compile-failed',\n expected:\n 'manifest entries include sprite.wgsl + sprite-lit.wgsl (when sprite-lit materials are used) + the engine triple (pbr + unlit + tonemap)',\n hint: 'verify @forgeax/engine-vite-plugin-shader emits manifest.json with sprite.wgsl AND sprite-lit.wgsl entries; check vite plugin engineEntries option',\n }),\n );\n }\n continue;\n }\n if (lastSpritePipelineHandle !== activeSpritePH) {\n spritePass.setPipeline(activeSpritePH);\n lastSpritePipelineHandle = activeSpritePH;\n }\n\n if (spriteEntry.mesh.vertexBuffer !== lastSpriteVertexBuffer) {\n spritePass.setVertexBuffer(0, spriteEntry.mesh.vertexBuffer.handle);\n lastSpriteVertexBuffer = spriteEntry.mesh.vertexBuffer;\n }\n if (\n spriteEntry.mesh.indexBuffer !== null &&\n spriteEntry.mesh.indexBuffer !== lastSpriteIndexBuffer\n ) {\n spritePass.setIndexBuffer(spriteEntry.mesh.indexBuffer.handle, spriteEntry.mesh.indexFormat);\n lastSpriteIndexBuffer = spriteEntry.mesh.indexBuffer;\n }\n\n // Instance buffer resolution: same cap-gate logic as the geometry\n // pass entity loop; sprites with Instances (e.g. hello-sprite-atlas\n // 100-instance walk-cycle) require per-entity storage buffer upload.\n // SSOT mirror of geometry pass instances block above (~line 1610):\n // identical cap-gate sequence (storageBuffer cap → limit-exceeded →\n // cache-lookup → createBuffer → writeBuffer); variable names carry\n // \"sprite\" prefix; logic divergence would be a bug.\n //\n // feat-20260622-chunk-gpu-instancing-sprite-tilemap M1 / w4-record-swap\n // (D-1): when `foldHeadBucket !== undefined` AND the sprite entity has\n // no explicit Instances component, assemble the bucket transforms into\n // a transient instance buffer + override `spriteInstanceCount =\n // bucket.bucketSize`. The mesh slot at `i*MESH_PER_ENTITY_STRIDE` was\n // already overwritten to identity in the mesh SSBO upload loop above,\n // so the shader computes `world = identity * bucket.transforms[idx] *\n // pos`, per-instance correct. Entities with explicit Instances bypass\n // fold (their per-entity Instances semantic wins); bucket key forces\n // such an entity to be a singleton bucket in practice because its\n // material is distinct or unfolded, but defensively check here as a\n // belt-and-suspenders guard.\n let spriteInstanceBuffer: Buffer = pipelineState.identityInstanceBuffer;\n let spriteInstanceCount = 1;\n const spriteInst = spriteEntry.source.instances;\n const useFold = foldHeadBucket !== undefined && spriteInst === undefined;\n if (useFold && foldHeadBucket !== undefined) {\n // w6 (D-8): bucket transient buffer reuse — composite cacheKey from\n // (materialHandle, layer, validatedOrdered head index) so the\n // existing `frameState.instanceBuffers` byteLength/archVersion path\n // covers static steady-state upload-skip. Numeric Map<number,…> key\n // requires a 32-bit-safe fold; we use a negative number-space prefix\n // (-1, -2, ...) by `((materialHandle << 16) | i)` shifted into the\n // negative half so it never collides with positive entity-Instances\n // cacheKeys (which are extracted from Instances component cacheKey\n // numeric ids, always non-negative). The `archVersion` proxy is\n // bucketSize (a structural-shape signal) so static frames hit the\n // cache.\n const bucketCacheKey = -1 - (((foldHeadBucket.materialHandle & 0xffff) << 16) | (i & 0xffff));\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n const bucketPayload = uniformFallback\n ? foldHeadBucket.transforms\n : packInstanceStorageBuffer(foldHeadBucket.transforms);\n const bucketBytes = bucketPayload.byteLength;\n const bucketBufUsage = uniformFallback\n ? GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST\n : GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;\n const cachedBucket = frameState.instanceBuffers.get(bucketCacheKey);\n let activeBucket: InstanceBufferCacheEntry | null = null;\n if (\n cachedBucket !== undefined &&\n cachedBucket.uploadedArchVersion === foldHeadBucket.bucketSize &&\n cachedBucket.uploadedByteLength === bucketBytes\n ) {\n activeBucket = cachedBucket;\n } else if (bucketBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: bucketBytes,\n usage: bucketBufUsage,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n if (cachedBucket !== undefined && !cachedBucket.buffer.isDestroyed) {\n const r = cachedBucket.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuf = new GpuBuffer(runtime.device, bufRes.value);\n activeBucket = {\n buffer: newBuf,\n uploadedArchVersion: foldHeadBucket.bucketSize,\n uploadedByteLength: bucketBytes,\n };\n frameState.instanceBuffers.set(bucketCacheKey, activeBucket);\n }\n }\n if (activeBucket !== null) {\n const writeRes = runtime.device.queue.writeBuffer(\n activeBucket.buffer.handle,\n 0,\n bucketPayload,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n spriteInstanceBuffer = activeBucket.buffer.handle;\n spriteInstanceCount = foldHeadBucket.bucketSize;\n }\n }\n } else if (spriteInst !== undefined) {\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n let spriteBufUsage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;\n\n if (uniformFallback) {\n if (spriteInst.instanceCount > MAX_UNIFORM_INSTANCES) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'limit-exceeded',\n expected: `instance count <= ${MAX_UNIFORM_INSTANCES} (uniform fallback cap)`,\n hint: `reduce instance count to ${MAX_UNIFORM_INSTANCES} or use a WebGPU-capable backend`,\n detail: {\n maxStorageBufferBindingSize: MAX_UNIFORM_INSTANCES * 64,\n requestedBytes: spriteInst.instanceCount * 64,\n },\n }),\n );\n spriteInstanceCount = spriteInst.instanceCount;\n spriteInstanceBuffer = pipelineState.identityInstanceBuffer;\n const spriteInstBgResult = runtime.device.createBindGroup({\n label: 'sprite-pass-instances-bg',\n layout: pipelineState.instancesBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: { buffer: spriteInstanceBuffer },\n },\n },\n ],\n });\n if (!spriteInstBgResult.ok) throw spriteInstBgResult.error;\n spritePass.setBindGroup(3, spriteInstBgResult.value as BindGroup);\n spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);\n continue;\n }\n spriteBufUsage = GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;\n }\n\n {\n const instancePayload = uniformFallback\n ? spriteInst.transforms\n : packInstanceStorageBuffer(spriteInst.transforms);\n const requestedBytes = instancePayload.byteLength;\n const cap = runtime.device.limits.maxStorageBufferBindingSize;\n if (typeof cap === 'number' && requestedBytes > cap) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'limit-exceeded',\n expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,\n hint: 'reduce instance count to fit within device.limits.maxStorageBufferBindingSize, or split transforms across multiple Instances entries',\n detail: {\n maxStorageBufferBindingSize: cap,\n requestedBytes,\n },\n }),\n );\n } else {\n const cachedSprite = frameState.instanceBuffers.get(\n worldEntityKey(spriteEntry.source.worldId, spriteInst.cacheKey),\n );\n let activeSprite: InstanceBufferCacheEntry | null = null;\n if (\n cachedSprite !== undefined &&\n cachedSprite.uploadedArchVersion === spriteInst.archVersion &&\n cachedSprite.uploadedByteLength === requestedBytes\n ) {\n activeSprite = cachedSprite;\n } else if (requestedBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: requestedBytes,\n usage: spriteBufUsage,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n // feat-20260619 M4 / F12: destroy the old cached buffer\n // before replacing it with the new one (D-6).\n if (cachedSprite !== undefined && !cachedSprite.buffer.isDestroyed) {\n const r = cachedSprite.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuf = new GpuBuffer(runtime.device, bufRes.value);\n activeSprite = {\n buffer: newBuf,\n uploadedArchVersion: spriteInst.archVersion,\n uploadedByteLength: requestedBytes,\n };\n frameState.instanceBuffers.set(\n worldEntityKey(spriteEntry.source.worldId, spriteInst.cacheKey),\n activeSprite,\n );\n }\n }\n if (activeSprite !== null) {\n const writeRes = runtime.device.queue.writeBuffer(\n activeSprite.buffer.handle,\n 0,\n instancePayload,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n spriteInstanceBuffer = activeSprite.buffer.handle;\n spriteInstanceCount = Math.max(1, spriteInst.instanceCount);\n }\n }\n }\n }\n }\n\n // feat-20260625-sprite-instances-and-tilemap-terrain-static-batch\n // M3 / w11: SpriteInstances 80B-per-instance interleaved upload path.\n // SSOT for the per-entity 2D mat4 + per-instance UV region buffer\n // (plan-strategy D-1 interleaved single buffer + single binding slot;\n // D-9 cacheKey = entity packed u32). The extract-stage validator\n // (M3 / w10) enforces the XOR contract `Instances XOR SpriteInstances`\n // (sprite-instances-mutually-exclusive-with-instances), so the\n // legacy `spriteInst` block above and this block are never both\n // active for the same entity.\n const _si = resolveSpriteInstancesBuffer(\n c,\n spriteEntry,\n spriteInstanceBuffer,\n spriteInstanceCount,\n );\n spriteInstanceBuffer = _si.buffer;\n spriteInstanceCount = _si.count;\n\n // M3 / w12: LDR sprite split pass per-entity instances BG cache.\n // Same pattern as #7.\n const spriteInstancesBg: BindGroup = getOrCreatePerEntity(\n frameState.instancesBgPerEntity,\n worldEntityKey(spriteEntry.source.worldId, spriteEntry.source.entityKey),\n [spriteInstanceBuffer],\n 'instances',\n () => {\n const result = runtime.device.createBindGroup({\n label: 'sprite-pass-instances-bg',\n layout: pipelineState.instancesBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: { buffer: spriteInstanceBuffer },\n },\n },\n ],\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n bindGroupCounts,\n );\n\n spritePass.setBindGroup(2, meshBindGroup as BindGroup, [i * MESH_PER_ENTITY_STRIDE]);\n\n // Per-entity sprite material bind group: same standard PBR user-region\n // layout as in the geometry pass sprite branch + Skylight merged entries\n // the geometry pass sprite branch + Skylight merged entries (same\n // skylightResources in scope from above). Texture view is resolved\n // from the sprite material's baseColorTexture handle.\n const spriteTexHandle = spriteEntry.source.material.baseColorTexture as\n | Handle<'TextureAsset', 'shared'>\n | undefined;\n let spriteTexView = pipelineState.defaultWhiteTextureView;\n if (spriteTexHandle !== undefined) {\n const tv = residentTextureView(spriteEntry.world ?? world, store, runtime, spriteTexHandle);\n if (tv !== undefined) spriteTexView = tv as never;\n }\n const spritePassBaseMaterialEntries = buildSpritePassBaseMaterialEntries(\n pipelineState,\n spriteTexView,\n );\n const spritePassMergedEntries = assembleMaterialWithSkylightEntries(\n spritePassBaseMaterialEntries,\n skylightResources,\n );\n\n // Sprite-pass material BG cache: keyed on shader id (shared across all\n // sprite entities) so entities using the same atlas texture share one\n // BindGroup instead of creating one per entity (O5 fix — inner WeakMap\n // chain naturally deduplicates by GPU resource object identity, so two\n // entities with different atlases still get distinct BGs).\n const spritePassBg: BindGroup = getOrCreatePerEntity(\n frameState.materialBgShared,\n 'forgeax::sprite',\n spritePassMergedEntries.map((e) => extractEntryResourceHandle(e)),\n 'sprite-pass-material',\n () => {\n const result = runtime.device.createBindGroup({\n label: 'sprite-pass-material-bg',\n layout: pipelineState.materialBindGroupLayout,\n entries: spritePassMergedEntries,\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n bindGroupCounts,\n );\n\n const materialSlot = materialSlotIndices[i]?.[0] ?? 0;\n spritePass.setBindGroup(1, spritePassBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);\n spritePass.setBindGroup(3, spriteInstancesBg);\n spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);\n }\n}\n\n/**\n * feat-20260704 M3/w19: resolve the interleaved SpriteInstances (@group(3))\n * buffer + instanceCount for a sprite entity in the LDR blend sub-pass,\n * extracted verbatim from recordSpriteEntityDraws. Uploads the interleaved\n * mat4 + per-instance UV region transforms (cache-keyed on the snapshot); on\n * over-cap fires the structured limit-exceeded error and leaves the passed-in\n * fallback buffer/count. Returns the resolved (or unchanged) buffer + count.\n *\n * @internal\n */\nfunction resolveSpriteInstancesBuffer(\n c: _InternalRenderPipelineContext,\n spriteEntry: _InternalRenderPipelineContext['validatedOrdered'][number],\n fallbackBuffer: Buffer,\n fallbackCount: number,\n): { buffer: Buffer; count: number } {\n const { runtime, frameState } = c;\n let buffer = fallbackBuffer;\n let count = fallbackCount;\n const spriteInstancesSnap: SpriteInstancesSnapshot | undefined =\n spriteEntry.source.spriteInstances;\n if (spriteInstancesSnap !== undefined) {\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n const interleaved = interleaveSpriteInstanceBuffer(\n spriteInstancesSnap.transforms,\n spriteInstancesSnap.regions,\n !uniformFallback,\n );\n const requestedBytes = interleaved.byteLength;\n const cap = runtime.device.limits.maxStorageBufferBindingSize;\n if (typeof cap === 'number' && requestedBytes > cap) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'limit-exceeded',\n expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,\n hint: 'reduce SpriteInstances instance count to fit within device.limits.maxStorageBufferBindingSize (144 bytes per instance: current mat4 64B + previous mat4 64B + region 16B)',\n detail: {\n maxStorageBufferBindingSize: cap,\n requestedBytes,\n },\n }),\n );\n } else {\n const cachedSpriteInst = frameState.instanceBuffers.get(\n worldEntityKey(spriteEntry.source.worldId, spriteInstancesSnap.cacheKey),\n );\n let activeSpriteInst: InstanceBufferCacheEntry | null = null;\n if (spriteInstancesCacheHit(cachedSpriteInst, spriteInstancesSnap, requestedBytes)) {\n activeSpriteInst = cachedSpriteInst ?? null;\n } else if (requestedBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: requestedBytes,\n usage:\n (uniformFallback ? GPU_BUFFER_USAGE_UNIFORM : GPU_BUFFER_USAGE_STORAGE) |\n GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n if (cachedSpriteInst !== undefined && !cachedSpriteInst.buffer.isDestroyed) {\n const r = cachedSpriteInst.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuf = new GpuBuffer(runtime.device, bufRes.value);\n activeSpriteInst = {\n buffer: newBuf,\n uploadedArchVersion: spriteInstancesSnap.archVersion,\n uploadedByteLength: requestedBytes,\n };\n frameState.instanceBuffers.set(\n worldEntityKey(spriteEntry.source.worldId, spriteInstancesSnap.cacheKey),\n activeSpriteInst,\n );\n }\n }\n if (activeSpriteInst !== null && requestedBytes > 0) {\n const writeRes = runtime.device.queue.writeBuffer(\n activeSpriteInst.buffer.handle,\n 0,\n interleaved,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n buffer = activeSpriteInst.buffer.handle;\n count = spriteInstancesSnap.instanceCount;\n }\n }\n }\n }\n return { buffer, count };\n}\n\nfunction transparentPassColorFormat(\n c: _InternalRenderPipelineContext,\n pipelineState: _InternalRenderPipelineContext['pipelineState'] = c.pipelineState,\n): string {\n if (c.transparentColorFormat !== undefined) return c.transparentColorFormat;\n if (!c.runtime.device.caps.storageBuffer) return pipelineState.colorAttachmentFormat;\n return pipelineState.format;\n}\n","// M3 / w19: PassSelector matching logic\n// (feat-20260526-material-asset-multipass-renderstate)\n//\n// Pure-function helpers for matching MaterialPass tags against\n// a PassSelector. Plan-strategy D-4: Tags free Record + PassSelector\n// Record<string, string[]>. Requirements AC-05.\n\nimport type { MaterialPass, PassSelector } from '@forgeax/engine-types';\n\n/**\n * Test whether a pass's tags match a {@link PassSelector}.\n *\n * Matching rule (AC-05): every key in the selector must exist in the pass's\n * `tags` and the pass's tag value must be in the selector's value list for\n * that key. An empty selector matches every pass.\n *\n * @param tags The pass-level tags (free key-value pairs)\n * @param selector The selector to match against\n */\nexport function matchPass(tags: Record<string, string>, selector: PassSelector): boolean {\n if (Object.keys(selector).length === 0) return true;\n for (const [key, allowedValues] of Object.entries(selector)) {\n const passValue = tags[key];\n if (passValue === undefined) return false;\n if ((allowedValues as readonly string[]).length === 0) return false;\n if (!(allowedValues as readonly string[]).includes(passValue)) return false;\n }\n return true;\n}\n\n/**\n * Filter passes whose tags match the given {@link PassSelector}.\n *\n * An empty selector matches all passes (returns the input array reference).\n * Otherwise each pass is checked via {@link matchPass}.\n *\n * @param passes The material's pass descriptors\n * @param selector The pass selector\n * @returns Filtered array of matching passes\n */\nexport function selectPasses(\n passes: readonly MaterialPass[],\n selector: PassSelector,\n): readonly MaterialPass[] {\n if (Object.keys(selector).length === 0) return passes;\n return passes.filter((p) =>\n matchPass((p.renderState?.tags as Record<string, string> | undefined) ?? {}, selector),\n );\n}\n","import {\n type BindGroup,\n type BindGroupEntry,\n type Buffer,\n type RenderPipeline,\n RhiError,\n type RhiQueue,\n type RhiRenderPassEncoder,\n} from '@forgeax/engine-rhi';\nimport type { PassSelector } from '@forgeax/engine-types';\nimport { GpuBuffer } from '../gpu-resource';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_STORAGE,\n GPU_BUFFER_USAGE_UNIFORM,\n} from '../gpu-usage';\nimport { assembleMaterialWithSkylightEntries } from '../ibl/skylight-bind-group';\nimport type { InstanceBufferCacheEntry } from '../instance-buffer-cache';\nimport {\n buildPbrMaterialUserRegionEntries,\n SHADOW_CASTER_SHADER_ID,\n shadowCasterVariantSet,\n} from '../pbr-pipeline';\nimport type { DispatchEntry, ExtractedLights } from '../render-system-extract';\nimport { matchPass } from '../systems/pass-selector';\nimport { worldEntityKey } from './frame-snapshot';\nimport {\n getOrCreateFromChain,\n getOrCreatePerEntity,\n MAX_UNIFORM_INSTANCES,\n MESH_PER_ENTITY_STRIDE,\n MESH_SSBO_BYTES,\n MESH_UBO_FULL_ARRAY_BYTES,\n packInstanceStorageBuffer,\n} from './mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { STANDARD_PBR_UBO_SIZE } from './render-context';\nimport { POINTS_LINES_VIEW_BYTES, pointShadowViewOffset, VIEW_UNIFORM_BYTES } from './view-ubo';\n\nexport const SHADOW_CASTER_SLOT_STRIDE = 256;\nexport const SHADOW_CASTER_BUFFER_SIZE = SHADOW_CASTER_SLOT_STRIDE * 8;\n\nexport function directionalShadowCasterOffset(cascadeIndex: number): number {\n return SHADOW_CASTER_SLOT_STRIDE * cascadeIndex;\n}\n\nexport function spotShadowCasterOffset(tile: number): number {\n return SHADOW_CASTER_SLOT_STRIDE * (4 + tile);\n}\n\nexport function writeShadowCasterUniforms(\n queue: RhiQueue,\n buffer: Buffer,\n lights: ExtractedLights,\n): void {\n for (let cascade = 0; cascade < 4; cascade += 1) {\n const written = queue.writeBuffer(\n buffer,\n directionalShadowCasterOffset(cascade),\n new Uint32Array([cascade, 0, 0, 0]),\n );\n if (!written.ok) throw written.error;\n }\n for (const snapshot of lights.spot) {\n const tile = snapshot.shadowAtlasTile;\n if (tile < 0 || tile >= 4 || snapshot.lightViewProj === undefined) continue;\n const offset = spotShadowCasterOffset(tile);\n const header = queue.writeBuffer(buffer, offset, new Uint32Array([0, 1, 0, 0]));\n if (!header.ok) throw header.error;\n const matrix = queue.writeBuffer(buffer, offset + 16, snapshot.lightViewProj);\n if (!matrix.ok) throw matrix.error;\n }\n}\n\nfunction ensureTypedShadowViewBg(\n c: _InternalRenderPipelineContext,\n viewOffset: number,\n cascadeOffset: number,\n variant: string,\n): BindGroup | null {\n const { runtime, frameState, pipelineState } = c;\n const shadowSampler = pipelineState.perPassResources.shadowSampler;\n if (shadowSampler === null) return null;\n try {\n return getOrCreateFromChain(\n frameState.viewBindGroupCache,\n [\n pipelineState.viewUniformBuffer,\n pipelineState.pointLightsBuffer,\n pipelineState.spotLightsBuffer,\n pipelineState.shadowFallbackTextureView,\n shadowSampler,\n pipelineState.shadowAtlasFallbackTextureView,\n pipelineState.shadowParamsBuffer,\n pipelineState.shadowCasterCascadeBuffer,\n pipelineState.shadowFallbackTextureView,\n pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,\n ],\n variant,\n () => {\n const created = runtime.device.createBindGroup({\n label: variant,\n layout: pipelineState.viewBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.viewUniformBuffer,\n offset: viewOffset,\n size: VIEW_UNIFORM_BYTES,\n },\n },\n },\n {\n binding: 1,\n resource: { kind: 'buffer', value: { buffer: pipelineState.pointLightsBuffer } },\n },\n {\n binding: 2,\n resource: { kind: 'buffer', value: { buffer: pipelineState.spotLightsBuffer } },\n },\n {\n binding: 3,\n resource: { kind: 'textureView', value: pipelineState.shadowFallbackTextureView },\n },\n {\n binding: 4,\n resource: { kind: 'sampler', value: shadowSampler },\n },\n {\n binding: 5,\n resource: {\n kind: 'textureView',\n value: pipelineState.shadowAtlasFallbackTextureView,\n },\n },\n {\n binding: 6,\n resource: { kind: 'buffer', value: { buffer: pipelineState.shadowParamsBuffer } },\n },\n {\n binding: 7,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.shadowCasterCascadeBuffer,\n offset: cascadeOffset,\n size: POINTS_LINES_VIEW_BYTES,\n },\n },\n },\n {\n binding: 8,\n resource: { kind: 'textureView', value: pipelineState.shadowFallbackTextureView },\n },\n {\n binding: 10,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,\n size: 80,\n },\n },\n },\n ],\n });\n if (!created.ok) throw created.error;\n return created.value;\n },\n c.bindGroupCounts,\n );\n } catch (error) {\n if (error instanceof RhiError) {\n runtime.errorRegistry.fire(error);\n return null;\n }\n throw error;\n }\n}\n\nfunction shadowShaderMap(c: _InternalRenderPipelineContext): ReadonlyMap<number, string> {\n const shaders = new Map<number, string>();\n for (const entry of c.dispatch) {\n if (entry.tags.LightMode === 'ShadowCaster' && entry.materialShaderId !== undefined) {\n shaders.set(entry.renderableIndex, entry.materialShaderId);\n }\n }\n return shaders;\n}\n\nfunction shadowPipeline(c: _InternalRenderPipelineContext): RenderPipeline | null {\n return (\n c.runtime.getMaterialShaderPipeline?.(\n SHADOW_CASTER_SHADER_ID,\n false,\n undefined,\n 'triangle-list',\n undefined,\n shadowCasterVariantSet(c.runtime.device.caps.storageBuffer, false),\n 'shadow-caster',\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n 'pbr',\n ) ?? null\n );\n}\n\nfunction skinnedShadowPipeline(\n c: _InternalRenderPipelineContext,\n entry: _InternalRenderPipelineContext['validatedOrdered'][number],\n): RenderPipeline | null {\n return (\n c.runtime.getMaterialShaderPipeline?.(\n SHADOW_CASTER_SHADER_ID,\n false,\n undefined,\n entry.mesh.submeshes[0]?.topology ?? 'triangle-list',\n entry.mesh.indexFormat,\n shadowCasterVariantSet(c.runtime.device.caps.storageBuffer, true),\n 'shadow-caster',\n undefined,\n 1,\n undefined,\n undefined,\n undefined,\n undefined,\n entry.mesh.layoutProjection,\n undefined,\n 'pbr-skin',\n ) ?? null\n );\n}\n\nfunction skinnedShadowMeshBindGroup(\n c: _InternalRenderPipelineContext,\n entry: _InternalRenderPipelineContext['validatedOrdered'][number],\n): BindGroup | null {\n const skin = entry.source.skin;\n const layout = c.pipelineState.pbrSkinMeshBindGroupLayout;\n const allocator = c.pipelineState.skinPaletteAllocator;\n if (skin === undefined || layout === null || allocator === null) return null;\n return getOrCreateFromChain(\n c.frameState.meshBindGroupCache,\n [c.pipelineState.meshStorageBuffer.buffer, skin.buffer],\n 'shadow-pbr-skin-mesh',\n () => {\n const created = c.runtime.device.createBindGroup({\n label: 'shadow-pbr-skin-mesh-bg',\n layout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: c.pipelineState.meshStorageBuffer.buffer,\n size: c.runtime.device.caps.storageBuffer\n ? MESH_SSBO_BYTES\n : MESH_UBO_FULL_ARRAY_BYTES,\n },\n },\n },\n {\n binding: 1,\n resource: {\n kind: 'buffer',\n value: { buffer: skin.buffer, size: allocator.bindingWindowBytes },\n },\n },\n ],\n });\n if (!created.ok) throw created.error;\n return created.value;\n },\n c.bindGroupCounts,\n );\n}\n\nexport function encodeDirectionalShadowPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n cascadeIndex: number,\n viewport: { readonly x: number; readonly y: number; readonly w: number; readonly h: number },\n): void {\n if (c.directionalShadowCacheReuse || c.meshBindGroup === null) return;\n const pipeline = shadowPipeline(c);\n const viewBg = ensureTypedShadowViewBg(\n c,\n 0,\n directionalShadowCasterOffset(cascadeIndex),\n `view-shadow-directional-${cascadeIndex}`,\n );\n const materialBg = ensureSpotShadowMaterialBg(c);\n if (pipeline === null || viewBg === null || materialBg === null) return;\n c.frameState.directionalShadowCacheRecorded = true;\n pass.setViewport(viewport.x, viewport.y, viewport.w, viewport.h, 0, 1);\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, viewBg, [0]);\n pass.setBindGroup(1, materialBg, [0]);\n recordShadowCasterDraws(\n c,\n pass,\n pipeline,\n c.meshBindGroup,\n buildMatchedRenderableIndices(c.dispatch, { LightMode: ['ShadowCaster'] }),\n shadowShaderMap(c),\n );\n}\n\nexport function encodePointShadowPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n snapshotIndex: number,\n face: number,\n): void {\n const snapshot = c.frameState.pointShadowSnapshots[snapshotIndex];\n if (snapshot === undefined || c.meshBindGroup === null) return;\n const pipeline = shadowPipeline(c);\n const viewBg = ensureTypedShadowViewBg(\n c,\n pointShadowViewOffset(snapshot.shadowAtlasLayer, face),\n 0,\n `view-shadow-point-${snapshot.shadowAtlasLayer}-${face}`,\n );\n const materialBg = ensureSpotShadowMaterialBg(c);\n if (pipeline === null || viewBg === null || materialBg === null) return;\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, viewBg, [0]);\n pass.setBindGroup(1, materialBg, [0]);\n recordShadowCasterDraws(\n c,\n pass,\n pipeline,\n c.meshBindGroup,\n buildMatchedRenderableIndices(c.dispatch, { LightMode: ['ShadowCaster'] }),\n shadowShaderMap(c),\n );\n}\n\nexport function encodeSpotShadowPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n snapshotIndex: number,\n): void {\n const snapshot = c.frameState.spotShadowSnapshots.filter(\n (candidate) => candidate.shadowAtlasTile >= 0 && candidate.lightViewProj !== undefined,\n )[snapshotIndex];\n if (\n snapshot === undefined ||\n snapshot.shadowAtlasTile < 0 ||\n snapshot.lightViewProj === undefined ||\n c.meshBindGroup === null\n ) {\n return;\n }\n const pipeline = shadowPipeline(c);\n const viewBg = ensureTypedShadowViewBg(\n c,\n 0,\n spotShadowCasterOffset(snapshot.shadowAtlasTile),\n `view-shadow-spot-${snapshot.shadowAtlasTile}`,\n );\n const materialBg = ensureSpotShadowMaterialBg(c);\n if (pipeline === null || viewBg === null || materialBg === null) return;\n const tileSize = c.pipelineState.perPassResources.shadowMapSize;\n const tile = snapshot.shadowAtlasTile;\n pass.setViewport(\n (tile % 2) * tileSize,\n Math.floor(tile / 2) * tileSize,\n tileSize,\n tileSize,\n 0,\n 1,\n );\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, viewBg, [0]);\n pass.setBindGroup(1, materialBg, [0]);\n // Reuse the shared caster recorder. The compact spot-only loop used to\n // depend on instance bindings created by a directional pass, so a scene\n // containing only a SpotLight opened the atlas pass but emitted no caster\n // draws.\n recordShadowCasterDraws(\n c,\n pass,\n pipeline,\n c.meshBindGroup,\n buildMatchedRenderableIndices(c.dispatch, { LightMode: ['ShadowCaster'] }),\n shadowShaderMap(c),\n );\n}\n\n/**\n * feat-20260609 M2: filter dispatch entries by a {@link PassSelector}.\n *\n * Each dispatch entry carries `tags` (a free key-value map) sourced from the\n * material's per-pass tags. The selector is matched entry-by-entry via\n * {@link matchPass}; entries whose tags satisfy the selector are returned.\n * An empty selector returns the input array unchanged (match-all semantics).\n *\n * @param dispatch Per-frame dispatch entries (from the extract stage).\n * @param selector Pipeline-specific pass selector (e.g. `{ LightMode: ['Forward'] }`).\n * @returns Dispatch entries whose tags match the selector.\n */\nexport function filterDispatchBySelector(\n dispatch: readonly DispatchEntry[],\n selector: PassSelector,\n): readonly DispatchEntry[] {\n if (Object.keys(selector).length === 0) return dispatch;\n return dispatch.filter((e) => matchPass(e.tags, selector));\n}\n\n/**\n * feat-20260609 M2: build a set of renderable indices whose dispatch entries\n * match the given selector. Used by the record pass closures to skip entities\n * that do not belong to the current pass.\n *\n * Returns null when the dispatch array is empty (no dispatch-based filtering\n * to apply — draw all entities). Returns an empty set when dispatch is\n * non-empty but no entries matched (draw nothing). Returns a populated set\n * when at least one dispatch entry matched.\n */\nexport function buildMatchedRenderableIndices(\n dispatch: readonly DispatchEntry[],\n selector: PassSelector,\n): Set<number> | null {\n // PRODUCTION INVARIANT: in real frames extractFrame always populates\n // dispatch[] for every visible renderable (Forward + ShadowCaster tags\n // emitted per validated entity, including the default-material handle=0\n // path — see render-system-extract.ts default-material dispatch emission).\n // The empty-dispatch null fallback below exists ONLY for unit-test\n // fixtures that mock dispatch out (early w-* tests written before\n // dispatch existed). Returning null causes the downstream loop to skip\n // selector filtering, preserving back-compat for those fixtures. If a\n // future refactor moves dispatch population earlier or makes it\n // conditional, the test fixtures should be updated rather than this\n // fallback widened to production.\n if (dispatch.length === 0) return null;\n const filtered = filterDispatchBySelector(dispatch, selector);\n const set = new Set<number>();\n for (const e of filtered) {\n set.add(e.renderableIndex);\n }\n return set;\n}\n\n/**\n * Build the material handles whose dispatch entries match a graph pass.\n *\n * A renderable can own more than one material pass, so renderable-level\n * filtering is insufficient for geometry recording: a Deferred graph pass\n * must not draw the same renderable's Forward-only material. Keep the\n * renderable key in the result so mixed-material meshes retain their\n * per-submesh routing.\n */\nexport function buildMatchedMaterialHandlesByRenderable(\n dispatch: readonly DispatchEntry[],\n selector: PassSelector,\n): ReadonlyMap<number, ReadonlySet<number>> | null {\n if (dispatch.length === 0) return null;\n const matched = filterDispatchBySelector(dispatch, selector);\n const handlesByRenderable = new Map<number, Set<number>>();\n for (const entry of matched) {\n const handles = handlesByRenderable.get(entry.renderableIndex);\n if (handles === undefined) {\n handlesByRenderable.set(entry.renderableIndex, new Set([entry.materialHandle]));\n } else {\n handles.add(entry.materialHandle);\n }\n }\n return handlesByRenderable;\n}\n\n/**\n * feat-20260704 M3/w20: per-entity directional shadow-caster draw loop,\n * extracted verbatim from {@link encodeDirectionalShadowPass}. Walks `c.validatedOrdered`,\n * selects the per-entity shadow PSO (default vertex-only caster or a custom\n * cutout caster), binds the per-entity mesh dynamic-offset + instance buffer,\n * and issues the per-submesh depth draws. `shadowPass` view/material bind\n * groups (@group 0/1) are already set by the caller; this loop owns @group\n * 2/3 + the vertex/index/pipeline de-dup state. Receives the explicit\n * `_InternalRenderPipelineContext` (`c`) plus the caller-resolved shadow\n * pipeline, mesh bind group, pass-selector match set, and per-renderable\n * custom-caster shader map so no cross-function mutable state is introduced.\n */\nfunction recordShadowCasterDraws(\n c: _InternalRenderPipelineContext,\n shadowPass: RhiRenderPassEncoder,\n shadowPipeline: RenderPipeline,\n shadowMeshBindGroup: BindGroup,\n matchedIndices: Set<number> | null,\n shadowShaderByRenderableIdx: ReadonlyMap<number, string>,\n): void {\n const { runtime, pipelineState, validatedOrdered } = c;\n // M-3 / w12: vertexBuffer/indexBuffer state locals migrate to GpuBuffer\n // (the wrapper) -- the de-dup compare uses wrapper identity (one wrapper\n // per RHI handle from gpuStore), and `.handle` is passed to the RHI\n // setVertexBuffer / setIndexBuffer call.\n let shadowLastVertexBuffer: GpuBuffer | null = null;\n let shadowLastIndexBuffer: GpuBuffer | null = null;\n // bug-20260619-csm RC-3 (D-3): track the currently-bound shadow PSO so\n // per-entity setPipeline only fires on change (same de-dup discipline as\n // vertex/index buffers above). The default-shadow-caster PSO is already\n // bound by the setPipeline call above; the loop switches to a custom\n // ShadowCaster PSO when a material supplies one.\n let shadowLastPipeline: RenderPipeline = shadowPipeline;\n\n for (let i = 0; i < validatedOrdered.length; i++) {\n const entry = validatedOrdered[i];\n if (entry === undefined) continue;\n\n // feat-20260609 M2: skip entities that don't match the pass selector.\n if (matchedIndices !== null && !matchedIndices.has(entry.renderableIndex)) continue;\n\n // bug-20260619-csm RC-3 (AC-10, D-3): resolve the per-entity shadow\n // PSO from its ShadowCaster shader id. Default casters keep the\n // vertex-only `forgeax::default-shadow-caster` PSO bound above; a\n // material with a custom ShadowCaster shader (cutout alpha-test) gets\n // its own fragment-carrying PSO so `discard` runs in the depth pass.\n const entryShadowShaderId = shadowShaderByRenderableIdx.get(entry.renderableIndex);\n let entryShadowPipeline = shadowPipeline;\n if (entry.source.skin !== undefined) {\n const skinPipeline = skinnedShadowPipeline(c, entry);\n if (skinPipeline === null) continue;\n entryShadowPipeline = skinPipeline;\n } else if (\n entryShadowShaderId !== undefined &&\n entryShadowShaderId !== SHADOW_CASTER_SHADER_ID\n ) {\n // Custom ShadowCaster PSO; same cache path as the default above\n // (passKind 'shadow-caster'). On a cache miss (async build in\n // flight / build failure) fall back to the default PSO so the\n // caster still writes depth rather than dropping its draw.\n entryShadowPipeline =\n runtime.getMaterialShaderPipeline?.(\n entryShadowShaderId,\n false, // isHdr — shadow depth pass is always LDR\n undefined, // renderState\n 'triangle-list', // topology — shadow PSO targets triangle-list\n undefined, // indexFormat\n undefined, // variantSet — shadow caster has no variant axes\n 'shadow-caster', // passKind\n ) ?? shadowPipeline;\n }\n if (entryShadowPipeline !== shadowLastPipeline && entryShadowPipeline !== null) {\n shadowPass.setPipeline(entryShadowPipeline);\n shadowLastPipeline = entryShadowPipeline;\n }\n\n // feat-20260604-mesh-topology-debug-draw M5 / w14 (AC-09, D-A6): the\n // shadow caster PSO is triangle-list; it only projects triangle faces.\n // line-list / line-strip / point-list meshes have no surface to cast a\n // shadow, so skip them here. triangle-strip is still a face topology\n // and projects (the shadow PSO's fixed triangle-list rasterizes its\n // expanded triangles correctly enough for the depth pass).\n //\n // feat-20260608 M4 / w16: per-submesh shadow draw — iterate submeshes\n // and skip non-triangle submeshes individually (each submesh may differ).\n const shadowSubmeshes = entry.mesh.submeshes;\n const hasAnyShadowSubmesh = shadowSubmeshes.some(\n (sm) => sm.topology === 'triangle-list' || sm.topology === 'triangle-strip',\n );\n if (!hasAnyShadowSubmesh) {\n continue;\n }\n\n if (entry.mesh.vertexBuffer !== shadowLastVertexBuffer) {\n shadowPass.setVertexBuffer(0, entry.mesh.vertexBuffer.handle);\n shadowLastVertexBuffer = entry.mesh.vertexBuffer;\n }\n if (entry.mesh.indexed && entry.mesh.indexBuffer !== shadowLastIndexBuffer) {\n // indexed=true implies indexBuffer is non-null GpuBuffer.\n if (entry.mesh.indexBuffer !== null) {\n shadowPass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);\n shadowLastIndexBuffer = entry.mesh.indexBuffer;\n }\n }\n\n if (entry.source.skin !== undefined) {\n const skinMeshBindGroup = skinnedShadowMeshBindGroup(c, entry);\n if (skinMeshBindGroup === null) continue;\n shadowPass.setBindGroup(2, skinMeshBindGroup, [\n i * MESH_PER_ENTITY_STRIDE,\n entry.source.skin.byteOffset,\n ]);\n } else {\n shadowPass.setBindGroup(2, shadowMeshBindGroup, [i * MESH_PER_ENTITY_STRIDE]);\n }\n\n // C1 + C2 (w12): per-entity instance buffer + instanceCount\n let shadowInstanceBuffer: Buffer = pipelineState.identityInstanceBuffer;\n let shadowInstanceCount = 1;\n const shadowInst = entry.source.instances;\n if (shadowInst !== undefined) {\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n // Over-cap uniform fallback can't fit the per-instance window — bind\n // identity and let the shader collapse (same semantics as the main\n // pass). Otherwise build/upload the per-entity instance buffer: storage\n // by default, uniform when the device lacks storage buffers.\n if (uniformFallback && shadowInst.instanceCount > MAX_UNIFORM_INSTANCES) {\n shadowInstanceCount = shadowInst.instanceCount;\n shadowInstanceBuffer = pipelineState.identityInstanceBuffer;\n } else {\n const bufUsage = uniformFallback\n ? GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST\n : GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;\n const instancePayload = uniformFallback\n ? shadowInst.transforms\n : packInstanceStorageBuffer(shadowInst.transforms);\n const requestedBytes = instancePayload.byteLength;\n const cached = c.frameState.instanceBuffers.get(\n worldEntityKey(entry.source.worldId, shadowInst.cacheKey),\n );\n let active: InstanceBufferCacheEntry | null = null;\n if (\n cached !== undefined &&\n cached.uploadedArchVersion === shadowInst.archVersion &&\n cached.uploadedByteLength === requestedBytes\n ) {\n active = cached;\n } else if (requestedBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: requestedBytes,\n usage: bufUsage,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n // feat-20260619 M4 / F12: destroy the old cached buffer\n // before replacing it with the new one (D-6).\n if (cached !== undefined && !cached.buffer.isDestroyed) {\n const r = cached.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuffer = new GpuBuffer(runtime.device, bufRes.value);\n active = {\n buffer: newBuffer,\n uploadedArchVersion: shadowInst.archVersion,\n uploadedByteLength: requestedBytes,\n };\n c.frameState.instanceBuffers.set(\n worldEntityKey(entry.source.worldId, shadowInst.cacheKey),\n active,\n );\n }\n }\n if (active !== null) {\n const writeRes = runtime.device.queue.writeBuffer(\n active.buffer.handle,\n 0,\n instancePayload,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n shadowInstanceBuffer = active.buffer.handle;\n shadowInstanceCount = Math.max(1, shadowInst.instanceCount);\n }\n }\n }\n }\n\n // Bind per-entity instances BG for @group(3) (or fallback identity).\n // D-4: write end of the HDRP shadow-instances producer/consumer pair.\n // outerKey = worldEntityKey(entry.source.worldId, entry.source.entityKey),\n // handle = shadowInstanceBuffer; the HDRP main pass read end (:3820 below)\n // must look up the same (compositeKey, instBuffer) leaf or the shadow\n // instances silently drop.\n const shadowInstancesBg = getOrCreatePerEntity(\n c.frameState.instancesBgPerEntity,\n worldEntityKey(entry.source.worldId, entry.source.entityKey),\n [shadowInstanceBuffer],\n 'shadow-instances',\n () => {\n const result = runtime.device.createBindGroup({\n label: 'shadow-instances-bg',\n layout: pipelineState.instancesBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: { buffer: shadowInstanceBuffer },\n },\n },\n ],\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n c.bindGroupCounts,\n );\n\n shadowPass.setBindGroup(3, shadowInstancesBg);\n // feat-20260608 M4 / w16: per-submesh shadow draw loop.\n // Only draw submeshes whose topology is triangle-list or triangle-strip\n // (line-list / point-list submeshes cast no shadow and are skipped).\n for (const sm of shadowSubmeshes) {\n if (sm.topology !== 'triangle-list' && sm.topology !== 'triangle-strip') {\n continue;\n }\n if (entry.mesh.indexed) {\n shadowPass.drawIndexed(sm.indexCount, shadowInstanceCount, sm.indexOffset, 0, 0);\n } else {\n shadowPass.draw(sm.vertexCount, shadowInstanceCount, 0, 0);\n }\n }\n }\n}\n\n/**\n * Build (or reuse) the dummy `shadow-material-singleton` @group(1) BG for the\n * spot shadow caster pass. The vertex-only shadow_caster shader never consumes\n * @group(1) but the PSO's BGL must validate. Reuses the same singleton Map\n * entry encodeDirectionalShadowPass / encodePointShadowPass write so the three paths share\n * one allocation per frame (D-6).\n */\nfunction ensureSpotShadowMaterialBg(c: _InternalRenderPipelineContext): BindGroup | null {\n const { runtime, frameState, pipelineState } = c;\n const cached = frameState.singletonMaterialCache.get('shadow-material-singleton');\n if (cached !== undefined) return cached;\n const fb = pipelineState.skylightFallback;\n const fallbackEntries: BindGroupEntry[] = buildPbrMaterialUserRegionEntries().map((entry) => {\n if (entry.buffer !== undefined) {\n return {\n binding: entry.binding,\n resource: {\n kind: 'buffer' as const,\n value: {\n buffer: pipelineState.materialUniformBuffer.buffer,\n offset: 0,\n size: STANDARD_PBR_UBO_SIZE,\n },\n },\n };\n }\n if (entry.sampler !== undefined) {\n return {\n binding: entry.binding,\n resource: { kind: 'sampler' as const, value: pipelineState.defaultSampler },\n };\n }\n return {\n binding: entry.binding,\n resource: {\n kind: 'textureView' as const,\n value:\n entry.binding === 6\n ? pipelineState.defaultNormalTextureView\n : pipelineState.fallbackTextureView,\n },\n };\n });\n const merged =\n fb !== null\n ? assembleMaterialWithSkylightEntries(fallbackEntries, {\n irradianceView: fb.irradianceView,\n irradianceSampler: fb.sampler,\n prefilterView: fb.prefilterView,\n prefilterSampler: fb.sampler,\n brdfLutView: fb.brdfLutView,\n brdfLutSampler: fb.sampler,\n intensityBuffer: fb.intensityBuffer,\n })\n : fallbackEntries;\n const r = runtime.device.createBindGroup({\n label: 'shadow-material-bg',\n layout: pipelineState.materialBindGroupLayout,\n entries: merged,\n });\n if (!r.ok) {\n runtime.errorRegistry.fire(r.error);\n return null;\n }\n c.bindGroupCounts.createBindGroup += 1;\n c.bindGroupCounts.keys.push('shadow-material-singleton');\n frameState.singletonMaterialCache.set('shadow-material-singleton', r.value);\n return r.value;\n}\n","import type { World } from '@forgeax/engine-ecs';\nimport { probeVideoHighPerfUpload } from '@forgeax/engine-graphics-extras';\nimport {\n type BindGroup,\n RhiError,\n type RhiRenderPassEncoder,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport type { Handle, PassKind, PassSelector } from '@forgeax/engine-types';\nimport { createHdrpUnifiedBindGroup, getOrCreateHdrpBuffers } from '../hdrp-buffers';\nimport { getOrCreateIblCache } from '../ibl/IblPipelineCache';\nimport { buildBeginRenderPassDescriptor } from '../pipeline-spec';\nimport { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';\nimport type { RenderRecordPhase } from '../render-contract';\nimport type { MaterialSnapshot } from '../render-system-extract';\nimport { recordGeometryDraws } from './main-pass-geometry';\nimport {\n applyMaterialTextureUvScales,\n applyParamSnapshotToUbo,\n buildPerSubmeshMaterialBg as buildPerSubmeshMaterialBgImpl,\n detectNineSliceScaleTooSmall,\n type PerSubmeshMaterialBgDeps,\n residentTextureView,\n writePbrMaterialUboPayload,\n} from './main-pass-material';\nimport { recordSpritePass } from './main-pass-sprite-draws';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { MATERIAL_PER_ENTITY_STRIDE, STANDARD_PBR_UBO_SIZE } from './render-context';\nimport {\n buildMatchedMaterialHandlesByRenderable,\n buildMatchedRenderableIndices,\n} from './shadow-pass';\n\nconst ZERO_SKYLIGHT_PAYLOAD = new Float32Array([0, 0, 0, 0, 0, 0, 0, 1]);\n\nexport type MainPassOptions = {\n readonly colorViews?: readonly (TextureView | null)[];\n readonly colorFormats?: readonly GPUTextureFormat[];\n readonly depthView?: TextureView | null;\n readonly passKind?: PassKind;\n readonly clearColor?: readonly [number, number, number, number];\n readonly recordMode?: 'opaque' | 'transmission' | 'transparent';\n readonly transmissionBackdropView?: TextureView | null;\n};\n\nconst TRANSMISSION_VARIANT_SET = 'TRANSMISSION_AVAILABLE=true';\n\nfunction isTransmissionMaterial(material: MaterialSnapshot): boolean {\n return (\n material.materialShaderId === 'forgeax::default-standard-pbr' &&\n typeof material.paramSnapshot?.transmission === 'number' &&\n material.paramSnapshot.transmission > 0\n );\n}\n\nfunction matchesRecordMode(\n material: MaterialSnapshot,\n mode: 'opaque' | 'transmission' | 'transparent',\n): boolean {\n const transmission = isTransmissionMaterial(material);\n if (mode === 'transmission') return transmission;\n if (mode === 'transparent') return material.transparent === true && !transmission;\n return !transmission && material.transparent !== true;\n}\n\nfunction matchedMaterialsForRecordMode(\n c: _InternalRenderPipelineContext,\n matchedMaterials: ReadonlyMap<number, ReadonlySet<number>> | null,\n mode: 'opaque' | 'transmission' | 'transparent' | undefined,\n): ReadonlyMap<number, ReadonlySet<number>> | null {\n if (mode === undefined) return matchedMaterials;\n const filtered = new Map<number, ReadonlySet<number>>();\n for (const entry of c.validatedOrdered) {\n const dispatchHandles = matchedMaterials?.get(entry.renderableIndex);\n if (matchedMaterials !== null && dispatchHandles === undefined) continue;\n const candidateHandles =\n dispatchHandles ??\n (mode === 'transmission'\n ? []\n : entry.source.materials.map((material) => material.materialHandle ?? 0));\n const handles = new Set<number>();\n for (const handle of candidateHandles) {\n const material =\n entry.source.materials.find((candidate) => (candidate.materialHandle ?? 0) === handle) ??\n entry.source.material;\n if (matchesRecordMode(material, mode)) handles.add(handle);\n }\n if (handles.size > 0) filtered.set(entry.renderableIndex, handles);\n }\n return filtered;\n}\n\n/**\n * feat-20260529-rendergraph-pass-abstraction M4 / w13b: main forward\n * (geometry) pass recording, extracted verbatim from recordFrame. Uses the\n * SHARED frame encoder (c.encoder); the geometry + optional LDR sprite-split\n * sub-pass write into geometryColorView (HDR target or swap-chain view).\n * Driven by the render-graph 'main' pass execute closure.\n */\nexport function recordMainPass(\n c: _InternalRenderPipelineContext,\n selector?: PassSelector,\n options?: MainPassOptions,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const {\n runtime,\n world,\n store,\n pipelineState,\n encoder,\n clear,\n geometryColorView,\n geometryDepthView,\n validatedOrdered,\n viewBindGroup,\n meshBindGroup,\n frameState,\n bindGroupCounts,\n skylight,\n skylightCount,\n skyboxActive,\n splitLdrSprite,\n msaaActive,\n geometryColorResolveView,\n dispatch,\n hdrpClusterBindGroup,\n materialSlotIndices,\n materialSlots,\n materialSlotOwners,\n materialSlotCount,\n } = c;\n // bug-20260615 M3 / m3-1: sampleCount is threaded through every\n // getMaterialShaderPipeline call site so the cache key / builder\n // disambiguate count=1 vs count=4 PSOs. Derived from the per-camera\n // msaaActive boolean (already on the context).\n const sampleCount = msaaActive ? 4 : 1;\n const passKind = options?.passKind ?? 'forward';\n const recordMode = options?.recordMode;\n const transmissionBackdropView = options?.transmissionBackdropView;\n if (recordMode === 'transmission' && transmissionBackdropView == null) {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'transmissionBackdropView != null for transmission record mode',\n hint: 'the typed Standard transmission pass must resolve its private backdrop view',\n });\n }\n const colorViews = options?.colorViews ?? [geometryColorView];\n const colorFormats = options?.colorFormats ?? [\n (c.tonemapActive || c.transparentColorFormat === 'rgba16float'\n ? 'rgba16float'\n : pipelineState.colorAttachmentFormat) as GPUTextureFormat,\n ];\n const targetDepthView = options?.depthView ?? geometryDepthView;\n const clearColor = options?.clearColor ?? clear;\n // feat-20260623-world-space-video-asset M4 / w17 (D-2 / AC-09): high-perf\n // GPUExternalTexture upload availability for video sources, resolved by the\n // explicit RhiCaps-based capability probe. The probe checks\n // backendKind==='webgpu' AND `importExternalTexture` method presence; the\n // latter is absent today (OOS-5), so this is false and the general\n // copyExternalImageToTexture path (w16) is the sole route. The branch exists\n // so the AC-09 two-path reserved hook is code-review-verifiable, not a TODO.\n const videoHighPerfAvailable = probeVideoHighPerfUpload(runtime.device);\n // feat-20260609-hdrp-cluster-fragment-ggx M4 / w16: HDRP active swaps the\n // group(2) bindGroup for the unified 7-entry layout (mesh SSBO at binding 0\n // + cluster 4 buffer at bindings 3..6). The dynamic offset\n // (`i * MESH_PER_ENTITY_STRIDE`) stays valid because the unified BGL binds\n // the SAME mesh SSBO at binding 0; the cluster-forward shader reads the\n // cluster bindings off the rest of the layout. Plan D-1 (URP path zero\n // change) is preserved — when `!isHdrpActive` the URP `meshBindGroup`\n // path runs verbatim.\n // feat-20260612-hdrp-ssao wiring fix: when the HDRP forward pass resolved a\n // real `ssaoBlurred` view (stashed on ctx by the pass execute closure), build\n // the unified group(2) bind group with that view at binding 7 so fs_main reads\n // the actual occlusion factor instead of the 1x1 white fallback. The default\n // `hdrpClusterBindGroup` (built ahead of graph.execute) always carries the\n // fallback because the transient SSAO texture does not exist that early.\n // Built per frame (the SSAO target is a graph transient, so no cross-frame\n // cache); HDRP-only and SSAO-only, so URP and SSAO-off paths are untouched.\n let hdrpSsaoBindGroup: BindGroup | null = null;\n if (\n frameState.isHdrpActive &&\n hdrpClusterBindGroup !== null &&\n c.hdrpSsaoBlurredView !== undefined\n ) {\n const hdrpBuffers = getOrCreateHdrpBuffers(\n runtime,\n frameState.installedPipelineConfig?.clusterGrid,\n );\n if (hdrpBuffers !== null) {\n hdrpSsaoBindGroup = createHdrpUnifiedBindGroup(\n runtime,\n hdrpBuffers,\n pipelineState.meshStorageBuffer.buffer,\n { enabled: true, ssaoBlurredView: c.hdrpSsaoBlurredView },\n );\n }\n }\n const meshGroup2: BindGroup | null =\n frameState.isHdrpActive && hdrpClusterBindGroup !== null\n ? (hdrpSsaoBindGroup ?? hdrpClusterBindGroup)\n : meshBindGroup;\n // ── Geometry (main colour) pass ──────────────────────────────────\n // D-2: tracks whether the geometry pass was explicitly ended inside\n // the `if (validatedOrdered.length > 0)` block (sprite split path),\n // to avoid a double-end at the unconditional `pass.end()` below.\n let geometryPassEnded = false;\n // feat-20260531-skybox-env-background M2 / w8: condition main colour\n // loadOp on skyboxActive (AC-05). When skybox is active, the skybox\n // pass writes the far plane + cubemap colour to hdrColor before main;\n // main must load (not clear) to composite geometry on top. Depth\n // loadOp stays 'clear' -- skybox does not write depth, so main's\n // depth test naturally covers skybox pixels with foreground geometry.\n const mainColorLoadOp = skyboxActive ? 'load' : 'clear';\n // feat-20260604 M2 / w9-w10: MSAA resolve placement. When MSAA is active the\n // geometry pass writes a count=4 multisample target. The resolve to the\n // single-sample output (LDR swap-chain view / HDR hdrColor) happens at the\n // LAST pass that writes that multisample target: the main pass itself when\n // there is no LDR sprite split, or the sprite sub-pass end when there is\n // (F-1 -- geometry + sprites share one multisample texture; resolving at the\n // main pass would drop the sprites drawn after). The sprite sub-pass is\n // LDR-only, so under HDR the main pass always resolves.\n const mainPassResolves =\n passKind === 'forward' && msaaActive && geometryColorResolveView !== null && !splitLdrSprite;\n // forward main pass: depth24plus-stencil8 auto-emits stencil ops via the\n // helper's stencil-op gate (plan-strategy M4 R3/R5 stencil-op SSOT).\n // mainColorLoadOp toggles between 'clear' and 'load' (skyboxActive case).\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n {\n colorFormats,\n depthFormat: 'depth24plus-stencil8',\n sampleCount: msaaActive ? 4 : 1,\n },\n {\n colorViews,\n depthView: targetDepthView,\n ...(mainPassResolves ? { resolveTargets: [geometryColorResolveView] } : {}),\n },\n passKind,\n {\n colorLoadOp: mainColorLoadOp,\n clearColor: {\n r: clearColor[0] ?? 0,\n g: clearColor[1] ?? 0,\n b: clearColor[2] ?? 0,\n a: clearColor[3] ?? 1,\n },\n },\n ) as never,\n );\n\n // Geometry submission block: setPipeline + 4 bind groups + per-entity\n // material uploads + drawIndexed.\n\n // feat-20260609 M2: filter entities by pass selector.\n const matchedIndices =\n selector !== undefined ? buildMatchedRenderableIndices(dispatch, selector) : null;\n const selectorMatchedMaterials =\n selector !== undefined ? buildMatchedMaterialHandlesByRenderable(dispatch, selector) : null;\n const matchedMaterials = matchedMaterialsForRecordMode(c, selectorMatchedMaterials, recordMode);\n const recordContext =\n recordMode === undefined\n ? c\n : {\n ...c,\n splitLdrSprite: recordMode === 'transparent' ? false : c.splitLdrSprite,\n validatedOrdered: c.validatedOrdered.map((entry) => ({\n ...entry,\n ...(recordMode === 'transmission' ? { variantSet: TRANSMISSION_VARIANT_SET } : {}),\n })),\n };\n\n if (validatedOrdered.length > 0) {\n // feat-20260518-pbr-direct-lighting-mvp M5 / w22.10 (D-4 + D-9 +\n // AC-07 std140): per-entity material slice grew from 32 B (legacy\n // baseColor:vec4 + metallic + roughness + 8B padding) to 48 B\n // mirroring the post-w22.10 `Material` WGSL struct field-for-field\n // (see STANDARD_PBR_UBO_SIZE JSDoc in render-system.ts). The dynamic-\n // offset stride is MATERIAL_PER_ENTITY_STRIDE; the BindGroup entry's\n // `size` remains the derived material payload size.\n const MATERIAL_SLICE = STANDARD_PBR_UBO_SIZE;\n // feat-20260515 M3 / T-M3-05 (research F-6 fix): materialBindGroup now\n // carries 3 entries -- the per-entity material UBO (binding 0,\n // dynamic-offset retained from D-P9), the default sampler (binding 1,\n // pipelineState.defaultSampler from createRenderer; research F-5\n // linear min/mag/mipmap + repeat addressMode), and the texture-view\n // (binding 2, resolved from MaterialSnapshot.baseColorTexture via\n // AssetRegistry.getTextureGpuView when present, falling back to the\n // pipelineState.fallbackTextureView 1x1 white pixel).\n //\n // The first validated renderable's material is sampled to choose the\n // texture-view (M3 milestone simplification; M5 lifts this to\n // per-entity slot writes once UV-driven sampling lands).\n //\n // feat-20260517-merge-mesh-renderer-material-renderer M3 / w10\n // (this commit): the prior structural cast over `firstMaterial`\n // (used to reach `baseColorTexture` before the snapshot carried\n // it as a first-class field) is removed in favour of direct\n // snapshot field access. `MaterialSnapshot` (extract-stage SSOT)\n // already declares `baseColorTexture` (M2 / w6); record reads it\n // directly with no asset registry round-trip and no cast --\n // Pipeline Isolation: extract owns the asset to snapshot\n // translation; record consumes the snapshot POD only (charter\n // proposition 5 consistent abstraction; AC-07 reverse-grep gate\n // `scripts/forgeax/check-render-record-no-material-asset-get.mjs`\n // forbids both the cast pattern and a direct material asset\n // typed-lookup regrowth in this file).\n // bug-20260522-per-entity-material-texture-binding D-1/D-2:\n // the pre-loop `firstMaterial` / `materialTextureView` / `\n // baseMaterialEntries` / single shared `materialBindGroup` are\n // removed. Each entity now creates its own per-entity material BG\n // inside the draw loop, resolving binding=2 from its own\n // `entry.source.material.baseColorTexture` (mirroring sprite path).\n //\n // feat-20260520-skylight-ibl-cubemap M3 round-4 / t48 amend: the\n // 14-entry merged BG (7 material + 7 Skylight) is now assembled per\n // entity inside the draw loop. The Skylight part stays scene-level\n // (single `skylightResources` resolved once below); only the first 7\n // material entries are rebuilt per-entity with the correct\n // per-entity textureView at binding=2.\n const skylightFallback = pipelineState.skylightFallback;\n if (skylightFallback === null) {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'pipelineState.skylightFallback != null when PBR pipeline is active',\n hint: 'createRenderer must allocate skylightFallback alongside the PBR pipeline (D-5 round-4)',\n });\n }\n // feat-20260520-skylight-ibl-cubemap M4 round-4 / t60 (D-5 round-4):\n // select active vs fallback Skylight resources by `skylightCount` from\n // the extract stage. Active path reaches into the per-device\n // `IblPipelineCache` slots (irradianceView / prefilterView / brdfLutView)\n // populated by the internal equirect-to-cubemap projection; fallback uses the\n // 1x1-zero identity bundle that converges ambient to 0 (D-4 physical\n // convergence -- no `if (hasSkylight)` shader branch).\n // The samplers are reused from `skylightFallback.sampler` for both\n // paths (linear / clamp-to-edge is correct for IBL cube + 2D LUT\n // sampling either way). The intensity uniform is rewritten per-frame\n // when active so `sampleIblSpecular * intensity` carries the user's\n // Skylight.intensity value; fallback keeps intensity=0 (createSkylightFallback\n // seed) so ambient = 0 even when the same buffer is shared.\n let activeViews: { irr: TextureView; pref: TextureView; brdf: TextureView } | undefined;\n // Per-frame Skylight uniform: std140 32 B = [intensity, colorR, colorG,\n // colorB, rotation quaternion]. Default to all-zero so a transition from \"has Skylight\" ->\n // \"no Skylight\" does not leak the prior frame's ambient (intensity 0\n // muzzles everything, including the white fallback irradiance cube).\n runtime.device.queue.writeBuffer(skylightFallback.intensityBuffer, 0, ZERO_SKYLIGHT_PAYLOAD);\n if (skylight !== undefined && skylightCount >= 1) {\n // A Skylight exists. Write its intensity + color regardless of whether\n // a cubemap is bound: with a cubemap the IBL views below light the\n // ambient; WITHOUT one, the white fallback irradiance cube + this color\n // give an instant solid-color ambient (downstream integration #4) with\n // no async precompute. The white fallback only contributes when a\n // Skylight is present because the zero-payload above sets intensity 0\n // when no Skylight exists.\n const [cr, cg, cb] = skylight.color;\n const [qx, qy, qz, qw] = skylight.rotation;\n const uniformPayload = new Float32Array([skylight.intensity, cr, cg, cb, qx, qy, qz, qw]);\n runtime.device.queue.writeBuffer(skylightFallback.intensityBuffer, 0, uniformPayload);\n const cache = getOrCreateIblCache(runtime.deviceScope);\n if (\n cache.irradianceView !== undefined &&\n cache.prefilterView !== undefined &&\n cache.brdfLutView !== undefined\n ) {\n activeViews = {\n irr: cache.irradianceView,\n pref: cache.prefilterView,\n brdf: cache.brdfLutView,\n };\n }\n }\n const skylightResources =\n activeViews !== undefined\n ? {\n irradianceView: activeViews.irr,\n irradianceSampler: skylightFallback.sampler,\n prefilterView: activeViews.pref,\n prefilterSampler: skylightFallback.sampler,\n brdfLutView: activeViews.brdf,\n brdfLutSampler: skylightFallback.sampler,\n intensityBuffer: skylightFallback.intensityBuffer,\n }\n : {\n irradianceView: skylightFallback.irradianceView,\n irradianceSampler: skylightFallback.sampler,\n prefilterView: skylightFallback.prefilterView,\n prefilterSampler: skylightFallback.sampler,\n brdfLutView: skylightFallback.brdfLutView,\n brdfLutSampler: skylightFallback.sampler,\n intensityBuffer: skylightFallback.intensityBuffer,\n };\n // Per-entity material uploads (D-P9 retained path).\n // feat-20260613 fix-issue-1 (D-8 channelMap split): the payload mirrors\n // the post-split sidecar paramSchema for default-standard-pbr (14 entries\n // packed std140 across a 96 B schema tail):\n // [0..3] baseColor vec4<f32> (offset 0)\n // [4] metallic f32 (offset 16)\n // [5] roughness f32 (offset 20)\n // [6] metallicChannel f32 (offset 24)\n // [7] roughnessChannel f32 (offset 28)\n // [8] aoChannel f32 (offset 32)\n // [9] extraChannel f32 (offset 36)\n // [12..14] emissive vec3<f32> (offset 48, vec3 align=16)\n // [15] emissiveIntensity f32 (offset 60)\n // [16] occlusionStrength f32 (offset 64)\n // Channel selectors default to (B,G,R,_) = (2,1,0,0) per glTF 2.0\n // KHR_materials_pbrSpecularGlossiness ARM packing; the fragment casts\n // each f32 to u32 at the pick_channel call site. The full 128 B bind window is\n // overwritten per-entity so unlit entities still produce a deterministic\n // payload (charter P3 explicit failure: zero-init via fresh ArrayBuffer).\n //\n // Material snapshots are interned by extract-owned identity before this\n // pass. Repeated scene instances therefore share one 256-byte UBO slot;\n // materialSlotIndices maps each authored submesh material to that slot.\n // feat-city-glb Bug 5 (per-submesh transparency): shared per-submesh\n // material bind-group assembly, called by BOTH the geometry pass and the\n // LDR blend sub-pass so a transparent PBR submesh binds the identical\n // metallic/roughness/normal/emissive/occlusion + Skylight layout\n // the geometry pass uses (the sub-pass previously bound a sprite-only BG,\n // which cannot render a PBR decal). Captures only frame-stable closure\n // state; the caller passes the per-submesh material snapshot + entityKey\n // (for video texture routing) and sets the dynamic UBO offset itself.\n const perSubmeshMaterialBgDeps: PerSubmeshMaterialBgDeps = {\n runtime,\n pipelineState,\n world,\n store,\n materialSlice: MATERIAL_SLICE,\n videoHighPerfAvailable,\n skylightResources,\n materialBgShared: frameState.materialBgShared,\n materialBgAssemblyCache: c.materialBgAssemblyCache,\n bindGroupCounts,\n ...(transmissionBackdropView === undefined ? {} : { transmissionBackdropView }),\n };\n const buildPerSubmeshMaterialBg = (\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World = world,\n ): BindGroup =>\n buildPerSubmeshMaterialBgImpl(\n perSubmeshMaterialBgDeps,\n submeshMaterial,\n entityKey,\n materialWorld,\n );\n\n const cachedMaterialUboPayload = c.materialUboPayloadCache;\n let materialUboPayload: Uint8Array;\n if (\n cachedMaterialUboPayload?.materialSlots === materialSlots &&\n cachedMaterialUboPayload.materialSlotCount === materialSlotCount\n ) {\n materialUboPayload = cachedMaterialUboPayload.payload;\n } else {\n materialUboPayload = new Uint8Array(materialSlotCount * MATERIAL_PER_ENTITY_STRIDE);\n const slotPayload = new Uint8Array(STANDARD_PBR_UBO_SIZE);\n const slotPayloadF32 = new Float32Array(\n slotPayload.buffer,\n slotPayload.byteOffset,\n slotPayload.byteLength / 4,\n );\n for (let materialSlot = 0; materialSlot < materialSlots.length; materialSlot += 1) {\n const mat = materialSlots[materialSlot];\n const entry = validatedOrdered[materialSlotOwners[materialSlot] ?? -1];\n if (mat === undefined || entry === undefined) continue;\n\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w13 (D-2):\n // single unified Material UBO write path. Sprite materials now flow\n // through the same `buildPbrMaterialUboPayload` baseline +\n // `applyParamSnapshotToUbo` generic std140 overlay every other\n // paramSchema-driven material uses. Extract folds the sprite-specific\n // user inputs into the UBO-aligned paramSnapshot vec4 entries\n // (colorTint / region / pivotAndSize / slicesAndMode); the writer\n // walks `derive(paramSchema).uboLayout.entries` and writes each at\n // its std140 offset. The legacy sprite-specific UBO builder + the\n // sprite-vs-PBR branch are gone (AC-03).\n writePbrMaterialUboPayload(slotPayloadF32, mat);\n // Schema-driven paramSnapshot overlay generalised in feat-20260625\n // M1 / w3: the writer walks `derive(paramSchema).uboLayout.entries`\n // and writes each numeric field at its std140 offset (plan-strategy\n // section 2 D-2). The engine's stock PBR material ships\n // `paramSnapshot: undefined`, so this is a no-op on the default\n // PBR path -- the explicit field writes in buildPbrMaterialUboPayload\n // already cover every byte. User shaders carrying a paramSnapshot\n // (including the post-ablation sprite path) get their fields\n // written at the derive-computed offsets; R-H gate keeps the\n // helper snapshot-only, no asset get.\n const materialShaderId = mat.materialShaderId;\n const schema =\n mat.materialParamSchema ??\n (materialShaderId !== undefined ? runtime.getParamSchema?.(materialShaderId) : undefined);\n applyParamSnapshotToUbo(slotPayloadF32, schema, mat.paramSnapshot);\n applyMaterialTextureUvScales(slotPayloadF32, mat, world);\n // Missing-texture detection: structural debug-pink fallback overrides\n // the baseColor/colorTint slot when a bound baseColorTexture handle\n // resolves to no GPU view. Runs for every textured material path\n // (sprite / sprite-lit / standard-pbr / pbr-skin / unlit) — the bound\n // texture would otherwise silently fall back to the 1x1 white view in\n // the per-submesh BG (main-pass-material.ts), rendering flat with no\n // warn / RhiError. Mirroring the telemetry here makes a missing/failed\n // GLB texture immediately diagnosable instead of a silent flat render\n // (feat-future-pbr-missing-texture-fallback-explicit; feedback\n // 2026-07-04-glb-pbr-textures-not-applied-flat-render).\n //\n // Reads only `mat.baseColorTexture` + the GPU view registry (plan R-H\n // gate: no asset.get<MaterialAsset> reach-back). The debug-pink write\n // lands on f32[0..2], which is baseColor.rgb for the PBR/skin UBO and\n // colorTint.rgb for the sprite UBO — same offset, so one override\n // covers both.\n {\n const matHandleRaw = mat.baseColorTexture as Handle<'TextureAsset', 'shared'> | undefined;\n if (matHandleRaw !== undefined) {\n const view = residentTextureView(entry.world ?? world, store, runtime, matHandleRaw);\n if (view === undefined) {\n const rawId: number = matHandleRaw;\n if (!frameState.warnedMissingBaseColorTextureHandles.has(rawId)) {\n frameState.warnedMissingBaseColorTextureHandles.add(rawId);\n console.warn(\n `[forgeax] baseColor texture ${rawId} missing GPU view, rendering debug pink (shader=${materialShaderId ?? '<none>'} entityIndex=${entry.renderableIndex})`,\n );\n }\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'asset-not-registered',\n expected: 'material baseColor TextureAsset uploaded to GPU',\n hint: 'register + uploadTexture the baseColor texture before draw([world], { cameraOwner: 0, resourceOwner: 0 }); rendering falls back to debug pink until then',\n detail: { assetHandle: rawId },\n }),\n );\n // Debug pink override on slot 0 baseColor/colorTint.rgb (alpha preserved).\n slotPayloadF32[0] = 1.0;\n slotPayloadF32[1] = 0.4;\n slotPayloadF32[2] = 0.7;\n }\n }\n }\n\n materialUboPayload.set(slotPayload, materialSlot * MATERIAL_PER_ENTITY_STRIDE);\n }\n\n // Material UBO slots can share one snapshot identity, but nine-slice\n // validity depends on each entity's transform. Preserve diagnostics per\n // renderable instead of inheriting the first owner of a shared slot.\n for (const entry of validatedOrdered) {\n const mat = entry.source.material;\n const materialShaderId = mat.materialShaderId;\n if (materialShaderId !== 'forgeax::sprite' && materialShaderId !== 'forgeax::sprite-lit')\n continue;\n const slicesAndMode = mat.paramSnapshot?.slicesAndMode as readonly number[] | undefined;\n if (slicesAndMode === undefined || slicesAndMode.length < 4) continue;\n const slicesArr: readonly [number, number, number, number] = [\n slicesAndMode[0] ?? 0,\n slicesAndMode[1] ?? 0,\n slicesAndMode[2] ?? 0,\n slicesAndMode[3] ?? 0,\n ];\n if (slicesArr[0] === 0 && slicesArr[1] === 0 && slicesArr[2] === 0 && slicesArr[3] === 0)\n continue;\n detectNineSliceScaleTooSmall(\n entry.source.transform.world,\n slicesArr,\n entry.renderableIndex,\n frameState.warnedNineSliceScaleEntities,\n runtime.metrics,\n );\n }\n c.materialUboPayloadCache = {\n materialSlots,\n materialSlotCount,\n payload: materialUboPayload,\n };\n }\n\n // All material slots are staged before the first geometry draw. One\n // stride-shaped upload preserves every dynamic offset while avoiding one\n // queue call per material; the RHI still validates alignment and bounds at\n // this single owner-level write boundary.\n const materialUboUpload = runtime.device.queue.writeBuffer(\n pipelineState.materialUniformBuffer.buffer,\n 0,\n materialUboPayload,\n );\n if (!materialUboUpload.ok) throw materialUboUpload.error;\n // Static material resources are a property of the frame-local material\n // slot, not of each submesh draw. Resolve them once here so the geometry\n // loop only selects a prepared binding. Video fields remain entity-bound:\n // their current frame view is keyed by entityKey and must be resolved at\n // the draw site.\n const preparedMaterialBindGroups = new Array<BindGroup | undefined>(materialSlotCount);\n for (let materialSlot = 0; materialSlot < materialSlotCount; materialSlot += 1) {\n const material = materialSlots[materialSlot];\n if (material === undefined || (material.videoTextureFields?.size ?? 0) > 0) continue;\n const owner = validatedOrdered[materialSlotOwners[materialSlot] ?? -1];\n if (owner === undefined) continue;\n preparedMaterialBindGroups[materialSlot] = buildPerSubmeshMaterialBg(\n material,\n owner.source.entityKey,\n owner.world ?? world,\n );\n }\n const resolveMaterialBindGroup = (\n materialSlot: number,\n material: MaterialSnapshot,\n entityKey: number,\n materialWorld: World = world,\n ): BindGroup =>\n material.materialShaderId !== POINTS_LINES_MATERIAL_SHADER_ID\n ? (preparedMaterialBindGroups[materialSlot] ??\n buildPerSubmeshMaterialBg(material, entityKey, materialWorld))\n : buildPerSubmeshMaterialBg(material, entityKey, materialWorld);\n\n pass.setBindGroup(0, viewBindGroup as BindGroup, [0]);\n\n // Track which (mesh-vertex-buffer, mesh-index-buffer, pipeline) combo\n // was last bound so consecutive entities sharing the same combo skip\n // the redundant rebinds (cheap GPU cost; net wins on workloads where\n // most entities share BUILTIN_CUBE + unlit). Initial nulls force the\n // first iteration to bind unconditionally.\n // M-3 / w12: vertexBuffer/indexBuffer state locals migrate to GpuBuffer.\n const recordGeometry = (): void => {\n recordGeometryDraws(\n recordContext,\n pass,\n matchedMaterials,\n materialSlotIndices,\n sampleCount,\n meshGroup2,\n meshBindGroup,\n resolveMaterialBindGroup,\n passKind,\n );\n };\n if (c.profilePhase === undefined) {\n recordGeometry();\n } else {\n const passName = passKind === 'deferred' ? 'g-buffer' : 'forward';\n c.profilePhase(\n `record/graph-execute/${passName}/geometry-loop` as RenderRecordPhase,\n recordGeometry,\n );\n }\n\n // D-2: LDR sprite pass. Runs after the geometry pass when there are\n // sprite entities in the draw list and the LDR path is active.\n // The geometry pass used the bgra8unorm-srgb sRGB view (hardware sRGB\n // encoding for unlit/standard/pbr output). The sprite pass uses the\n // bgra8unorm storage view (loadOp=load) so the sprite LDR pipeline\n // (target=bgra8unorm, blend=premultiplied-alpha) can write over the\n // already-encoded geometry pixels. Depth is loaded from the geometry\n // pass so sprite-vs-mesh occlusion (depthCompare=less-equal) is\n // preserved (plan-strategy §2 D-2 + §4 R-4).\n if (passKind === 'forward' && recordMode === undefined) {\n geometryPassEnded = recordSpritePass(\n c,\n pass,\n matchedIndices,\n materialSlotIndices,\n sampleCount,\n resolveMaterialBindGroup,\n skylightResources,\n graphPass,\n );\n }\n } // end if (validatedOrdered.length > 0) -- Case E falls through to pass.end()\n\n if (!geometryPassEnded && graphPass === undefined) {\n pass.end();\n }\n}\n\nexport function encodeMainPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n selector?: PassSelector,\n options?: MainPassOptions,\n): void {\n recordMainPass(c, selector, options, pass);\n}\n","import type { ResolveContext } from '@forgeax/engine-render-graph';\nimport { RhiError, type RhiRenderPassEncoder, type TextureView } from '@forgeax/engine-rhi';\nimport { toShared } from '@forgeax/engine-types';\nimport { buildBeginRenderPassDescriptor } from '../pipeline-spec';\nimport type { BloomFrameReceipts } from './frame-snapshot';\nimport { getOrCreateFromChain } from './mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { VIEW_UNIFORM_BYTES } from './view-ubo';\n\n/**\n * feat-20260531-skybox-env-background M2 / w8: skybox pass recording stub.\n * Renders a fullscreen triangle that samples a cubemap using the camera's\n * inverseViewProj from the View UBO and writes the result to the hdrColor\n * render target. The pass runs after shadow and before main (D-1 topology).\n *\n * This stub early-returns when skyboxActive is false -- the actual execute\n * body is implemented in M3 / w16 (recordSkyboxPass execute). The render-\n * graph still declares the pass so the compile() step validates the\n * dependency edges (shadow -> skybox -> main) even before the execute\n * body is filled in.\n */\nexport function recordSkyboxPass(\n c: _InternalRenderPipelineContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n // Early-return when skybox is not active (no SkyboxBackground entity,\n // or tonemap is disabled -- plan-strategy D-2 NOTE). The graph still\n // compiles because the pass declaration is unconditional; only the\n // execute body is gated on skyboxActive.\n if (!c.skyboxActive) return;\n const skyboxSnapshot = c.skybox;\n if (skyboxSnapshot === undefined) return;\n\n const { runtime, store, encoder, pipelineState } = c;\n\n // Guard: hdrColorView must be allocated (tonemapActive implies it)\n const hdrColorView = pipelineState.perPassResources.hdrColorView;\n if (graphPass === undefined && hdrColorView === null) return;\n\n // feat-20260604 M2 / w10: under MSAA the skybox + main passes share the\n // count=4 multisample target (hdrColorMsaa); only the main pass (last to\n // write) resolves to the single-sample hdrColor (D-8 -- avoids a wasteful\n // mid-chain resolve). The skybox pass writes the multisample target with no\n // resolveTarget and uses the count=4 skybox pipeline variant.\n const skyboxColorView =\n graphPass === undefined\n ? c.msaaActive\n ? pipelineState.perPassResources.hdrColorMsaaView\n : hdrColorView\n : null;\n if (graphPass === undefined && skyboxColorView === null) return;\n\n // Guard: pipeline resources must exist (null when manifest has no\n // skybox entry -- legacy manifests continue to boot)\n const skyboxPipeline = c.msaaActive\n ? pipelineState.perPassResources.skyboxPipelineMsaa\n : pipelineState.perPassResources.skyboxPipeline;\n const skyboxBgl = pipelineState.perPassResources.skyboxBindGroupLayout;\n const skyboxSampler = pipelineState.perPassResources.skyboxSampler;\n const skyboxRotationBuffer = pipelineState.perPassResources.skyboxRotationBuffer;\n if (\n skyboxPipeline === null ||\n skyboxBgl === null ||\n skyboxSampler === null ||\n skyboxRotationBuffer === null\n )\n return;\n\n const rotation = skyboxSnapshot.rotation;\n const rotationUpload = runtime.device.queue.writeBuffer(\n skyboxRotationBuffer,\n 0,\n new Float32Array([rotation[0], rotation[1], rotation[2], rotation[3]]),\n );\n if (!rotationUpload.ok) throw rotationUpload.error;\n\n // Resolve cubemap GPU view from AssetRegistry. Returns undefined if\n // the cubemap has not been uploaded yet (async equirect upload in\n // progress). In that case, degradation to main pass loadOp:'clear'\n // is handled by the passCtx.skyboxActive gate above -- if the\n // cubemap isn't ready, skyboxActive is already false (see w18).\n const cubemapView = store.getCubemapGpuView(\n toShared<'EquirectAsset'>(skyboxSnapshot.equirectHandle),\n );\n if (cubemapView === undefined) return;\n\n // Identity-cached skybox BindGroup keyed on the cubemap GpuView. The only\n // varying binding is the cubemap view (sampler + View UBO are stable); it is\n // recreated on each internal equirect-to-cubemap projection (which may happen\n // mid-app asynchronously), so keying on its identity rebuilds exactly when the\n // cubemap changes. This supersedes the prior `hdrTextureWidth`/`Height`\n // size-guard, which tracked the wrong resource (the skybox BindGroup never\n // binds hdrColor -- it writes the color attachment) and missed cubemap\n // re-projections that reused the old cached bind group.\n const skyboxBg = getOrCreateFromChain(\n c.frameState.postProcessBgCache,\n [cubemapView],\n 'skybox',\n () => {\n const skyboxBgRes = runtime.device.createBindGroup({\n label: 'skybox-bg',\n layout: skyboxBgl,\n entries: [\n {\n binding: 0,\n resource: { kind: 'textureView', value: cubemapView },\n },\n {\n binding: 1,\n resource: { kind: 'sampler', value: skyboxSampler },\n },\n {\n binding: 2,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.viewUniformBuffer, size: VIEW_UNIFORM_BYTES },\n },\n },\n {\n binding: 3,\n resource: {\n kind: 'buffer',\n value: { buffer: skyboxRotationBuffer },\n },\n },\n ],\n });\n if (!skyboxBgRes.ok) throw skyboxBgRes.error;\n return skyboxBgRes.value;\n },\n c.bindGroupCounts,\n );\n\n // Skybox pass: clear hdrColor (first pass writing to it),\n // draw fullscreen triangle, write cubemap colour.\n // No depth/stencil -- skybox is the far plane; main pass depth test rejects\n // occluded skybox pixels (plan-strategy D-1). HDR target ('rgba16float') is\n // declared on specAttachments for descriptor parity, even though color-only\n // policies do not gate on format.\n const skyboxPass =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [skyboxColorView as TextureView] },\n 'skybox',\n ) as never,\n );\n\n skyboxPass.setPipeline(skyboxPipeline);\n skyboxPass.setBindGroup(0, skyboxBg);\n skyboxPass.draw(3);\n if (graphPass === undefined) skyboxPass.end();\n}\n\nexport function encodeSkyboxPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n): void {\n recordSkyboxPass(c, pass);\n}\n\n/**\n * feat-20260529-rendergraph-pass-abstraction M4 / w13c: FXAA post-process\n * fullscreen pass, extracted verbatim from recordFrame. copyTextureToTexture\n * (swap-chain -> intermediate) then a fullscreen FXAA fragment pass writes\n * the anti-aliased result back into the swap-chain view, all on the SHARED\n * frame encoder (c.encoder). The pre-pass copy stays inside this closure\n * (graph first version models copy as a pass-internal op, not a separate\n * graph node). Gated on camera.antialias==='fxaa'. Driven by the 'fxaa'\n * graph pass.\n */\n// ── feat-20260531-bloom-first-declarative-render-graph-pass / w14 ──\n// Bloom execute closure placeholders. Real implementations in w15.\n// The graph must declare execute callbacks for addPass; these empty stubs\n// keep compile() satisfied until w15 fills in the actual record logic.\n//\n// Gate: bloom === 'off' || !tonemapActive => early-return (AC-04/AC-05).\n// The closures receive RenderPipelineContext and route to w15 record functions.\n\nconst EMPTY_BLOOM_RECEIPTS: BloomFrameReceipts = {\n uploadCount: 0,\n bindGroupCount: 0,\n encodeCount: 0,\n};\n\nfunction updateBloomReceipts(\n c: _InternalRenderPipelineContext,\n field: keyof BloomFrameReceipts,\n): void {\n const current = c.frameState.bloomFrameReceipts ?? EMPTY_BLOOM_RECEIPTS;\n c.frameState.bloomFrameReceipts = {\n ...current,\n [field]: current[field] + 1,\n };\n}\n\nfunction stageBloomUpload(c: _InternalRenderPipelineContext): void {\n updateBloomReceipts(c, 'uploadCount');\n}\n\nfunction stageBloomBindGroup(c: _InternalRenderPipelineContext): void {\n updateBloomReceipts(c, 'bindGroupCount');\n}\n\nfunction stageBloomEncode(c: _InternalRenderPipelineContext): void {\n updateBloomReceipts(c, 'encodeCount');\n}\n\nfunction throwBloomRecordFailure(expected: string): never {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected,\n hint: 'repair the Bloom candidate resources before retrying the frame',\n });\n}\n\nexport function recordBloomBrightPass(\n _c: _InternalRenderPipelineContext,\n resolve?: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, encoder, camera, tonemapActive, frameState, bindGroupCounts } = _c;\n const pp = _c.bloomResources;\n\n // Double gate: bloom=off => zero-overhead; tonemap=none => no HDR domain\n if (camera.bloom !== 'on' || !tonemapActive) return;\n if (pp === null || pp === undefined) {\n throwBloomRecordFailure('Bloom persistent resources are ready before bright-pass encoding');\n }\n if (\n pp.bloomBrightPipeline === null ||\n pp.bloomBrightBindGroupLayout === null ||\n pp.bloomSampler === null ||\n pp.bloomBrightParamsBuffer === null\n ) {\n throwBloomRecordFailure('Bloom bright pass has pipeline, layout, sampler, and params buffer');\n }\n\n // M1 / w7: bloom intermediate textures owned by render-graph. Resolve\n // the GPU TextureView via the resolve context passed by graph.execute().\n const bloomBrightView = resolve?.resolve('bloomBright') as TextureView | undefined;\n const hdrColorView = resolve?.resolve('hdrColor') as TextureView | undefined;\n if (!bloomBrightView || !hdrColorView) {\n throwBloomRecordFailure('Bloom bright pass resolves its source and target views');\n }\n const bglBright = pp.bloomBrightBindGroupLayout;\n const bloomSampler = pp.bloomSampler;\n const paramsBuffer = pp.bloomBrightParamsBuffer;\n\n // 2. Write threshold UBO (16 B std140: threshold f32 + 12 B pad).\n const brightParams = new Float32Array(4);\n brightParams[0] = camera.bloomThreshold;\n brightParams[1] = 0;\n brightParams[2] = 0;\n brightParams[3] = 0;\n const paramsWrite = runtime.device.queue.writeBuffer(paramsBuffer, 0, brightParams);\n if (!paramsWrite.ok) throw paramsWrite.error;\n stageBloomUpload(_c);\n\n // 3. Identity-cached BindGroup (1 tex + 1 sampler + 1 UBO). Keyed on the\n // graph-resolved hdrColor TextureView: resize retires hdrColor and the new\n // view yields a WeakMap miss -> rebuild referencing the live texture.\n const bindGroup = getOrCreateFromChain(\n frameState.postProcessBgCache,\n [hdrColorView],\n 'bloom-bright',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'bloom-bright-bg',\n layout: bglBright,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: hdrColorView } },\n { binding: 1, resource: { kind: 'sampler', value: bloomSampler } },\n { binding: 2, resource: { kind: 'buffer', value: { buffer: paramsBuffer } } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n bindGroupCounts,\n );\n\n // 4. Render pass into the 1/2-res intermediate.\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [bloomBrightView] },\n 'bloom-bright',\n ) as never,\n );\n pass.setPipeline(pp.bloomBrightPipeline);\n pass.setBindGroup(0, bindGroup);\n stageBloomBindGroup(_c);\n pass.draw(3, 1, 0, 0);\n stageBloomEncode(_c);\n if (graphPass === undefined) pass.end();\n}\n\nexport function recordBloomBlurHPass(\n _c: _InternalRenderPipelineContext,\n resolve?: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, encoder, camera, targetW, tonemapActive, frameState, bindGroupCounts } = _c;\n const pp = _c.bloomResources;\n\n if (camera.bloom !== 'on' || !tonemapActive) return;\n if (pp === null || pp === undefined) {\n throwBloomRecordFailure('Bloom persistent resources are ready before blur-H encoding');\n }\n if (\n pp.bloomBlurHPipeline === null ||\n pp.bloomBlurBindGroupLayout === null ||\n pp.bloomSampler === null ||\n pp.bloomBlurHParamsBuffer === null\n ) {\n throwBloomRecordFailure('Bloom blur-H pass has pipeline, layout, sampler, and params buffer');\n }\n\n // M1 / w7: bloom intermediate textures owned by render-graph. Resolve\n // via the resolve context passed by graph.execute().\n const bloomBlurHView = resolve?.resolve('bloomBlurH') as TextureView | undefined;\n const bloomBrightView = resolve?.resolve('bloomBright') as TextureView | undefined;\n if (!bloomBlurHView || !bloomBrightView) {\n throwBloomRecordFailure('Bloom blur-H pass resolves its source and target views');\n }\n const bglBlur = pp.bloomBlurBindGroupLayout;\n const bloomSampler = pp.bloomSampler;\n const paramsBuffer = pp.bloomBlurHParamsBuffer;\n\n // 2. Write H-axis blur params into the H-only UBO (bug-20260625: a separate\n // buffer per axis so V's write cannot clobber H's before the GPU runs).\n // H-axis: texel offset along x only.\n const bw = Math.floor(targetW / 2);\n const blurParams = new Float32Array(4);\n blurParams[0] = bw > 0 ? 1.0 / bw : 1.0; // texelSize.x\n blurParams[1] = 0; // texelSize.y = 0 for H pass\n blurParams[2] = camera.bloomBlurRadius;\n blurParams[3] = 0;\n const paramsWrite = runtime.device.queue.writeBuffer(paramsBuffer, 0, blurParams);\n if (!paramsWrite.ok) throw paramsWrite.error;\n stageBloomUpload(_c);\n\n // 3. Identity-cached BindGroup (reads bloomBright from graph). Keyed on the\n // graph-resolved bloomBright view so resize rebuilds against the new texture.\n const bindGroup = getOrCreateFromChain(\n frameState.postProcessBgCache,\n [bloomBrightView],\n 'bloom-blur-h',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'bloom-blur-h-bg',\n layout: bglBlur,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: bloomBrightView } },\n { binding: 1, resource: { kind: 'sampler', value: bloomSampler } },\n { binding: 2, resource: { kind: 'buffer', value: { buffer: paramsBuffer } } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n bindGroupCounts,\n );\n\n // 4. Render pass into bloomBlurH intermediate (graph-owned).\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [bloomBlurHView] },\n 'bloom-blur',\n ) as never,\n );\n pass.setPipeline(pp.bloomBlurHPipeline);\n pass.setBindGroup(0, bindGroup);\n stageBloomBindGroup(_c);\n pass.draw(3, 1, 0, 0);\n stageBloomEncode(_c);\n if (graphPass === undefined) pass.end();\n}\n\nexport function recordBloomBlurVPass(\n _c: _InternalRenderPipelineContext,\n resolve?: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, encoder, camera, targetH, tonemapActive, frameState, bindGroupCounts } = _c;\n const pp = _c.bloomResources;\n\n if (camera.bloom !== 'on' || !tonemapActive) return;\n if (pp === null || pp === undefined) {\n throwBloomRecordFailure('Bloom persistent resources are ready before blur-V encoding');\n }\n if (\n pp.bloomBlurVPipeline === null ||\n pp.bloomBlurBindGroupLayout === null ||\n pp.bloomSampler === null ||\n pp.bloomBlurVParamsBuffer === null\n ) {\n throwBloomRecordFailure('Bloom blur-V pass has pipeline, layout, sampler, and params buffer');\n }\n\n // M1 / w7: bloom intermediate textures owned by render-graph. Resolve\n // via the resolve context passed by graph.execute().\n const bloomBlurVView = resolve?.resolve('bloomBlurV') as TextureView | undefined;\n const bloomBlurHView = resolve?.resolve('bloomBlurH') as TextureView | undefined;\n if (!bloomBlurVView || !bloomBlurHView) {\n throwBloomRecordFailure('Bloom blur-V pass resolves its source and target views');\n }\n const bglBlur = pp.bloomBlurBindGroupLayout;\n const bloomSampler = pp.bloomSampler;\n const paramsBuffer = pp.bloomBlurVParamsBuffer;\n\n // 2. Write V-axis blur params into the V-only UBO (bug-20260625: separate\n // buffer per axis -- see the H pass comment).\n // V-axis: texel offset along y only.\n const bh = Math.floor(targetH / 2);\n const blurParams = new Float32Array(4);\n blurParams[0] = 0; // texelSize.x = 0 for V pass\n blurParams[1] = bh > 0 ? 1.0 / bh : 1.0; // texelSize.y\n blurParams[2] = camera.bloomBlurRadius;\n blurParams[3] = 0;\n const paramsWrite = runtime.device.queue.writeBuffer(paramsBuffer, 0, blurParams);\n if (!paramsWrite.ok) throw paramsWrite.error;\n stageBloomUpload(_c);\n\n // 3. Identity-cached BindGroup (reads bloomBlurH from graph). Keyed on the\n // graph-resolved bloomBlurH view so resize rebuilds against the new texture.\n const bindGroup = getOrCreateFromChain(\n frameState.postProcessBgCache,\n [bloomBlurHView],\n 'bloom-blur-v',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'bloom-blur-v-bg',\n layout: bglBlur,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: bloomBlurHView } },\n { binding: 1, resource: { kind: 'sampler', value: bloomSampler } },\n { binding: 2, resource: { kind: 'buffer', value: { buffer: paramsBuffer } } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n bindGroupCounts,\n );\n\n // 4. Render pass into bloomBlurV intermediate (graph-owned).\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [bloomBlurVView] },\n 'bloom-blur',\n ) as never,\n );\n pass.setPipeline(pp.bloomBlurVPipeline);\n pass.setBindGroup(0, bindGroup);\n stageBloomBindGroup(_c);\n pass.draw(3, 1, 0, 0);\n stageBloomEncode(_c);\n if (graphPass === undefined) pass.end();\n}\n\nexport function recordBloomCompositePass(\n _c: _InternalRenderPipelineContext,\n resolve?: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, encoder, camera, tonemapActive, frameState, bindGroupCounts } = _c;\n const pp = _c.bloomResources;\n\n if (camera.bloom !== 'on' || !tonemapActive) return;\n if (pp === null || pp === undefined) {\n throwBloomRecordFailure('Bloom persistent resources are ready before composite encoding');\n }\n if (\n pp.bloomCompositePipeline === null ||\n pp.bloomCompositeBindGroupLayout === null ||\n pp.bloomSampler === null ||\n pp.bloomCompositeParamsBuffer === null\n ) {\n throwBloomRecordFailure(\n 'Bloom composite pass has pipeline, layout, sampler, and params buffer',\n );\n }\n\n // M1 / w7: hdrColor + bloomBlurV textures owned by render-graph.\n // bug-20260625: composite READS hdrColor (scene, binding 0) and WRITES the\n // separate hdrComposited target -- never the same texture in one pass.\n const hdrColorView = resolve?.resolve('hdrColor') as TextureView | undefined;\n const bloomBlurVView = resolve?.resolve('bloomBlurV') as TextureView | undefined;\n const hdrCompositedView = resolve?.resolve('hdrComposited') as TextureView | undefined;\n if (!hdrColorView || !bloomBlurVView || !hdrCompositedView) {\n throwBloomRecordFailure('Bloom composite pass resolves its source and target views');\n }\n const bglComposite = pp.bloomCompositeBindGroupLayout;\n const bloomSampler = pp.bloomSampler;\n const paramsBuffer = pp.bloomCompositeParamsBuffer;\n\n // 1. Write composite params UBO (16 B std140: intensity + 12 B pad).\n const compositeParams = new Float32Array(4);\n compositeParams[0] = camera.bloomIntensity;\n compositeParams[1] = 0;\n compositeParams[2] = 0;\n compositeParams[3] = 0;\n const paramsWrite = runtime.device.queue.writeBuffer(paramsBuffer, 0, compositeParams);\n if (!paramsWrite.ok) throw paramsWrite.error;\n stageBloomUpload(_c);\n\n // 2. Identity-cached BindGroup (2 tex: hdrColor + bloomBlurV, 1 sampler,\n // 1 UBO). Keys on both sampled views: resize retires both hdrColor and\n // bloomBlurV, so a two-node chain rebuilds when either identity changes.\n const bindGroup = getOrCreateFromChain(\n frameState.postProcessBgCache,\n [hdrColorView, bloomBlurVView],\n 'bloom-composite',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'bloom-composite-bg',\n layout: bglComposite,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: hdrColorView } },\n { binding: 1, resource: { kind: 'textureView', value: bloomBlurVView } },\n { binding: 2, resource: { kind: 'sampler', value: bloomSampler } },\n {\n binding: 3,\n resource: { kind: 'buffer', value: { buffer: paramsBuffer } },\n },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n bindGroupCounts,\n );\n\n // 3. Render pass: write the separate hdrComposited target (bug-20260625).\n // The fragment shader outputs the COMPLETE composited colour\n // (scene + intensity*bloom, sampling scene from hdrColor itself), so the\n // destination needs no prior content -> loadOp='clear' (no stale dependency\n // on hdrComposited's previous-frame content, and no in-place hazard).\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [hdrCompositedView] },\n 'bloom-composite',\n { colorLoadOp: 'clear' },\n ) as never,\n );\n pass.setPipeline(pp.bloomCompositePipeline);\n pass.setBindGroup(0, bindGroup);\n stageBloomBindGroup(_c);\n pass.draw(3, 1, 0, 0);\n stageBloomEncode(_c);\n if (graphPass === undefined) pass.end();\n}\n\nexport function recordFxaaPass(\n c: _InternalRenderPipelineContext,\n resolve: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, pipelineState, encoder, camera, currentTexture } = c;\n // FXAA samples the graph-owned LDR target and writes the current surface.\n // The surface is an output attachment only: no COPY_SRC usage, no\n // copyTextureToTexture, and no backend-specific surface sampling path.\n const fxaaActive = camera.antialias === 'fxaa';\n if (\n fxaaActive &&\n pipelineState.perPassResources.fxaaPipeline !== null &&\n pipelineState.perPassResources.fxaaBindGroupLayout !== null &&\n pipelineState.perPassResources.fxaaSampler !== null\n ) {\n const inputView = resolve.resolve('ldrColor') as TextureView | undefined;\n if (inputView === undefined) return;\n\n // Compose the 2-entry FXAA BindGroup (input texture + sampler). The\n // graph view identity changes when the graph reallocates on resize, so\n // the identity-keyed cache rebuilds against the live target.\n const fxaaBglLayout = pipelineState.perPassResources.fxaaBindGroupLayout;\n const fxaaSampler = pipelineState.perPassResources.fxaaSampler;\n const fxaaBg = getOrCreateFromChain(\n c.frameState.postProcessBgCache,\n [inputView],\n 'fxaa',\n () => {\n const fxaaBgRes = runtime.device.createBindGroup({\n label: 'fxaa-bg',\n layout: fxaaBglLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'textureView',\n value: inputView,\n },\n },\n {\n binding: 1,\n resource: { kind: 'sampler', value: fxaaSampler },\n },\n ],\n });\n if (!fxaaBgRes.ok) throw fxaaBgRes.error;\n return fxaaBgRes.value;\n },\n c.bindGroupCounts,\n );\n\n const fxaaColorFormat = runtime.device.caps.storageBuffer\n ? pipelineState.format\n : pipelineState.colorAttachmentFormat;\n let fxaaPass = graphPass;\n if (fxaaPass === undefined) {\n const fxaaOutputView = runtime.device.createTextureView(currentTexture, {\n format: fxaaColorFormat as GPUTextureFormat,\n });\n if (!fxaaOutputView.ok) {\n runtime.errorRegistry.fire(fxaaOutputView.error);\n return;\n }\n fxaaPass = encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n {\n colorFormats: [fxaaColorFormat as GPUTextureFormat],\n depthFormat: undefined,\n sampleCount: 1,\n },\n { colorViews: [fxaaOutputView.value] },\n 'fxaa',\n ) as never,\n );\n }\n fxaaPass.setPipeline(pipelineState.perPassResources.fxaaPipeline);\n fxaaPass.setBindGroup(0, fxaaBg);\n fxaaPass.draw(3, 1, 0, 0);\n if (graphPass === undefined) fxaaPass.end();\n }\n}\n","// @forgeax/engine-runtime - FullscreenPostProcessPass primitive\n// (feat-20260604-resource-owning-render-graph-and-fullscreen-postpr M2 / w13).\n//\n// A declarative fullscreen post-process pass that:\n// - Uses the `fullscreen_triangle` vertex shader (common.wgsl:194, SSOT — not rewritten)\n// - Supports optional params UBO (FXAA has no params, tonemap has params — plan-strategy D-4 /\n// Finding M2-1)\n// - Auto-builds: input-texture BGL, pipeline, offscreen RT, ViewTarget ping-pong (KB-2),\n// and swap-chain non-srgb storage view write (R-COLORSPACE)\n// - Reads input texture, writes to declared color target with fullscreen 3-vertex draw\n//\n// Registered through the feature host ({source, params, reads?}) — a parallel\n// channel to installMaterialArtifact (D-4: material shader = 4-BGL / 12-float vertex / depth /\n// triangle-list; fullscreen post-process = 0 vertex buffer / no depth / input-texture BGL).\n\nimport type {\n BindGroup,\n BindGroupLayout,\n Buffer,\n RhiDevice,\n RhiError,\n RhiRenderPassEncoder,\n Sampler,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport { GPU_SHADER_STAGE_FRAGMENT } from './gpu-stage';\nimport type { BglKind } from './pipeline-spec';\nimport { buildBindGroupLayoutDescriptor, type PipelineSpec } from './pipeline-spec';\n\n// Default fullscreen-post spec stub. The dispatcher's 'fullscreen-post' arm\n// reads spec.attachments.depthFormat / colorFormats[0] to derive the texture\n// binding's sampleType (R3 fix). Default colorFormats=['rgba16float'] gives\n// the historical 'float' / 'filtering' shape preserved across all existing\n// post-process call sites.\nconst FULLSCREEN_DEFAULT_SPEC: PipelineSpec = Object.freeze({\n shader: { id: '', passKind: 'forward', variantSet: undefined },\n attachments: {\n colorFormats: ['rgba16float'] as readonly GPUTextureFormat[],\n depthFormat: undefined,\n sampleCount: 1,\n },\n geometry: { topology: 'triangle-list', vertexLayout: {} },\n renderState: undefined,\n}) as PipelineSpec;\n\n// ─── Post-process read sample type union ─────────────────────────────────\n\n/**\n * Declared sample type for a post-process read entry.\n *\n * Closed union (plan-strategy D-7): only `'depth'` is an explicit sampleType\n * discriminant; color inputs are the default (bare `string` or un-suffixed\n * `{ key }`). Future texture types (`r32float`, etc.) are add-only.\n *\n * AI-user affordance: IDE autocomplete exposes `'depth'` at the register call\n * site; misspellings are caught by the type system (AC-08).\n */\nexport type PostProcessReadSampleType = 'depth';\n\n// ─── Post-process shader entry (owned by the fullscreen feature host) ──────\n\n/**\n * A fullscreen post-process shader entry owned by the feature host.\n *\n * Analogous to MaterialShaderEntry in the ShaderCatalog but with post-process-specific\n * fields: the input-texture + sampler BGL is auto-built by the primitive,\n * no paramSchema (params are passed inline via a {type, value} struct — plan-strategy D-4).\n *\n * `params` carries the WGSL struct definition + default value. When `params` is\n * `undefined`, the post-process shader has no UBO (e.g. FXAA — Finding M2-1).\n *\n * `reads` declares graph resource keys this pass samples as input texture(s).\n * If omitted, the pass samples the swap-chain color attachment (default path).\n *\n * Structured reads (plan-strategy D-1): each entry can be a bare string\n * (backward-compatible color input) or an object `{ key, sampleType? }`.\n * When `sampleType` is `'depth'`, the dispatcher resolves a depth-only view\n * and binds it at depthTex@3 / depthSampler@4 in the fullscreen bind group.\n */\nexport interface PostProcessShaderEntry {\n /** Composed WGSL source for the fragment stage (post-naga_oil). */\n readonly source: string;\n /**\n * Params UBO schema. When undefined, the shader has no uniform buffer (e.g. FXAA)\n * and the BGL degrades to 2 entries (texture@0 + sampler@1). When present, the\n * primitive eager-creates a params UBO (at register, sized `byteSize`) and binds\n * it at bindgroup(1) binding(2) as part of a 3-entry BGL\n * (texture@0 + sampler@1 + buffer@2). feat-20260621 M-A2 / D-2.\n */\n readonly params?: PostProcessParamsSchema | undefined;\n /**\n * Graph resource keys this post-process reads (as input textures).\n * The primitive binds the first read as its input texture at @group(1)\n * @binding(0) (the sampler is @group(1) @binding(1); group 0 is reserved for a\n * future view bind group — dispatchFullscreenPass calls setBindGroup(1, ...)).\n * When empty or omitted, the pass reads the swap-chain directly.\n *\n * Each entry is either a bare string (backward-compatible color input) or an\n * object `{ key: string; sampleType?: PostProcessReadSampleType }` for typed\n * reads (e.g. `{ key: 'depth', sampleType: 'depth' }` for depth sampling).\n * Bare strings and `{ key }` without `sampleType` are equivalent — both\n * represent a color input (plan-strategy D-1 / D-7).\n */\n readonly reads?: readonly (string | PostProcessReadEntry)[] | undefined;\n}\n\n/** Whether a feature binding opts into the temporal multi-read contract. */\nexport function isTemporalFullscreenBinding(values: Readonly<Record<string, unknown>>): boolean {\n return (\n values.temporal !== undefined ||\n values.shader === 'forgeax.taa-resolve' ||\n values.shader === 'forgeax.motion-blur'\n );\n}\n\n/**\n * Structured read entry for a post-process shader.\n *\n * `key` is the graph resource key (matching a graph color target).\n * `sampleType` is an optional type discriminant (D-1 SSOT); when omitted\n * the entry is treated as a color input (same as a bare string).\n */\nexport interface PostProcessReadEntry {\n readonly key: string;\n readonly sampleType?: PostProcessReadSampleType | undefined;\n}\n\n/**\n * Params schema: the WGSL struct definition + default byte array for a post-process\n * UBO. The primitive allocates a GPU buffer of `byteSize` and uploads `defaultValue`\n * at register time; the UBO is then updated per-frame via the data-driven\n * `PostProcessParams` ECS component (component `data` -> extract snapshot ->\n * dispatchFullscreenPass `queue.writeBuffer`), NOT via an imperative setter.\n * feat-20260621 M-A1/M-A2 / D-1.\n */\nexport interface PostProcessParamsSchema {\n /** Byte size of the WGSL params struct (must be UBO-aligned, min 16 B). */\n readonly byteSize: number;\n /** Default UBO contents (length must equal `byteSize`). */\n readonly defaultValue: Uint8Array;\n}\n\n// ─── Context passed to typed fullscreen feature injectors ─────────────────\n\n/**\n * The minimal surface a `registerFullscreenPostProcess` injector receives.\n * Contains the RHI device (for creating BGLs / pipelines / samplers) and the\n * error registry for structured failure reporting.\n */\nexport interface FullscreenPostProcessDeviceContext {\n readonly device: RhiDevice;\n readonly errorRegistry: {\n fire(error: RhiError): void;\n };\n}\n\n// ─── Built-in fullscreen post-process BGL + pipeline state ───────────────\n\n// Fullscreen bind-group layout: a single input-texture binding (0) +\n// a single sampler binding (1). The descriptor SSOT moved to\n// buildBindGroupLayoutDescriptor(spec, { kind: 'fullscreen-post' }) in\n// pipeline-spec.ts (D-13 round-2).\n//\n// Historical context: this BGL was duplicated across recordFxaaPass +\n// register-default-post-process before convergence (feat-20260609 framebuffers\n// demo M5R2 / T-12-a). R3 historical bug: the descriptor wrote sampleType:\n// 'float' for every input including depth32float views, tripping wgpu's\n// Filtering sampler vs UnfilterableFloat / Depth texture static-sample-pair\n// validation. The dispatcher derives sampleType from spec.attachments\n// (depth32float -> 'depth' + 'comparison' sampler; r32float ->\n// 'unfilterable-float'; else -> 'float' + 'filtering').\n\n/**\n * Create a linear clamp-to-edge sampler — reused across all fullscreen passes\n * (identical to the recordFxaaPass sampler).\n */\nfunction createFullscreenSampler(device: RhiDevice): Sampler | null {\n const res = device.createSampler({\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n magFilter: 'linear',\n minFilter: 'linear',\n });\n if (!res.ok) return null;\n return res.value;\n}\n\n/**\n * Create a non-filtering depth sampler for post-process passes that read the\n * camera scene depth (plan-strategy D-2: nearest + clamp-to-edge).\n * Aligns with the SSAO depth sampler shape (render-graph-primitives.ts:634-647)\n * — NOT a comparison sampler (D-2 rejects comparison because the post-process\n * shader reads raw depth values via `textureSampleLevel`, not PCF shadow lookup).\n */\nfunction createDepthSampler(device: RhiDevice): Sampler | null {\n const res = device.createSampler({\n magFilter: 'nearest',\n minFilter: 'nearest',\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n });\n if (!res.ok) return null;\n return res.value;\n}\n\n/**\n * Check whether the entry's {@link PostProcessShaderEntry.reads} declares a read\n * with `sampleType: 'depth'`. Used by {@link buildFullscreenPostProcessPass} to\n * select between the single-sample and multisample depth BGL variants and the\n * existing color-only kinds.\n */\nexport function entryHasDepthRead(entry: PostProcessShaderEntry): boolean {\n if (!entry.reads) return false;\n return entry.reads.some((r) => typeof r !== 'string' && r.sampleType === 'depth');\n}\n\n/**\n * Byte size of the minimal params UBO auto-allocated for a depth-reading entry\n * that declares no `params`. The `'fullscreen-post-with-scene-depth'` BGL always\n * declares `params@2`, so a bound UBO must exist even when the shader has no\n * user params (plan D-3: param-less depth effect gets a minimal 16B UBO). 16 B\n * is WebGPU's minimum uniform-buffer binding size.\n */\nexport const DEPTH_MIN_PARAMS_BYTE_SIZE = 16;\n\n// ─── Public: register / build a fullscreen post-process pass ─────────────\n\n/**\n * State of a registered fullscreen post-process pass.\n *\n * Created by the typed fullscreen feature graph and stored per-pass in the render system.\n * The `draw` method is called by the per-frame execute closure.\n */\nexport interface FullscreenPostProcessPassHandle {\n /** The pass name (same as the `color` target key). */\n readonly name: string;\n /** Execute one fullscreen draw: bind input texture, set pipeline, draw 3 vertices. */\n draw(encoder: RhiRenderPassEncoder, inputView: TextureView): void;\n /**\n * The per-frame params UBO this pass binds at group(1) binding(2), or null\n * when `entry.params === undefined` (param-less consumer, 2-entry BGL). The\n * dispatcher writes the snapshot bytes into it before draw and composes it\n * into the bind group via {@link createFullscreenBindGroup}.\n */\n readonly paramsBuffer: Buffer | null;\n}\n\n/**\n * Build a fullscreen post-process pass primitive.\n *\n * Creates BGL, sampler, and pipeline state from the registered shader entry.\n * Returns the pass handle + the BGL + the sampler so the caller can compose\n * bind groups. The BGL + sampler are shared across instances of the same shader.\n *\n * @returns The BGL, sampler, and a factory to create pass handles.\n */\nexport function buildFullscreenPostProcessPass(\n ctx: FullscreenPostProcessDeviceContext,\n entry: PostProcessShaderEntry,\n depthMultisampled = false,\n): {\n bindGroupLayout: BindGroupLayout;\n sampler: Sampler | null;\n depthSampler: Sampler | null;\n extraColorBindings: readonly number[];\n createHandle: (\n name: string,\n pipeline: unknown,\n paramsBuffer: Buffer | null,\n ) => FullscreenPostProcessPassHandle;\n} | null {\n const { device } = ctx;\n\n // Step 1: BGL (input texture + sampler [+ params buffer] [+ depth]).\n // D-13 round-2: route through dispatcher; sampleType derives from\n // spec.attachments (R3 fix). Default spec yields the historical 'float'\n // / 'filtering' shape for color inputs.\n // feat-20260621 D-2: when entry.params is present the BGL is the 3-entry\n // 'fullscreen-post-with-params' kind (adds buffer@2 uniform); otherwise the\n // 2-entry 'fullscreen-post' kind (param-less zero-regression, R-A7).\n // plan-strategy D-3: when entry.reads declares sampleType:'depth', use the\n // 5-entry scene-depth kind; depthMultisampled selects its multisampled\n // texture variant for a 4-sample scene target. params@2 is always present to\n // avoid 2x2 kind explosion.\n const hasDepth = entryHasDepthRead(entry);\n const bglKind: BglKind = hasDepth\n ? depthMultisampled\n ? 'fullscreen-post-with-scene-depth-msaa'\n : 'fullscreen-post-with-scene-depth'\n : entry.params !== undefined\n ? 'fullscreen-post-with-params'\n : 'fullscreen-post';\n const descriptor = buildBindGroupLayoutDescriptor(FULLSCREEN_DEFAULT_SPEC, { kind: bglKind });\n const colorReads = (entry.reads ?? []).filter(\n (read) => typeof read === 'string' || read.sampleType !== 'depth',\n );\n const extraColorCount = Math.max(0, colorReads.length - 1);\n const firstExtraBinding = hasDepth ? 5 : entry.params === undefined ? 2 : 3;\n for (let index = 0; index < extraColorCount; index += 1) {\n descriptor.entries.push({\n binding: firstExtraBinding + index,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n });\n }\n const bglRes = device.createBindGroupLayout(descriptor);\n if (!bglRes.ok) {\n ctx.errorRegistry.fire(bglRes.error);\n return null;\n }\n\n // Step 2: Samplers.\n const sampler = createFullscreenSampler(device);\n const depthSampler = hasDepth ? createDepthSampler(device) : null;\n\n return {\n bindGroupLayout: bglRes.value,\n sampler,\n depthSampler,\n extraColorBindings: Object.freeze(\n Array.from({ length: extraColorCount }, (_, index) => firstExtraBinding + index),\n ),\n createHandle: (name, pipeline, paramsBuffer) => ({\n name,\n paramsBuffer,\n draw(encoder, _inputView) {\n encoder.setPipeline(pipeline as never);\n // The bind group is composed per-frame by the record stage (mirrors\n // recordFxaaPass's lazy bindgroup compose in render-system-record.ts).\n // This draw() method only sets the pipeline — the caller is responsible\n // for bind group composition + setBindGroup before calling draw().\n encoder.draw(3, 1, 0, 0);\n },\n }),\n };\n}\n\n/**\n * Create a fullscreen bind group (lazy, per-frame). Composes the input texture\n * view + the linear sampler into group(1) (texture@0 + sampler@1). When\n * `paramsBuffer` is supplied (feat-20260621 D-2: `entry.params !== undefined`),\n * appends the per-frame params UBO at binding 2 (uniform), matching the 3-entry\n * `'fullscreen-post-with-params'` BGL. Omitting it yields the 2-entry shape\n * param-less consumers degrade to (R-A7).\n *\n * When `depthTexView` + `depthSampler` are supplied (plan-strategy D-3:\n * depth reads present), appends the depth texture view at binding 3 and the\n * non-filtering depth sampler at binding 4, matching the 5-entry\n * `'fullscreen-post-with-scene-depth'` BGL. Both must be supplied together\n * (or both omitted for existing color-only consumers — AC-03 zero-regression).\n */\nexport function createFullscreenBindGroup(\n device: RhiDevice,\n bgl: BindGroupLayout,\n inputView: TextureView,\n sampler: Sampler | null,\n paramsBuffer?: Buffer | null,\n depthTexView?: TextureView | null,\n depthSampler?: Sampler | null,\n additionalViews: readonly { readonly binding: number; readonly view: TextureView }[] = [],\n): BindGroup | null {\n const entries: { binding: number; resource: { kind: string; value: unknown } }[] = [\n { binding: 0, resource: { kind: 'textureView', value: inputView } },\n ];\n if (sampler) {\n entries.push({ binding: 1, resource: { kind: 'sampler', value: sampler } });\n }\n if (paramsBuffer) {\n // RHI buffer binding resource is `{ kind: 'buffer', value: { buffer } }` —\n // the nested `{ buffer }` wrapper is the GPUBufferBinding shape dawn expects\n // (mirrors createRenderer's shadow-probe UBO bindings). Passing the raw\n // handle as `value` makes dawn reject createBindGroup (\"no overload matched\n // ... member 'resource' for array element 2\").\n entries.push({ binding: 2, resource: { kind: 'buffer', value: { buffer: paramsBuffer } } });\n }\n if (depthTexView && depthSampler) {\n entries.push({ binding: 3, resource: { kind: 'textureView', value: depthTexView } });\n entries.push({ binding: 4, resource: { kind: 'sampler', value: depthSampler } });\n }\n for (const additional of additionalViews) {\n entries.push({\n binding: additional.binding,\n resource: { kind: 'textureView', value: additional.view },\n });\n }\n const res = device.createBindGroup({\n label: 'fullscreen-post-process-bg',\n layout: bgl,\n entries: entries as never,\n });\n if (!res.ok) return null;\n return res.value;\n}\n","// @forgeax/engine-render - low-level record/encode graph primitives.\n//\n// Standard owns pass topology through typed-render-graph-primitives. This module\n// retains the RHI-facing record helpers used by that typed graph: SSAO record\n// closures, fullscreen dispatch, depth resolution, and encoding.\n//\n// Public graph assembly does not depend on legacy add* wrappers.\nimport { mat4 } from '@forgeax/engine-math';\nimport type { ResolveContext } from '@forgeax/engine-render-graph';\nimport type {\n Buffer,\n RhiRenderPassEncoder,\n Sampler,\n Texture,\n TextureFormat,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport {\n buildFullscreenPostProcessPass,\n createFullscreenBindGroup,\n entryHasDepthRead,\n} from './fullscreen-post-process-pass';\nimport { buildBeginRenderPassDescriptor } from './pipeline-spec';\nimport { PostProcessError } from './post-process-errors';\nimport { computeProjectionMatrix, computeViewMatrix } from './record/helpers';\nimport { getOrCreateFromChain } from './record/mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './record/render-context';\nimport { recordFxaaPass } from './record/skybox-post-pass';\nimport type { RenderPipelineContext } from './render-contract';\nimport { getOrCreateSsaoBuffers, getOrCreateSsaoFallbackTexture } from './ssao-buffers';\nimport { getSsaoParameters } from './ssao-config';\n\ntype DepthResolutionContext = Pick<_InternalRenderPipelineContext, 'runtime'> & {\n readonly frameState: {\n readonly perFrameGraph?: {\n readonly getColorTargetTexture: (key: string) => Texture | undefined;\n } | null;\n };\n};\n\ntype RenderGraphRecordContext = _InternalRenderPipelineContext & {\n readonly frameState: _InternalRenderPipelineContext['frameState'] & {\n readonly perFrameGraph?: {\n readonly getColorTargetDescriptor: (\n key: string,\n ) => { readonly format: TextureFormat } | undefined;\n readonly getColorTargetView: (key: string) => TextureView | undefined;\n readonly getColorTargetTexture: (key: string) => Texture | undefined;\n } | null;\n };\n};\n\nfunction requireRenderGraphRecordContext(ctx: RenderPipelineContext): RenderGraphRecordContext {\n if (!('frameState' in ctx) || !('bindGroupCounts' in ctx) || !('geometryDepthKey' in ctx)) {\n throw new Error('typed render graph frame lacks the built-in record context');\n }\n return ctx as RenderGraphRecordContext;\n}\n\n/**\n * Resolve a depth-only view of a graph color target by key.\n *\n * On dawn the BindGroup validation rejects a default-view (aspect=all on a\n * depth+stencil texture) with \"Multiple aspects (Depth|Stencil) selected\".\n * A separate createTextureView({aspect:'depth-only'}) is required.\n *\n * @param internals - internal render pipeline context\n * @param key - graph color-target key to resolve depth from\n * @param label - debug label for the depth-only TextureView\n * @returns a depth-only TextureView, or null if the graph / texture is absent\n * or creation fires a structured error\n */\nexport function resolveDepthOnlyView(\n internals: DepthResolutionContext,\n key: string,\n label: string,\n preferredKey?: string | null,\n): TextureView | null {\n const graph = internals.frameState.perFrameGraph;\n if (graph === null || graph === undefined) return null;\n const preferredTexture =\n preferredKey === null || preferredKey === undefined\n ? undefined\n : graph.getColorTargetTexture(preferredKey);\n const tex = preferredTexture ?? graph.getColorTargetTexture(key);\n if (tex === undefined) return null;\n const res = internals.runtime.device.createTextureView(tex as never, {\n label,\n dimension: '2d',\n aspect: 'depth-only',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!res.ok) {\n internals.runtime.errorRegistry.fire(res.error);\n return null;\n }\n return res.value;\n}\n\n/**\n * Resolve a depth-only view of the graph's hdrDepth texture.\n *\n * Thin delegate to {@link resolveDepthOnlyView} (plan-strategy D-5: extract\n * the shared depth-only view helper, SSAO delegates). Behaviour is byte-identical\n * to the pre-extraction inline version. The SSAO BGL / bindings / sampler are\n * untouched (OOS-4).\n */\nfunction resolveHdrDepthDepthOnlyView(\n internals: DepthResolutionContext,\n hdrDepthKey: string,\n): TextureView | null {\n return resolveDepthOnlyView(internals, hdrDepthKey, 'ssao-hdr-depth-only-view');\n}\n\nfunction ensureSsaoRecordCompanions(internals: _InternalRenderPipelineContext): {\n filteringSampler: Sampler;\n depthSampler: Sampler;\n fallbackRawView: TextureView;\n} | null {\n const pp = internals.pipelineState.perPassResources;\n if (\n pp.ssaoFilteringSampler !== null &&\n pp.ssaoDepthSampler !== null &&\n pp.ssaoFallbackRawView !== null\n ) {\n return {\n filteringSampler: pp.ssaoFilteringSampler,\n depthSampler: pp.ssaoDepthSampler,\n fallbackRawView: pp.ssaoFallbackRawView as TextureView,\n };\n }\n\n const device = internals.runtime.device;\n\n if (pp.ssaoFilteringSampler === null) {\n // Despite the field name, this sampler is non-filtering (NEAREST):\n // bindings 3 (noise sampler) + 8 (ssaoSampler) pair with unfilterable\n // float textures (rgba32float noise / r8unorm ssaoRaw on dawn without\n // float32-filterable). The \"filtering\" label in the field name predates\n // the sampler-type split; the resource itself is non-filtering.\n const res = device.createSampler({\n label: 'ssao-noise-sampler',\n magFilter: 'nearest',\n minFilter: 'nearest',\n mipmapFilter: 'nearest',\n addressModeU: 'repeat',\n addressModeV: 'repeat',\n });\n if (!res.ok) {\n internals.runtime.errorRegistry.fire(res.error);\n return null;\n }\n pp.ssaoFilteringSampler = res.value;\n }\n\n if (pp.ssaoDepthSampler === null) {\n const res = device.createSampler({\n label: 'ssao-depth-sampler',\n magFilter: 'nearest',\n minFilter: 'nearest',\n mipmapFilter: 'nearest',\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n });\n if (!res.ok) {\n internals.runtime.errorRegistry.fire(res.error);\n return null;\n }\n pp.ssaoDepthSampler = res.value;\n }\n\n if (pp.ssaoFallbackRawView === null) {\n const fb = getOrCreateSsaoFallbackTexture(internals.runtime);\n if (fb === null) return null;\n pp.ssaoFallbackRawView = fb.view;\n }\n\n return {\n filteringSampler: pp.ssaoFilteringSampler,\n depthSampler: pp.ssaoDepthSampler,\n fallbackRawView: pp.ssaoFallbackRawView as TextureView,\n };\n}\n\n/**\n * Pack the 256B SSAO uniform payload from the camera + config.ssao.\n *\n * Layout (plan-strategy D-1 + D-C):\n * floats [0..15] view mat4\n * floats [16..31] projection mat4\n * floats [32..47] inverseProjection mat4\n * floats [48..51] intensityPad vec4 (x=intensity, y=radius, z=bias)\n * floats [52..63] trailing zero-pad to round to 256B / 64f UBO alignment.\n */\nfunction buildSsaoUniformPayload(internals: _InternalRenderPipelineContext): Float32Array {\n const { camera, frameState } = internals;\n const sProj = computeProjectionMatrix(camera);\n const sView = computeViewMatrix(camera);\n const invProj = mat4.create();\n mat4.invert(invProj, sProj);\n\n const out = new Float32Array(64);\n out.set(sView, 0);\n out.set(sProj, 16);\n out.set(invProj, 32);\n\n const ssaoConfig = frameState.installedPipelineConfig?.ssao;\n const parameters = getSsaoParameters(\n ssaoConfig !== undefined && ssaoConfig.enabled === true ? ssaoConfig : undefined,\n );\n out[48] = parameters.intensity;\n out[49] = parameters.radius;\n out[50] = parameters.bias;\n return out;\n}\n\n/**\n * recordSsaoCalcPass — fullscreen SSAO occlusion calculation (M8 / w38).\n *\n * Resolves the graph-owned half-resolution ssaoRaw color target, writes the\n * 256 B SSAO uniform (view/proj/invProj/intensity) once per frame, then runs\n * a 3-vertex fullscreen-triangle draw with fs_ssao_calc.\n *\n * Bind group entries (must match the 9-entry SSAO BGL declared in\n * createRenderer.ts; see hdrp-ssao.wgsl §BGL layout):\n * 0 ssao_uniform UBO 5 hdr_depth view\n * 1 ssao_kernel UBO 6 ssao_depth_sampler (non-filtering)\n * 2 ssao_noise_texture 7 fallback ssaoRaw view (calc never samples)\n * 3 ssao_noise_sampler 8 ssaoSampler (unused by calc, BGL slot)\n * 4 gbuffer_normal view\n *\n * Skips with no GPU work when the optional SSAO pipelines are unavailable\n * (manifest without hdrp-ssao.wgsl), when the dedicated BGL is null, when\n * the SSAO buffers fail to allocate, or when the graph cannot resolve the\n * required views.\n */\nexport interface SsaoCalcPassViews {\n readonly output: TextureView;\n readonly normal: TextureView;\n readonly depth: TextureView;\n readonly depthCacheKey: TextureView;\n}\n\nexport function recordSsaoCalcPass(\n _c: _InternalRenderPipelineContext,\n resolveCtx?: ResolveContext,\n ssaoRawKey?: string,\n gbuf0Key?: string,\n hdrDepthKey?: string,\n graphPass?: RhiRenderPassEncoder,\n graphViews?: SsaoCalcPassViews,\n): void {\n const { runtime, pipelineState, encoder } = _c;\n const pp = pipelineState.perPassResources;\n\n if (pp.ssaoCalcPipeline === null || pp.ssaoBgl === null) return;\n if (graphViews === undefined && (resolveCtx === undefined || ssaoRawKey === undefined)) return;\n\n const ssaoRawView =\n graphViews?.output ?? (resolveCtx?.resolve(ssaoRawKey as string) as TextureView | undefined);\n const gbuf0View =\n graphViews?.normal ??\n (gbuf0Key !== undefined\n ? (resolveCtx?.resolve(gbuf0Key) as TextureView | undefined)\n : undefined);\n if (!ssaoRawView || !gbuf0View || (graphViews === undefined && hdrDepthKey === undefined)) return;\n\n // hdrDepth needs a depth-only view (BGL binding 5 sampleType=depth);\n // resolveCtx returns a default all-aspects view that dawn rejects when\n // paired with a depth sampler.\n const hdrDepthView = graphViews?.depth ?? resolveHdrDepthDepthOnlyView(_c, hdrDepthKey as string);\n if (hdrDepthView === null) return;\n\n // Cache key: the graph's pooled hdrDepth view (stable object per size, new\n // object on resize). The depth-only view above is created fresh every frame\n // so it cannot key the cache; the pooled all-aspects view co-varies with it\n // (both are views of the same transient hdrDepth texture) and changes exactly\n // on resize. Used only as a WeakMap key, never bound.\n const hdrDepthPooledView =\n graphViews?.depthCacheKey ??\n (resolveCtx?.resolve(hdrDepthKey as string) as TextureView | undefined);\n if (hdrDepthPooledView === undefined) return;\n\n const ssaoBufs = getOrCreateSsaoBuffers(runtime);\n if (ssaoBufs === null) return;\n\n const noiseViewRes = runtime.device.createTextureView(ssaoBufs.noiseTexture, {\n label: 'hdrp-ssao-noise-view',\n format: 'rgba32float',\n dimension: '2d',\n aspect: 'all',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!noiseViewRes.ok) {\n runtime.errorRegistry.fire(noiseViewRes.error);\n return;\n }\n\n const companions = ensureSsaoRecordCompanions(_c);\n if (companions === null) return;\n\n // Per-frame uniform write (D-C: view+proj+invProj+intensity at one queue\n // call). 256 B Float32Array (64 f32) lands in ssao_uniform UBO offset 0.\n const payload = buildSsaoUniformPayload(_c);\n const writeRes = runtime.device.queue.writeBuffer(ssaoBufs.uniformBuffer, 0, payload);\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n return;\n }\n\n // Identity-cached bind group: 9 entries mirror the BGL declared in\n // createRenderer. Keyed on the graph-pooled gbuf0 + hdrDepth views (both\n // retire + reallocate on resize), so the WeakMap misses after a resize and\n // rebuilds against the live textures. The noise / depth-only views bound\n // below are created fresh each frame but back stable textures; keying on the\n // resize-varying graph views is what makes invalidation correct. Replaces\n // the prior `=== null` slot cache that submitted a destroyed gbuf0/hdrDepth\n // after resize.\n const ssaoBgl = pp.ssaoBgl;\n const bindGroup = getOrCreateFromChain(\n _c.frameState.postProcessBgCache,\n [gbuf0View, hdrDepthPooledView],\n 'ssao-calc',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'ssao-calc-bg',\n layout: ssaoBgl,\n entries: [\n { binding: 0, resource: { kind: 'buffer', value: { buffer: ssaoBufs.uniformBuffer } } },\n { binding: 1, resource: { kind: 'buffer', value: { buffer: ssaoBufs.kernelBuffer } } },\n { binding: 2, resource: { kind: 'textureView', value: noiseViewRes.value } },\n {\n binding: 3,\n resource: { kind: 'sampler', value: companions.filteringSampler },\n },\n { binding: 4, resource: { kind: 'textureView', value: gbuf0View } },\n { binding: 5, resource: { kind: 'textureView', value: hdrDepthView } },\n { binding: 6, resource: { kind: 'sampler', value: companions.depthSampler } },\n { binding: 7, resource: { kind: 'textureView', value: companions.fallbackRawView } },\n { binding: 8, resource: { kind: 'sampler', value: companions.filteringSampler } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n _c.bindGroupCounts,\n );\n\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['r8unorm'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [ssaoRawView] },\n 'post-process',\n ) as never,\n );\n pass.setPipeline(pp.ssaoCalcPipeline);\n pass.setBindGroup(0, bindGroup);\n pass.draw(3, 1, 0, 0);\n if (graphPass === undefined) pass.end();\n}\n\n/**\n * recordSsaoBlurPass — fullscreen SSAO 4x4 box blur (M8 / w38).\n *\n * Reads the half-resolution ssaoRaw (R8), applies a 16-tap box blur, writes\n * the blurred result to ssaoBlurred. The BGL is the same 9-entry SSAO BGL\n * as the calc pass; the only difference is binding 7 carries the real\n * ssaoRaw view (vs the 1x1 fallback the calc pass binds).\n */\nexport interface SsaoBlurPassViews extends SsaoCalcPassViews {\n readonly raw: TextureView;\n}\n\nexport function recordSsaoBlurPass(\n _c: _InternalRenderPipelineContext,\n resolveCtx?: ResolveContext,\n ssaoBlurredKey?: string,\n ssaoRawKey?: string,\n gbuf0Key?: string,\n hdrDepthKey?: string,\n graphPass?: RhiRenderPassEncoder,\n graphViews?: SsaoBlurPassViews,\n): void {\n const { runtime, pipelineState, encoder } = _c;\n const pp = pipelineState.perPassResources;\n\n if (pp.ssaoBlurPipeline === null || pp.ssaoBgl === null) return;\n if (\n graphViews === undefined &&\n (resolveCtx === undefined || ssaoBlurredKey === undefined || ssaoRawKey === undefined)\n )\n return;\n\n const ssaoBlurredView =\n graphViews?.output ??\n (resolveCtx?.resolve(ssaoBlurredKey as string) as TextureView | undefined);\n const ssaoRawView =\n graphViews?.raw ?? (resolveCtx?.resolve(ssaoRawKey as string) as TextureView | undefined);\n const gbuf0View =\n graphViews?.normal ??\n (gbuf0Key !== undefined\n ? (resolveCtx?.resolve(gbuf0Key) as TextureView | undefined)\n : undefined);\n if (!ssaoBlurredView || !ssaoRawView) return;\n\n // hdrDepth depth-only view (see recordSsaoCalcPass).\n const hdrDepthView =\n graphViews?.depth ??\n (hdrDepthKey !== undefined ? resolveHdrDepthDepthOnlyView(_c, hdrDepthKey) : null);\n // Pooled hdrDepth view for the cache key (the depth-only view above is\n // recreated every frame; see recordSsaoCalcPass).\n const hdrDepthPooledView =\n graphViews?.depthCacheKey ??\n (hdrDepthKey !== undefined\n ? (resolveCtx?.resolve(hdrDepthKey) as TextureView | undefined)\n : undefined);\n\n const ssaoBufs = getOrCreateSsaoBuffers(runtime);\n if (ssaoBufs === null) return;\n\n const noiseViewRes = runtime.device.createTextureView(ssaoBufs.noiseTexture, {\n label: 'hdrp-ssao-noise-view',\n format: 'rgba32float',\n dimension: '2d',\n aspect: 'all',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!noiseViewRes.ok) {\n runtime.errorRegistry.fire(noiseViewRes.error);\n return;\n }\n\n const companions = ensureSsaoRecordCompanions(_c);\n if (companions === null) return;\n\n // The blur reads ssaoRaw via binding 7 + ssaoSampler at binding 8. The\n // remaining slots 0..6 are bound for BGL completeness (BGL is shared with\n // the calc pass): WebGPU requires every BGL slot carry a valid resource\n // even when the active fragment entry does not statically reference it.\n // gbuf0 + hdr_depth views are resolved from the graph; they must exist\n // because the typed SSAO graph declares them as reads on the blur node.\n if (gbuf0View === undefined || hdrDepthView === null || hdrDepthPooledView === undefined) return;\n // Identity-cached bind group keyed on the graph-pooled ssaoRaw + gbuf0 +\n // hdrDepth views (all retire + reallocate on resize). Replaces the prior\n // `=== null` slot cache that submitted destroyed transients after resize.\n const ssaoBgl = pp.ssaoBgl;\n const bindGroup = getOrCreateFromChain(\n _c.frameState.postProcessBgCache,\n [ssaoRawView, gbuf0View, hdrDepthPooledView],\n 'ssao-blur',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'ssao-blur-bg',\n layout: ssaoBgl,\n entries: [\n { binding: 0, resource: { kind: 'buffer', value: { buffer: ssaoBufs.uniformBuffer } } },\n { binding: 1, resource: { kind: 'buffer', value: { buffer: ssaoBufs.kernelBuffer } } },\n { binding: 2, resource: { kind: 'textureView', value: noiseViewRes.value } },\n {\n binding: 3,\n resource: { kind: 'sampler', value: companions.filteringSampler },\n },\n { binding: 4, resource: { kind: 'textureView', value: gbuf0View } },\n { binding: 5, resource: { kind: 'textureView', value: hdrDepthView } },\n { binding: 6, resource: { kind: 'sampler', value: companions.depthSampler } },\n { binding: 7, resource: { kind: 'textureView', value: ssaoRawView } },\n { binding: 8, resource: { kind: 'sampler', value: companions.filteringSampler } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n _c.bindGroupCounts,\n );\n\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['r8unorm'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [ssaoBlurredView] },\n 'post-process',\n ) as never,\n );\n pass.setPipeline(pp.ssaoBlurPipeline);\n pass.setBindGroup(0, bindGroup);\n pass.draw(3, 1, 0, 0);\n if (graphPass === undefined) pass.end();\n}\n\n/**\n * F-3 fix-up + feat-20260609 M1 / T-3 patch: per-frame fullscreen-post-process\n * dispatcher.\n *\n * Two-branch fan-out by shader id:\n * - `'fxaa'` (engine-built-in hardwire): delegate to `recordFxaaPass`. The\n * FXAA implementation owns its graph input view, surface output attachment,\n * pipeline cache, and bindgroup-resize invalidation; that mechanics is engine-internal and\n * not expressible through the generic public primitive. recordFxaaPass's\n * body is intentionally unchanged across this refactor to preserve the\n * AC-09 dualPassDiff=1069 (hello-fxaa) / 768 (learn-render-4-10-MSAA)\n * byte-equivalence with the pre-feat baseline.\n * - every other id (AI-user path): the M1 patch wires `reads[0]` through the\n * render-graph `resolveCtx` so the bind group samples the upstream\n * graph-owned color target (e.g. the typed scene pass writes `'offscreenColor'`,\n * a custom post-process pass declares `reads: ['offscreenColor']`).\n * Failure modes (charter P3 fail-fast):\n * - `lookupPostProcess(shader) === undefined` -> throw\n * `PostProcessError({code:'post-process-not-found'})`\n * - `reads.length > 0` but `resolveCtx.resolve(reads[0]) === undefined`\n * -> throw `PostProcessError({code:'fullscreen-input-not-found',\n * detail:{readsKey, passName}})`. AI users read err.detail.readsKey\n * to find the missing graph.addColorTarget declaration.\n * On success the dispatcher builds the input-texture BGL + sampler via\n * `buildFullscreenPostProcessPass`, composes the per-frame bind group\n * via `createFullscreenBindGroup`, opens a render pass writing the\n * declared `color` (resolved through the graph's color-target view, or\n * the swap-chain `ctx.view` when the graph has not allocated a target),\n * binds the input bind group at slot 1 (the 0 slot is reserved for\n * future view bind groups), and calls `handle.draw(pass)` which\n * internally does `setPipeline(pipeline)` + `draw(3, 1, 0, 0)` over the\n * fullscreen-triangle vertex shader.\n *\n * Extracted from the addPass execute closure so the topology fan-out is in\n * one named place; the typed graph has a single\n * call site, and future post-process branches (e.g. tonemap migrated onto\n * this dispatcher per OOS-3) extend this function rather than the addPass\n * inline closure.\n */\nfunction dispatchFullscreenPass(\n ctx: RenderPipelineContext,\n name: string,\n shader: string,\n color: string,\n reads: readonly string[],\n resolveCtx?: ResolveContext,\n compositeOverSwapchain = false,\n rawSwapchainOutput = false,\n graphPass?: RhiRenderPassEncoder,\n graphOutputFormat?: GPUTextureFormat,\n graphDepthView?: TextureView,\n): void {\n if (shader === 'fxaa') {\n if (resolveCtx === undefined) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey: reads[0] ?? 'ldrColor', passName: name },\n });\n }\n recordFxaaPass(requireRenderGraphRecordContext(ctx), resolveCtx, graphPass);\n return;\n }\n const lookup = ctx.runtime.lookupPostProcess;\n const entry = lookup === undefined ? undefined : lookup(shader);\n if (entry === undefined) {\n throw new PostProcessError({\n code: 'post-process-not-found',\n detail: { id: shader },\n });\n }\n // feat-20260621 M4' composite-over-swap-chain: copy the current swap-chain\n // into the `color` scratch target BEFORE sampling, so the effect reads the\n // already-composited final image (shadows + tonemap + fxaa). Generalises the\n // built-in FXAA copy idiom. The `color` key is BOTH the copy dst and the\n // sampled input (resolve its GPU texture via `${color}::tex` for the copy,\n // its TextureView via `${color}` for the bind group).\n let inputView: TextureView | null;\n if (compositeOverSwapchain) {\n const scratchTex = resolveCtx?.resolve(`${color}::tex`);\n const scratchView = resolveCtx?.resolve(color);\n if (scratchTex === undefined || scratchView === undefined) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey: color, passName: name },\n });\n }\n ctx.encoder.copyTextureToTexture(\n { texture: ctx.currentTexture as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },\n { texture: scratchTex as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },\n { width: ctx.targetW, height: ctx.targetH, depthOrArrayLayers: 1 },\n );\n inputView = scratchView as TextureView;\n } else if (reads.length === 0) {\n // reads === [] preserves the legacy swap-chain sample path (used by\n // tonemap-style passes that read the framebuffer directly).\n inputView = ctx.view;\n } else {\n // reads with a key MUST resolve through the graph compile output, otherwise\n // the dispatcher throws fullscreen-input-not-found (charter P3 fail-fast).\n const readsKey = reads[0] as string;\n const resolved = resolveCtx?.resolve(readsKey);\n if (resolved === undefined) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey, passName: name },\n });\n }\n inputView = resolved as TextureView;\n }\n if (inputView === null) return;\n\n // ── BGL/Pipeline build (before depth resolution so built.depthSampler is\n // available for the depth threading block below; ctx.msaaActive selects\n // the multisampled depth BGL when the scene target uses sample=4) ───────\n const built = buildFullscreenPostProcessPass(\n { device: ctx.runtime.device, errorRegistry: ctx.runtime.errorRegistry },\n entry,\n ctx.msaaActive,\n );\n if (built === null) return;\n\n // ── plan-strategy D-6: depth read resolution (pipeline-agnostic, AC-02) ────\n // Iterate entry.reads looking for sampleType:'depth' entries. For each depth\n // entry, resolve a depth-only TextureView from the graph via\n // resolveDepthOnlyView, fail-fast on unresolvable keys. The depth sampler\n // is produced by buildFullscreenPostProcessPass (via createDepthSampler,\n // plan-strategy D-2: non-filtering nearest+clamp-to-edge).\n //\n // Both composite and non-composite branches handle depth symmetrically —\n // the depth resolution block is branch-agnostic (AC-02: no URP/HDRP\n // discrimination). Color input logic is unchanged (AC-03 zero-regression).\n let depthTexView: TextureView | null = graphDepthView ?? null;\n let depthSampler: Sampler | null = null;\n if (entry.reads && entry.reads.length > 0) {\n const internals = requireRenderGraphRecordContext(ctx);\n for (const read of entry.reads) {\n if (typeof read !== 'string' && read.sampleType === 'depth') {\n const depthKey = read.key;\n depthTexView ??= resolveDepthOnlyView(\n internals,\n depthKey,\n 'post-process-scene-depth-only-view',\n internals.geometryDepthKey,\n );\n if (depthTexView === null) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey: depthKey, passName: name },\n });\n }\n depthSampler = built.depthSampler;\n }\n }\n }\n\n // feat-20260621 M4' composite-over-swap-chain write target: the swap-chain's\n // NON-srgb storage view (R-COLORSPACE — the scratch holds an already-sRGB-\n // encoded copy, so writing through the srgb view would double-encode; mirrors\n // recordFxaaPass). Otherwise resolve the declared color through the graph and\n // fall back to ctx.view (swap-chain srgb view) for normal post passes.\n let writeView: TextureView | null | undefined;\n // The attachment format follows the actual write target. Graph-owned\n // targets may be linear HDR/LDR textures (for example rgba16float), while\n // the swap-chain path uses the backend-selected surface view format.\n let writeFormat = ctx.pipelineState?.colorAttachmentFormat ?? 'rgba8unorm-srgb';\n if (graphPass !== undefined) {\n // Typed graph passes must write their declared output target. The frame\n // surface view is only the fallback for legacy passes; using it here\n // leaves a typed output target cleared while the next pass samples it.\n writeView = (resolveCtx?.resolve(color) as TextureView | undefined) ?? ctx.view;\n writeFormat = graphOutputFormat ?? writeFormat;\n } else if (rawSwapchainOutput && color === 'swapchain') {\n const rawViewRes = ctx.runtime.device.createTextureView(ctx.currentTexture, {});\n if (!rawViewRes.ok) {\n ctx.runtime.errorRegistry.fire(rawViewRes.error);\n return;\n }\n writeView = rawViewRes.value;\n writeFormat = ctx.pipelineState?.format ?? 'rgba8unorm';\n } else if (compositeOverSwapchain) {\n const storageViewRes = ctx.runtime.device.createTextureView(ctx.currentTexture, {});\n if (!storageViewRes.ok) {\n ctx.runtime.errorRegistry.fire(storageViewRes.error);\n return;\n }\n writeView = storageViewRes.value;\n writeFormat = ctx.pipelineState?.format ?? 'rgba8unorm';\n } else {\n const legacyGraph = requireRenderGraphRecordContext(ctx).frameState.perFrameGraph;\n const graphColorFormat = legacyGraph?.getColorTargetDescriptor(color)?.format;\n if (graphColorFormat !== undefined) writeFormat = graphColorFormat;\n const resolvedColor = (resolveCtx?.resolve(color) as TextureView | undefined) ?? null;\n writeView = legacyGraph?.getColorTargetView(color) ?? resolvedColor ?? ctx.view;\n }\n if (writeView === null || writeView === undefined) return;\n\n // feat-20260621 M-A2 / w8: per-frame data-driven params channel. When the\n // entry declares params, look up the per-id eager-created UBO + the per-frame\n // bytes from the PostProcessParams snapshot, fail-fast on a byteLength\n // mismatch, then writeBuffer + bind the UBO at group(1) binding(2). When\n // entry.params is undefined this whole block is skipped and the BGL degrades\n // to 2-entry (param-less zero-regression, R-A7).\n let paramsBuffer: Buffer | null = null;\n if (entry.params !== undefined) {\n const ubo = ctx.runtime.getPostProcessParamsBuffer?.(shader);\n if (ubo !== undefined) {\n const data = ctx.postProcessParams.get(shader);\n if (data !== undefined) {\n if (data.byteLength !== entry.params.byteSize) {\n throw new PostProcessError({\n code: 'params-update-size-mismatch',\n detail: { byteSize: entry.params.byteSize, actualLength: data.byteLength },\n });\n }\n const writeResult = ctx.runtime.device.queue.writeBuffer(ubo, 0, data);\n if (!writeResult.ok) return;\n } else {\n const writeResult = ctx.runtime.device.queue.writeBuffer(ubo, 0, entry.params.defaultValue);\n if (!writeResult.ok) return;\n }\n paramsBuffer = ubo;\n }\n } else if (entryHasDepthRead(entry)) {\n // D-3: a param-less depth entry still binds the minimal UBO auto-allocated\n // at register (the 'fullscreen-post-with-scene-depth' BGL always declares\n // params@2). No per-frame write -- the buffer stays zero-filled.\n paramsBuffer = ctx.runtime.getPostProcessParamsBuffer?.(shader) ?? null;\n }\n\n const bindGroup = createFullscreenBindGroup(\n ctx.runtime.device,\n built.bindGroupLayout,\n inputView,\n built.sampler,\n paramsBuffer,\n depthTexView,\n depthSampler,\n built.extraColorBindings.map((binding, index) => {\n const read = entry.reads?.filter(\n (candidate) => typeof candidate === 'string' || candidate.sampleType !== 'depth',\n )[index + 1];\n const key = typeof read === 'string' ? read : read?.key;\n const view = key === undefined ? undefined : resolveCtx?.resolve(key);\n if (view === undefined) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey: key ?? 'additional-read', passName: name },\n });\n }\n return { binding, view: view as TextureView };\n }),\n );\n if (bindGroup === null) return;\n\n // Pipeline source-of-truth (M4 / T-10-a, solving M1 CONCERN-1):\n // RenderSystemRuntime.getPostProcessPipeline is the sync wrapper over the\n // shared shader-module adapter (1-frame warmup). First frame after\n // fullscreen effect registration: shader compile is in flight -> returns null -> we\n // skip the pass for that frame. Second frame onward: cached pipeline is\n // returned synchronously.\n //\n // Color format SSOT: graph-owned writes use their resolved descriptor format;\n // swap-chain writes use the backend-aware surface format in pipelineState.\n // This keeps the PSO target and render-pass attachment identical when a\n // fullscreen pass writes an intermediate rgba16float target (for example\n // tonemap -> FXAA), while preserving the native surface storage/sRGB split.\n const lookupPipeline = ctx.runtime.getPostProcessPipeline;\n if (lookupPipeline === undefined) return;\n const postColorFormat = writeFormat;\n const pipeline = lookupPipeline(shader, built.bindGroupLayout, postColorFormat);\n if (pipeline === null) {\n return;\n }\n const handle = built.createHandle(name, pipeline, paramsBuffer);\n\n // Open a render pass writing into the resolved color target. Fullscreen\n // post-process passes are non-MSAA, depth-less, single-attachment.\n // setBindGroup(1, ...) (group=1 reserved per plan-strategy convention;\n // group=0 is reserved for future view bind groups, mirroring the\n // recordTonemap / recordSkybox pattern that uses slot 0 only when the\n // pipeline declares a single bind group at slot 0).\n const pass =\n graphPass ??\n ctx.encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n {\n colorFormats: [writeFormat],\n depthFormat: undefined,\n sampleCount: 1,\n },\n { colorViews: [writeView] },\n 'post-process',\n ) as never,\n );\n pass.setBindGroup(1, bindGroup);\n handle.draw(pass, inputView);\n if (graphPass === undefined) pass.end();\n}\n\nexport function encodeFullscreenPass(\n ctx: RenderPipelineContext,\n pass: RhiRenderPassEncoder,\n input: {\n readonly name: string;\n readonly shader: string;\n readonly color: string;\n readonly reads: readonly string[];\n readonly resolve: ResolveContext;\n readonly outputFormat: GPUTextureFormat;\n readonly rawSwapchainOutput?: boolean | undefined;\n readonly depthView?: TextureView | undefined;\n },\n): void {\n dispatchFullscreenPass(\n ctx,\n input.name,\n input.shader,\n input.color,\n input.reads,\n input.resolve,\n false,\n input.rawSwapchainOutput ?? false,\n pass,\n input.outputFormat,\n input.depthView,\n );\n}\n","import type {\n BindGroupLayout,\n Buffer,\n RhiDevice,\n RhiQueue,\n Sampler,\n Texture,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport type { DeviceScope } from '../device/device-scope';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\nimport { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';\nimport type { RenderFrameState } from '../record/frame-snapshot';\n\ninterface TemporalSurface {\n readonly texture: Texture;\n readonly view: TextureView;\n}\n\nexport interface TemporalGpuState {\n readonly device: RhiDevice;\n readonly scope: DeviceScope;\n readonly childScope: DeviceScope;\n width: number;\n height: number;\n valid: boolean;\n readIndex: 0 | 1;\n pendingIndex: 0 | 1 | undefined;\n readonly color: [TemporalSurface, TemporalSurface];\n readonly temporal: [TemporalSurface, TemporalSurface];\n bindGroupLayout: BindGroupLayout | undefined;\n sampler: Sampler | undefined;\n paramsBuffer: Buffer | undefined;\n committed: boolean;\n}\n\nfunction createSurface(\n device: RhiDevice,\n childScope: DeviceScope,\n label: string,\n width: number,\n height: number,\n): TemporalSurface {\n const texture = device.createTexture({\n label,\n size: { width, height, depthOrArrayLayers: 1 },\n format: 'rgba16float',\n textureBindingViewDimension: undefined,\n usage:\n GPU_TEXTURE_USAGE_COPY_SRC |\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n });\n if (!texture.ok) throw texture.error;\n childScope._adopt('texture', texture.value, (value) => {\n device.destroyTexture(value);\n });\n const view = device.createTextureView(texture.value, {\n label: `${label}.view`,\n dimension: '2d',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!view.ok) throw view.error;\n return { texture: texture.value, view: view.value };\n}\n\nfunction createState(\n device: RhiDevice,\n scope: DeviceScope,\n width: number,\n height: number,\n): TemporalGpuState {\n const childScope = scope.createChild(`${scope.owner}:temporal`);\n try {\n return {\n device,\n scope,\n childScope,\n width,\n height,\n valid: false,\n readIndex: 0,\n pendingIndex: undefined,\n color: [\n createSurface(device, childScope, 'taa-history-color-a', width, height),\n createSurface(device, childScope, 'taa-history-color-b', width, height),\n ],\n temporal: [\n createSurface(device, childScope, 'taa-history-temporal-a', width, height),\n createSurface(device, childScope, 'taa-history-temporal-b', width, height),\n ],\n bindGroupLayout: undefined,\n sampler: undefined,\n paramsBuffer: undefined,\n committed: false,\n };\n } catch (cause) {\n childScope.abandon();\n throw cause;\n }\n}\n\nexport function getTemporalParamsBuffer(state: TemporalGpuState): Buffer {\n if (state.paramsBuffer !== undefined) return state.paramsBuffer;\n const created = state.device.createBuffer({\n label: 'taa-resolve-params',\n size: 16,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!created.ok) {\n if (!state.committed) state.childScope.abandon();\n throw created.error;\n }\n state.childScope._adopt('buffer', created.value, (value) => {\n state.device.destroyBuffer(value);\n });\n const written = state.device.queue.writeBuffer(created.value, 0, new Uint8Array(16));\n if (!written.ok) {\n if (!state.committed) state.childScope.abandon();\n throw written.error;\n }\n state.paramsBuffer = created.value;\n return created.value;\n}\n\nexport function getTemporalGpuState(\n frameState: RenderFrameState,\n device: RhiDevice,\n scope: DeviceScope,\n width: number,\n height: number,\n): TemporalGpuState {\n const staged = frameState.temporalGpuState;\n if (\n staged !== undefined &&\n staged.scope === scope &&\n staged.width === width &&\n staged.height === height\n ) {\n return staged;\n }\n const existing = frameState.activeTemporalGpuState;\n if (\n existing !== undefined &&\n existing.scope === scope &&\n existing.width === width &&\n existing.height === height\n ) {\n return existing;\n }\n const next = createState(device, scope, width, height);\n frameState.temporalGpuState = next;\n return next;\n}\n\nexport function getTemporalBindGroupResources(state: TemporalGpuState): {\n readonly layout: BindGroupLayout;\n readonly sampler: Sampler | null;\n} {\n if (state.bindGroupLayout !== undefined) {\n return {\n layout: state.bindGroupLayout,\n sampler: state.sampler ?? null,\n };\n }\n try {\n const layout = state.device.createBindGroupLayout({\n label: 'taa-resolve-bind-group',\n entries: [\n {\n binding: 0,\n visibility: 2,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n },\n { binding: 1, visibility: 2, sampler: { type: 'non-filtering' } },\n {\n binding: 2,\n visibility: 2,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n },\n { binding: 3, visibility: 2, sampler: { type: 'non-filtering' } },\n {\n binding: 4,\n visibility: 2,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n },\n { binding: 5, visibility: 2, sampler: { type: 'non-filtering' } },\n {\n binding: 6,\n visibility: 2,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n },\n { binding: 7, visibility: 2, sampler: { type: 'non-filtering' } },\n { binding: 8, visibility: 2, buffer: { type: 'uniform' } },\n ],\n });\n if (!layout.ok) throw layout.error;\n state.childScope._adopt('binding', layout.value, () => undefined);\n const sampler = state.device.createSampler({\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n magFilter: 'nearest',\n minFilter: 'nearest',\n });\n if (!sampler.ok) throw sampler.error;\n state.childScope._adopt('binding', sampler.value, () => undefined);\n state.bindGroupLayout = layout.value;\n state.sampler = sampler.value;\n return { layout: layout.value, sampler: sampler.value };\n } catch (cause) {\n if (!state.committed) {\n state.childScope.abandon();\n state.bindGroupLayout = undefined;\n state.sampler = undefined;\n }\n throw cause;\n }\n}\n\nexport function temporalReadIndex(state: TemporalGpuState): 0 | 1 {\n return state.readIndex;\n}\n\nexport function temporalWriteIndex(state: TemporalGpuState): 0 | 1 {\n return state.readIndex === 0 ? 1 : 0;\n}\n\nexport function stageTemporalGpuSubmit(state: TemporalGpuState): void {\n state.pendingIndex = state.readIndex === 0 ? 1 : 0;\n}\n\nexport function hasPendingTemporalGpuSubmit(state: TemporalGpuState): boolean {\n return state.pendingIndex !== undefined;\n}\n\nexport function commitTemporalGpuSubmit(state: TemporalGpuState): boolean {\n if (state.pendingIndex === undefined) return false;\n state.readIndex = state.pendingIndex;\n state.pendingIndex = undefined;\n state.valid = true;\n state.committed = true;\n return true;\n}\n\nexport function abortTemporalGpuSubmit(state: TemporalGpuState): void {\n state.pendingIndex = undefined;\n}\n\nexport function retireTemporalGpuState(state: TemporalGpuState): void {\n state.pendingIndex = undefined;\n state.childScope.retire();\n state.valid = false;\n state.committed = false;\n state.bindGroupLayout = undefined;\n state.sampler = undefined;\n state.paramsBuffer = undefined;\n}\n\nexport function retireTemporalGpuStateAfterFence(\n state: TemporalGpuState,\n queue: RhiQueue,\n retiring: Set<TemporalGpuState>,\n onFailure: (cause: unknown) => void,\n): void {\n if (state.childScope.state === 'retired' || state.childScope.state === 'abandoned') return;\n state.childScope.beginRetire();\n retiring.add(state);\n void queue.onSubmittedWorkDone().then(\n () => {\n retiring.delete(state);\n retireTemporalGpuState(state);\n },\n (cause) => {\n retiring.delete(state);\n onFailure(cause);\n retireTemporalGpuState(state);\n },\n );\n}\n","import type {\n GraphAccess,\n GraphResourceResolver,\n GraphTextureView,\n RenderGraphBuilder,\n RenderGraphError,\n ResolveContext,\n} from '@forgeax/engine-render-graph';\nimport { RhiError, type TextureView } from '@forgeax/engine-rhi';\nimport { ok, type PassKind, type PassSelector, type Result } from '@forgeax/engine-types';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from './gpu-texture-usage';\nimport { buildPerFrameBindGroups } from './record/frame-lighting';\nimport { encodeMainPass } from './record/main-pass';\nimport type {\n _InternalRenderPipelineContext,\n RenderSystemInternals,\n} from './record/render-context';\nimport {\n encodeSkyboxPass,\n recordBloomBlurHPass,\n recordBloomBlurVPass,\n recordBloomBrightPass,\n recordBloomCompositePass,\n} from './record/skybox-post-pass';\nimport { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from './render-contract';\nimport {\n encodeFullscreenPass,\n recordSsaoBlurPass,\n recordSsaoCalcPass,\n} from './render-graph-primitives';\nimport type { RenderPipelineFrame, RenderPipelineGpuDrivenProjection } from './render-pipeline';\nimport { createRenderPipelineTarget, type RenderPipelineTarget } from './render-pipeline';\nimport {\n getTemporalBindGroupResources,\n getTemporalGpuState,\n getTemporalParamsBuffer,\n stageTemporalGpuSubmit,\n} from './temporal/gpu';\n\nfunction resolvedView(resources: GraphResourceResolver, view: GraphTextureView): TextureView {\n const result = resources.textureView(view);\n if (!result.ok) throw result.error;\n return result.value;\n}\n\nfunction throwTemporalEncodeFailure(expected: string, cause?: unknown): never {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected,\n hint:\n cause === undefined\n ? 'retry the temporal frame after repairing its GPU resource'\n : String(cause),\n });\n}\n\nexport function typedFrameClearColor(frame: RenderPipelineFrame): GPUColor {\n return {\n r: frame.clear[0] ?? 0,\n g: frame.clear[1] ?? 0,\n b: frame.clear[2] ?? 0,\n a: frame.clear[3] ?? 1,\n };\n}\n\nfunction resolvedDepthView(\n frame: RenderPipelineFrame,\n resources: GraphResourceResolver,\n target: RenderPipelineTarget,\n): TextureView {\n const texture = resources.texture(target.texture);\n if (!texture.ok) throw texture.error;\n const view = frame.runtime.device.createTextureView(texture.value, {\n label: 'typed-ssao-depth-only-view',\n dimension: '2d',\n aspect: 'depth-only',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!view.ok) throw view.error;\n return view.value;\n}\n\nfunction legacyResolver(\n resources: GraphResourceResolver,\n targets: Readonly<Record<string, RenderPipelineTarget>>,\n): ResolveContext {\n return {\n resolve: (name) => {\n const target = targets[name];\n return target === undefined ? undefined : resolvedView(resources, target.view);\n },\n };\n}\n\nexport function addTypedSkyboxPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n color: RenderPipelineTarget,\n): Result<void, RenderGraphError> {\n return graph.addRasterPass('skybox', {\n accesses: [{ resource: color.view, usage: 'color-attachment' }],\n colorAttachments: [\n {\n view: color.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: typedFrameClearColor,\n },\n ],\n encode: ({ pass, frame }) => encodeSkyboxPass(frame as _InternalRenderPipelineContext, pass),\n });\n}\n\nexport interface TypedScenePassOptions {\n readonly name: string;\n readonly color: RenderPipelineTarget;\n readonly depth: RenderPipelineTarget;\n readonly resolve?: RenderPipelineTarget | undefined;\n readonly sampled?: readonly RenderPipelineTarget[] | undefined;\n readonly directionalShadow?: RenderPipelineTarget | undefined;\n readonly spotShadow?: RenderPipelineTarget | undefined;\n readonly ssao?: RenderPipelineTarget | undefined;\n readonly selector: PassSelector;\n readonly passKind?: PassKind | undefined;\n readonly colorTargets?: readonly RenderPipelineTarget[] | undefined;\n readonly clearColor?: readonly [number, number, number, number] | undefined;\n readonly colorLoadOp?: GPULoadOp | undefined;\n readonly depthLoadOp?: GPULoadOp | undefined;\n readonly recordMode?: 'opaque' | 'transmission' | 'transparent' | undefined;\n readonly transmissionBackdrop?: GraphTextureView | undefined;\n readonly extraAccesses?: readonly GraphAccess[] | undefined;\n readonly gpuDriven?: RenderPipelineGpuDrivenProjection | undefined;\n}\n\nexport function addTypedScenePass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n options: TypedScenePassOptions,\n): Result<void, RenderGraphError> {\n const colorTargets = options.colorTargets ?? [options.color];\n const accesses: GraphAccess[] = [\n ...colorTargets.map((target) => ({\n resource: target.view,\n usage: 'color-attachment' as const,\n })),\n { resource: options.depth.view, usage: 'depth-stencil-write' },\n ...(options.sampled ?? []).map((target) => ({\n resource: target.view,\n usage: 'sampled-read' as const,\n })),\n ...(options.transmissionBackdrop === undefined\n ? []\n : [{ resource: options.transmissionBackdrop, usage: 'sampled-read' as const }]),\n ...(options.extraAccesses ?? []),\n ...(options.gpuDriven?.accesses ?? []),\n ];\n if (options.resolve !== undefined) {\n accesses.push({ resource: options.resolve.view, usage: 'color-attachment' });\n }\n return graph.addRasterPass(options.name, {\n accesses,\n colorAttachments: colorTargets.map((target, index) => ({\n view: target.view,\n ...(index === 0 && options.resolve !== undefined\n ? { resolveTarget: options.resolve.view }\n : {}),\n loadOp: options.colorLoadOp ?? 'clear',\n storeOp: 'store',\n clearValue: {\n r: options.clearColor?.[0] ?? 0,\n g: options.clearColor?.[1] ?? 0,\n b: options.clearColor?.[2] ?? 0,\n a: options.clearColor?.[3] ?? 1,\n },\n })),\n depthStencilAttachment: {\n view: options.depth.view,\n depthClearValue: 1,\n depthLoadOp: options.depthLoadOp ?? 'clear',\n depthStoreOp: 'store',\n stencilClearValue: 0,\n stencilLoadOp: options.depthLoadOp ?? 'clear',\n stencilStoreOp: 'store',\n },\n encode: ({ pass, frame, resources }) => {\n const colorViews = colorTargets.map((target) => resolvedView(resources, target.view));\n const depthView = resolvedView(resources, options.depth.view);\n const resolveView =\n options.resolve === undefined ? null : resolvedView(resources, options.resolve.view);\n const internal = frame as _InternalRenderPipelineContext;\n const directionalShadow =\n options.directionalShadow === undefined\n ? undefined\n : resolvedView(resources, options.directionalShadow.view);\n const spotShadow =\n options.spotShadow === undefined\n ? undefined\n : resolvedView(resources, options.spotShadow.view);\n const ssao =\n options.ssao === undefined ? undefined : resolvedView(resources, options.ssao.view);\n const transmissionBackdrop =\n options.transmissionBackdrop === undefined\n ? null\n : resolvedView(resources, options.transmissionBackdrop);\n internal.frameState.currentDirectionalShadowView = directionalShadow ?? null;\n internal.frameState.currentSpotShadowView = spotShadow ?? null;\n const groups = buildPerFrameBindGroups(\n internal.runtime as RenderSystemInternals,\n internal.frameState,\n internal.pipelineState,\n internal.validated.length > 0 || options.gpuDriven !== undefined,\n internal.bindGroupCounts,\n { directionalShadow, spotShadow },\n );\n if (groups.viewBindGroup !== null) {\n options.gpuDriven?.encode(groups.viewBindGroup, pass, resources);\n }\n encodeMainPass(\n {\n ...internal,\n geometryColorView: colorViews[0] ?? null,\n geometryDepthView: depthView,\n geometryColorResolveView: resolveView,\n transparentColorFormat: colorTargets[0]?.format as GPUTextureFormat,\n msaaActive: colorTargets[0]?.sampleCount === 4,\n viewBindGroup: groups.viewBindGroup,\n meshBindGroup: groups.meshBindGroup,\n hdrpClusterBindGroup: groups.hdrpClusterBindGroup,\n hdrpClusterMembershipBindGroup: groups.hdrpClusterMembershipBindGroup,\n ...(ssao === undefined ? {} : { hdrpSsaoBlurredView: ssao }),\n },\n pass,\n options.selector,\n {\n colorViews,\n colorFormats: colorTargets.map((target) => target.format as GPUTextureFormat),\n depthView,\n passKind: options.passKind ?? 'forward',\n ...(options.clearColor === undefined ? {} : { clearColor: options.clearColor }),\n ...(options.recordMode === undefined ? {} : { recordMode: options.recordMode }),\n ...(options.transmissionBackdrop === undefined\n ? {}\n : { transmissionBackdropView: transmissionBackdrop }),\n },\n );\n },\n });\n}\n\nexport function addTypedFrameObservationPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n target: RenderPipelineTarget,\n pipelineId: 'forgeax::standard',\n): Result<void, RenderGraphError> {\n return graph.addCopyPass('linear-hdr-observation', {\n accesses: [{ resource: target.view, usage: 'copy-src' }],\n encode: ({ frame, resources }) => {\n const internal = frame as _InternalRenderPipelineContext;\n const texture = resources.texture(target.texture);\n if (!texture.ok) throw texture.error;\n internal.frameState.currentFrameObservationSource = {\n texture: texture.value,\n descriptor: {\n texture: texture.value,\n format: target.format,\n size: { width: frame.targetW, height: frame.targetH },\n usage:\n GPU_TEXTURE_USAGE_COPY_SRC |\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n sample: target.sampleCount,\n },\n frameId: internal.frameState.frameNumber,\n pipelineId,\n backendId: frame.runtime.device.caps.backendKind,\n };\n },\n });\n}\n\nexport interface TypedBloomTargets {\n readonly scene: RenderPipelineTarget;\n readonly composited: RenderPipelineTarget;\n readonly bright: RenderPipelineTarget;\n readonly blurH: RenderPipelineTarget;\n readonly blurV: RenderPipelineTarget;\n}\n\n/** The semantic Bloom pass owner; graph inspection consumes these same identities. */\nexport const TYPED_BLOOM_PASS_NAMES = {\n bright: 'bloom-bright',\n blurH: 'bloom-blur-h',\n blurV: 'bloom-blur-v',\n composite: 'bloom-composite',\n} as const;\n\nexport function addTypedBloomPasses(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n targets: TypedBloomTargets,\n): Result<void, RenderGraphError> {\n const named = {\n hdrColor: targets.scene,\n hdrComposited: targets.composited,\n bloomBright: targets.bright,\n bloomBlurH: targets.blurH,\n bloomBlurV: targets.blurV,\n };\n const descriptors = [\n {\n name: TYPED_BLOOM_PASS_NAMES.bright,\n reads: [targets.scene],\n write: targets.bright,\n encode: recordBloomBrightPass,\n },\n {\n name: TYPED_BLOOM_PASS_NAMES.blurH,\n reads: [targets.bright],\n write: targets.blurH,\n encode: recordBloomBlurHPass,\n },\n {\n name: TYPED_BLOOM_PASS_NAMES.blurV,\n reads: [targets.blurH],\n write: targets.blurV,\n encode: recordBloomBlurVPass,\n },\n {\n name: TYPED_BLOOM_PASS_NAMES.composite,\n reads: [targets.scene, targets.blurV],\n write: targets.composited,\n encode: recordBloomCompositePass,\n },\n ] as const;\n for (const descriptor of descriptors) {\n const added = graph.addRasterPass(descriptor.name, {\n accesses: [\n ...descriptor.reads.map((target) => ({\n resource: target.view,\n usage: 'sampled-read' as const,\n })),\n { resource: descriptor.write.view, usage: 'color-attachment' },\n ],\n colorAttachments: [\n {\n view: descriptor.write.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n },\n ],\n encode: ({ pass, frame, resources }) =>\n descriptor.encode(\n frame as _InternalRenderPipelineContext,\n legacyResolver(resources, named),\n pass,\n ),\n });\n if (!added.ok) return added;\n }\n return ok(undefined);\n}\n\nexport interface TypedSsaoTargets {\n readonly normal: RenderPipelineTarget;\n readonly depth: RenderPipelineTarget;\n readonly raw: RenderPipelineTarget;\n readonly blurred: RenderPipelineTarget;\n}\n\nexport function addTypedSsaoPasses(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n targets: TypedSsaoTargets,\n): Result<void, RenderGraphError> {\n const calc = graph.addRasterPass('ssao-calc', {\n accesses: [\n { resource: targets.normal.view, usage: 'sampled-read' },\n { resource: targets.depth.view, usage: 'sampled-read' },\n { resource: targets.raw.view, usage: 'color-attachment' },\n ],\n colorAttachments: [\n {\n view: targets.raw.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 1, g: 1, b: 1, a: 1 },\n },\n ],\n encode: ({ pass, frame, resources }) => {\n const normal = resolvedView(resources, targets.normal.view);\n const depthCacheKey = resolvedView(resources, targets.depth.view);\n recordSsaoCalcPass(\n frame as _InternalRenderPipelineContext,\n undefined,\n undefined,\n undefined,\n undefined,\n pass,\n {\n output: resolvedView(resources, targets.raw.view),\n normal,\n depth: resolvedDepthView(frame, resources, targets.depth),\n depthCacheKey,\n },\n );\n },\n });\n if (!calc.ok) return calc;\n\n return graph.addRasterPass('ssao-blur', {\n accesses: [\n { resource: targets.raw.view, usage: 'sampled-read' },\n { resource: targets.normal.view, usage: 'sampled-read' },\n { resource: targets.depth.view, usage: 'sampled-read' },\n { resource: targets.blurred.view, usage: 'color-attachment' },\n ],\n colorAttachments: [\n {\n view: targets.blurred.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 1, g: 1, b: 1, a: 1 },\n },\n ],\n encode: ({ pass, frame, resources }) => {\n const normal = resolvedView(resources, targets.normal.view);\n const depthCacheKey = resolvedView(resources, targets.depth.view);\n recordSsaoBlurPass(\n frame as _InternalRenderPipelineContext,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n pass,\n {\n output: resolvedView(resources, targets.blurred.view),\n raw: resolvedView(resources, targets.raw.view),\n normal,\n depth: resolvedDepthView(frame, resources, targets.depth),\n depthCacheKey,\n },\n );\n },\n });\n}\n\nexport interface TypedFullscreenPassOptions {\n readonly name: string;\n readonly shader: string;\n readonly input: RenderPipelineTarget;\n readonly output: RenderPipelineTarget;\n readonly outputOnly?: boolean | undefined;\n readonly rawSwapchainOutput?: boolean | undefined;\n readonly depth?: RenderPipelineTarget | undefined;\n readonly additionalReads?: readonly {\n readonly key: string;\n readonly target: RenderPipelineTarget;\n }[];\n}\n\nexport interface TypedTemporalResolveTargets {\n readonly scene: RenderPipelineTarget;\n readonly currentTemporal: RenderPipelineTarget;\n readonly depth: RenderPipelineTarget;\n readonly historyColor: RenderPipelineTarget;\n readonly historyTemporal: RenderPipelineTarget;\n readonly writeColor: RenderPipelineTarget;\n readonly writeTemporal: RenderPipelineTarget;\n}\n\nexport function addTypedTemporalResolvePass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n targets: TypedTemporalResolveTargets,\n): Result<void, RenderGraphError> {\n const added = graph.addRasterPass('taa-resolve', {\n accesses: [\n { resource: targets.scene.view, usage: 'sampled-read' },\n { resource: targets.currentTemporal.view, usage: 'sampled-read' },\n { resource: targets.historyColor.view, usage: 'sampled-read' },\n { resource: targets.historyTemporal.view, usage: 'sampled-read' },\n { resource: targets.writeColor.view, usage: 'color-attachment' },\n { resource: targets.writeTemporal.view, usage: 'color-attachment' },\n ],\n colorAttachments: [\n {\n view: targets.writeColor.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n {\n view: targets.writeTemporal.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n },\n ],\n encode: ({ pass, frame, resources }) => {\n const internal = frame as _InternalRenderPipelineContext;\n const state = getTemporalGpuState(\n internal.frameState,\n frame.runtime.device,\n (frame.runtime as import('./record/render-context').RenderSystemRuntime).deviceScope,\n frame.targetW,\n frame.targetH,\n );\n const built = getTemporalBindGroupResources(state);\n const current = resolvedView(resources, targets.scene.view);\n const currentTemporal = resolvedView(resources, targets.currentTemporal.view);\n const historyColor = resolvedView(resources, targets.historyColor.view);\n const historyTemporal = resolvedView(resources, targets.historyTemporal.view);\n const params = getTemporalParamsBuffer(state);\n if (params === undefined || built.sampler === null) {\n throwTemporalEncodeFailure('TAA resolve has an admitted params buffer and sampler');\n }\n const payload = new ArrayBuffer(16);\n new Float32Array(payload).set([\n frame.camera.temporal?.currentJitterUv?.[0] ?? 0,\n frame.camera.temporal?.currentJitterUv?.[1] ?? 0,\n ]);\n const words = new Uint32Array(payload);\n words[2] = state.valid && (frame.camera.temporal?.historyValid ?? true) ? 1 : 0;\n words[3] = frame.camera.temporal?.temporalFrameIndex ?? 0;\n const written = frame.runtime.device.queue.writeBuffer(params, 0, new Uint8Array(payload));\n if (!written.ok)\n throwTemporalEncodeFailure('TAA resolve params upload succeeds', written.error);\n const bindGroup = frame.runtime.device.createBindGroup({\n label: 'taa-resolve-bind-group',\n layout: built.layout,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: current } },\n { binding: 1, resource: { kind: 'sampler', value: built.sampler } },\n { binding: 2, resource: { kind: 'textureView', value: historyColor } },\n { binding: 3, resource: { kind: 'sampler', value: built.sampler } },\n { binding: 4, resource: { kind: 'textureView', value: historyTemporal } },\n { binding: 5, resource: { kind: 'sampler', value: built.sampler } },\n { binding: 6, resource: { kind: 'textureView', value: currentTemporal } },\n { binding: 7, resource: { kind: 'sampler', value: built.sampler } },\n { binding: 8, resource: { kind: 'buffer', value: { buffer: params } } },\n ] as never,\n });\n if (!bindGroup.ok) {\n throwTemporalEncodeFailure('TAA resolve bind group creation succeeds', bindGroup.error);\n }\n const pipeline = frame.runtime.getPostProcessPipeline?.(\n 'forgeax.taa-resolve',\n built.layout,\n targets.writeColor.format as GPUTextureFormat,\n );\n if (pipeline === null || pipeline === undefined) {\n throwTemporalEncodeFailure('TAA resolve pipeline is ready before frame encoding');\n }\n pass.setPipeline(pipeline);\n pass.setBindGroup(1, bindGroup.value);\n pass.draw(3, 1, 0, 0);\n stageTemporalGpuSubmit(state);\n internal.frameState.temporalGpuState = state;\n },\n });\n return added;\n}\n\nexport function addTypedFullscreenPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n options: TypedFullscreenPassOptions,\n): Result<void, RenderGraphError> {\n return graph.addRasterPass(options.name, {\n accesses: [\n { resource: options.input.view, usage: 'sampled-read' },\n { resource: options.output.view, usage: 'color-attachment' },\n ...(options.depth === undefined\n ? []\n : [{ resource: options.depth.view, usage: 'sampled-read' as const }]),\n ...(options.additionalReads?.map((read) => ({\n resource: read.target.view,\n usage: 'sampled-read' as const,\n })) ?? []),\n ],\n colorAttachments: [\n {\n view: options.output.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n ],\n encode: ({ pass, frame, resources }) => {\n if (options.outputOnly && frame.runtime.lookupPostProcess?.(options.shader) === undefined) {\n return;\n }\n encodeFullscreenPass(frame, pass, {\n name: options.name,\n shader: options.shader,\n color: 'output',\n reads: ['input'],\n resolve: legacyResolver(resources, {\n input: options.input,\n output: options.output,\n ldrColor: options.input,\n 'scene-color': options.input,\n ...(options.depth === undefined ? {} : { 'scene-depth': options.depth }),\n ...(options.additionalReads === undefined\n ? {}\n : Object.fromEntries(options.additionalReads.map((read) => [read.key, read.target]))),\n }),\n outputFormat: options.output.format as GPUTextureFormat,\n ...(options.depth === undefined\n ? {}\n : { depthView: resolvedDepthView(frame, resources, options.depth) }),\n ...(options.rawSwapchainOutput === undefined\n ? {}\n : { rawSwapchainOutput: options.rawSwapchainOutput }),\n });\n },\n });\n}\n\nexport function addTypedCompositePostEffects(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n effects: readonly string[],\n input: RenderPipelineTarget,\n output: RenderPipelineTarget,\n depth: RenderPipelineTarget,\n size: { readonly width: number; readonly height: number },\n): Result<void, RenderGraphError> {\n let currentInput = input;\n for (let index = 0; index < effects.length; index += 1) {\n const shader = effects[index];\n if (shader === undefined) continue;\n const effectInput = currentInput;\n const scratch = createRenderPipelineTarget(graph, `post-effect-scratch-${index}`, {\n format: output.format as GPUTextureFormat,\n size: 'surface',\n });\n if (!scratch.ok) return scratch;\n const effectOutput =\n index === effects.length - 1\n ? ok(output)\n : createRenderPipelineTarget(graph, `post-effect-output-${index}`, {\n format: output.format as GPUTextureFormat,\n size: 'surface',\n });\n if (!effectOutput.ok) return effectOutput;\n const copied = graph.addCopyPass(`post-effect-copy-${index}`, {\n accesses: [\n { resource: effectInput.view, usage: 'copy-src' },\n { resource: scratch.value.view, usage: 'copy-dst' },\n ],\n encode: ({ encoder, resources }) => {\n const source = resources.texture(effectInput.texture);\n if (!source.ok) throw source.error;\n const destination = resources.texture(scratch.value.texture);\n if (!destination.ok) throw destination.error;\n encoder.copyTextureToTexture(\n { texture: source.value as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },\n { texture: destination.value as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },\n { width: size.width, height: size.height, depthOrArrayLayers: 1 },\n );\n },\n });\n if (!copied.ok) return copied;\n const effect = addTypedFullscreenPass(graph, {\n name: `post-effect-${index}`,\n shader,\n input: scratch.value,\n output: effectOutput.value,\n depth,\n });\n if (!effect.ok) return effect;\n currentInput = effectOutput.value;\n }\n return ok(undefined);\n}\n\nexport function addTypedOutputTransformPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n input: RenderPipelineTarget,\n output: RenderPipelineTarget,\n outputOnly = false,\n): Result<void, RenderGraphError> {\n return addTypedFullscreenPass(graph, {\n name: outputOnly ? 'present' : 'output-transform',\n shader: STANDARD_OUTPUT_TRANSFORM_FEATURE_ID,\n input,\n output,\n outputOnly,\n rawSwapchainOutput: outputOnly,\n });\n}\n","import type {\n GraphTextureDescriptor,\n RenderGraphBuilder,\n RenderGraphError,\n} from '@forgeax/engine-render-graph';\nimport { ok, type Result } from '@forgeax/engine-types';\nimport type { RenderPipelineFrame, RenderPipelineTarget } from '../render-pipeline';\nimport { createRenderPipelineTarget } from '../render-pipeline';\nimport { addTypedFullscreenPass, addTypedScenePass } from '../typed-render-graph-primitives';\n\nexport interface StandardTemporalDemandInput {\n readonly taa: boolean;\n readonly motionBlur: boolean;\n}\n\nexport interface StandardTemporalDemand {\n readonly consumerIds: readonly ('taa' | 'motion-blur')[];\n readonly targetCount: 0 | 1;\n readonly producerPassCount: 0 | 1;\n readonly historyCount: 0 | 1;\n}\n\nexport interface StandardTemporalDemandDescription {\n readonly consumerCount: number;\n readonly targetCount: 0 | 1;\n readonly producerPassCount: 0 | 1;\n readonly historyCount: 0 | 1;\n readonly byteLength: 0 | 1;\n}\n\n/** Aggregate all temporal consumers before any graph resource is allocated. */\nexport function aggregateTemporalDemand(\n input: StandardTemporalDemandInput,\n): StandardTemporalDemand {\n const consumerIds = [\n ...(input.taa ? (['taa'] as const) : []),\n ...(input.motionBlur ? (['motion-blur'] as const) : []),\n ];\n const requested = consumerIds.length > 0;\n return Object.freeze({\n consumerIds: Object.freeze(consumerIds),\n targetCount: requested ? 1 : 0,\n producerPassCount: requested ? 1 : 0,\n historyCount: input.taa ? 1 : 0,\n });\n}\n\nexport function describeTemporalDemand(\n demand: StandardTemporalDemand,\n): StandardTemporalDemandDescription {\n return {\n consumerCount: demand.consumerIds.length,\n targetCount: demand.targetCount,\n producerPassCount: demand.producerPassCount,\n historyCount: demand.historyCount,\n byteLength: demand.targetCount,\n };\n}\n\nexport type StandardTemporalLane = 'direct' | 'clustered' | 'cpu-webgl2' | 'rhi-null';\n\nexport type StandardTemporalLaneAdmission =\n | {\n readonly status: 'available';\n readonly schema: typeof import('./scene-data').SCENE_DATA_TEMPORAL_V1_SCHEMA;\n readonly producerId: 'forgeax::standard::scene-data';\n readonly structuralOnly: boolean;\n readonly format: 'rgba16float';\n }\n | {\n readonly status: 'unavailable';\n readonly reason: 'capability-missing' | 'producer-missing' | 'no-demand';\n readonly format?: never;\n };\n\nexport function standardTemporalLaneAdmission(input: {\n readonly lane: StandardTemporalLane;\n readonly demand: StandardTemporalDemand;\n readonly capabilities: {\n readonly compute: boolean;\n readonly storageBuffer: boolean;\n readonly rgba16floatRenderable: boolean;\n readonly filterable?: boolean;\n readonly copy?: boolean;\n readonly readback?: boolean;\n readonly producerPresent?: boolean;\n };\n}): StandardTemporalLaneAdmission {\n if (input.demand.targetCount === 0) return { status: 'unavailable', reason: 'no-demand' };\n if (input.capabilities.producerPresent === false)\n return { status: 'unavailable', reason: 'producer-missing' };\n if (\n !input.capabilities.rgba16floatRenderable ||\n input.capabilities.filterable === false ||\n input.capabilities.copy === false ||\n input.capabilities.readback === false\n ) {\n return { status: 'unavailable', reason: 'capability-missing' };\n }\n return {\n status: 'available',\n schema: 'forgeax::scene-data::temporal-v1',\n producerId: 'forgeax::standard::scene-data',\n structuralOnly: input.lane === 'rhi-null',\n format: 'rgba16float',\n };\n}\n\nexport function standardTemporalPostOrder(input: {\n readonly taa: boolean;\n readonly motionBlur: boolean;\n readonly bloom: boolean;\n}): readonly string[] {\n const order = ['scene'];\n if (input.taa || input.motionBlur) order.push('standard-scene-data');\n if (input.taa) order.push('taa-resolve');\n if (input.motionBlur) order.push('motion-blur');\n if (input.bloom) order.push('bloom', 'tone');\n order.push('output');\n return Object.freeze(order);\n}\n\nexport interface StandardSceneDataTargets {\n readonly temporal: RenderPipelineTarget;\n}\n\nconst TEMPORAL_TARGET: GraphTextureDescriptor = {\n format: 'rgba16float',\n size: 'surface',\n sampleCount: 1,\n};\n\n/** The single Standard TAA current-frame producer target. */\nexport function createStandardSceneDataTarget(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n): Result<StandardSceneDataTargets, RenderGraphError> {\n const temporal = createRenderPipelineTarget(graph, 'standard-scene-temporal', TEMPORAL_TARGET);\n return temporal.ok ? ok({ temporal: temporal.value }) : temporal;\n}\n\nexport function addStandardSceneDataPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n target: RenderPipelineTarget,\n depth: RenderPipelineTarget,\n): Result<void, RenderGraphError> {\n return addTypedScenePass(graph, {\n name: 'standard-scene-data',\n color: target,\n depth,\n selector: { LightMode: ['Deferred', 'Forward'] },\n passKind: 'temporal',\n // The temporal producer re-rasterizes the current scene after the main\n // color pass has populated depth. Its output is a semantic motion target;\n // it must cover the same fragments even when TAA jitter moves the raster\n // edge by a subpixel, while the loaded scene depth remains the consumer's\n // depth-rejection source for Motion Blur/TAA.\n clearColor: [0, 0, -1, 1],\n colorLoadOp: 'clear',\n depthLoadOp: 'load',\n });\n}\n\nexport function addTaaResolvePass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n current: RenderPipelineTarget,\n currentTemporal: RenderPipelineTarget,\n previousColor: RenderPipelineTarget,\n previousTemporal: RenderPipelineTarget,\n output: RenderPipelineTarget,\n): Result<void, RenderGraphError> {\n return addTypedFullscreenPass(graph, {\n name: 'taa-resolve',\n shader: 'forgeax.taa-resolve',\n input: current,\n output,\n additionalReads: [\n { key: 'scene-temporal', target: currentTemporal },\n { key: 'taa-history-color', target: previousColor },\n { key: 'taa-history-temporal', target: previousTemporal },\n ],\n });\n}\n"]}
|