@babylonjs/lite 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/index.js +457 -458
  2. package/dist/index.js.map +1 -1
  3. package/index.d.ts +107 -48
  4. package/lib/camera/geospatial-camera-controls.js +22 -0
  5. package/lib/camera/geospatial-camera-controls.js.map +1 -1
  6. package/lib/camera/geospatial-camera-fly.js +2 -1
  7. package/lib/camera/geospatial-camera-fly.js.map +1 -1
  8. package/lib/effect/effect-renderer.js +1 -1
  9. package/lib/effect/effect-renderer.js.map +1 -1
  10. package/lib/engine/engine.js +1 -1
  11. package/lib/frame-graph/depth-resolve-task.js +117 -0
  12. package/lib/frame-graph/depth-resolve-task.js.map +1 -0
  13. package/lib/frame-graph/transmission.js +4 -3
  14. package/lib/frame-graph/transmission.js.map +1 -1
  15. package/lib/index.js +5 -1
  16. package/lib/index.js.map +1 -1
  17. package/lib/material/shader/shader-material.js +4 -2
  18. package/lib/material/shader/shader-material.js.map +1 -1
  19. package/lib/material/shader/shader-pipeline.js +10 -0
  20. package/lib/material/shader/shader-pipeline.js.map +1 -1
  21. package/lib/material/shader/shader-renderable.js +19 -6
  22. package/lib/material/shader/shader-renderable.js.map +1 -1
  23. package/lib/material/shader/shader-thin-instance.js +1 -1
  24. package/lib/material/shader/shader-thin-instance.js.map +1 -1
  25. package/lib/post-process/taa.js +193 -0
  26. package/lib/post-process/taa.js.map +1 -0
  27. package/lib/scene/scene-core.js +5 -2
  28. package/lib/scene/scene-core.js.map +1 -1
  29. package/lib/shadow/csm-shadow-task-hooks.js +14 -6
  30. package/lib/shadow/csm-shadow-task-hooks.js.map +1 -1
  31. package/lib/shadow/pcf-shadow-task-hooks.js +6 -0
  32. package/lib/shadow/pcf-shadow-task-hooks.js.map +1 -1
  33. package/lib/sprite/billboard-custom-shader.js +32 -32
  34. package/lib/sprite/billboard-custom-shader.js.map +1 -1
  35. package/lib/sprite/billboard-pipeline.js +54 -56
  36. package/lib/sprite/billboard-pipeline.js.map +1 -1
  37. package/lib/sprite/custom-shader-core.js +1 -1
  38. package/lib/sprite/custom-shader-core.js.map +1 -1
  39. package/lib/sprite/shared/sprite-atlas.js +2 -2
  40. package/lib/sprite/shared/sprite-atlas.js.map +1 -1
  41. package/lib/sprite/sprite-2d-coverage-gamma.js +58 -0
  42. package/lib/sprite/sprite-2d-coverage-gamma.js.map +1 -0
  43. package/lib/sprite/sprite-2d-uvscroll.js +39 -0
  44. package/lib/sprite/sprite-2d-uvscroll.js.map +1 -0
  45. package/lib/sprite/sprite-2d.js +6 -40
  46. package/lib/sprite/sprite-2d.js.map +1 -1
  47. package/lib/sprite/sprite-coverage-gamma-hook.js +10 -0
  48. package/lib/sprite/sprite-coverage-gamma-hook.js.map +1 -0
  49. package/lib/sprite/sprite-custom-shader.js +2 -2
  50. package/lib/sprite/sprite-custom-shader.js.map +1 -1
  51. package/lib/sprite/sprite-pipeline.js +56 -71
  52. package/lib/sprite/sprite-pipeline.js.map +1 -1
  53. package/lib/sprite/sprite-renderable.js +5 -5
  54. package/lib/sprite/sprite-renderable.js.map +1 -1
  55. package/lib/sprite/sprite-renderer.js +4 -4
  56. package/lib/sprite/sprite-renderer.js.map +1 -1
  57. package/lib/sprite/sprite-scene.js +1 -1
  58. package/lib/sprite/sprite-scene.js.map +1 -1
  59. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"geospatial-camera-fly.js","sources":["../../../src/camera/geospatial-camera-fly.ts"],"sourcesContent":["import type { GeospatialCamera } from \"./geospatial-camera.js\";\nimport { normalizeRadians } from \"./geospatial-camera.js\";\nimport type { SceneContext } from \"./../scene/scene-core.js\";\nimport type { Vec3 } from \"../math/types.js\";\n\n/** Options for {@link flyGeospatialCameraToAsync}. Omitted target fields keep their current value. */\nexport interface GeospatialFlyOptions {\n /** Target yaw (radians). Shortest angular path is taken. */\n yaw?: number;\n /** Target pitch (radians). */\n pitch?: number;\n /** Target radius. */\n radius?: number;\n /** Target centre (ECEF). Animated along a great-circle (slerp). */\n center?: Vec3;\n /** Flight duration in ms. Default 1000. */\n durationMs?: number;\n /** Parabolic \"hop\" height scale for the centre animation (0 = none). */\n centerHopScale?: number;\n}\n\n/** Cubic ease-in-out (matches Babylon.js `CubicEase` with `EASINGMODE_EASEINOUT`). */\nfunction easeInOut(g: number): number {\n if (g >= 0.5) {\n const f = 2 * (1 - g);\n return (1 - f * f * f) * 0.5 + 0.5;\n }\n const f = 2 * g;\n return f * f * f * 0.5;\n}\n\n/** Spherical interpolation of two ECEF positions (great-circle direction + lerped magnitude). */\nfunction slerpEcef(a: Vec3, b: Vec3, t: number, out: Vec3): void {\n const la = Math.hypot(a.x, a.y, a.z) || 1;\n const lb = Math.hypot(b.x, b.y, b.z) || 1;\n const ax = a.x / la;\n const ay = a.y / la;\n const az = a.z / la;\n const bx = b.x / lb;\n const by = b.y / lb;\n const bz = b.z / lb;\n let dot = ax * bx + ay * by + az * bz;\n dot = dot < -1 ? -1 : dot > 1 ? 1 : dot;\n const theta = Math.acos(dot) * t;\n // rel = normalize(b - a*dot)\n let rx = bx - ax * dot;\n let ry = by - ay * dot;\n let rz = bz - az * dot;\n const rlen = Math.hypot(rx, ry, rz);\n if (rlen > 1e-9) {\n rx /= rlen;\n ry /= rlen;\n rz /= rlen;\n }\n const ct = Math.cos(theta);\n const st = Math.sin(theta);\n const len = la + (lb - la) * t;\n out.x = (ax * ct + rx * st) * len;\n out.y = (ay * ct + ry * st) * len;\n out.z = (az * ct + rz * st) * len;\n}\n\n/**\n * Smoothly animate a {@link GeospatialCamera} to new yaw/pitch/radius/centre over\n * `durationMs`, driven by the scene's render loop. Yaw takes the shortest angular\n * path; the centre follows a great-circle (with an optional parabolic hop).\n *\n * The returned promise resolves when the flight completes; it also resolves early\n * if the flight is interrupted (by user input through `attachGeospatialControls`,\n * or by a subsequent `flyGeospatialCameraToAsync` call). Only one flight runs at a time.\n */\nexport function flyGeospatialCameraToAsync(camera: GeospatialCamera, scene: SceneContext, options: GeospatialFlyOptions): Promise<void> {\n // Interrupt any in-flight animation.\n camera._cancelFly?.();\n\n const duration = Math.max(1, options.durationMs ?? 1000);\n const hopScale = options.centerHopScale ?? 0;\n\n const yaw0 = camera.yaw;\n const pitch0 = camera.pitch;\n const radius0 = camera.radius;\n const center0: Vec3 = { x: camera.center.x, y: camera.center.y, z: camera.center.z };\n\n const targetYaw = options.yaw !== undefined ? yaw0 + normalizeRadians(normalizeRadians(options.yaw) - yaw0) : yaw0;\n const targetPitch = options.pitch !== undefined ? normalizeRadians(options.pitch) : pitch0;\n const targetRadius = options.radius ?? radius0;\n const animateCenter = options.center !== undefined;\n const targetCenter: Vec3 = animateCenter ? { x: options.center!.x, y: options.center!.y, z: options.center!.z } : center0;\n const startToEndDist = Math.hypot(targetCenter.x - center0.x, targetCenter.y - center0.y, targetCenter.z - center0.z);\n\n const centerScratch: Vec3 = { x: 0, y: 0, z: 0 };\n let elapsed = 0;\n\n return new Promise<void>((resolve) => {\n const driver = (deltaMs: number): void => {\n elapsed += deltaMs > 0 ? deltaMs : 1000 / 60;\n const g = Math.min(1, elapsed / duration);\n const e = easeInOut(g);\n\n const yaw = yaw0 + (targetYaw - yaw0) * e;\n const pitch = pitch0 + (targetPitch - pitch0) * e;\n const radius = radius0 + (targetRadius - radius0) * e;\n\n let center: Vec3 = center0;\n if (animateCenter) {\n slerpEcef(center0, targetCenter, e, centerScratch);\n if (hopScale > 0) {\n const hopPeak = hopScale * startToEndDist;\n const hop = hopPeak * Math.max(0, (e * e - e) / -0.25);\n const clen = Math.hypot(centerScratch.x, centerScratch.y, centerScratch.z) || 1;\n const k = 1 + hop / clen;\n centerScratch.x *= k;\n centerScratch.y *= k;\n centerScratch.z *= k;\n }\n center = centerScratch;\n }\n\n camera._setOrientation(yaw, pitch, radius, center);\n\n if (g >= 1) {\n finish();\n }\n };\n\n function finish(): void {\n const idx = scene._beforeRender.indexOf(driver);\n if (idx >= 0) {\n scene._beforeRender.splice(idx, 1);\n }\n if (camera._cancelFly === finish) {\n camera._cancelFly = undefined;\n }\n resolve();\n }\n\n camera._cancelFly = finish;\n scene._beforeRender.push(driver);\n });\n}\n"],"names":["f"],"mappings":"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"}
1
+ {"version":3,"file":"geospatial-camera-fly.js","sources":["../../../src/camera/geospatial-camera-fly.ts"],"sourcesContent":["import type { GeospatialCamera } from \"./geospatial-camera.js\";\nimport { normalizeRadians } from \"./geospatial-camera.js\";\nimport type { SceneContext } from \"./../scene/scene-core.js\";\nimport type { Vec3 } from \"../math/types.js\";\n\n/** Options for {@link flyGeospatialCameraToAsync}. Omitted target fields keep their current value. */\nexport interface GeospatialFlyOptions {\n /** Target yaw (radians). Shortest angular path is taken. */\n yaw?: number;\n /** Target pitch (radians). */\n pitch?: number;\n /** Target radius. */\n radius?: number;\n /** Target centre (ECEF). Animated along a great-circle (slerp). */\n center?: Vec3;\n /** Flight duration in ms. Default 1000. */\n durationMs?: number;\n /** Parabolic \"hop\" height scale for the centre animation (0 = none). */\n centerHopScale?: number;\n /** Easing applied to the normalized progress `g` ∈ [0,1]. Default cubic ease-in-out. */\n ease?: (g: number) => number;\n}\n\n/** Cubic ease-in-out (matches Babylon.js `CubicEase` with `EASINGMODE_EASEINOUT`). */\nfunction easeInOut(g: number): number {\n if (g >= 0.5) {\n const f = 2 * (1 - g);\n return (1 - f * f * f) * 0.5 + 0.5;\n }\n const f = 2 * g;\n return f * f * f * 0.5;\n}\n\n/** Spherical interpolation of two ECEF positions (great-circle direction + lerped magnitude). */\nfunction slerpEcef(a: Vec3, b: Vec3, t: number, out: Vec3): void {\n const la = Math.hypot(a.x, a.y, a.z) || 1;\n const lb = Math.hypot(b.x, b.y, b.z) || 1;\n const ax = a.x / la;\n const ay = a.y / la;\n const az = a.z / la;\n const bx = b.x / lb;\n const by = b.y / lb;\n const bz = b.z / lb;\n let dot = ax * bx + ay * by + az * bz;\n dot = dot < -1 ? -1 : dot > 1 ? 1 : dot;\n const theta = Math.acos(dot) * t;\n // rel = normalize(b - a*dot)\n let rx = bx - ax * dot;\n let ry = by - ay * dot;\n let rz = bz - az * dot;\n const rlen = Math.hypot(rx, ry, rz);\n if (rlen > 1e-9) {\n rx /= rlen;\n ry /= rlen;\n rz /= rlen;\n }\n const ct = Math.cos(theta);\n const st = Math.sin(theta);\n const len = la + (lb - la) * t;\n out.x = (ax * ct + rx * st) * len;\n out.y = (ay * ct + ry * st) * len;\n out.z = (az * ct + rz * st) * len;\n}\n\n/**\n * Smoothly animate a {@link GeospatialCamera} to new yaw/pitch/radius/centre over\n * `durationMs`, driven by the scene's render loop. Yaw takes the shortest angular\n * path; the centre follows a great-circle (with an optional parabolic hop).\n *\n * The returned promise resolves when the flight completes; it also resolves early\n * if the flight is interrupted (by user input through `attachGeospatialControls`,\n * or by a subsequent `flyGeospatialCameraToAsync` call). Only one flight runs at a time.\n */\nexport function flyGeospatialCameraToAsync(camera: GeospatialCamera, scene: SceneContext, options: GeospatialFlyOptions): Promise<void> {\n // Interrupt any in-flight animation.\n camera._cancelFly?.();\n\n const duration = Math.max(1, options.durationMs ?? 1000);\n const hopScale = options.centerHopScale ?? 0;\n const ease = options.ease ?? easeInOut;\n\n const yaw0 = camera.yaw;\n const pitch0 = camera.pitch;\n const radius0 = camera.radius;\n const center0: Vec3 = { x: camera.center.x, y: camera.center.y, z: camera.center.z };\n\n const targetYaw = options.yaw !== undefined ? yaw0 + normalizeRadians(normalizeRadians(options.yaw) - yaw0) : yaw0;\n const targetPitch = options.pitch !== undefined ? normalizeRadians(options.pitch) : pitch0;\n const targetRadius = options.radius ?? radius0;\n const animateCenter = options.center !== undefined;\n const targetCenter: Vec3 = animateCenter ? { x: options.center!.x, y: options.center!.y, z: options.center!.z } : center0;\n const startToEndDist = Math.hypot(targetCenter.x - center0.x, targetCenter.y - center0.y, targetCenter.z - center0.z);\n\n const centerScratch: Vec3 = { x: 0, y: 0, z: 0 };\n let elapsed = 0;\n\n return new Promise<void>((resolve) => {\n const driver = (deltaMs: number): void => {\n elapsed += deltaMs > 0 ? deltaMs : 1000 / 60;\n const g = Math.min(1, elapsed / duration);\n // Force the final frame to land exactly on the target even if the easing curve\n // does not satisfy ease(1) === 1, so the flight never resolves short of its goal.\n const e = g >= 1 ? 1 : ease(g);\n\n const yaw = yaw0 + (targetYaw - yaw0) * e;\n const pitch = pitch0 + (targetPitch - pitch0) * e;\n const radius = radius0 + (targetRadius - radius0) * e;\n\n let center: Vec3 = center0;\n if (animateCenter) {\n slerpEcef(center0, targetCenter, e, centerScratch);\n if (hopScale > 0) {\n const hopPeak = hopScale * startToEndDist;\n const hop = hopPeak * Math.max(0, (e * e - e) / -0.25);\n const clen = Math.hypot(centerScratch.x, centerScratch.y, centerScratch.z) || 1;\n const k = 1 + hop / clen;\n centerScratch.x *= k;\n centerScratch.y *= k;\n centerScratch.z *= k;\n }\n center = centerScratch;\n }\n\n camera._setOrientation(yaw, pitch, radius, center);\n\n if (g >= 1) {\n finish();\n }\n };\n\n function finish(): void {\n const idx = scene._beforeRender.indexOf(driver);\n if (idx >= 0) {\n scene._beforeRender.splice(idx, 1);\n }\n if (camera._cancelFly === finish) {\n camera._cancelFly = undefined;\n }\n resolve();\n }\n\n camera._cancelFly = finish;\n scene._beforeRender.push(driver);\n });\n}\n"],"names":["f"],"mappings":"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"}
@@ -302,7 +302,7 @@ function bindingLayoutEntry(layout) {
302
302
  return { binding: layout.binding, visibility, buffer: { type: "uniform" } };
303
303
  }
304
304
  if (layout.kind === "texture") {
305
- return { binding: layout.binding, visibility, texture: { sampleType: layout.textureSampleType ?? "float" } };
305
+ return { binding: layout.binding, visibility, texture: { sampleType: layout.textureSampleType ?? "float", viewDimension: layout.viewDimension ?? "2d" } };
306
306
  }
307
307
  return { binding: layout.binding, visibility, sampler: { type: layout.samplerType ?? "filtering" } };
308
308
  }
@@ -1 +1 @@
1
- {"version":3,"file":"effect-renderer.js","sources":["../../../src/effect/effect-renderer.ts"],"sourcesContent":["import { U8 } from \"../engine/typed-arrays.js\";\nimport { BU, SS } from \"../engine/gpu-flags.js\";\nimport { registerRenderingContext, unregisterRenderingContext } from \"../engine/engine.js\";\nimport type { EngineContext, RenderingContext } from \"../engine/engine.js\";\nimport type { SurfaceContext } from \"../engine/surface.js\";\nimport type { RenderTarget, RenderTargetSignature } from \"../engine/render-target.js\";\nimport { buildRenderTarget, createRenderTarget, disposeRenderTarget, targetSignatureKey } from \"../engine/render-target.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport type { Task } from \"../frame-graph/task.js\";\n\nconst DEFAULT_VERTEX_WGSL = `struct EffectVertexOutput{@builtin(position) position:vec4<f32>,@location(0) uv:vec2<f32>};\n@vertex fn effectFullscreenVertex(@builtin(vertex_index) vertexIndex:u32)->EffectVertexOutput{var positions=array<vec2<f32>,3>(vec2<f32>(-1.0,-1.0),vec2<f32>(3.0,-1.0),vec2<f32>(-1.0,3.0));let p=positions[vertexIndex];var out:EffectVertexOutput;out.position=vec4<f32>(p,0.0,1.0);out.uv=p*0.5+vec2<f32>(0.5,0.5);return out;}`;\n\n/** Kind of GPU binding an effect exposes: a uniform buffer, a sampled texture, or a sampler. */\nexport type EffectBindingKind = \"uniform\" | \"texture\" | \"sampler\";\n\n/** Describes a single bind-group entry (binding slot, kind, and type details) for an effect wrapper. */\nexport interface EffectBindingLayout {\n name?: string;\n binding: number;\n kind: EffectBindingKind;\n visibility?: GPUShaderStageFlags;\n uniformByteLength?: number;\n textureSampleType?: GPUTextureSampleType;\n samplerType?: GPUSamplerBindingType;\n textureBinding?: string | number;\n}\n\n/** Configuration for `createEffectWrapper`: the fullscreen fragment shader plus optional vertex shader, bindings, and blend state. */\nexport interface EffectWrapperOptions {\n name?: string;\n fragmentWGSL: string;\n vertexWGSL?: string;\n bindings?: EffectBindingLayout[];\n blend?: GPUBlendState;\n}\n\ninterface EffectUniformSlot {\n readonly layout: EffectBindingLayout;\n buffer: GPUBuffer;\n byteLength: number;\n}\n\ninterface EffectTextureSlot {\n readonly layout: EffectBindingLayout;\n texture: Texture2D | null;\n}\n\n/** A reusable fullscreen effect: owns its shader module, bind-group layout, pipelines, and uniform/texture slots. */\nexport interface EffectWrapper {\n readonly name: string;\n readonly options: EffectWrapperOptions;\n}\n\ninterface EffectWrapperInternal extends EffectWrapper {\n _engine: EngineContext;\n _shader: GPUShaderModule | null;\n _bindGroupLayout: GPUBindGroupLayout | null;\n _pipelineLayout: GPUPipelineLayout | null;\n _bindGroup: GPUBindGroup | null;\n _bindGroupDirty: boolean;\n _pipelines: Map<string, GPURenderPipeline> | null;\n _uniforms: EffectUniformSlot[];\n _textures: EffectTextureSlot[];\n}\n\n/** Configuration for `createEffectRenderTask`: the effect to draw, its render target, and optional clear state. */\nexport interface EffectRenderTaskConfig {\n name: string;\n effect: EffectWrapper;\n target: RenderTarget;\n clear?: boolean;\n clearColor?: GPUColorDict;\n}\n\n/** A frame-graph task that renders an `EffectWrapper` as a fullscreen pass into an offscreen `RenderTarget`. */\nexport interface EffectRenderTask extends Task {\n readonly name: string;\n /** @internal */\n readonly _config: EffectRenderTaskConfig;\n /** @internal */\n readonly _rt: RenderTarget;\n}\n\ninterface EffectRenderTaskInternal extends EffectRenderTask {\n _targetSignature: RenderTargetSignature;\n _renderPassDescriptor: GPURenderPassDescriptor;\n _colorAttachment: GPURenderPassColorAttachment;\n _pipeline: GPURenderPipeline | null;\n _bindGroup: GPUBindGroup | null;\n}\n\n// ─── Direct swapchain renderer (no scene / frame graph required) ─────────────\n\n/** Options for `createEffectRenderer`. */\nexport interface EffectRendererOptions {\n /** Label for GPU resources. Defaults to the effect's own name. */\n name?: string;\n /** Whether to clear the swapchain before drawing. Defaults to `true`. */\n clear?: boolean;\n /** Clear colour. Defaults to opaque black. */\n clearColor?: GPUColorDict;\n /**\n * Per-frame callback invoked just before the effect is drawn, receiving the\n * frame delta in milliseconds. Use it to update uniforms (e.g. time, animation\n * state). This is the effect-path equivalent of a scene's `onBeforeRender`.\n */\n update?: (deltaMs: number) => void;\n}\n\n/**\n * `EffectRenderer` — a fullscreen-effect `RenderingContext` that draws\n * directly to the swapchain without a `SceneContext` or frame-graph task.\n * Use `registerEffectRenderer` / `unregisterEffectRenderer` to attach it to\n * an engine, then call `startEngine` as usual.\n *\n * For offscreen render-to-texture workflows (effect result consumed by a\n * scene material) continue to use `createEffectRenderTask` inside a scene\n * frame graph.\n */\nexport interface EffectRenderer extends RenderingContext {\n readonly name: string;\n}\n\ninterface EffectRendererInternal extends EffectRenderer {\n _surface: SurfaceContext;\n _effect: EffectWrapperInternal;\n _clear: boolean;\n _rt: RenderTarget;\n _targetSignature: RenderTargetSignature;\n _renderPassDescriptor: GPURenderPassDescriptor;\n _colorAttachment: GPURenderPassColorAttachment;\n _pipeline: GPURenderPipeline | null;\n _bindGroup: GPUBindGroup | null;\n _disposed: boolean;\n}\n\n/**\n * Create an `EffectWrapper` for the given engine, allocating uniform buffers and\n * texture slots from `options.bindings`.\n * @param engine - The engine that owns the GPU resources.\n * @param options - Shader source and binding layout for the effect.\n * @returns The new effect wrapper.\n */\nexport function createEffectWrapper(engine: EngineContext, options: EffectWrapperOptions): EffectWrapper {\n const eng = engine as EngineContext;\n const wrapper: EffectWrapperInternal = {\n name: options.name ?? \"effect-wrapper\",\n options,\n _engine: eng,\n _shader: null,\n _bindGroupLayout: null,\n _pipelineLayout: null,\n _bindGroup: null,\n _bindGroupDirty: true,\n _pipelines: null,\n _uniforms: [],\n _textures: [],\n };\n createBindingSlots(wrapper);\n return wrapper;\n}\n\n/**\n * Write data into the effect's uniform buffer(s). Pass a single buffer to write the\n * wrapper's only uniform slot, or a record keyed by binding name/index to write specific slots.\n * @param wrapper - The effect wrapper to update.\n * @param data - The uniform bytes, or a map of binding key to uniform bytes.\n */\nexport function setEffectUniforms(wrapper: EffectWrapper, data: ArrayBuffer | ArrayBufferView | Record<string | number, ArrayBuffer | ArrayBufferView>): void {\n const internal = wrapper as EffectWrapperInternal;\n if (isBufferData(data)) {\n const slot = internal._uniforms[0];\n if (!slot) {\n throw new Error(\"setEffectUniforms: wrapper has no uniform binding.\");\n }\n writeUniformSlot(internal, slot, data);\n return;\n }\n for (const key of Object.keys(data)) {\n const slot = findUniformSlot(internal, key);\n if (!slot) {\n throw new Error(`setEffectUniforms: unknown uniform binding \"${key}\".`);\n }\n writeUniformSlot(internal, slot, data[key]!);\n }\n}\n\n/**\n * Bind a texture to one of the effect's texture slots, marking the bind group dirty so it is rebuilt.\n * @param wrapper - The effect wrapper to update.\n * @param bindingNameOrIndex - The texture binding's name or numeric index.\n * @param texture - The texture to bind.\n */\nexport function setEffectTexture(wrapper: EffectWrapper, bindingNameOrIndex: string | number, texture: Texture2D): void {\n const internal = wrapper as EffectWrapperInternal;\n const slot = findTextureSlot(internal, bindingNameOrIndex);\n if (!slot) {\n throw new Error(`setEffectTexture: unknown texture binding \"${String(bindingNameOrIndex)}\".`);\n }\n slot.texture = texture;\n internal._bindGroupDirty = true;\n}\n\n/**\n * Create a frame-graph task that draws an effect as a fullscreen pass into `config.target`.\n * @param config - The effect, target, and clear settings.\n * @param engine - The owning engine.\n * @param scene - Optional owning scene. Omit for scene-less standalone frame graphs.\n * @returns The render task to add to a frame graph.\n */\nexport function createEffectRenderTask(config: EffectRenderTaskConfig, engine: EngineContext, scene?: SceneContext): EffectRenderTask {\n const eng = engine as EngineContext;\n const effect = config.effect as EffectWrapperInternal;\n const rt = config.target;\n config.clearColor ??= { r: 0, g: 0, b: 0, a: 1 };\n const sampleCount = rt._descriptor.samples ?? 1;\n const targetSignature: RenderTargetSignature = {\n _colorFormat: rt._descriptor.format,\n _sampleCount: sampleCount,\n };\n const colorAttachment = { loadOp: \"clear\", storeOp: \"store\" } as GPURenderPassColorAttachment;\n const task: EffectRenderTaskInternal = {\n name: config.name,\n _config: config,\n engine: eng,\n scene,\n _passes: [],\n _rt: rt,\n _targetSignature: targetSignature,\n _renderPassDescriptor: { label: config.name, colorAttachments: [colorAttachment] },\n _colorAttachment: colorAttachment,\n _pipeline: null,\n _bindGroup: null,\n record(): void {\n buildRenderTarget(rt, eng);\n task._pipeline = getEffectPipeline(effect, task._targetSignature);\n task._bindGroup = getEffectBindGroup(effect);\n },\n execute(): number {\n const pipeline = task._pipeline;\n if (!pipeline) {\n throw new Error(`EffectRenderTask \"${task.name}\" executed before record().`);\n }\n task._bindGroup = getEffectBindGroup(effect);\n applyColorAttachmentState(task._colorAttachment, rt, undefined, task._config.clear !== false, task._config.clearColor!);\n const pass = eng._currentEncoder.beginRenderPass(task._renderPassDescriptor);\n pass.setPipeline(pipeline);\n if (task._bindGroup) {\n pass.setBindGroup(0, task._bindGroup);\n }\n pass.draw(3);\n pass.end();\n return 1;\n },\n dispose(): void {\n task._passes.length = 0;\n disposeRenderTarget(task._rt);\n task._pipeline = null;\n task._bindGroup = null;\n },\n };\n return task;\n}\n\n/** Destroy the uniform buffers and clear the cached pipelines, bind groups, and slots owned by the effect wrapper. */\nexport function disposeEffectWrapper(wrapper: EffectWrapper): void {\n const internal = wrapper as EffectWrapperInternal;\n for (const slot of internal._uniforms) {\n slot.buffer.destroy();\n }\n internal._uniforms.length = 0;\n internal._textures.length = 0;\n internal._pipelines?.clear();\n internal._pipelines = null;\n internal._shader = null;\n internal._bindGroupLayout = null;\n internal._pipelineLayout = null;\n internal._bindGroup = null;\n internal._bindGroupDirty = true;\n}\n\n/**\n * Create an `EffectRenderer` that draws `effect` as a fullscreen pass to the\n * swapchain each frame. The renderer owns a swapchain `RenderTarget` and\n * implements `RenderingContext` directly — no `SceneContext` is needed.\n *\n * Call `registerEffectRenderer` to start rendering, `unregisterEffectRenderer`\n * to pause, and `disposeEffectRenderer` to free GPU resources.\n */\nexport function createEffectRenderer(surface: SurfaceContext, effect: EffectWrapper, options?: EffectRendererOptions): EffectRenderer {\n const eng = surface.engine;\n const ew = effect as EffectWrapperInternal;\n const name = options?.name ?? effect.name;\n const clear = options?.clear !== false;\n const clearColor: GPUColorDict = options?.clearColor ?? { r: 0, g: 0, b: 0, a: 1 };\n const update = options?.update;\n\n // No MSAA → render straight into the single-sample surface scRT; MSAA →\n // render into an MSAA colour RT and resolve into the scRT at end-of-pass.\n const useMsaa = surface.msaaSamples > 1;\n const rt = useMsaa ? createRenderTarget({ lbl: `${name}-msaa`, format: surface.format, samples: surface.msaaSamples, size: surface }) : surface.scRT;\n const resolveRt = useMsaa ? surface.scRT : undefined;\n\n const targetSignature: RenderTargetSignature = {\n _colorFormat: rt._descriptor.format,\n _sampleCount: rt._descriptor.samples ?? 1,\n };\n\n const colorAttachment: GPURenderPassColorAttachment = {\n view: undefined!,\n loadOp: \"clear\",\n storeOp: \"store\",\n };\n const renderPassDescriptor: GPURenderPassDescriptor = { label: name, colorAttachments: [colorAttachment] };\n\n const er: EffectRendererInternal = {\n name,\n clearColor,\n _drawCallsPre: 0,\n _surface: surface,\n _effect: ew,\n _clear: clear,\n _rt: rt,\n _targetSignature: targetSignature,\n _renderPassDescriptor: renderPassDescriptor,\n _colorAttachment: colorAttachment,\n _pipeline: null,\n _bindGroup: null,\n _disposed: false,\n _update(): void {\n update?.(eng._currentDelta);\n },\n _record(): number {\n if (er._disposed) {\n return 0;\n }\n ensureRtCanvasSize(er._rt);\n applyColorAttachmentState(er._colorAttachment, er._rt, resolveRt, er._clear, er.clearColor);\n const encoder = er._surface.engine._currentEncoder;\n if (!encoder) {\n return 0;\n }\n const pipeline = er._pipeline;\n if (!pipeline) {\n throw new Error(`EffectRenderer \"${er.name}\" recorded before registerEffectRenderer().`);\n }\n const pass = encoder.beginRenderPass(er._renderPassDescriptor);\n pass.setPipeline(pipeline);\n if (er._bindGroup) {\n pass.setBindGroup(0, er._bindGroup);\n }\n pass.draw(3);\n pass.end();\n return 1;\n },\n _resize(): void {\n if (er._disposed) {\n return;\n }\n buildRenderTarget(er._rt, er._surface.engine);\n },\n };\n return er;\n}\n\n/** Register the effect renderer with its surface. Idempotent — a second call is a no-op. */\nexport function registerEffectRenderer(er: EffectRenderer): void {\n const internal = er as EffectRendererInternal;\n prepareEffectRenderer(internal);\n registerRenderingContext(internal._surface, er);\n}\n\n/** Unregister the effect renderer from its surface. No-op if not registered. */\nexport function unregisterEffectRenderer(er: EffectRenderer): void {\n unregisterRenderingContext((er as EffectRendererInternal)._surface, er);\n}\n\n/** Unregister and free all GPU resources owned by the renderer. */\nexport function disposeEffectRenderer(er: EffectRenderer): void {\n const internal = er as EffectRendererInternal;\n if (internal._disposed) {\n return;\n }\n unregisterEffectRenderer(er);\n disposeRenderTarget(internal._rt);\n internal._disposed = true;\n}\n\nfunction createBindingSlots(wrapper: EffectWrapperInternal): void {\n const layouts = [...(wrapper.options.bindings ?? [])].sort((a, b) => a.binding - b.binding);\n const seen = new Set<number>();\n for (const layout of layouts) {\n if (seen.has(layout.binding)) {\n throw new Error(`createEffectWrapper: duplicate binding ${layout.binding}.`);\n }\n seen.add(layout.binding);\n if (layout.kind === \"uniform\") {\n const byteLength = align4(layout.uniformByteLength ?? 16);\n const buffer = wrapper._engine._device.createBuffer({\n label: `${wrapper.name}-${layout.name ?? layout.binding}-ubo`,\n size: byteLength,\n usage: BU.UNIFORM | BU.COPY_DST,\n });\n wrapper._uniforms.push({ layout, buffer, byteLength });\n } else if (layout.kind === \"texture\") {\n wrapper._textures.push({ layout, texture: null });\n }\n }\n}\n\nfunction applyColorAttachmentState(att: GPURenderPassColorAttachment, rt: RenderTarget, resolveRt: RenderTarget | undefined, clear: boolean, clearColor: GPUColorDict): void {\n att.clearValue = clearColor;\n att.loadOp = clear ? \"clear\" : \"load\";\n // Re-read each frame so a swapchain target (used as `rt` when single-sample, or as\n // the MSAA `resolveRt`) picks up its fresh per-frame view.\n att.view = rt._colorView!;\n att.resolveTarget = resolveRt?._colorView ?? undefined;\n}\n\nfunction ensureRtCanvasSize(rt: RenderTarget): void {\n const size = rt._descriptor.size;\n if (!(\"canvas\" in size)) {\n return;\n }\n // Surface-sized RT: rebuild when the surface's canvas backing-store has resized.\n const canvas = size.canvas;\n if (rt._width === canvas.width && rt._height === canvas.height) {\n return;\n }\n buildRenderTarget(rt, size.engine);\n}\n\nfunction getEffectPipeline(wrapper: EffectWrapperInternal, targetSignature: RenderTargetSignature): GPURenderPipeline {\n const key = targetSignatureKey(targetSignature);\n if (!wrapper._pipelines) {\n wrapper._pipelines = new Map();\n }\n const hit = wrapper._pipelines.get(key);\n if (hit) {\n return hit;\n }\n const device = wrapper._engine._device;\n const pipeline = device.createRenderPipeline({\n label: `${wrapper.name}-${key}`,\n layout: getPipelineLayout(wrapper),\n vertex: { module: getShaderModule(wrapper), entryPoint: \"effectFullscreenVertex\" },\n fragment: {\n module: getShaderModule(wrapper),\n entryPoint: \"effectFragment\",\n targets: [{ format: targetSignature._colorFormat!, blend: wrapper.options.blend }],\n },\n primitive: { topology: \"triangle-list\" },\n multisample: { count: targetSignature._sampleCount },\n });\n wrapper._pipelines.set(key, pipeline);\n return pipeline;\n}\n\nfunction getShaderModule(wrapper: EffectWrapperInternal): GPUShaderModule {\n if (!wrapper._shader) {\n wrapper._shader = wrapper._engine._device.createShaderModule({\n label: wrapper.name,\n code: `${wrapper.options.vertexWGSL ?? DEFAULT_VERTEX_WGSL}\\n${wrapper.options.fragmentWGSL}`,\n });\n }\n return wrapper._shader;\n}\n\nfunction getPipelineLayout(wrapper: EffectWrapperInternal): GPUPipelineLayout {\n if (!wrapper._pipelineLayout) {\n wrapper._pipelineLayout = wrapper._engine._device.createPipelineLayout({\n label: `${wrapper.name}-pipeline-layout`,\n bindGroupLayouts: [getBindGroupLayout(wrapper)],\n });\n }\n return wrapper._pipelineLayout;\n}\n\nfunction getBindGroupLayout(wrapper: EffectWrapperInternal): GPUBindGroupLayout {\n if (!wrapper._bindGroupLayout) {\n const entries = (wrapper.options.bindings ?? [])\n .slice()\n .sort((a, b) => a.binding - b.binding)\n .map((layout) => bindingLayoutEntry(layout));\n wrapper._bindGroupLayout = wrapper._engine._device.createBindGroupLayout({\n label: `${wrapper.name}-bgl`,\n entries,\n });\n }\n return wrapper._bindGroupLayout;\n}\n\nfunction bindingLayoutEntry(layout: EffectBindingLayout): GPUBindGroupLayoutEntry {\n const visibility = layout.visibility ?? SS.FRAGMENT;\n if (layout.kind === \"uniform\") {\n return { binding: layout.binding, visibility, buffer: { type: \"uniform\" } };\n }\n if (layout.kind === \"texture\") {\n return { binding: layout.binding, visibility, texture: { sampleType: layout.textureSampleType ?? \"float\" } };\n }\n return { binding: layout.binding, visibility, sampler: { type: layout.samplerType ?? \"filtering\" } };\n}\n\nfunction getEffectBindGroup(wrapper: EffectWrapperInternal): GPUBindGroup | null {\n const bindings = wrapper.options.bindings ?? [];\n if (bindings.length === 0) {\n return null;\n }\n if (!wrapper._bindGroupDirty && wrapper._bindGroup) {\n return wrapper._bindGroup;\n }\n const entries = bindings\n .slice()\n .sort((a, b) => a.binding - b.binding)\n .map((layout) => bindGroupEntry(wrapper, layout));\n wrapper._bindGroup = wrapper._engine._device.createBindGroup({\n label: `${wrapper.name}-bg`,\n layout: getBindGroupLayout(wrapper),\n entries,\n });\n wrapper._bindGroupDirty = false;\n return wrapper._bindGroup;\n}\n\nfunction prepareEffectRenderer(er: EffectRendererInternal): void {\n er._pipeline ??= getEffectPipeline(er._effect, er._targetSignature);\n er._bindGroup = getEffectBindGroup(er._effect);\n}\n\nfunction bindGroupEntry(wrapper: EffectWrapperInternal, layout: EffectBindingLayout): GPUBindGroupEntry {\n if (layout.kind === \"uniform\") {\n const slot = findUniformSlot(wrapper, layout.binding);\n if (!slot) {\n throw new Error(`Effect \"${wrapper.name}\" missing uniform binding ${layout.binding}.`);\n }\n return { binding: layout.binding, resource: { buffer: slot.buffer, size: slot.byteLength } };\n }\n if (layout.kind === \"texture\") {\n const slot = findTextureSlot(wrapper, layout.binding);\n if (!slot?.texture) {\n throw new Error(`Effect \"${wrapper.name}\" missing texture binding ${layout.binding}.`);\n }\n return { binding: layout.binding, resource: slot.texture.view };\n }\n const textureSlot = layout.textureBinding != null ? findTextureSlot(wrapper, layout.textureBinding) : wrapper._textures[0];\n if (!textureSlot?.texture) {\n throw new Error(`Effect \"${wrapper.name}\" missing texture for sampler binding ${layout.binding}.`);\n }\n return { binding: layout.binding, resource: textureSlot.texture.sampler };\n}\n\nfunction findUniformSlot(wrapper: EffectWrapperInternal, bindingNameOrIndex: string | number): EffectUniformSlot | undefined {\n return wrapper._uniforms.find((slot) => matchesBinding(slot.layout, bindingNameOrIndex));\n}\n\nfunction findTextureSlot(wrapper: EffectWrapperInternal, bindingNameOrIndex: string | number): EffectTextureSlot | undefined {\n return wrapper._textures.find((slot) => matchesBinding(slot.layout, bindingNameOrIndex));\n}\n\nfunction matchesBinding(layout: EffectBindingLayout, bindingNameOrIndex: string | number): boolean {\n if (typeof bindingNameOrIndex === \"number\") {\n return layout.binding === bindingNameOrIndex;\n }\n return layout.name === bindingNameOrIndex || String(layout.binding) === bindingNameOrIndex;\n}\n\nfunction writeUniformSlot(wrapper: EffectWrapperInternal, slot: EffectUniformSlot, data: ArrayBuffer | ArrayBufferView): void {\n const bytes = toBytes(data);\n if (bytes.byteLength > slot.byteLength) {\n throw new Error(`writeUniformSlot: ${bytes.byteLength} bytes exceeds uniform binding ${slot.layout.binding} size ${slot.byteLength}.`);\n }\n wrapper._engine._device.queue.writeBuffer(slot.buffer, 0, bytes.buffer, bytes.byteOffset, bytes.byteLength);\n}\n\nfunction toBytes(data: ArrayBuffer | ArrayBufferView): Uint8Array {\n if (data instanceof ArrayBuffer) {\n return new U8(data);\n }\n return new U8(data.buffer, data.byteOffset, data.byteLength);\n}\n\nfunction isBufferData(data: ArrayBuffer | ArrayBufferView | Record<string | number, ArrayBuffer | ArrayBufferView>): data is ArrayBuffer | ArrayBufferView {\n return data instanceof ArrayBuffer || ArrayBuffer.isView(data);\n}\n\nfunction align4(value: number): number {\n return (value + 3) & ~3;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"effect-renderer.js","sources":["../../../src/effect/effect-renderer.ts"],"sourcesContent":["import { U8 } from \"../engine/typed-arrays.js\";\nimport { BU, SS } from \"../engine/gpu-flags.js\";\nimport { registerRenderingContext, unregisterRenderingContext } from \"../engine/engine.js\";\nimport type { EngineContext, RenderingContext } from \"../engine/engine.js\";\nimport type { SurfaceContext } from \"../engine/surface.js\";\nimport type { RenderTarget, RenderTargetSignature } from \"../engine/render-target.js\";\nimport { buildRenderTarget, createRenderTarget, disposeRenderTarget, targetSignatureKey } from \"../engine/render-target.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport type { Task } from \"../frame-graph/task.js\";\n\nconst DEFAULT_VERTEX_WGSL = `struct EffectVertexOutput{@builtin(position) position:vec4<f32>,@location(0) uv:vec2<f32>};\n@vertex fn effectFullscreenVertex(@builtin(vertex_index) vertexIndex:u32)->EffectVertexOutput{var positions=array<vec2<f32>,3>(vec2<f32>(-1.0,-1.0),vec2<f32>(3.0,-1.0),vec2<f32>(-1.0,3.0));let p=positions[vertexIndex];var out:EffectVertexOutput;out.position=vec4<f32>(p,0.0,1.0);out.uv=p*0.5+vec2<f32>(0.5,0.5);return out;}`;\n\n/** Kind of GPU binding an effect exposes: a uniform buffer, a sampled texture, or a sampler. */\nexport type EffectBindingKind = \"uniform\" | \"texture\" | \"sampler\";\n\n/** Describes a single bind-group entry (binding slot, kind, and type details) for an effect wrapper. */\nexport interface EffectBindingLayout {\n name?: string;\n binding: number;\n kind: EffectBindingKind;\n visibility?: GPUShaderStageFlags;\n uniformByteLength?: number;\n textureSampleType?: GPUTextureSampleType;\n /** Texture view dimension for a `texture` binding (default `\"2d\"`). Set `\"2d-array\"`/`\"cube\"`/… so a\n * fullscreen effect can sample an array/cube texture (e.g. the CSM cascade depth array). */\n viewDimension?: GPUTextureViewDimension;\n samplerType?: GPUSamplerBindingType;\n textureBinding?: string | number;\n}\n\n/** Configuration for `createEffectWrapper`: the fullscreen fragment shader plus optional vertex shader, bindings, and blend state. */\nexport interface EffectWrapperOptions {\n name?: string;\n fragmentWGSL: string;\n vertexWGSL?: string;\n bindings?: EffectBindingLayout[];\n blend?: GPUBlendState;\n}\n\ninterface EffectUniformSlot {\n readonly layout: EffectBindingLayout;\n buffer: GPUBuffer;\n byteLength: number;\n}\n\ninterface EffectTextureSlot {\n readonly layout: EffectBindingLayout;\n texture: Texture2D | null;\n}\n\n/** A reusable fullscreen effect: owns its shader module, bind-group layout, pipelines, and uniform/texture slots. */\nexport interface EffectWrapper {\n readonly name: string;\n readonly options: EffectWrapperOptions;\n}\n\ninterface EffectWrapperInternal extends EffectWrapper {\n _engine: EngineContext;\n _shader: GPUShaderModule | null;\n _bindGroupLayout: GPUBindGroupLayout | null;\n _pipelineLayout: GPUPipelineLayout | null;\n _bindGroup: GPUBindGroup | null;\n _bindGroupDirty: boolean;\n _pipelines: Map<string, GPURenderPipeline> | null;\n _uniforms: EffectUniformSlot[];\n _textures: EffectTextureSlot[];\n}\n\n/** Configuration for `createEffectRenderTask`: the effect to draw, its render target, and optional clear state. */\nexport interface EffectRenderTaskConfig {\n name: string;\n effect: EffectWrapper;\n target: RenderTarget;\n clear?: boolean;\n clearColor?: GPUColorDict;\n}\n\n/** A frame-graph task that renders an `EffectWrapper` as a fullscreen pass into an offscreen `RenderTarget`. */\nexport interface EffectRenderTask extends Task {\n readonly name: string;\n /** @internal */\n readonly _config: EffectRenderTaskConfig;\n /** @internal */\n readonly _rt: RenderTarget;\n}\n\ninterface EffectRenderTaskInternal extends EffectRenderTask {\n _targetSignature: RenderTargetSignature;\n _renderPassDescriptor: GPURenderPassDescriptor;\n _colorAttachment: GPURenderPassColorAttachment;\n _pipeline: GPURenderPipeline | null;\n _bindGroup: GPUBindGroup | null;\n}\n\n// ─── Direct swapchain renderer (no scene / frame graph required) ─────────────\n\n/** Options for `createEffectRenderer`. */\nexport interface EffectRendererOptions {\n /** Label for GPU resources. Defaults to the effect's own name. */\n name?: string;\n /** Whether to clear the swapchain before drawing. Defaults to `true`. */\n clear?: boolean;\n /** Clear colour. Defaults to opaque black. */\n clearColor?: GPUColorDict;\n /**\n * Per-frame callback invoked just before the effect is drawn, receiving the\n * frame delta in milliseconds. Use it to update uniforms (e.g. time, animation\n * state). This is the effect-path equivalent of a scene's `onBeforeRender`.\n */\n update?: (deltaMs: number) => void;\n}\n\n/**\n * `EffectRenderer` — a fullscreen-effect `RenderingContext` that draws\n * directly to the swapchain without a `SceneContext` or frame-graph task.\n * Use `registerEffectRenderer` / `unregisterEffectRenderer` to attach it to\n * an engine, then call `startEngine` as usual.\n *\n * For offscreen render-to-texture workflows (effect result consumed by a\n * scene material) continue to use `createEffectRenderTask` inside a scene\n * frame graph.\n */\nexport interface EffectRenderer extends RenderingContext {\n readonly name: string;\n}\n\ninterface EffectRendererInternal extends EffectRenderer {\n _surface: SurfaceContext;\n _effect: EffectWrapperInternal;\n _clear: boolean;\n _rt: RenderTarget;\n _targetSignature: RenderTargetSignature;\n _renderPassDescriptor: GPURenderPassDescriptor;\n _colorAttachment: GPURenderPassColorAttachment;\n _pipeline: GPURenderPipeline | null;\n _bindGroup: GPUBindGroup | null;\n _disposed: boolean;\n}\n\n/**\n * Create an `EffectWrapper` for the given engine, allocating uniform buffers and\n * texture slots from `options.bindings`.\n * @param engine - The engine that owns the GPU resources.\n * @param options - Shader source and binding layout for the effect.\n * @returns The new effect wrapper.\n */\nexport function createEffectWrapper(engine: EngineContext, options: EffectWrapperOptions): EffectWrapper {\n const eng = engine as EngineContext;\n const wrapper: EffectWrapperInternal = {\n name: options.name ?? \"effect-wrapper\",\n options,\n _engine: eng,\n _shader: null,\n _bindGroupLayout: null,\n _pipelineLayout: null,\n _bindGroup: null,\n _bindGroupDirty: true,\n _pipelines: null,\n _uniforms: [],\n _textures: [],\n };\n createBindingSlots(wrapper);\n return wrapper;\n}\n\n/**\n * Write data into the effect's uniform buffer(s). Pass a single buffer to write the\n * wrapper's only uniform slot, or a record keyed by binding name/index to write specific slots.\n * @param wrapper - The effect wrapper to update.\n * @param data - The uniform bytes, or a map of binding key to uniform bytes.\n */\nexport function setEffectUniforms(wrapper: EffectWrapper, data: ArrayBuffer | ArrayBufferView | Record<string | number, ArrayBuffer | ArrayBufferView>): void {\n const internal = wrapper as EffectWrapperInternal;\n if (isBufferData(data)) {\n const slot = internal._uniforms[0];\n if (!slot) {\n throw new Error(\"setEffectUniforms: wrapper has no uniform binding.\");\n }\n writeUniformSlot(internal, slot, data);\n return;\n }\n for (const key of Object.keys(data)) {\n const slot = findUniformSlot(internal, key);\n if (!slot) {\n throw new Error(`setEffectUniforms: unknown uniform binding \"${key}\".`);\n }\n writeUniformSlot(internal, slot, data[key]!);\n }\n}\n\n/**\n * Bind a texture to one of the effect's texture slots, marking the bind group dirty so it is rebuilt.\n * @param wrapper - The effect wrapper to update.\n * @param bindingNameOrIndex - The texture binding's name or numeric index.\n * @param texture - The texture to bind.\n */\nexport function setEffectTexture(wrapper: EffectWrapper, bindingNameOrIndex: string | number, texture: Texture2D): void {\n const internal = wrapper as EffectWrapperInternal;\n const slot = findTextureSlot(internal, bindingNameOrIndex);\n if (!slot) {\n throw new Error(`setEffectTexture: unknown texture binding \"${String(bindingNameOrIndex)}\".`);\n }\n slot.texture = texture;\n internal._bindGroupDirty = true;\n}\n\n/**\n * Create a frame-graph task that draws an effect as a fullscreen pass into `config.target`.\n * @param config - The effect, target, and clear settings.\n * @param engine - The owning engine.\n * @param scene - Optional owning scene. Omit for scene-less standalone frame graphs.\n * @returns The render task to add to a frame graph.\n */\nexport function createEffectRenderTask(config: EffectRenderTaskConfig, engine: EngineContext, scene?: SceneContext): EffectRenderTask {\n const eng = engine as EngineContext;\n const effect = config.effect as EffectWrapperInternal;\n const rt = config.target;\n config.clearColor ??= { r: 0, g: 0, b: 0, a: 1 };\n const sampleCount = rt._descriptor.samples ?? 1;\n const targetSignature: RenderTargetSignature = {\n _colorFormat: rt._descriptor.format,\n _sampleCount: sampleCount,\n };\n const colorAttachment = { loadOp: \"clear\", storeOp: \"store\" } as GPURenderPassColorAttachment;\n const task: EffectRenderTaskInternal = {\n name: config.name,\n _config: config,\n engine: eng,\n scene,\n _passes: [],\n _rt: rt,\n _targetSignature: targetSignature,\n _renderPassDescriptor: { label: config.name, colorAttachments: [colorAttachment] },\n _colorAttachment: colorAttachment,\n _pipeline: null,\n _bindGroup: null,\n record(): void {\n buildRenderTarget(rt, eng);\n task._pipeline = getEffectPipeline(effect, task._targetSignature);\n task._bindGroup = getEffectBindGroup(effect);\n },\n execute(): number {\n const pipeline = task._pipeline;\n if (!pipeline) {\n throw new Error(`EffectRenderTask \"${task.name}\" executed before record().`);\n }\n task._bindGroup = getEffectBindGroup(effect);\n applyColorAttachmentState(task._colorAttachment, rt, undefined, task._config.clear !== false, task._config.clearColor!);\n const pass = eng._currentEncoder.beginRenderPass(task._renderPassDescriptor);\n pass.setPipeline(pipeline);\n if (task._bindGroup) {\n pass.setBindGroup(0, task._bindGroup);\n }\n pass.draw(3);\n pass.end();\n return 1;\n },\n dispose(): void {\n task._passes.length = 0;\n disposeRenderTarget(task._rt);\n task._pipeline = null;\n task._bindGroup = null;\n },\n };\n return task;\n}\n\n/** Destroy the uniform buffers and clear the cached pipelines, bind groups, and slots owned by the effect wrapper. */\nexport function disposeEffectWrapper(wrapper: EffectWrapper): void {\n const internal = wrapper as EffectWrapperInternal;\n for (const slot of internal._uniforms) {\n slot.buffer.destroy();\n }\n internal._uniforms.length = 0;\n internal._textures.length = 0;\n internal._pipelines?.clear();\n internal._pipelines = null;\n internal._shader = null;\n internal._bindGroupLayout = null;\n internal._pipelineLayout = null;\n internal._bindGroup = null;\n internal._bindGroupDirty = true;\n}\n\n/**\n * Create an `EffectRenderer` that draws `effect` as a fullscreen pass to the\n * swapchain each frame. The renderer owns a swapchain `RenderTarget` and\n * implements `RenderingContext` directly — no `SceneContext` is needed.\n *\n * Call `registerEffectRenderer` to start rendering, `unregisterEffectRenderer`\n * to pause, and `disposeEffectRenderer` to free GPU resources.\n */\nexport function createEffectRenderer(surface: SurfaceContext, effect: EffectWrapper, options?: EffectRendererOptions): EffectRenderer {\n const eng = surface.engine;\n const ew = effect as EffectWrapperInternal;\n const name = options?.name ?? effect.name;\n const clear = options?.clear !== false;\n const clearColor: GPUColorDict = options?.clearColor ?? { r: 0, g: 0, b: 0, a: 1 };\n const update = options?.update;\n\n // No MSAA → render straight into the single-sample surface scRT; MSAA →\n // render into an MSAA colour RT and resolve into the scRT at end-of-pass.\n const useMsaa = surface.msaaSamples > 1;\n const rt = useMsaa ? createRenderTarget({ lbl: `${name}-msaa`, format: surface.format, samples: surface.msaaSamples, size: surface }) : surface.scRT;\n const resolveRt = useMsaa ? surface.scRT : undefined;\n\n const targetSignature: RenderTargetSignature = {\n _colorFormat: rt._descriptor.format,\n _sampleCount: rt._descriptor.samples ?? 1,\n };\n\n const colorAttachment: GPURenderPassColorAttachment = {\n view: undefined!,\n loadOp: \"clear\",\n storeOp: \"store\",\n };\n const renderPassDescriptor: GPURenderPassDescriptor = { label: name, colorAttachments: [colorAttachment] };\n\n const er: EffectRendererInternal = {\n name,\n clearColor,\n _drawCallsPre: 0,\n _surface: surface,\n _effect: ew,\n _clear: clear,\n _rt: rt,\n _targetSignature: targetSignature,\n _renderPassDescriptor: renderPassDescriptor,\n _colorAttachment: colorAttachment,\n _pipeline: null,\n _bindGroup: null,\n _disposed: false,\n _update(): void {\n update?.(eng._currentDelta);\n },\n _record(): number {\n if (er._disposed) {\n return 0;\n }\n ensureRtCanvasSize(er._rt);\n applyColorAttachmentState(er._colorAttachment, er._rt, resolveRt, er._clear, er.clearColor);\n const encoder = er._surface.engine._currentEncoder;\n if (!encoder) {\n return 0;\n }\n const pipeline = er._pipeline;\n if (!pipeline) {\n throw new Error(`EffectRenderer \"${er.name}\" recorded before registerEffectRenderer().`);\n }\n const pass = encoder.beginRenderPass(er._renderPassDescriptor);\n pass.setPipeline(pipeline);\n if (er._bindGroup) {\n pass.setBindGroup(0, er._bindGroup);\n }\n pass.draw(3);\n pass.end();\n return 1;\n },\n _resize(): void {\n if (er._disposed) {\n return;\n }\n buildRenderTarget(er._rt, er._surface.engine);\n },\n };\n return er;\n}\n\n/** Register the effect renderer with its surface. Idempotent — a second call is a no-op. */\nexport function registerEffectRenderer(er: EffectRenderer): void {\n const internal = er as EffectRendererInternal;\n prepareEffectRenderer(internal);\n registerRenderingContext(internal._surface, er);\n}\n\n/** Unregister the effect renderer from its surface. No-op if not registered. */\nexport function unregisterEffectRenderer(er: EffectRenderer): void {\n unregisterRenderingContext((er as EffectRendererInternal)._surface, er);\n}\n\n/** Unregister and free all GPU resources owned by the renderer. */\nexport function disposeEffectRenderer(er: EffectRenderer): void {\n const internal = er as EffectRendererInternal;\n if (internal._disposed) {\n return;\n }\n unregisterEffectRenderer(er);\n disposeRenderTarget(internal._rt);\n internal._disposed = true;\n}\n\nfunction createBindingSlots(wrapper: EffectWrapperInternal): void {\n const layouts = [...(wrapper.options.bindings ?? [])].sort((a, b) => a.binding - b.binding);\n const seen = new Set<number>();\n for (const layout of layouts) {\n if (seen.has(layout.binding)) {\n throw new Error(`createEffectWrapper: duplicate binding ${layout.binding}.`);\n }\n seen.add(layout.binding);\n if (layout.kind === \"uniform\") {\n const byteLength = align4(layout.uniformByteLength ?? 16);\n const buffer = wrapper._engine._device.createBuffer({\n label: `${wrapper.name}-${layout.name ?? layout.binding}-ubo`,\n size: byteLength,\n usage: BU.UNIFORM | BU.COPY_DST,\n });\n wrapper._uniforms.push({ layout, buffer, byteLength });\n } else if (layout.kind === \"texture\") {\n wrapper._textures.push({ layout, texture: null });\n }\n }\n}\n\nfunction applyColorAttachmentState(att: GPURenderPassColorAttachment, rt: RenderTarget, resolveRt: RenderTarget | undefined, clear: boolean, clearColor: GPUColorDict): void {\n att.clearValue = clearColor;\n att.loadOp = clear ? \"clear\" : \"load\";\n // Re-read each frame so a swapchain target (used as `rt` when single-sample, or as\n // the MSAA `resolveRt`) picks up its fresh per-frame view.\n att.view = rt._colorView!;\n att.resolveTarget = resolveRt?._colorView ?? undefined;\n}\n\nfunction ensureRtCanvasSize(rt: RenderTarget): void {\n const size = rt._descriptor.size;\n if (!(\"canvas\" in size)) {\n return;\n }\n // Surface-sized RT: rebuild when the surface's canvas backing-store has resized.\n const canvas = size.canvas;\n if (rt._width === canvas.width && rt._height === canvas.height) {\n return;\n }\n buildRenderTarget(rt, size.engine);\n}\n\nfunction getEffectPipeline(wrapper: EffectWrapperInternal, targetSignature: RenderTargetSignature): GPURenderPipeline {\n const key = targetSignatureKey(targetSignature);\n if (!wrapper._pipelines) {\n wrapper._pipelines = new Map();\n }\n const hit = wrapper._pipelines.get(key);\n if (hit) {\n return hit;\n }\n const device = wrapper._engine._device;\n const pipeline = device.createRenderPipeline({\n label: `${wrapper.name}-${key}`,\n layout: getPipelineLayout(wrapper),\n vertex: { module: getShaderModule(wrapper), entryPoint: \"effectFullscreenVertex\" },\n fragment: {\n module: getShaderModule(wrapper),\n entryPoint: \"effectFragment\",\n targets: [{ format: targetSignature._colorFormat!, blend: wrapper.options.blend }],\n },\n primitive: { topology: \"triangle-list\" },\n multisample: { count: targetSignature._sampleCount },\n });\n wrapper._pipelines.set(key, pipeline);\n return pipeline;\n}\n\nfunction getShaderModule(wrapper: EffectWrapperInternal): GPUShaderModule {\n if (!wrapper._shader) {\n wrapper._shader = wrapper._engine._device.createShaderModule({\n label: wrapper.name,\n code: `${wrapper.options.vertexWGSL ?? DEFAULT_VERTEX_WGSL}\\n${wrapper.options.fragmentWGSL}`,\n });\n }\n return wrapper._shader;\n}\n\nfunction getPipelineLayout(wrapper: EffectWrapperInternal): GPUPipelineLayout {\n if (!wrapper._pipelineLayout) {\n wrapper._pipelineLayout = wrapper._engine._device.createPipelineLayout({\n label: `${wrapper.name}-pipeline-layout`,\n bindGroupLayouts: [getBindGroupLayout(wrapper)],\n });\n }\n return wrapper._pipelineLayout;\n}\n\nfunction getBindGroupLayout(wrapper: EffectWrapperInternal): GPUBindGroupLayout {\n if (!wrapper._bindGroupLayout) {\n const entries = (wrapper.options.bindings ?? [])\n .slice()\n .sort((a, b) => a.binding - b.binding)\n .map((layout) => bindingLayoutEntry(layout));\n wrapper._bindGroupLayout = wrapper._engine._device.createBindGroupLayout({\n label: `${wrapper.name}-bgl`,\n entries,\n });\n }\n return wrapper._bindGroupLayout;\n}\n\nfunction bindingLayoutEntry(layout: EffectBindingLayout): GPUBindGroupLayoutEntry {\n const visibility = layout.visibility ?? SS.FRAGMENT;\n if (layout.kind === \"uniform\") {\n return { binding: layout.binding, visibility, buffer: { type: \"uniform\" } };\n }\n if (layout.kind === \"texture\") {\n return { binding: layout.binding, visibility, texture: { sampleType: layout.textureSampleType ?? \"float\", viewDimension: layout.viewDimension ?? \"2d\" } };\n }\n return { binding: layout.binding, visibility, sampler: { type: layout.samplerType ?? \"filtering\" } };\n}\n\nfunction getEffectBindGroup(wrapper: EffectWrapperInternal): GPUBindGroup | null {\n const bindings = wrapper.options.bindings ?? [];\n if (bindings.length === 0) {\n return null;\n }\n if (!wrapper._bindGroupDirty && wrapper._bindGroup) {\n return wrapper._bindGroup;\n }\n const entries = bindings\n .slice()\n .sort((a, b) => a.binding - b.binding)\n .map((layout) => bindGroupEntry(wrapper, layout));\n wrapper._bindGroup = wrapper._engine._device.createBindGroup({\n label: `${wrapper.name}-bg`,\n layout: getBindGroupLayout(wrapper),\n entries,\n });\n wrapper._bindGroupDirty = false;\n return wrapper._bindGroup;\n}\n\nfunction prepareEffectRenderer(er: EffectRendererInternal): void {\n er._pipeline ??= getEffectPipeline(er._effect, er._targetSignature);\n er._bindGroup = getEffectBindGroup(er._effect);\n}\n\nfunction bindGroupEntry(wrapper: EffectWrapperInternal, layout: EffectBindingLayout): GPUBindGroupEntry {\n if (layout.kind === \"uniform\") {\n const slot = findUniformSlot(wrapper, layout.binding);\n if (!slot) {\n throw new Error(`Effect \"${wrapper.name}\" missing uniform binding ${layout.binding}.`);\n }\n return { binding: layout.binding, resource: { buffer: slot.buffer, size: slot.byteLength } };\n }\n if (layout.kind === \"texture\") {\n const slot = findTextureSlot(wrapper, layout.binding);\n if (!slot?.texture) {\n throw new Error(`Effect \"${wrapper.name}\" missing texture binding ${layout.binding}.`);\n }\n return { binding: layout.binding, resource: slot.texture.view };\n }\n const textureSlot = layout.textureBinding != null ? findTextureSlot(wrapper, layout.textureBinding) : wrapper._textures[0];\n if (!textureSlot?.texture) {\n throw new Error(`Effect \"${wrapper.name}\" missing texture for sampler binding ${layout.binding}.`);\n }\n return { binding: layout.binding, resource: textureSlot.texture.sampler };\n}\n\nfunction findUniformSlot(wrapper: EffectWrapperInternal, bindingNameOrIndex: string | number): EffectUniformSlot | undefined {\n return wrapper._uniforms.find((slot) => matchesBinding(slot.layout, bindingNameOrIndex));\n}\n\nfunction findTextureSlot(wrapper: EffectWrapperInternal, bindingNameOrIndex: string | number): EffectTextureSlot | undefined {\n return wrapper._textures.find((slot) => matchesBinding(slot.layout, bindingNameOrIndex));\n}\n\nfunction matchesBinding(layout: EffectBindingLayout, bindingNameOrIndex: string | number): boolean {\n if (typeof bindingNameOrIndex === \"number\") {\n return layout.binding === bindingNameOrIndex;\n }\n return layout.name === bindingNameOrIndex || String(layout.binding) === bindingNameOrIndex;\n}\n\nfunction writeUniformSlot(wrapper: EffectWrapperInternal, slot: EffectUniformSlot, data: ArrayBuffer | ArrayBufferView): void {\n const bytes = toBytes(data);\n if (bytes.byteLength > slot.byteLength) {\n throw new Error(`writeUniformSlot: ${bytes.byteLength} bytes exceeds uniform binding ${slot.layout.binding} size ${slot.byteLength}.`);\n }\n wrapper._engine._device.queue.writeBuffer(slot.buffer, 0, bytes.buffer, bytes.byteOffset, bytes.byteLength);\n}\n\nfunction toBytes(data: ArrayBuffer | ArrayBufferView): Uint8Array {\n if (data instanceof ArrayBuffer) {\n return new U8(data);\n }\n return new U8(data.buffer, data.byteOffset, data.byteLength);\n}\n\nfunction isBufferData(data: ArrayBuffer | ArrayBufferView | Record<string | number, ArrayBuffer | ArrayBufferView>): data is ArrayBuffer | ArrayBufferView {\n return data instanceof ArrayBuffer || ArrayBuffer.isView(data);\n}\n\nfunction align4(value: number): number {\n return (value + 3) & ~3;\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { _setHpmAllocator } from '../math/_matrix-allocator.js';
2
2
  import { isDomCanvas, _buildSurface, resizeSurface, _refreshScRT, setSurfaceSize } from './surface.js';
3
3
 
4
- const VERSION = /* @__PURE__ */ (() => "1.5.0" )();
4
+ const VERSION = /* @__PURE__ */ (() => "1.7.0" )();
5
5
  let _vis = 0;
6
6
  function bumpVisibilityEpoch() {
7
7
  _vis = _vis + 1 | 0;
@@ -0,0 +1,117 @@
1
+ import { SS } from '../engine/gpu-flags.js';
2
+ import { buildRenderTarget } from '../engine/render-target.js';
3
+
4
+ const VERTEX_WGSL = `struct V{@builtin(position)p:vec4f};
5
+ @vertex fn vs(@builtin(vertex_index)i:u32)->V{
6
+ var pos=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3));
7
+ return V(vec4f(pos[i],0,1));}`;
8
+ const FRAGMENT_WGSL = `@group(0)@binding(0)var src:texture_depth_multisampled_2d;
9
+ @fragment fn fs(v:V)->@builtin(frag_depth)f32{return textureLoad(src,vec2i(v.p.xy),0);}`;
10
+ let _cacheDevice = null;
11
+ let _bgl = null;
12
+ let _pipelines = null;
13
+ function getOrCreatePipeline(engine, depthFormat) {
14
+ const device = engine._device;
15
+ if (_cacheDevice !== device) {
16
+ _cacheDevice = device;
17
+ _bgl = null;
18
+ _pipelines = /* @__PURE__ */ new Map();
19
+ }
20
+ const cached = _pipelines.get(depthFormat);
21
+ if (cached) {
22
+ return cached;
23
+ }
24
+ _bgl ??= device.createBindGroupLayout({
25
+ label: "depth-resolve-bgl",
26
+ entries: [{ binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: "depth", multisampled: true } }]
27
+ });
28
+ const module = device.createShaderModule({ code: `${VERTEX_WGSL}
29
+ ${FRAGMENT_WGSL}`, label: "depth-resolve" });
30
+ const pipeline = device.createRenderPipeline({
31
+ label: `depth-resolve-${depthFormat}`,
32
+ layout: device.createPipelineLayout({ label: "depth-resolve-layout", bindGroupLayouts: [_bgl] }),
33
+ vertex: { module, entryPoint: "vs" },
34
+ fragment: { module, entryPoint: "fs", targets: [] },
35
+ // depth-only: no colour target
36
+ primitive: { topology: "triangle-list" },
37
+ depthStencil: { format: depthFormat, depthWriteEnabled: true, depthCompare: "always" }
38
+ });
39
+ _pipelines.set(depthFormat, pipeline);
40
+ return pipeline;
41
+ }
42
+ function createDepthResolveTask(config, engine, scene) {
43
+ const eng = engine;
44
+ const depthAttachment = {
45
+ view: void 0,
46
+ depthClearValue: 0,
47
+ // every fragment overwrites it (depthCompare "always"), so the clear value is moot
48
+ depthLoadOp: "clear",
49
+ depthStoreOp: "store"
50
+ };
51
+ const renderPassDescriptor = {
52
+ label: config.name ?? "depth-resolve",
53
+ colorAttachments: [],
54
+ depthStencilAttachment: depthAttachment
55
+ };
56
+ let pipeline = null;
57
+ let bindGroup = null;
58
+ let boundSrc = null;
59
+ let boundDst = null;
60
+ const build = () => {
61
+ const source = config.sourceTexture;
62
+ const target = config.targetTexture;
63
+ if (!source._depthTexture) {
64
+ throw new Error(`DepthResolveTask "${config.name}": sourceTexture has no depth attachment.`);
65
+ }
66
+ if ((source._descriptor.samples ?? 1) < 2) {
67
+ throw new Error(`DepthResolveTask "${config.name}": sourceTexture must be multisampled (sampleCount > 1).`);
68
+ }
69
+ if (!target._depthTexture || target._width !== (source._width || 0) || target._height !== (source._height || 0)) {
70
+ buildRenderTarget(target, eng);
71
+ if (target._width !== source._width || target._height !== source._height) {
72
+ throw new Error(
73
+ `DepthResolveTask "${config.name}": targetTexture size ${target._width}×${target._height} must match sourceTexture size ${source._width}×${source._height} (size the target's descriptor like the source, e.g. both \`size: surface\`).`
74
+ );
75
+ }
76
+ }
77
+ const depthFormat = target._descriptor.dFormat;
78
+ if (!depthFormat) {
79
+ throw new Error(`DepthResolveTask "${config.name}": targetTexture has no depth format.`);
80
+ }
81
+ pipeline = getOrCreatePipeline(eng, depthFormat);
82
+ const srcView = source._depthTexture.createView({ aspect: "depth-only" });
83
+ bindGroup = eng._device.createBindGroup({ label: `${config.name ?? "depth-resolve"}-bg`, layout: _bgl, entries: [{ binding: 0, resource: srcView }] });
84
+ depthAttachment.view = target._depthView;
85
+ boundSrc = source._depthTexture;
86
+ boundDst = target._depthTexture;
87
+ };
88
+ return {
89
+ name: config.name ?? "depth-resolve",
90
+ engine: eng,
91
+ scene,
92
+ _passes: [],
93
+ record() {
94
+ build();
95
+ },
96
+ execute() {
97
+ if (config.sourceTexture._depthTexture !== boundSrc || config.targetTexture._depthTexture !== boundDst) {
98
+ build();
99
+ }
100
+ const pass = eng._currentEncoder.beginRenderPass(renderPassDescriptor);
101
+ pass.setPipeline(pipeline);
102
+ pass.setBindGroup(0, bindGroup);
103
+ pass.draw(3);
104
+ pass.end();
105
+ return 1;
106
+ },
107
+ dispose() {
108
+ pipeline = null;
109
+ bindGroup = null;
110
+ boundSrc = null;
111
+ boundDst = null;
112
+ }
113
+ };
114
+ }
115
+
116
+ export { createDepthResolveTask };
117
+ //# sourceMappingURL=depth-resolve-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"depth-resolve-task.js","sources":["../../../src/frame-graph/depth-resolve-task.ts"],"sourcesContent":["/**\n * DepthResolveTask — resolve a multisampled depth attachment into a single-sample depth texture.\n *\n * A multisampled depth texture can't be bound to a normal shader (no sampler/textureSample path), so any pass\n * that SAMPLES the scene depth (a screen-space shadow stabiliser, screen-space contact shadows, SSAO — all of\n * which reconstruct world position from depth) breaks once the scene renders to an MSAA target. This task\n * bridges that: a full-screen triangle reads sample 0 of the source `texture_depth_multisampled_2d` and writes\n * it to `@builtin(frag_depth)` through a depth-only render pass (no colour attachment) targeting a single-sample\n * destination depth.\n *\n * Sample 0 (not an average) is deliberate — depth is non-linear, so averaging samples is meaningless; sample 0\n * is a real surface depth at each pixel, which is exactly what depth-reconstruction consumers need. Modelled on\n * copy-to-texture-task's raw-pipeline pattern (cached pipeline + bind-group layout per device).\n */\n\nimport { SS } from \"../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { RenderTarget } from \"../engine/render-target.js\";\nimport { buildRenderTarget } from \"../engine/render-target.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\nimport type { Task } from \"./task.js\";\n\n/** Options for a depth-resolve frame-graph task. */\nexport interface DepthResolveTaskConfig {\n name?: string;\n /** Multisampled source render target whose DEPTH attachment is resolved (must have sampleCount \\> 1). */\n sourceTexture: RenderTarget;\n /** Single-sample destination render target whose DEPTH attachment receives the resolved depth. */\n targetTexture: RenderTarget;\n}\n\nconst VERTEX_WGSL = `struct V{@builtin(position)p:vec4f};\n@vertex fn vs(@builtin(vertex_index)i:u32)->V{\nvar pos=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3));\nreturn V(vec4f(pos[i],0,1));}`;\nconst FRAGMENT_WGSL = `@group(0)@binding(0)var src:texture_depth_multisampled_2d;\n@fragment fn fs(v:V)->@builtin(frag_depth)f32{return textureLoad(src,vec2i(v.p.xy),0);}`;\n\n// Per-device cache (keyed by GPUDevice identity), lazily built on first use so scenes that never resolve depth\n// pay nothing.\nlet _cacheDevice: GPUDevice | null = null;\nlet _bgl: GPUBindGroupLayout | null = null;\nlet _pipelines: Map<GPUTextureFormat, GPURenderPipeline> | null = null;\n\nfunction getOrCreatePipeline(engine: EngineContext, depthFormat: GPUTextureFormat): GPURenderPipeline {\n const device = engine._device;\n if (_cacheDevice !== device) {\n _cacheDevice = device;\n _bgl = null;\n _pipelines = new Map();\n }\n const cached = _pipelines!.get(depthFormat);\n if (cached) {\n return cached;\n }\n _bgl ??= device.createBindGroupLayout({\n label: \"depth-resolve-bgl\",\n entries: [{ binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: \"depth\", multisampled: true } }],\n });\n const module = device.createShaderModule({ code: `${VERTEX_WGSL}\\n${FRAGMENT_WGSL}`, label: \"depth-resolve\" });\n const pipeline = device.createRenderPipeline({\n label: `depth-resolve-${depthFormat}`,\n layout: device.createPipelineLayout({ label: \"depth-resolve-layout\", bindGroupLayouts: [_bgl] }),\n vertex: { module, entryPoint: \"vs\" },\n fragment: { module, entryPoint: \"fs\", targets: [] }, // depth-only: no colour target\n primitive: { topology: \"triangle-list\" },\n depthStencil: { format: depthFormat, depthWriteEnabled: true, depthCompare: \"always\" },\n });\n _pipelines!.set(depthFormat, pipeline);\n return pipeline;\n}\n\n/** Create a frame-graph task that resolves `sourceTexture`'s multisampled depth into `targetTexture`'s\n * single-sample depth. Add it AFTER the source render task and BEFORE any depth-sampling consumer. */\nexport function createDepthResolveTask(config: DepthResolveTaskConfig, engine: EngineContext, scene: SceneContext): Task {\n const eng = engine;\n const depthAttachment: GPURenderPassDepthStencilAttachment = {\n view: undefined!,\n depthClearValue: 0, // every fragment overwrites it (depthCompare \"always\"), so the clear value is moot\n depthLoadOp: \"clear\",\n depthStoreOp: \"store\",\n };\n const renderPassDescriptor: GPURenderPassDescriptor = {\n label: config.name ?? \"depth-resolve\",\n colorAttachments: [],\n depthStencilAttachment: depthAttachment,\n };\n let pipeline: GPURenderPipeline | null = null;\n let bindGroup: GPUBindGroup | null = null;\n let boundSrc: GPUTexture | null = null;\n let boundDst: GPUTexture | null = null;\n\n // (Re)build the pipeline, bind group and depth-attachment view from the live RT textures. Run at record()\n // and again whenever a resize reallocates either texture (checked in execute, mirroring the DoF getters).\n const build = (): void => {\n const source = config.sourceTexture;\n const target = config.targetTexture;\n if (!source._depthTexture) {\n throw new Error(`DepthResolveTask \"${config.name}\": sourceTexture has no depth attachment.`);\n }\n if ((source._descriptor.samples ?? 1) < 2) {\n throw new Error(`DepthResolveTask \"${config.name}\": sourceTexture must be multisampled (sampleCount > 1).`);\n }\n if (!target._depthTexture || target._width !== (source._width || 0) || target._height !== (source._height || 0)) {\n // Build (or REBUILD) the offscreen destination so it tracks the source size. No render task owns this\n // target, so the frame graph never resizes it on its own — without this, a window resize leaves the\n // resolved depth stuck at the OLD size, and every depth-reconstruction consumer (SSCS, SSAO, the\n // shadow-TAA stabiliser) then samples a mismatched-size depth → screen-space streaks until reload.\n buildRenderTarget(target, eng);\n // buildRenderTarget sizes the target from its OWN descriptor (resolveSize), not the source. The whole\n // point of this task is a 1:1 depth copy, so the target descriptor MUST resolve to the source size\n // (e.g. both `size: surface`). Fail fast on a mismatch instead of silently thrashing — otherwise this\n // branch's condition would stay true and rebuild/destroy the target on every build() call.\n if (target._width !== source._width || target._height !== source._height) {\n throw new Error(\n `DepthResolveTask \"${config.name}\": targetTexture size ${target._width}×${target._height} must match ` +\n `sourceTexture size ${source._width}×${source._height} (size the target's descriptor like the source, e.g. both \\`size: surface\\`).`\n );\n }\n }\n const depthFormat = target._descriptor.dFormat;\n if (!depthFormat) {\n throw new Error(`DepthResolveTask \"${config.name}\": targetTexture has no depth format.`);\n }\n pipeline = getOrCreatePipeline(eng, depthFormat);\n // A DEPTH-aspect view of the MSAA source: a depth-stencil texture must be bound through its depth aspect\n // to read as texture_depth_multisampled_2d.\n const srcView = source._depthTexture.createView({ aspect: \"depth-only\" });\n bindGroup = eng._device.createBindGroup({ label: `${config.name ?? \"depth-resolve\"}-bg`, layout: _bgl!, entries: [{ binding: 0, resource: srcView }] });\n depthAttachment.view = target._depthView!;\n boundSrc = source._depthTexture;\n boundDst = target._depthTexture;\n };\n\n return {\n name: config.name ?? \"depth-resolve\",\n engine: eng,\n scene,\n _passes: [],\n record(): void {\n build();\n },\n execute(): number {\n if (config.sourceTexture._depthTexture !== boundSrc || config.targetTexture._depthTexture !== boundDst) {\n build(); // a resize reallocated the MSAA depth and/or the resolve target — rebind to the new textures\n }\n const pass = eng._currentEncoder.beginRenderPass(renderPassDescriptor);\n pass.setPipeline(pipeline!);\n pass.setBindGroup(0, bindGroup!);\n pass.draw(3);\n pass.end();\n return 1;\n },\n dispose(): void {\n pipeline = null;\n bindGroup = null;\n boundSrc = null;\n boundDst = null;\n },\n };\n}\n"],"names":[],"mappings":"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"}
@@ -202,7 +202,8 @@ function disposeRenderTaskTransmission(state) {
202
202
  function executePassWithTransmission(task, engine, state, sampleCount) {
203
203
  state._copies = 0;
204
204
  const transparent = task._transparentBindings;
205
- let pass = beginTaskPass(task, null, sampleCount, false);
205
+ const resolveView = sampleCount > 1 ? task._config.rst?._colorView ?? null : null;
206
+ let pass = beginTaskPass(task, resolveView, sampleCount, false);
206
207
  let draws = drawBaseTask(task, pass);
207
208
  let lastPipeline = null;
208
209
  let overlay = null;
@@ -216,7 +217,7 @@ function executePassWithTransmission(task, engine, state, sampleCount) {
216
217
  if (transmissive && canUpdateTransmission(state)) {
217
218
  pass.end();
218
219
  updateTransmissionTexture(state, engine);
219
- pass = beginTaskPass(task, null, sampleCount, true);
220
+ pass = beginTaskPass(task, resolveView, sampleCount, true);
220
221
  setPassState(task, pass);
221
222
  lastPipeline = null;
222
223
  }
@@ -337,7 +338,7 @@ function beginTaskPass(task, resolveTarget, sampleCount, load) {
337
338
  }
338
339
  }
339
340
  if (sampleCount > 1) {
340
- att.resolveTarget = void 0;
341
+ att.resolveTarget = resolveTarget ?? void 0;
341
342
  } else {
342
343
  att.resolveTarget = void 0;
343
344
  }