@zephyr3d/scene 0.8.2 → 0.9.1

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 (241) hide show
  1. package/dist/animation/animationset.js +473 -60
  2. package/dist/animation/animationset.js.map +1 -1
  3. package/dist/animation/cloth/gpu_cloth_system.js +2516 -0
  4. package/dist/animation/cloth/gpu_cloth_system.js.map +1 -0
  5. package/dist/animation/fixed_geometry_cache_track.js +138 -0
  6. package/dist/animation/fixed_geometry_cache_track.js.map +1 -0
  7. package/dist/animation/geometry_cache_utils.js +120 -0
  8. package/dist/animation/geometry_cache_utils.js.map +1 -0
  9. package/dist/animation/ik_modifier.js +9 -1
  10. package/dist/animation/ik_modifier.js.map +1 -1
  11. package/dist/animation/joint_dynamics/collision.js +469 -0
  12. package/dist/animation/joint_dynamics/collision.js.map +1 -0
  13. package/dist/animation/joint_dynamics/constraints.js +329 -0
  14. package/dist/animation/joint_dynamics/constraints.js.map +1 -0
  15. package/dist/animation/joint_dynamics/controller.js +699 -0
  16. package/dist/animation/joint_dynamics/controller.js.map +1 -0
  17. package/dist/animation/joint_dynamics/joint_dynamics_system.js +393 -0
  18. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -0
  19. package/dist/animation/joint_dynamics/solver.js +794 -0
  20. package/dist/animation/joint_dynamics/solver.js.map +1 -0
  21. package/dist/animation/joint_dynamics/types.js +19 -0
  22. package/dist/animation/joint_dynamics/types.js.map +1 -0
  23. package/dist/animation/joint_dynamics/vrm_spring_bone.js +46 -0
  24. package/dist/animation/joint_dynamics/vrm_spring_bone.js.map +1 -0
  25. package/dist/animation/joint_dynamics_modifier.js +51 -0
  26. package/dist/animation/joint_dynamics_modifier.js.map +1 -0
  27. package/dist/animation/pca_geometry_cache_track.js +222 -0
  28. package/dist/animation/pca_geometry_cache_track.js.map +1 -0
  29. package/dist/animation/skeleton.js +2011 -139
  30. package/dist/animation/skeleton.js.map +1 -1
  31. package/dist/animation/skeleton_modifier.js +3 -5
  32. package/dist/animation/skeleton_modifier.js.map +1 -1
  33. package/dist/animation/spring/multi_chain_spring_system.js +2 -0
  34. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  35. package/dist/animation/spring/spring_chain.js +3 -2
  36. package/dist/animation/spring/spring_chain.js.map +1 -1
  37. package/dist/animation/spring/spring_collider.js +35 -5
  38. package/dist/animation/spring/spring_collider.js.map +1 -1
  39. package/dist/animation/spring/spring_particle.js +1 -0
  40. package/dist/animation/spring/spring_particle.js.map +1 -1
  41. package/dist/animation/spring/spring_system.js +325 -28
  42. package/dist/animation/spring/spring_system.js.map +1 -1
  43. package/dist/animation/spring2/collision.js +469 -0
  44. package/dist/animation/spring2/collision.js.map +1 -0
  45. package/dist/animation/spring2/constraints.js +329 -0
  46. package/dist/animation/spring2/constraints.js.map +1 -0
  47. package/dist/animation/spring2/controller.js +434 -0
  48. package/dist/animation/spring2/controller.js.map +1 -0
  49. package/dist/animation/spring2/math.js +16 -0
  50. package/dist/animation/spring2/math.js.map +1 -0
  51. package/dist/animation/spring2/solver.js +624 -0
  52. package/dist/animation/spring2/solver.js.map +1 -0
  53. package/dist/animation/spring2/spring_system.js +118 -0
  54. package/dist/animation/spring2/spring_system.js.map +1 -0
  55. package/dist/animation/spring2/types.js +19 -0
  56. package/dist/animation/spring2/types.js.map +1 -0
  57. package/dist/animation/spring_modifier.js +17 -1
  58. package/dist/animation/spring_modifier.js.map +1 -1
  59. package/dist/app/engine.js +42 -15
  60. package/dist/app/engine.js.map +1 -1
  61. package/dist/app/runtimescript.js +132 -1
  62. package/dist/app/runtimescript.js.map +1 -1
  63. package/dist/app/screen.js +3 -3
  64. package/dist/app/screen.js.map +1 -1
  65. package/dist/app/scriptingsystem.js +69 -37
  66. package/dist/app/scriptingsystem.js.map +1 -1
  67. package/dist/app/scriptregistry.js +14 -3
  68. package/dist/app/scriptregistry.js.map +1 -1
  69. package/dist/asset/assetmanager.js +2 -1
  70. package/dist/asset/assetmanager.js.map +1 -1
  71. package/dist/asset/loaders/zabc/zabc_loader.js +570 -0
  72. package/dist/asset/loaders/zabc/zabc_loader.js.map +1 -0
  73. package/dist/asset/model.js +192 -0
  74. package/dist/asset/model.js.map +1 -1
  75. package/dist/camera/base.js +26 -7
  76. package/dist/camera/base.js.map +1 -1
  77. package/dist/camera/camera.js +146 -24
  78. package/dist/camera/camera.js.map +1 -1
  79. package/dist/camera/fps.js +2 -2
  80. package/dist/camera/fps.js.map +1 -1
  81. package/dist/camera/orbit.js +2 -2
  82. package/dist/camera/orbit.js.map +1 -1
  83. package/dist/index.d.ts +11728 -8535
  84. package/dist/index.js +29 -8
  85. package/dist/index.js.map +1 -1
  86. package/dist/material/lambert.js +1 -1
  87. package/dist/material/lambert.js.map +1 -1
  88. package/dist/material/material.js +9 -3
  89. package/dist/material/material.js.map +1 -1
  90. package/dist/material/meshmaterial.js +54 -7
  91. package/dist/material/meshmaterial.js.map +1 -1
  92. package/dist/material/mixins/lightmodel/blinnphong.js +17 -7
  93. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  94. package/dist/material/mixins/lightmodel/lambert.js +7 -2
  95. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  96. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +108 -16
  97. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  98. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +209 -14
  99. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  100. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +24 -12
  101. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  102. package/dist/material/mixins/lit.js +11 -8
  103. package/dist/material/mixins/lit.js.map +1 -1
  104. package/dist/material/mixins/pbr/common.js +72 -5
  105. package/dist/material/mixins/pbr/common.js.map +1 -1
  106. package/dist/material/pbrblueprint.js +148 -1
  107. package/dist/material/pbrblueprint.js.map +1 -1
  108. package/dist/material/pbrmr.js +115 -2
  109. package/dist/material/pbrmr.js.map +1 -1
  110. package/dist/material/shader/helper.js +10 -4
  111. package/dist/material/shader/helper.js.map +1 -1
  112. package/dist/material/water.js +2 -2
  113. package/dist/material/water.js.map +1 -1
  114. package/dist/posteffect/coloradjust.js +145 -0
  115. package/dist/posteffect/coloradjust.js.map +1 -0
  116. package/dist/posteffect/taa.js +68 -32
  117. package/dist/posteffect/taa.js.map +1 -1
  118. package/dist/render/cluster_light.js +17 -12
  119. package/dist/render/cluster_light.js.map +1 -1
  120. package/dist/render/deferredlightpass.js +510 -0
  121. package/dist/render/deferredlightpass.js.map +1 -0
  122. package/dist/render/deferredshadowlightpass.js +428 -0
  123. package/dist/render/deferredshadowlightpass.js.map +1 -0
  124. package/dist/render/drawable.js.map +1 -1
  125. package/dist/render/drawable_mixin.js +21 -12
  126. package/dist/render/drawable_mixin.js.map +1 -1
  127. package/dist/render/envlight.js +20 -22
  128. package/dist/render/envlight.js.map +1 -1
  129. package/dist/render/gbufferpass.js +50 -0
  130. package/dist/render/gbufferpass.js.map +1 -0
  131. package/dist/render/lightpass.js +1 -2
  132. package/dist/render/lightpass.js.map +1 -1
  133. package/dist/render/primitive.js +1 -1
  134. package/dist/render/primitive.js.map +1 -1
  135. package/dist/render/render_queue.js +3 -2
  136. package/dist/render/render_queue.js.map +1 -1
  137. package/dist/render/renderer.js +5 -358
  138. package/dist/render/renderer.js.map +1 -1
  139. package/dist/render/rendergraph/executor.js +15 -12
  140. package/dist/render/rendergraph/executor.js.map +1 -1
  141. package/dist/render/rendergraph/forward_plus_builder.js +144 -88
  142. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  143. package/dist/render/rendergraph/history_resource_manager.js +178 -0
  144. package/dist/render/rendergraph/history_resource_manager.js.map +1 -0
  145. package/dist/render/rendergraph/rendergraph.js +12 -1
  146. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  147. package/dist/render/rendergraph/types.js +2 -2
  148. package/dist/render/rendergraph/types.js.map +1 -1
  149. package/dist/render/sky.js +26 -9
  150. package/dist/render/sky.js.map +1 -1
  151. package/dist/scene/basesprite.js +4 -3
  152. package/dist/scene/basesprite.js.map +1 -1
  153. package/dist/scene/batchgroup.js +4 -4
  154. package/dist/scene/environment.js +7 -4
  155. package/dist/scene/environment.js.map +1 -1
  156. package/dist/scene/light.js +184 -18
  157. package/dist/scene/light.js.map +1 -1
  158. package/dist/scene/mesh.js +30 -0
  159. package/dist/scene/mesh.js.map +1 -1
  160. package/dist/scene/particlesys.js +3 -2
  161. package/dist/scene/particlesys.js.map +1 -1
  162. package/dist/scene/raycast_visitor.js +29 -3
  163. package/dist/scene/raycast_visitor.js.map +1 -1
  164. package/dist/scene/scene.js +86 -19
  165. package/dist/scene/scene.js.map +1 -1
  166. package/dist/scene/scene_node.js +87 -31
  167. package/dist/scene/scene_node.js.map +1 -1
  168. package/dist/scene/script_attachment.js +59 -0
  169. package/dist/scene/script_attachment.js.map +1 -0
  170. package/dist/scene/terrain-cm/grass.js +3 -2
  171. package/dist/scene/terrain-cm/grass.js.map +1 -1
  172. package/dist/scene/terrain-cm/terrain-cm.js +4 -3
  173. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  174. package/dist/scene/water.js +3 -2
  175. package/dist/scene/water.js.map +1 -1
  176. package/dist/shaders/shadow.js +2 -2
  177. package/dist/shaders/shadow.js.map +1 -1
  178. package/dist/shadow/shadowmapper.js +74 -4
  179. package/dist/shadow/shadowmapper.js.map +1 -1
  180. package/dist/shapes/box.js +163 -0
  181. package/dist/shapes/box.js.map +1 -1
  182. package/dist/shapes/capsule.js +216 -0
  183. package/dist/shapes/capsule.js.map +1 -0
  184. package/dist/shapes/cylinder.js +91 -0
  185. package/dist/shapes/cylinder.js.map +1 -1
  186. package/dist/shapes/plane.js +32 -0
  187. package/dist/shapes/plane.js.map +1 -1
  188. package/dist/shapes/tetrahedron.js +211 -0
  189. package/dist/shapes/tetrahedron.js.map +1 -1
  190. package/dist/shapes/torus.js +173 -0
  191. package/dist/shapes/torus.js.map +1 -1
  192. package/dist/utility/blueprint/common/math.js +111 -1
  193. package/dist/utility/blueprint/common/math.js.map +1 -1
  194. package/dist/utility/blueprint/material/inputs.js +235 -1
  195. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  196. package/dist/utility/blueprint/material/ir.js +154 -10
  197. package/dist/utility/blueprint/material/ir.js.map +1 -1
  198. package/dist/utility/blueprint/material/texture.js +273 -19
  199. package/dist/utility/blueprint/material/texture.js.map +1 -1
  200. package/dist/utility/serialization/json.js +12 -2
  201. package/dist/utility/serialization/json.js.map +1 -1
  202. package/dist/utility/serialization/manager.js +30 -11
  203. package/dist/utility/serialization/manager.js.map +1 -1
  204. package/dist/utility/serialization/scene/animation.js +250 -7
  205. package/dist/utility/serialization/scene/animation.js.map +1 -1
  206. package/dist/utility/serialization/scene/batch.js +4 -2
  207. package/dist/utility/serialization/scene/batch.js.map +1 -1
  208. package/dist/utility/serialization/scene/camera.js +154 -2
  209. package/dist/utility/serialization/scene/camera.js.map +1 -1
  210. package/dist/utility/serialization/scene/cloth_script.js +834 -0
  211. package/dist/utility/serialization/scene/cloth_script.js.map +1 -0
  212. package/dist/utility/serialization/scene/common.js +7 -0
  213. package/dist/utility/serialization/scene/common.js.map +1 -1
  214. package/dist/utility/serialization/scene/light.js +120 -4
  215. package/dist/utility/serialization/scene/light.js.map +1 -1
  216. package/dist/utility/serialization/scene/material.js +453 -1
  217. package/dist/utility/serialization/scene/material.js.map +1 -1
  218. package/dist/utility/serialization/scene/mesh.js +4 -2
  219. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  220. package/dist/utility/serialization/scene/node.js +298 -10
  221. package/dist/utility/serialization/scene/node.js.map +1 -1
  222. package/dist/utility/serialization/scene/particle.js +4 -2
  223. package/dist/utility/serialization/scene/particle.js.map +1 -1
  224. package/dist/utility/serialization/scene/primitive.js +100 -3
  225. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  226. package/dist/utility/serialization/scene/scene.js +130 -3
  227. package/dist/utility/serialization/scene/scene.js.map +1 -1
  228. package/dist/utility/serialization/scene/script.js +66 -0
  229. package/dist/utility/serialization/scene/script.js.map +1 -0
  230. package/dist/utility/serialization/scene/spring_script.js +596 -0
  231. package/dist/utility/serialization/scene/spring_script.js.map +1 -0
  232. package/dist/utility/serialization/scene/sprite.js +5 -3
  233. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  234. package/dist/utility/serialization/scene/terrain.js +4 -2
  235. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  236. package/dist/utility/serialization/scene/water.js +4 -2
  237. package/dist/utility/serialization/scene/water.js.map +1 -1
  238. package/dist/utility/serialization/types.js.map +1 -1
  239. package/dist/values.js +5 -1
  240. package/dist/values.js.map +1 -1
  241. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"forward_plus_builder.js","sources":["../../../src/render/rendergraph/forward_plus_builder.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\nimport { Vector4 } from '@zephyr3d/base';\nimport type {\n BindGroup,\n ColorState,\n FrameBuffer,\n GPUProgram,\n Texture2D,\n TextureFormat\n} from '@zephyr3d/device';\nimport type { DrawContext } from '../drawable';\nimport type { RenderQueue } from '../render_queue';\nimport type { PunctualLight, Scene } from '../../scene';\nimport type { Camera } from '../../camera';\nimport { LightPass } from '../lightpass';\nimport { ShadowMapPass } from '../shadowmap_pass';\nimport { DepthPass } from '../depthpass';\nimport { ClusteredLight } from '../cluster_light';\nimport { buildHiZ } from '../hzb';\nimport { CopyBlitter } from '../../blitter';\nimport { fetchSampler } from '../../utility/misc';\nimport { MaterialVaryingFlags } from '../../values';\nimport { AbstractPostEffect, PostEffectLayer } from '../../posteffect/posteffect';\nimport { RenderGraph } from './rendergraph';\nimport type { RGHandle } from './types';\nimport { renderObjectColors } from '../gpu_picking';\nimport type { Primitive } from '../primitive';\nimport { BoxShape } from '../../shapes';\n\n// ─── Shared Pass Instances ──────────────────────────────────────────\n\nconst _scenePass = new LightPass();\nconst _depthPass = new DepthPass();\nconst _shadowMapPass = new ShadowMapPass();\nconst _clusters: ClusteredLight[] = [];\nlet _backDepthColorState: Nullable<ColorState> = null;\nlet _frontDepthColorState: Nullable<ColorState> = null;\n\nfunction getClusteredLight(): ClusteredLight {\n return _clusters.length > 0 ? _clusters.pop()! : new ClusteredLight();\n}\nfunction freeClusteredLight(cl: ClusteredLight): void {\n _clusters.push(cl);\n}\n\n// ─── Pipeline Options ───────────────────────────────────────────────\n\n/**\n * Options controlling which features are enabled in the forward+ pipeline.\n *\n * Derived from camera settings and device capabilities each frame.\n *\n * @public\n */\nexport interface ForwardPlusOptions {\n /** Enable depth prepass (always true for now). */\n depthPrepass: boolean;\n /** Enable motion vectors (requires TAA or motionBlur). */\n motionVectors: boolean;\n /** Enable Hi-Z pyramid (for SSR ray tracing). */\n hiZ: boolean;\n /** Enable screen-space reflections. */\n ssr: boolean;\n /** Whether to compute SSR thickness. */\n ssrCalcThickness: boolean;\n /** Whether GPU picking is requested this frame. */\n gpuPicking: boolean;\n /** Whether transmission/refraction materials are present. */\n needSceneColor: boolean;\n}\n\n/**\n * Derive pipeline options from the current scene/camera state.\n * @internal\n */\nexport function deriveForwardPlusOptions(\n scene: Scene,\n camera: Camera,\n deviceType: string,\n renderQueue: RenderQueue\n): ForwardPlusOptions {\n const ssr = camera.SSR && scene.env.light.envLight && scene.env.light.envLight.hasRadiance();\n return {\n depthPrepass: true,\n motionVectors: deviceType !== 'webgl' && (camera.TAA || camera.motionBlur),\n hiZ: camera.HiZ && deviceType !== 'webgl',\n ssr: !!ssr,\n ssrCalcThickness: !!ssr && camera.ssrCalcThickness,\n gpuPicking: !!camera.getPickResultResolveFunc(),\n needSceneColor: renderQueue.needSceneColor()\n };\n}\n\n// ─── Shared Frame State ─────────────────────────────────────────────\n\n/**\n * Mutable state shared between pass execute callbacks within a single frame.\n *\n * This replaces the monolithic DrawContext mutation pattern with an explicit\n * object that graph passes can read from and write to.\n *\n * @internal\n */\nexport interface FrameState {\n ctx: DrawContext;\n renderQueue: RenderQueue;\n depthFramebuffer: Nullable<FrameBuffer>;\n sunLightColor: Nullable<any>;\n options: ForwardPlusOptions;\n}\n\n// ─── Forward+ Graph Builder ─────────────────────────────────────────\n\n/**\n * Constructs a render graph representing the forward+ pipeline.\n *\n * Each step in the existing `SceneRenderer._renderScene` becomes a graph pass.\n * Execute callbacks delegate to the existing rendering code, sharing a mutable\n * {@link FrameState}.\n *\n * @param graph - The render graph to populate.\n * @param ctx - The draw context for this frame.\n * @param renderQueue - The culled render queue.\n * @param options - Pipeline feature toggles.\n * @returns The backbuffer handle (graph output).\n *\n * @public\n */\nexport function buildForwardPlusGraph(\n graph: RenderGraph,\n ctx: DrawContext,\n renderQueue: RenderQueue,\n options: ForwardPlusOptions\n): RGHandle {\n const device = ctx.device;\n const backbuffer = graph.importTexture('backbuffer');\n\n // Shared mutable frame state\n const frame: FrameState = {\n ctx,\n renderQueue,\n depthFramebuffer: null,\n sunLightColor: null,\n options\n };\n\n // ── 1. Sky Update ─────────────────────────────────────────────────\n graph.addPass('SkyUpdate', (builder) => {\n builder.sideEffect();\n builder.setExecute(() => {\n frame.sunLightColor = ctx.scene.env.sky.update(ctx);\n });\n });\n\n // ── 2. Clustered Light Setup ──────────────────────────────────────\n graph.addPass('ClusterLights', (builder) => {\n builder.sideEffect();\n builder.setExecute(() => {\n ctx.clusteredLight = getClusteredLight();\n ctx.clusteredLight.calculateLightIndex(ctx.camera, renderQueue);\n });\n });\n\n // ── 3. GPU Picking (optional, sideEffect) ─────────────────────────\n if (options.gpuPicking) {\n graph.addPass('GPUPicking', (builder) => {\n builder.sideEffect();\n builder.setExecute(() => {\n const pickResolveFunc = ctx.camera.getPickResultResolveFunc();\n if (pickResolveFunc) {\n renderObjectColors(ctx, pickResolveFunc, renderQueue);\n }\n });\n });\n }\n\n // ── 4. Shadow Maps ────────────────────────────────────────────────\n let shadowMapsHandle: RGHandle | undefined;\n if (renderQueue.shadowedLights.length > 0) {\n graph.addPass('ShadowMaps', (builder) => {\n shadowMapsHandle = builder.createTexture({ format: 'r32f', label: 'shadowMaps' });\n builder.setExecute(() => {\n renderShadowMaps(ctx, renderQueue.shadowedLights);\n });\n });\n }\n\n // ── 5. Depth Prepass ──────────────────────────────────────────────\n let depthHandle: RGHandle;\n let motionVectorHandle: RGHandle | undefined;\n\n graph.addPass('DepthPrepass', (builder) => {\n depthHandle = builder.createTexture({\n format: ctx.SSRCalcThickness\n ? device.type === 'webgl'\n ? 'rgba16f'\n : 'rg32f'\n : device.type === 'webgl'\n ? 'rgba8unorm'\n : 'r32f',\n label: 'linearDepth'\n });\n if (options.motionVectors) {\n motionVectorHandle = builder.createTexture({ format: 'rgba16f', label: 'motionVector' });\n }\n builder.setExecute(() => {\n frame.depthFramebuffer = renderSceneDepth(frame, null);\n });\n });\n\n // ── 6. Hi-Z (optional) ───────────────────────────────────────────\n let hiZHandle: RGHandle | undefined;\n if (options.hiZ) {\n graph.addPass('HiZ', (builder) => {\n builder.read(depthHandle!);\n hiZHandle = builder.createTexture({ format: 'r32f', label: 'hiZ', mipLevels: 10 });\n builder.setExecute(() => {\n // HiZ is already built inside renderSceneDepth, but we declare it\n // for graph dependency tracking. In the future this will be split out.\n });\n });\n }\n\n // ── 7. Main Light Pass ────────────────────────────────────────────\n let sceneColorHandle: RGHandle;\n graph.addPass('LightPass', (builder) => {\n builder.read(depthHandle!);\n if (shadowMapsHandle) {\n builder.read(shadowMapsHandle);\n }\n if (hiZHandle) {\n builder.read(hiZHandle);\n }\n sceneColorHandle = builder.createTexture({ format: ctx.colorFormat, label: 'sceneColor' });\n builder.setExecute(() => {\n renderMainLightPass(frame);\n });\n });\n\n // ── 8. Post Effects + Final Composite ─────────────────────────────\n graph.addPass('Composite', (builder) => {\n builder.read(sceneColorHandle!);\n if (motionVectorHandle) {\n builder.read(motionVectorHandle);\n }\n builder.write(backbuffer);\n builder.setExecute(() => {\n renderComposite(frame);\n });\n });\n\n return backbuffer;\n}\n\n// ─── Pass Implementation Helpers ────────────────────────────────────\n// These wrap the existing SceneRenderer static methods, adapted to work\n// with the FrameState pattern. They contain the same logic as the\n// original methods but read/write through FrameState.\n\n/** @internal */\nfunction renderShadowMaps(ctx: DrawContext, lights: PunctualLight[]): void {\n ctx.renderPass = _shadowMapPass;\n ctx.device.pushDeviceStates();\n for (const light of lights) {\n light.shadow.render(ctx, _shadowMapPass);\n }\n ctx.device.popDeviceStates();\n}\n\n/** @internal */\nfunction renderSceneDepth(frame: FrameState, existingDepthFb: Nullable<FrameBuffer>): FrameBuffer {\n const ctx = frame.ctx;\n const renderQueue = frame.renderQueue;\n const transmission = !!existingDepthFb;\n let depthFramebuffer = existingDepthFb;\n\n if (!depthFramebuffer) {\n const format: TextureFormat =\n ctx.device.type === 'webgl'\n ? ctx.SSRCalcThickness\n ? 'rgba16f'\n : 'rgba8unorm'\n : ctx.SSRCalcThickness\n ? 'rg32f'\n : 'r32f';\n const mvFormat: TextureFormat = 'rgba16f';\n if (!ctx.finalFramebuffer) {\n depthFramebuffer = ctx.device.pool.fetchTemporalFramebuffer(\n true,\n ctx.renderWidth,\n ctx.renderHeight,\n ctx.motionVectors ? [format, mvFormat] : format,\n ctx.depthFormat,\n false\n );\n } else {\n const originDepth = ctx.finalFramebuffer?.getDepthAttachment();\n depthFramebuffer = originDepth?.isTexture2D()\n ? ctx.device.pool.fetchTemporalFramebuffer(\n true,\n originDepth.width,\n originDepth.height,\n ctx.motionVectors ? [format, mvFormat] : format,\n originDepth,\n false\n )\n : ctx.device.pool.fetchTemporalFramebuffer(\n true,\n ctx.renderWidth,\n ctx.renderHeight,\n ctx.motionVectors ? [format, mvFormat] : format,\n ctx.depthFormat,\n false\n );\n }\n }\n\n ctx.device.pushDeviceStates();\n ctx.device.setFramebuffer(depthFramebuffer!);\n _depthPass.encodeDepth = depthFramebuffer!.getColorAttachments()[0].format === 'rgba8unorm';\n _depthPass.clearColor = transmission\n ? null\n : _depthPass.encodeDepth\n ? new Vector4(0, 0, 0, 1)\n : new Vector4(1, 1, 1, 1);\n _depthPass.clearDepth = transmission ? null : 1;\n _depthPass.clearStencil = null;\n _depthPass.transmission = transmission;\n\n if (ctx.SSRCalcThickness && !transmission) {\n if (!_backDepthColorState) {\n _backDepthColorState = ctx.device.createColorState().setColorMask(false, true, false, false);\n }\n if (!_frontDepthColorState) {\n _frontDepthColorState = ctx.device.createColorState().setColorMask(true, false, false, false);\n }\n ctx.forceColorState = _backDepthColorState;\n ctx.forceCullMode = 'front';\n _depthPass.renderBackface = true;\n _depthPass.transmission = false;\n _depthPass.render(ctx, null, null, renderQueue);\n _depthPass.clearColor = null;\n _depthPass.renderBackface = false;\n ctx.forceColorState = _frontDepthColorState;\n ctx.forceCullMode = null;\n }\n _depthPass.render(ctx, null, null, renderQueue);\n ctx.forceColorState = null;\n ctx.device.popDeviceStates();\n\n if (!transmission) {\n ctx.motionVectorTexture = ctx.motionVectors\n ? (depthFramebuffer!.getColorAttachments()[1] as Texture2D)\n : null;\n ctx.linearDepthTexture = depthFramebuffer!.getColorAttachments()[0] as Texture2D;\n ctx.depthTexture = depthFramebuffer!.getDepthAttachment() as Texture2D;\n if (ctx.motionVectorTexture) {\n // Sky motion vectors rendering is handled inline\n renderSkyMotionVectors(ctx);\n }\n if (ctx.HiZ) {\n const w = ctx.linearDepthTexture.width;\n const h = ctx.linearDepthTexture.height;\n const HiZFrameBuffer = ctx.device.pool.fetchTemporalFramebuffer(\n true,\n w,\n h,\n ctx.linearDepthTexture.format,\n null,\n true\n );\n buildHiZ(ctx.depthTexture, HiZFrameBuffer);\n ctx.HiZTexture = HiZFrameBuffer.getColorAttachments()[0] as Texture2D;\n }\n }\n return depthFramebuffer!;\n}\n\n// ─── Sky Motion Vector State ────────────────────────────────────────\n\nlet _skyMVProgram: Nullable<GPUProgram> = null;\nlet _skyMVBindGroup: Nullable<BindGroup> = null;\nlet _skyMVBox: Nullable<Primitive> = null;\n\n/** @internal */\nfunction renderSkyMotionVectors(ctx: DrawContext): void {\n if (!ctx.motionVectorTexture) {\n return;\n }\n\n const device = ctx.device;\n const fb = device.pool.fetchTemporalFramebuffer(false, 0, 0, ctx.motionVectorTexture, ctx.depthTexture);\n\n if (!_skyMVProgram) {\n _skyMVProgram = device.buildRenderProgram({\n vertex(pb) {\n this.$inputs.pos = pb.vec3().attrib('position');\n this.VPMatrix = pb.mat4().uniform(0);\n this.prevVPMatrix = pb.mat4().uniform(0);\n this.cameraPos = pb.vec3().uniform(0);\n this.prevCameraPos = pb.vec3().uniform(0);\n pb.main(function () {\n this.$l.worldPos = pb.add(this.$inputs.pos, this.cameraPos);\n this.$l.prevWorldPos = pb.add(this.$inputs.pos, this.prevCameraPos);\n this.$l.clipPos = pb.mul(this.VPMatrix, pb.vec4(this.worldPos, 1));\n this.$l.prevClipPos = pb.mul(this.prevVPMatrix, pb.vec4(this.prevWorldPos, 1));\n this.clipPos.z = this.clipPos.w;\n this.$builtins.position = this.clipPos;\n this.$outputs.currentPos = this.clipPos;\n this.$outputs.prevPos = this.prevClipPos;\n });\n },\n fragment(pb) {\n this.$outputs.color = pb.vec4();\n pb.main(function () {\n this.$l.motionVector = pb.mul(\n pb.sub(\n pb.div(this.$inputs.currentPos.xy, this.$inputs.currentPos.w),\n pb.div(this.$inputs.prevPos.xy, this.$inputs.prevPos.w)\n ),\n 0.5\n );\n this.$outputs.color = pb.vec4(this.motionVector, 0, 1);\n });\n }\n })!;\n _skyMVProgram.name = '@TAA_SkyMotionVector';\n }\n\n if (!_skyMVBindGroup) {\n _skyMVBindGroup = device.createBindGroup(_skyMVProgram.bindGroupLayouts[0]);\n }\n\n if (!_skyMVBox) {\n _skyMVBox = new BoxShape({ size: 2, needNormal: false, needUV: false });\n }\n\n _skyMVBindGroup.setValue('VPMatrix', ctx.camera.viewProjectionMatrix);\n _skyMVBindGroup.setValue('prevVPMatrix', ctx.camera.prevVPMatrix!);\n _skyMVBindGroup.setValue('cameraPos', ctx.camera.getWorldPosition());\n _skyMVBindGroup.setValue('prevCameraPos', ctx.camera.prevPosition!);\n\n device.pushDeviceStates();\n device.setProgram(_skyMVProgram);\n device.setBindGroup(0, _skyMVBindGroup);\n device.setRenderStates(AbstractPostEffect.getDefaultRenderState(ctx, 'le'));\n device.setFramebuffer(fb);\n _skyMVBox.draw();\n device.popDeviceStates();\n device.pool.releaseFrameBuffer(fb);\n}\n\n/** @internal */\nfunction renderMainLightPass(frame: FrameState): void {\n const { ctx, renderQueue } = frame;\n const device = ctx.device;\n\n if (ctx.depthTexture === ctx.finalFramebuffer?.getDepthAttachment()) {\n ctx.intermediateFramebuffer = ctx.finalFramebuffer;\n } else {\n ctx.intermediateFramebuffer = device.pool.fetchTemporalFramebuffer(\n false,\n ctx.depthTexture!.width,\n ctx.depthTexture!.height,\n ctx.colorFormat!,\n ctx.depthTexture\n );\n }\n if (ctx.intermediateFramebuffer && ctx.intermediateFramebuffer !== ctx.finalFramebuffer) {\n device.pushDeviceStates();\n device.setFramebuffer(ctx.intermediateFramebuffer);\n } else {\n device.setViewport(null);\n device.setScissor(null);\n }\n\n _scenePass.transmission = false;\n _scenePass.clearDepth = ctx.depthTexture ? null : 1;\n _scenePass.clearStencil = ctx.depthTexture ? null : 0;\n\n if (ctx.SSR && !renderQueue.needSceneColor()) {\n ctx.materialFlags |= MaterialVaryingFlags.SSR_STORE_ROUGHNESS;\n }\n\n ctx.compositor?.begin(ctx);\n\n if (renderQueue.needSceneColor()) {\n const compositor = ctx.compositor;\n ctx.compositor = null;\n const sceneColorFramebuffer = device.pool.fetchTemporalFramebuffer(\n true,\n ctx.depthTexture!.width,\n ctx.depthTexture!.height,\n ctx.materialFlags & MaterialVaryingFlags.SSR_STORE_ROUGHNESS\n ? [\n ctx.colorFormat!,\n device.getFramebuffer()!.getColorAttachments()[1]!,\n device.getFramebuffer()!.getColorAttachments()[2]!\n ]\n : ctx.colorFormat!,\n ctx.depthTexture,\n false\n );\n device.pushDeviceStates();\n device.setFramebuffer(sceneColorFramebuffer);\n _scenePass.transmission = false;\n _scenePass.render(ctx, null, null, renderQueue);\n device.popDeviceStates();\n ctx.sceneColorTexture = sceneColorFramebuffer.getColorAttachments()[0] as Texture2D;\n new CopyBlitter().blit(\n ctx.sceneColorTexture,\n device.getFramebuffer() ?? null,\n fetchSampler('clamp_nearest_nomip')\n );\n _scenePass.transmission = true;\n _scenePass.clearColor = null;\n _scenePass.clearDepth = null;\n _scenePass.clearStencil = null;\n ctx.compositor = compositor;\n }\n _scenePass.render(ctx, null, null, renderQueue);\n\n if (renderQueue.needSceneColor()) {\n renderSceneDepth(frame, frame.depthFramebuffer);\n }\n}\n\n/** @internal */\nfunction renderComposite(frame: FrameState): void {\n const { ctx, renderQueue } = frame;\n const device = ctx.device;\n\n ctx.compositor?.drawPostEffects(ctx, PostEffectLayer.end, ctx.linearDepthTexture!);\n ctx.compositor?.end(ctx);\n renderQueue.dispose();\n ctx.materialFlags &= ~MaterialVaryingFlags.SSR_STORE_ROUGHNESS;\n\n if (ctx.intermediateFramebuffer && ctx.intermediateFramebuffer !== ctx.finalFramebuffer) {\n const blitter = new CopyBlitter();\n blitter.srgbOut = !ctx.finalFramebuffer;\n const srcTex = ctx.intermediateFramebuffer.getColorAttachments()[0] as Texture2D;\n blitter.blit(srcTex, ctx.finalFramebuffer ?? null, fetchSampler('clamp_nearest_nomip'));\n device.popDeviceStates();\n device.pool.releaseFrameBuffer(ctx.intermediateFramebuffer);\n }\n\n freeClusteredLight(ctx.clusteredLight!);\n\n if (frame.sunLightColor) {\n ctx.sunLight!.color = frame.sunLightColor;\n }\n}\n\n// ─── Convenience: Execute Full Pipeline ─────────────────────────────\n\n/**\n * Build, compile, and execute the forward+ pipeline as a render graph.\n *\n * This is the drop-in replacement for `SceneRenderer._renderScene`.\n *\n * @param ctx - The draw context for this frame.\n * @public\n */\nexport function executeForwardPlusGraph(ctx: DrawContext): void {\n const device = ctx.device;\n const graph = new RenderGraph();\n\n // Cull scene first (needed to derive options)\n const renderQueue = _scenePass.cullScene(ctx, ctx.camera);\n\n const options = deriveForwardPlusOptions(ctx.scene, ctx.camera, device.type, renderQueue);\n const backbuffer = buildForwardPlusGraph(graph, ctx, renderQueue, options);\n\n const compiled = graph.compile([backbuffer]);\n graph.execute(compiled);\n}\n"],"names":["_scenePass","LightPass","_depthPass","DepthPass","_shadowMapPass","ShadowMapPass","_clusters","_backDepthColorState","_frontDepthColorState","getClusteredLight","length","pop","ClusteredLight","freeClusteredLight","cl","push","deriveForwardPlusOptions","scene","camera","deviceType","renderQueue","ssr","SSR","env","light","envLight","hasRadiance","depthPrepass","motionVectors","TAA","motionBlur","hiZ","HiZ","ssrCalcThickness","gpuPicking","getPickResultResolveFunc","needSceneColor","buildForwardPlusGraph","graph","ctx","options","device","backbuffer","importTexture","frame","depthFramebuffer","sunLightColor","addPass","builder","sideEffect","setExecute","sky","update","clusteredLight","calculateLightIndex","pickResolveFunc","renderObjectColors","shadowMapsHandle","shadowedLights","createTexture","format","label","renderShadowMaps","depthHandle","motionVectorHandle","SSRCalcThickness","type","renderSceneDepth","hiZHandle","read","mipLevels","sceneColorHandle","colorFormat","renderMainLightPass","write","renderComposite","lights","renderPass","pushDeviceStates","shadow","render","popDeviceStates","existingDepthFb","transmission","mvFormat","finalFramebuffer","pool","fetchTemporalFramebuffer","renderWidth","renderHeight","depthFormat","originDepth","getDepthAttachment","isTexture2D","width","height","setFramebuffer","encodeDepth","getColorAttachments","clearColor","Vector4","clearDepth","clearStencil","createColorState","setColorMask","forceColorState","forceCullMode","renderBackface","motionVectorTexture","linearDepthTexture","depthTexture","renderSkyMotionVectors","w","h","HiZFrameBuffer","buildHiZ","HiZTexture","_skyMVProgram","_skyMVBindGroup","_skyMVBox","fb","buildRenderProgram","vertex","pb","$inputs","pos","vec3","attrib","VPMatrix","mat4","uniform","prevVPMatrix","cameraPos","prevCameraPos","main","$l","worldPos","add","prevWorldPos","clipPos","mul","vec4","prevClipPos","z","$builtins","position","$outputs","currentPos","prevPos","fragment","color","motionVector","sub","div","xy","name","createBindGroup","bindGroupLayouts","BoxShape","size","needNormal","needUV","setValue","viewProjectionMatrix","getWorldPosition","prevPosition","setProgram","setBindGroup","setRenderStates","AbstractPostEffect","getDefaultRenderState","draw","releaseFrameBuffer","intermediateFramebuffer","setViewport","setScissor","materialFlags","MaterialVaryingFlags","SSR_STORE_ROUGHNESS","compositor","begin","sceneColorFramebuffer","getFramebuffer","sceneColorTexture","CopyBlitter","blit","fetchSampler","drawPostEffects","PostEffectLayer","end","dispose","blitter","srgbOut","srcTex","sunLight","executeForwardPlusGraph","RenderGraph","cullScene","compiled","compile","execute"],"mappings":"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"}
1
+ {"version":3,"file":"forward_plus_builder.js","sources":["../../../src/render/rendergraph/forward_plus_builder.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { Vector4 } from '@zephyr3d/base';\r\nimport type {\r\n BindGroup,\r\n ColorState,\r\n FrameBuffer,\r\n GPUProgram,\r\n Texture2D,\r\n TextureFormat\r\n} from '@zephyr3d/device';\r\nimport type { DrawContext } from '../drawable';\r\nimport type { RenderQueue } from '../render_queue';\r\nimport type { PunctualLight, Scene } from '../../scene';\r\nimport type { Camera } from '../../camera';\r\nimport { LightPass } from '../lightpass';\r\nimport { ShadowMapPass } from '../shadowmap_pass';\r\nimport { DepthPass } from '../depthpass';\r\nimport { ClusteredLight } from '../cluster_light';\r\nimport { buildHiZ } from '../hzb';\r\nimport { CopyBlitter } from '../../blitter';\r\nimport { fetchSampler } from '../../utility/misc';\r\nimport { MaterialVaryingFlags } from '../../values';\r\nimport { AbstractPostEffect, PostEffectLayer } from '../../posteffect/posteffect';\r\nimport { RenderGraph } from './rendergraph';\r\nimport { RenderGraphExecutor } from './executor';\r\nimport { DevicePoolAllocator } from './device_pool_allocator';\r\nimport { HistoryResourceManager } from './history_resource_manager';\r\nimport type { RGHandle } from './types';\r\nimport { renderObjectColors } from '../gpu_picking';\r\nimport type { Primitive } from '../primitive';\r\nimport { BoxShape } from '../../shapes';\r\n\r\n// ─── Shared Pass Instances ──────────────────────────────────────────\r\n\r\nconst _scenePass = new LightPass();\r\nconst _depthPass = new DepthPass();\r\nconst _shadowMapPass = new ShadowMapPass();\r\nconst _clusters: ClusteredLight[] = [];\r\nconst _devicePoolAllocator = new DevicePoolAllocator();\r\nlet _backDepthColorState: Nullable<ColorState> = null;\r\nlet _frontDepthColorState: Nullable<ColorState> = null;\r\n\r\nfunction getClusteredLight(): ClusteredLight {\r\n return _clusters.length > 0 ? _clusters.pop()! : new ClusteredLight();\r\n}\r\nfunction freeClusteredLight(cl: ClusteredLight): void {\r\n _clusters.push(cl);\r\n}\r\n\r\n// ─── Pipeline Options ───────────────────────────────────────────────\r\n\r\n/**\r\n * Options controlling which features are enabled in the forward+ pipeline.\r\n *\r\n * Derived from camera settings and device capabilities each frame.\r\n *\r\n * @public\r\n */\r\nexport interface ForwardPlusOptions {\r\n /** Enable depth prepass (always true for now). */\r\n depthPrepass: boolean;\r\n /** Enable motion vectors (requires TAA or motionBlur). */\r\n motionVectors: boolean;\r\n /** Enable Hi-Z pyramid (for SSR ray tracing). */\r\n hiZ: boolean;\r\n /** Enable screen-space reflections. */\r\n ssr: boolean;\r\n /** Whether to compute SSR thickness. */\r\n ssrCalcThickness: boolean;\r\n /** Whether GPU picking is requested this frame. */\r\n gpuPicking: boolean;\r\n /** Whether transmission/refraction materials are present. */\r\n needSceneColor: boolean;\r\n}\r\n\r\n/**\r\n * Derive pipeline options from the current scene/camera state.\r\n * @internal\r\n */\r\nexport function deriveForwardPlusOptions(\r\n scene: Scene,\r\n camera: Camera,\r\n deviceType: string,\r\n renderQueue: RenderQueue\r\n): ForwardPlusOptions {\r\n const ssr = camera.SSR && scene.env.light.envLight && scene.env.light.envLight.hasRadiance();\r\n return {\r\n depthPrepass: true,\r\n motionVectors: deviceType !== 'webgl' && (camera.TAA || camera.motionBlur),\r\n hiZ: camera.HiZ && deviceType !== 'webgl',\r\n ssr: !!ssr,\r\n ssrCalcThickness: !!ssr && camera.ssrCalcThickness,\r\n gpuPicking: !!camera.getPickResultResolveFunc(),\r\n needSceneColor: renderQueue.needSceneColor()\r\n };\r\n}\r\n\r\n// ─── Shared Frame State ─────────────────────────────────────────────\r\n\r\n/**\r\n * Mutable state shared between pass execute callbacks within a single frame.\r\n *\r\n * This replaces the monolithic DrawContext mutation pattern with an explicit\r\n * object that graph passes can read from and write to.\r\n *\r\n * @internal\r\n */\r\nexport interface FrameState {\r\n ctx: DrawContext;\r\n renderQueue: RenderQueue;\r\n depthFramebuffer: Nullable<FrameBuffer>;\r\n sunLightColor: Nullable<any>;\r\n options: ForwardPlusOptions;\r\n}\r\n\r\n// ─── Forward+ Graph Builder ─────────────────────────────────────────\r\n\r\n/**\r\n * Constructs a render graph representing the forward+ pipeline.\r\n *\r\n * Each step in the existing `SceneRenderer._renderScene` becomes a graph pass.\r\n * Execute callbacks delegate to the existing rendering code, sharing a mutable\r\n * {@link FrameState}.\r\n *\r\n * @param graph - The render graph to populate.\r\n * @param ctx - The draw context for this frame.\r\n * @param renderQueue - The culled render queue.\r\n * @param options - Pipeline feature toggles.\r\n * @returns The backbuffer handle (graph output).\r\n *\r\n * @public\r\n */\r\nexport function buildForwardPlusGraph(\r\n graph: RenderGraph,\r\n ctx: DrawContext,\r\n renderQueue: RenderQueue,\r\n options: ForwardPlusOptions\r\n): RGHandle {\r\n const backbuffer = graph.importTexture('backbuffer');\r\n\r\n // Shared mutable frame state\r\n const frame: FrameState = {\r\n ctx,\r\n renderQueue,\r\n depthFramebuffer: null,\r\n sunLightColor: null,\r\n options\r\n };\r\n\r\n // ── 1. Sky Update ─────────────────────────────────────────────────\r\n graph.addPass('SkyUpdate', (builder) => {\r\n builder.sideEffect();\r\n builder.setExecute(() => {\r\n frame.sunLightColor = ctx.scene.env.sky.update(ctx);\r\n });\r\n });\r\n\r\n // ── 2. Clustered Light Setup ──────────────────────────────────────\r\n graph.addPass('ClusterLights', (builder) => {\r\n builder.sideEffect();\r\n builder.setExecute(() => {\r\n ctx.clusteredLight = getClusteredLight();\r\n ctx.clusteredLight.calculateLightIndex(ctx.camera, renderQueue);\r\n });\r\n });\r\n\r\n // ── 3. GPU Picking (optional, sideEffect) ─────────────────────────\r\n if (options.gpuPicking) {\r\n graph.addPass('GPUPicking', (builder) => {\r\n builder.sideEffect();\r\n builder.setExecute(() => {\r\n const pickResolveFunc = ctx.camera.getPickResultResolveFunc();\r\n if (pickResolveFunc) {\r\n renderObjectColors(ctx, pickResolveFunc, renderQueue);\r\n }\r\n });\r\n });\r\n }\r\n\r\n // ── 4. Shadow Maps ────────────────────────────────────────────────\r\n // Shadow maps are managed internally by lights, mark as side effect\r\n if (renderQueue.shadowedLights.length > 0) {\r\n graph.addPass('ShadowMaps', (builder) => {\r\n builder.sideEffect();\r\n builder.setExecute(() => {\r\n renderShadowMaps(ctx, renderQueue.shadowedLights);\r\n });\r\n });\r\n }\r\n\r\n // ── 5. Depth Prepass ──────────────────────────────────────────────\r\n // Declare transient depth and motion vector textures\r\n const depthPassResult = graph.addPass('DepthPrepass', (builder) => {\r\n const format: TextureFormat =\r\n ctx.device.type === 'webgl'\r\n ? ctx.SSRCalcThickness\r\n ? 'rgba16f'\r\n : 'rgba8unorm'\r\n : ctx.SSRCalcThickness\r\n ? 'rg32f'\r\n : 'r32f';\r\n const mvFormat: TextureFormat = 'rgba16f';\r\n\r\n const depthHandle = builder.createTexture({ format, label: 'linearDepth' });\r\n const motionVectorHandle = options.motionVectors\r\n ? builder.createTexture({ format: mvFormat, label: 'motionVector' })\r\n : undefined;\r\n\r\n builder.setExecute((rgCtx) => {\r\n const depthTex = rgCtx.getTexture<Texture2D>(depthHandle);\r\n const mvTex = motionVectorHandle ? rgCtx.getTexture<Texture2D>(motionVectorHandle) : null;\r\n frame.depthFramebuffer = renderSceneDepth(frame, null, depthTex, mvTex);\r\n });\r\n\r\n return { depthHandle, motionVectorHandle };\r\n });\r\n\r\n const depthHandle = depthPassResult.depthHandle;\r\n const motionVectorHandle = depthPassResult.motionVectorHandle;\r\n\r\n // ── 6. Hi-Z (optional) ───────────────────────────────────────────\r\n let hiZHandle: RGHandle | undefined;\r\n if (options.hiZ) {\r\n graph.addPass('HiZ', (builder) => {\r\n builder.read(depthHandle!);\r\n hiZHandle = builder.createTexture({ format: 'r32f', label: 'hiZ', mipLevels: 10 });\r\n builder.setExecute((rgCtx) => {\r\n const ctx = frame.ctx;\r\n // Use the depth texture from the framebuffer (which contains the RenderGraph texture)\r\n const depthTex = frame.depthFramebuffer?.getDepthAttachment() as Texture2D;\r\n if (depthTex) {\r\n // Get the HiZ texture allocated by the executor\r\n const hiZTex = rgCtx.getTexture<Texture2D>(hiZHandle!);\r\n const w = hiZTex.width;\r\n const h = hiZTex.height;\r\n const HiZFrameBuffer = ctx.device.pool.fetchTemporalFramebuffer(false, w, h, hiZTex, null, false);\r\n buildHiZ(depthTex, HiZFrameBuffer);\r\n ctx.HiZTexture = hiZTex;\r\n ctx.device.pool.releaseFrameBuffer(HiZFrameBuffer);\r\n }\r\n });\r\n });\r\n }\r\n\r\n // ── 7. Main Light Pass ────────────────────────────────────────────\r\n const lightPassResult = graph.addPass('LightPass', (builder) => {\r\n builder.read(depthHandle);\r\n if (hiZHandle) {\r\n builder.read(hiZHandle);\r\n }\r\n\r\n // Create scene color texture (intermediate render target)\r\n const sceneColorHandle = builder.createTexture({\r\n format: ctx.colorFormat!,\r\n label: 'sceneColor'\r\n });\r\n\r\n // Create optional sceneColorCopy for transmission/refraction materials\r\n let sceneColorCopyHandle: RGHandle | undefined;\r\n if (options.needSceneColor) {\r\n sceneColorCopyHandle = builder.createTexture({\r\n format: ctx.colorFormat!,\r\n label: 'sceneColorCopy'\r\n });\r\n }\r\n\r\n builder.setExecute((rgCtx) => {\r\n const sceneColorTex = rgCtx.getTexture<Texture2D>(sceneColorHandle);\r\n const sceneColorCopyTex = sceneColorCopyHandle\r\n ? rgCtx.getTexture<Texture2D>(sceneColorCopyHandle)\r\n : null;\r\n renderMainLightPass(frame, sceneColorTex, sceneColorCopyTex);\r\n });\r\n\r\n return { sceneColorHandle, sceneColorCopyHandle };\r\n });\r\n\r\n const sceneColorHandle = lightPassResult.sceneColorHandle;\r\n\r\n // ── 8. Post Effects + Final Composite ─────────────────────────────\r\n graph.addPass('Composite', (builder) => {\r\n builder.read(sceneColorHandle);\r\n if (motionVectorHandle) {\r\n builder.read(motionVectorHandle);\r\n }\r\n builder.write(backbuffer);\r\n builder.setExecute(() => {\r\n renderComposite(frame);\r\n });\r\n });\r\n\r\n return backbuffer;\r\n}\r\n\r\n// ─── Pass Implementation Helpers ────────────────────────────────────\r\n// These wrap the existing SceneRenderer static methods, adapted to work\r\n// with the FrameState pattern. They contain the same logic as the\r\n// original methods but read/write through FrameState.\r\n\r\n/** @internal */\r\nfunction renderShadowMaps(ctx: DrawContext, lights: PunctualLight[]): void {\r\n ctx.renderPass = _shadowMapPass;\r\n ctx.device.pushDeviceStates();\r\n for (const light of lights) {\r\n light.shadow.render(ctx, _shadowMapPass);\r\n }\r\n ctx.device.popDeviceStates();\r\n}\r\n\r\n/** @internal */\r\nfunction renderSceneDepth(\r\n frame: FrameState,\r\n existingDepthFb: Nullable<FrameBuffer>,\r\n depthTex?: Texture2D,\r\n motionVectorTex?: Nullable<Texture2D>\r\n): FrameBuffer {\r\n const ctx = frame.ctx;\r\n const renderQueue = frame.renderQueue;\r\n const transmission = !!existingDepthFb;\r\n let depthFramebuffer = existingDepthFb;\r\n\r\n if (!depthFramebuffer) {\r\n // Use RenderGraph-allocated textures if provided\r\n if (depthTex) {\r\n const colorAttachments = motionVectorTex ? [depthTex, motionVectorTex] : depthTex;\r\n const depthAttachment = ctx.finalFramebuffer?.getDepthAttachment();\r\n const depthTexOrFormat = depthAttachment?.isTexture2D() ? depthAttachment : ctx.depthFormat;\r\n\r\n depthFramebuffer = ctx.device.pool.fetchTemporalFramebuffer(\r\n true,\r\n depthTex.width,\r\n depthTex.height,\r\n colorAttachments,\r\n depthTexOrFormat,\r\n false\r\n );\r\n } else {\r\n // Fallback: allocate from pool (legacy path)\r\n const format: TextureFormat =\r\n ctx.device.type === 'webgl'\r\n ? ctx.SSRCalcThickness\r\n ? 'rgba16f'\r\n : 'rgba8unorm'\r\n : ctx.SSRCalcThickness\r\n ? 'rg32f'\r\n : 'r32f';\r\n const mvFormat: TextureFormat = 'rgba16f';\r\n if (!ctx.finalFramebuffer) {\r\n depthFramebuffer = ctx.device.pool.fetchTemporalFramebuffer(\r\n true,\r\n ctx.renderWidth,\r\n ctx.renderHeight,\r\n ctx.motionVectors ? [format, mvFormat] : format,\r\n ctx.depthFormat,\r\n false\r\n );\r\n } else {\r\n const originDepth = ctx.finalFramebuffer?.getDepthAttachment();\r\n depthFramebuffer = originDepth?.isTexture2D()\r\n ? ctx.device.pool.fetchTemporalFramebuffer(\r\n true,\r\n originDepth.width,\r\n originDepth.height,\r\n ctx.motionVectors ? [format, mvFormat] : format,\r\n originDepth,\r\n false\r\n )\r\n : ctx.device.pool.fetchTemporalFramebuffer(\r\n true,\r\n ctx.renderWidth,\r\n ctx.renderHeight,\r\n ctx.motionVectors ? [format, mvFormat] : format,\r\n ctx.depthFormat,\r\n false\r\n );\r\n }\r\n }\r\n }\r\n\r\n ctx.device.pushDeviceStates();\r\n ctx.device.setFramebuffer(depthFramebuffer!);\r\n _depthPass.encodeDepth = depthFramebuffer!.getColorAttachments()[0].format === 'rgba8unorm';\r\n _depthPass.clearColor = transmission\r\n ? null\r\n : _depthPass.encodeDepth\r\n ? new Vector4(0, 0, 0, 1)\r\n : new Vector4(1, 1, 1, 1);\r\n _depthPass.clearDepth = transmission ? null : 1;\r\n _depthPass.clearStencil = null;\r\n _depthPass.transmission = transmission;\r\n\r\n if (ctx.SSRCalcThickness && !transmission) {\r\n if (!_backDepthColorState) {\r\n _backDepthColorState = ctx.device.createColorState().setColorMask(false, true, false, false);\r\n }\r\n if (!_frontDepthColorState) {\r\n _frontDepthColorState = ctx.device.createColorState().setColorMask(true, false, false, false);\r\n }\r\n ctx.forceColorState = _backDepthColorState;\r\n ctx.forceCullMode = 'front';\r\n _depthPass.renderBackface = true;\r\n _depthPass.transmission = false;\r\n _depthPass.render(ctx, null, null, renderQueue);\r\n _depthPass.clearColor = null;\r\n _depthPass.renderBackface = false;\r\n ctx.forceColorState = _frontDepthColorState;\r\n ctx.forceCullMode = null;\r\n }\r\n _depthPass.render(ctx, null, null, renderQueue);\r\n ctx.forceColorState = null;\r\n ctx.device.popDeviceStates();\r\n\r\n if (!transmission) {\r\n ctx.motionVectorTexture = ctx.motionVectors\r\n ? (depthFramebuffer!.getColorAttachments()[1] as Texture2D)\r\n : null;\r\n ctx.linearDepthTexture = depthFramebuffer!.getColorAttachments()[0] as Texture2D;\r\n ctx.depthTexture = depthFramebuffer!.getDepthAttachment() as Texture2D;\r\n if (ctx.motionVectorTexture) {\r\n // Sky motion vectors rendering is handled inline\r\n renderSkyMotionVectors(ctx);\r\n }\r\n // HiZ is now built in the dedicated HiZ pass\r\n }\r\n return depthFramebuffer!;\r\n}\r\n\r\n// ─── Sky Motion Vector State ────────────────────────────────────────\r\n\r\nlet _skyMVProgram: Nullable<GPUProgram> = null;\r\nlet _skyMVBindGroup: Nullable<BindGroup> = null;\r\nlet _skyMVBox: Nullable<Primitive> = null;\r\n\r\n/** @internal */\r\nfunction renderSkyMotionVectors(ctx: DrawContext): void {\r\n if (!ctx.motionVectorTexture) {\r\n return;\r\n }\r\n\r\n const device = ctx.device;\r\n const fb = device.pool.fetchTemporalFramebuffer(false, 0, 0, ctx.motionVectorTexture, ctx.depthTexture);\r\n\r\n if (!_skyMVProgram) {\r\n _skyMVProgram = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec3().attrib('position');\r\n this.VPMatrix = pb.mat4().uniform(0);\r\n this.prevVPMatrix = pb.mat4().uniform(0);\r\n this.cameraPos = pb.vec3().uniform(0);\r\n this.prevCameraPos = pb.vec3().uniform(0);\r\n pb.main(function () {\r\n this.$l.worldPos = pb.add(this.$inputs.pos, this.cameraPos);\r\n this.$l.prevWorldPos = pb.add(this.$inputs.pos, this.prevCameraPos);\r\n this.$l.clipPos = pb.mul(this.VPMatrix, pb.vec4(this.worldPos, 1));\r\n this.$l.prevClipPos = pb.mul(this.prevVPMatrix, pb.vec4(this.prevWorldPos, 1));\r\n this.clipPos.z = this.clipPos.w;\r\n this.$builtins.position = this.clipPos;\r\n this.$outputs.currentPos = this.clipPos;\r\n this.$outputs.prevPos = this.prevClipPos;\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.color = pb.vec4();\r\n pb.main(function () {\r\n this.$l.motionVector = pb.mul(\r\n pb.sub(\r\n pb.div(this.$inputs.currentPos.xy, this.$inputs.currentPos.w),\r\n pb.div(this.$inputs.prevPos.xy, this.$inputs.prevPos.w)\r\n ),\r\n 0.5\r\n );\r\n this.$outputs.color = pb.vec4(this.motionVector, 0, 1);\r\n });\r\n }\r\n })!;\r\n _skyMVProgram.name = '@TAA_SkyMotionVector';\r\n }\r\n\r\n if (!_skyMVBindGroup) {\r\n _skyMVBindGroup = device.createBindGroup(_skyMVProgram.bindGroupLayouts[0]);\r\n }\r\n\r\n if (!_skyMVBox) {\r\n _skyMVBox = new BoxShape({ size: 2, needNormal: false, needUV: false });\r\n }\r\n\r\n _skyMVBindGroup.setValue('VPMatrix', ctx.camera.viewProjectionMatrix);\r\n _skyMVBindGroup.setValue('prevVPMatrix', ctx.camera.prevVPMatrix!);\r\n _skyMVBindGroup.setValue('cameraPos', ctx.camera.getWorldPosition());\r\n _skyMVBindGroup.setValue('prevCameraPos', ctx.camera.prevPosition!);\r\n\r\n device.pushDeviceStates();\r\n device.setProgram(_skyMVProgram);\r\n device.setBindGroup(0, _skyMVBindGroup);\r\n device.setRenderStates(AbstractPostEffect.getDefaultRenderState(ctx, 'le'));\r\n device.setFramebuffer(fb);\r\n _skyMVBox.draw();\r\n device.popDeviceStates();\r\n device.pool.releaseFrameBuffer(fb);\r\n}\r\n\r\n/** @internal */\r\nfunction renderMainLightPass(\r\n frame: FrameState,\r\n sceneColorTex: Texture2D,\r\n sceneColorCopyTex: Nullable<Texture2D>\r\n): void {\r\n const { ctx, renderQueue } = frame;\r\n const device = ctx.device;\r\n\r\n // Use RenderGraph-allocated scene color texture\r\n const depthTex = frame.depthFramebuffer?.getDepthAttachment() as Texture2D;\r\n\r\n if (depthTex === ctx.finalFramebuffer?.getDepthAttachment()) {\r\n ctx.intermediateFramebuffer = ctx.finalFramebuffer;\r\n } else {\r\n ctx.intermediateFramebuffer = device.pool.fetchTemporalFramebuffer(\r\n false,\r\n sceneColorTex.width,\r\n sceneColorTex.height,\r\n sceneColorTex,\r\n depthTex\r\n );\r\n }\r\n\r\n if (ctx.intermediateFramebuffer && ctx.intermediateFramebuffer !== ctx.finalFramebuffer) {\r\n device.pushDeviceStates();\r\n device.setFramebuffer(ctx.intermediateFramebuffer);\r\n } else {\r\n device.setViewport(null);\r\n device.setScissor(null);\r\n }\r\n\r\n _scenePass.transmission = false;\r\n _scenePass.clearDepth = depthTex ? null : 1;\r\n _scenePass.clearStencil = depthTex ? null : 0;\r\n\r\n if (ctx.SSR && !renderQueue.needSceneColor()) {\r\n ctx.materialFlags |= MaterialVaryingFlags.SSR_STORE_ROUGHNESS;\r\n }\r\n\r\n ctx.compositor?.begin(ctx);\r\n\r\n if (renderQueue.needSceneColor() && sceneColorCopyTex) {\r\n const compositor = ctx.compositor;\r\n ctx.compositor = null;\r\n\r\n // Use RenderGraph-allocated sceneColorCopy texture\r\n const sceneColorFramebuffer = device.pool.fetchTemporalFramebuffer(\r\n true,\r\n sceneColorCopyTex.width,\r\n sceneColorCopyTex.height,\r\n ctx.materialFlags & MaterialVaryingFlags.SSR_STORE_ROUGHNESS\r\n ? [\r\n sceneColorCopyTex,\r\n device.getFramebuffer()!.getColorAttachments()[1]!,\r\n device.getFramebuffer()!.getColorAttachments()[2]!\r\n ]\r\n : sceneColorCopyTex,\r\n depthTex,\r\n false\r\n );\r\n device.pushDeviceStates();\r\n device.setFramebuffer(sceneColorFramebuffer);\r\n _scenePass.transmission = false;\r\n _scenePass.render(ctx, null, null, renderQueue);\r\n device.popDeviceStates();\r\n ctx.sceneColorTexture = sceneColorCopyTex;\r\n new CopyBlitter().blit(\r\n ctx.sceneColorTexture,\r\n device.getFramebuffer() ?? null,\r\n fetchSampler('clamp_nearest_nomip')\r\n );\r\n _scenePass.transmission = true;\r\n _scenePass.clearColor = null;\r\n _scenePass.clearDepth = null;\r\n _scenePass.clearStencil = null;\r\n ctx.compositor = compositor;\r\n }\r\n _scenePass.render(ctx, null, null, renderQueue);\r\n\r\n if (renderQueue.needSceneColor()) {\r\n renderSceneDepth(frame, frame.depthFramebuffer);\r\n }\r\n}\r\n\r\n/** @internal */\r\nfunction renderComposite(frame: FrameState): void {\r\n const { ctx, renderQueue } = frame;\r\n const device = ctx.device;\r\n\r\n ctx.compositor?.drawPostEffects(ctx, PostEffectLayer.end, ctx.linearDepthTexture!);\r\n ctx.compositor?.end(ctx);\r\n renderQueue.dispose();\r\n ctx.materialFlags &= ~MaterialVaryingFlags.SSR_STORE_ROUGHNESS;\r\n\r\n if (ctx.intermediateFramebuffer && ctx.intermediateFramebuffer !== ctx.finalFramebuffer) {\r\n const blitter = new CopyBlitter();\r\n blitter.srgbOut = !ctx.finalFramebuffer;\r\n const srcTex = ctx.intermediateFramebuffer.getColorAttachments()[0] as Texture2D;\r\n blitter.blit(srcTex, ctx.finalFramebuffer ?? null, fetchSampler('clamp_nearest_nomip'));\r\n device.popDeviceStates();\r\n device.pool.releaseFrameBuffer(ctx.intermediateFramebuffer);\r\n }\r\n\r\n freeClusteredLight(ctx.clusteredLight!);\r\n\r\n if (frame.sunLightColor) {\r\n ctx.sunLight!.color = frame.sunLightColor;\r\n }\r\n}\r\n\r\n// ─── Convenience: Execute Full Pipeline ─────────────────────────────\r\n\r\n/**\r\n * Build, compile, and execute the forward+ pipeline as a render graph.\r\n *\r\n * This is the drop-in replacement for `SceneRenderer._renderScene`.\r\n *\r\n * @param ctx - The draw context for this frame.\r\n * @public\r\n */\r\nexport function executeForwardPlusGraph(ctx: DrawContext): void {\r\n const device = ctx.device;\r\n const graph = new RenderGraph();\r\n\r\n // Cull scene first (needed to derive options)\r\n const renderQueue = _scenePass.cullScene(ctx, ctx.camera);\r\n\r\n const options = deriveForwardPlusOptions(ctx.scene, ctx.camera, device.type, renderQueue);\r\n\r\n // Ensure the camera has a history resource manager for temporal effects (TAA, motion blur)\r\n let historyManager = ctx.camera.getHistoryResourceManager();\r\n if (!historyManager) {\r\n historyManager = new HistoryResourceManager<Texture2D>(_devicePoolAllocator);\r\n ctx.camera.setHistoryResourceManager(historyManager);\r\n }\r\n\r\n const backbuffer = buildForwardPlusGraph(graph, ctx, renderQueue, options);\r\n\r\n const compiled = graph.compile([backbuffer]);\r\n\r\n // Use RenderGraphExecutor for automatic resource management\r\n const executor = new RenderGraphExecutor(_devicePoolAllocator, ctx.renderWidth, ctx.renderHeight);\r\n\r\n // Register imported backbuffer (if using finalFramebuffer)\r\n if (ctx.finalFramebuffer) {\r\n const backbufferTex = ctx.finalFramebuffer.getColorAttachments()[0] as Texture2D;\r\n executor.setImportedTexture(backbuffer, backbufferTex);\r\n }\r\n\r\n executor.execute(compiled);\r\n executor.reset();\r\n\r\n // Swap history buffers at frame end (ping-pong)\r\n historyManager.swap();\r\n}\r\n"],"names":["_scenePass","LightPass","_depthPass","DepthPass","_shadowMapPass","ShadowMapPass","_clusters","_devicePoolAllocator","DevicePoolAllocator","_backDepthColorState","_frontDepthColorState","getClusteredLight","length","pop","ClusteredLight","freeClusteredLight","cl","push","deriveForwardPlusOptions","scene","camera","deviceType","renderQueue","ssr","SSR","env","light","envLight","hasRadiance","depthPrepass","motionVectors","TAA","motionBlur","hiZ","HiZ","ssrCalcThickness","gpuPicking","getPickResultResolveFunc","needSceneColor","buildForwardPlusGraph","graph","ctx","options","backbuffer","importTexture","frame","depthFramebuffer","sunLightColor","addPass","builder","sideEffect","setExecute","sky","update","clusteredLight","calculateLightIndex","pickResolveFunc","renderObjectColors","shadowedLights","renderShadowMaps","depthPassResult","format","device","type","SSRCalcThickness","mvFormat","depthHandle","createTexture","label","motionVectorHandle","undefined","rgCtx","depthTex","getTexture","mvTex","renderSceneDepth","hiZHandle","read","mipLevels","getDepthAttachment","hiZTex","w","width","h","height","HiZFrameBuffer","pool","fetchTemporalFramebuffer","buildHiZ","HiZTexture","releaseFrameBuffer","lightPassResult","sceneColorHandle","colorFormat","sceneColorCopyHandle","sceneColorTex","sceneColorCopyTex","renderMainLightPass","write","renderComposite","lights","renderPass","pushDeviceStates","shadow","render","popDeviceStates","existingDepthFb","motionVectorTex","transmission","colorAttachments","depthAttachment","finalFramebuffer","depthTexOrFormat","isTexture2D","depthFormat","renderWidth","renderHeight","originDepth","setFramebuffer","encodeDepth","getColorAttachments","clearColor","Vector4","clearDepth","clearStencil","createColorState","setColorMask","forceColorState","forceCullMode","renderBackface","motionVectorTexture","linearDepthTexture","depthTexture","renderSkyMotionVectors","_skyMVProgram","_skyMVBindGroup","_skyMVBox","fb","buildRenderProgram","vertex","pb","$inputs","pos","vec3","attrib","VPMatrix","mat4","uniform","prevVPMatrix","cameraPos","prevCameraPos","main","$l","worldPos","add","prevWorldPos","clipPos","mul","vec4","prevClipPos","z","$builtins","position","$outputs","currentPos","prevPos","fragment","color","motionVector","sub","div","xy","name","createBindGroup","bindGroupLayouts","BoxShape","size","needNormal","needUV","setValue","viewProjectionMatrix","getWorldPosition","prevPosition","setProgram","setBindGroup","setRenderStates","AbstractPostEffect","getDefaultRenderState","draw","intermediateFramebuffer","setViewport","setScissor","materialFlags","MaterialVaryingFlags","SSR_STORE_ROUGHNESS","compositor","begin","sceneColorFramebuffer","getFramebuffer","sceneColorTexture","CopyBlitter","blit","fetchSampler","drawPostEffects","PostEffectLayer","end","dispose","blitter","srgbOut","srcTex","sunLight","executeForwardPlusGraph","RenderGraph","cullScene","historyManager","getHistoryResourceManager","HistoryResourceManager","setHistoryResourceManager","compiled","compile","executor","RenderGraphExecutor","backbufferTex","setImportedTexture","execute","reset","swap"],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Manages cross-frame history resources with automatic ping-pong buffering.
3
+ *
4
+ * History resources are textures that persist across frames for temporal effects
5
+ * like TAA, motion blur, or temporal upscaling. The manager maintains two copies
6
+ * of each resource and automatically swaps them at frame boundaries.
7
+ *
8
+ * Usage:
9
+ * ```ts
10
+ * const historyMgr = new HistoryResourceManager(allocator);
11
+ *
12
+ * // Register a history resource (typically once at initialization)
13
+ * historyMgr.register('taaHistory', {
14
+ * format: TextureFormat.RGBA16F,
15
+ * width: 1920,
16
+ * height: 1080
17
+ * }, { width: 1920, height: 1080 });
18
+ *
19
+ * // In your render pass:
20
+ * const prevFrame = historyMgr.getPrevious('taaHistory'); // Read from previous frame
21
+ * const currentFrame = historyMgr.getCurrent('taaHistory'); // Write to current frame
22
+ *
23
+ * // At frame end:
24
+ * historyMgr.swap(); // Swap current and previous
25
+ * ```
26
+ *
27
+ * @typeParam TTexture - The concrete texture type (e.g. `Texture2D`).
28
+ * @public
29
+ */ class HistoryResourceManager {
30
+ _resources = new Map();
31
+ _allocator;
32
+ _frameIndex = 0;
33
+ /**
34
+ * Create a new history resource manager.
35
+ *
36
+ * @param allocator - Texture allocator for creating history textures.
37
+ */ constructor(allocator){
38
+ this._allocator = allocator;
39
+ }
40
+ /**
41
+ * Register a new history resource with ping-pong buffering.
42
+ *
43
+ * Allocates two textures matching the given descriptor. If a resource
44
+ * with the same name already exists, this is a no-op.
45
+ *
46
+ * @param name - Unique identifier for this history resource.
47
+ * @param desc - Texture descriptor (format, size, etc.).
48
+ * @param size - Resolved pixel dimensions.
49
+ */ register(name, desc, size) {
50
+ if (!this._resources.has(name)) {
51
+ const tex0 = this._allocator.allocate(desc, size);
52
+ const tex1 = this._allocator.allocate(desc, size);
53
+ this._resources.set(name, [
54
+ tex0,
55
+ tex1
56
+ ]);
57
+ }
58
+ }
59
+ /**
60
+ * Register a new history resource with an existing texture (zero-copy).
61
+ *
62
+ * This is more efficient than register() + updateCurrent() for first-frame setup,
63
+ * as it avoids allocating dummy textures that are immediately replaced.
64
+ *
65
+ * @param name - Unique identifier for this history resource.
66
+ * @param desc - Texture descriptor (format, size, etc.).
67
+ * @param size - Resolved pixel dimensions.
68
+ * @param initialTexture - The initial texture to use as current frame.
69
+ */ registerWithTexture(name, desc, size, initialTexture) {
70
+ if (!this._resources.has(name)) {
71
+ // Allocate only one texture for the "previous" slot
72
+ const prevTexture = this._allocator.allocate(desc, size);
73
+ // Use the provided texture as "current"
74
+ this._resources.set(name, [
75
+ initialTexture,
76
+ prevTexture
77
+ ]);
78
+ }
79
+ }
80
+ /**
81
+ * Get the current frame's texture for a history resource.
82
+ *
83
+ * This is typically used as the write target in render passes.
84
+ *
85
+ * @param name - Name of the history resource.
86
+ * @returns The current frame's texture.
87
+ * @throws If the resource has not been registered.
88
+ */ getCurrent(name) {
89
+ const textures = this._resources.get(name);
90
+ if (!textures) {
91
+ throw new Error(`History resource '${name}' not found. Did you forget to call register()?`);
92
+ }
93
+ return textures[this._frameIndex % 2];
94
+ }
95
+ /**
96
+ * Get the previous frame's texture for a history resource.
97
+ *
98
+ * This is typically used as a read input in temporal effects like TAA.
99
+ *
100
+ * @param name - Name of the history resource.
101
+ * @returns The previous frame's texture.
102
+ * @throws If the resource has not been registered.
103
+ */ getPrevious(name) {
104
+ const textures = this._resources.get(name);
105
+ if (!textures) {
106
+ throw new Error(`History resource '${name}' not found. Did you forget to call register()?`);
107
+ }
108
+ return textures[(this._frameIndex + 1) % 2];
109
+ }
110
+ /**
111
+ * Check if a history resource exists.
112
+ *
113
+ * @param name - Name of the history resource.
114
+ * @returns True if the resource has been registered.
115
+ */ has(name) {
116
+ return this._resources.has(name);
117
+ }
118
+ /**
119
+ * Unregister a history resource and release its textures.
120
+ *
121
+ * @param name - Name of the history resource to remove.
122
+ * @returns True if the resource was found and removed.
123
+ */ unregister(name) {
124
+ const textures = this._resources.get(name);
125
+ if (textures) {
126
+ textures.forEach((tex)=>this._allocator.release(tex));
127
+ this._resources.delete(name);
128
+ return true;
129
+ }
130
+ return false;
131
+ }
132
+ /**
133
+ * Swap current and previous textures for all history resources.
134
+ *
135
+ * Call this at the end of each frame to advance the ping-pong buffers.
136
+ * After swapping, what was "current" becomes "previous" for the next frame.
137
+ */ swap() {
138
+ this._frameIndex++;
139
+ }
140
+ /**
141
+ * Release all history resources and clear the manager.
142
+ *
143
+ * Call this when disposing the render context or when history is no longer needed.
144
+ */ dispose() {
145
+ for (const textures of this._resources.values()){
146
+ textures.forEach((tex)=>this._allocator.release(tex));
147
+ }
148
+ this._resources.clear();
149
+ this._frameIndex = 0;
150
+ }
151
+ /**
152
+ * Update the current frame's texture with an external texture (for zero-copy workflows).
153
+ *
154
+ * This is useful when you want to use the output of a render pass directly as history,
155
+ * without copying. The manager will release the old texture and use the new one.
156
+ *
157
+ * @param name - Name of the history resource.
158
+ * @param texture - The new texture to use as current frame.
159
+ */ updateCurrent(name, texture) {
160
+ const textures = this._resources.get(name);
161
+ if (!textures) {
162
+ throw new Error(`History resource '${name}' not found. Did you forget to call register()?`);
163
+ }
164
+ // Release the old current texture
165
+ const oldTexture = textures[this._frameIndex % 2];
166
+ this._allocator.release(oldTexture);
167
+ // Replace with new texture
168
+ textures[this._frameIndex % 2] = texture;
169
+ }
170
+ /**
171
+ * Get the number of registered history resources.
172
+ */ get size() {
173
+ return this._resources.size;
174
+ }
175
+ }
176
+
177
+ export { HistoryResourceManager };
178
+ //# sourceMappingURL=history_resource_manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history_resource_manager.js","sources":["../../../src/render/rendergraph/history_resource_manager.ts"],"sourcesContent":["import type { Texture2D } from '@zephyr3d/device';\r\nimport type { RGTextureAllocator, RGTextureDesc, RGResolvedSize } from './types';\r\n\r\n/**\r\n * Manages cross-frame history resources with automatic ping-pong buffering.\r\n *\r\n * History resources are textures that persist across frames for temporal effects\r\n * like TAA, motion blur, or temporal upscaling. The manager maintains two copies\r\n * of each resource and automatically swaps them at frame boundaries.\r\n *\r\n * Usage:\r\n * ```ts\r\n * const historyMgr = new HistoryResourceManager(allocator);\r\n *\r\n * // Register a history resource (typically once at initialization)\r\n * historyMgr.register('taaHistory', {\r\n * format: TextureFormat.RGBA16F,\r\n * width: 1920,\r\n * height: 1080\r\n * }, { width: 1920, height: 1080 });\r\n *\r\n * // In your render pass:\r\n * const prevFrame = historyMgr.getPrevious('taaHistory'); // Read from previous frame\r\n * const currentFrame = historyMgr.getCurrent('taaHistory'); // Write to current frame\r\n *\r\n * // At frame end:\r\n * historyMgr.swap(); // Swap current and previous\r\n * ```\r\n *\r\n * @typeParam TTexture - The concrete texture type (e.g. `Texture2D`).\r\n * @public\r\n */\r\nexport class HistoryResourceManager<TTexture = Texture2D> {\r\n private _resources: Map<string, TTexture[]> = new Map();\r\n private _allocator: RGTextureAllocator<TTexture>;\r\n private _frameIndex = 0;\r\n\r\n /**\r\n * Create a new history resource manager.\r\n *\r\n * @param allocator - Texture allocator for creating history textures.\r\n */\r\n constructor(allocator: RGTextureAllocator<TTexture>) {\r\n this._allocator = allocator;\r\n }\r\n\r\n /**\r\n * Register a new history resource with ping-pong buffering.\r\n *\r\n * Allocates two textures matching the given descriptor. If a resource\r\n * with the same name already exists, this is a no-op.\r\n *\r\n * @param name - Unique identifier for this history resource.\r\n * @param desc - Texture descriptor (format, size, etc.).\r\n * @param size - Resolved pixel dimensions.\r\n */\r\n register(name: string, desc: RGTextureDesc, size: RGResolvedSize): void {\r\n if (!this._resources.has(name)) {\r\n const tex0 = this._allocator.allocate(desc, size);\r\n const tex1 = this._allocator.allocate(desc, size);\r\n this._resources.set(name, [tex0, tex1]);\r\n }\r\n }\r\n\r\n /**\r\n * Register a new history resource with an existing texture (zero-copy).\r\n *\r\n * This is more efficient than register() + updateCurrent() for first-frame setup,\r\n * as it avoids allocating dummy textures that are immediately replaced.\r\n *\r\n * @param name - Unique identifier for this history resource.\r\n * @param desc - Texture descriptor (format, size, etc.).\r\n * @param size - Resolved pixel dimensions.\r\n * @param initialTexture - The initial texture to use as current frame.\r\n */\r\n registerWithTexture(\r\n name: string,\r\n desc: RGTextureDesc,\r\n size: RGResolvedSize,\r\n initialTexture: TTexture\r\n ): void {\r\n if (!this._resources.has(name)) {\r\n // Allocate only one texture for the \"previous\" slot\r\n const prevTexture = this._allocator.allocate(desc, size);\r\n // Use the provided texture as \"current\"\r\n this._resources.set(name, [initialTexture, prevTexture]);\r\n }\r\n }\r\n\r\n /**\r\n * Get the current frame's texture for a history resource.\r\n *\r\n * This is typically used as the write target in render passes.\r\n *\r\n * @param name - Name of the history resource.\r\n * @returns The current frame's texture.\r\n * @throws If the resource has not been registered.\r\n */\r\n getCurrent(name: string): TTexture {\r\n const textures = this._resources.get(name);\r\n if (!textures) {\r\n throw new Error(`History resource '${name}' not found. Did you forget to call register()?`);\r\n }\r\n return textures[this._frameIndex % 2];\r\n }\r\n\r\n /**\r\n * Get the previous frame's texture for a history resource.\r\n *\r\n * This is typically used as a read input in temporal effects like TAA.\r\n *\r\n * @param name - Name of the history resource.\r\n * @returns The previous frame's texture.\r\n * @throws If the resource has not been registered.\r\n */\r\n getPrevious(name: string): TTexture {\r\n const textures = this._resources.get(name);\r\n if (!textures) {\r\n throw new Error(`History resource '${name}' not found. Did you forget to call register()?`);\r\n }\r\n return textures[(this._frameIndex + 1) % 2];\r\n }\r\n\r\n /**\r\n * Check if a history resource exists.\r\n *\r\n * @param name - Name of the history resource.\r\n * @returns True if the resource has been registered.\r\n */\r\n has(name: string): boolean {\r\n return this._resources.has(name);\r\n }\r\n\r\n /**\r\n * Unregister a history resource and release its textures.\r\n *\r\n * @param name - Name of the history resource to remove.\r\n * @returns True if the resource was found and removed.\r\n */\r\n unregister(name: string): boolean {\r\n const textures = this._resources.get(name);\r\n if (textures) {\r\n textures.forEach((tex) => this._allocator.release(tex));\r\n this._resources.delete(name);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Swap current and previous textures for all history resources.\r\n *\r\n * Call this at the end of each frame to advance the ping-pong buffers.\r\n * After swapping, what was \"current\" becomes \"previous\" for the next frame.\r\n */\r\n swap(): void {\r\n this._frameIndex++;\r\n }\r\n\r\n /**\r\n * Release all history resources and clear the manager.\r\n *\r\n * Call this when disposing the render context or when history is no longer needed.\r\n */\r\n dispose(): void {\r\n for (const textures of this._resources.values()) {\r\n textures.forEach((tex) => this._allocator.release(tex));\r\n }\r\n this._resources.clear();\r\n this._frameIndex = 0;\r\n }\r\n\r\n /**\r\n * Update the current frame's texture with an external texture (for zero-copy workflows).\r\n *\r\n * This is useful when you want to use the output of a render pass directly as history,\r\n * without copying. The manager will release the old texture and use the new one.\r\n *\r\n * @param name - Name of the history resource.\r\n * @param texture - The new texture to use as current frame.\r\n */\r\n updateCurrent(name: string, texture: TTexture): void {\r\n const textures = this._resources.get(name);\r\n if (!textures) {\r\n throw new Error(`History resource '${name}' not found. Did you forget to call register()?`);\r\n }\r\n\r\n // Release the old current texture\r\n const oldTexture = textures[this._frameIndex % 2];\r\n this._allocator.release(oldTexture);\r\n\r\n // Replace with new texture\r\n textures[this._frameIndex % 2] = texture;\r\n }\r\n\r\n /**\r\n * Get the number of registered history resources.\r\n */\r\n get size(): number {\r\n return this._resources.size;\r\n }\r\n}\r\n"],"names":["HistoryResourceManager","_resources","Map","_allocator","_frameIndex","allocator","register","name","desc","size","has","tex0","allocate","tex1","set","registerWithTexture","initialTexture","prevTexture","getCurrent","textures","get","Error","getPrevious","unregister","forEach","tex","release","delete","swap","dispose","values","clear","updateCurrent","texture","oldTexture"],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BC,IACM,MAAMA,sBAAAA,CAAAA;AACHC,IAAAA,UAAAA,GAAsC,IAAIC,GAAM,EAAA;IAChDC,UAAyC;AACzCC,IAAAA,WAAAA,GAAc,CAAE;AAExB;;;;MAKA,WAAA,CAAYC,SAAuC,CAAE;QACnD,IAAI,CAACF,UAAU,GAAGE,SAAAA;AACpB;AAEA;;;;;;;;;AASC,MACDC,SAASC,IAAY,EAAEC,IAAmB,EAAEC,IAAoB,EAAQ;AACtE,QAAA,IAAI,CAAC,IAAI,CAACR,UAAU,CAACS,GAAG,CAACH,IAAO,CAAA,EAAA;AAC9B,YAAA,MAAMI,OAAO,IAAI,CAACR,UAAU,CAACS,QAAQ,CAACJ,IAAMC,EAAAA,IAAAA,CAAAA;AAC5C,YAAA,MAAMI,OAAO,IAAI,CAACV,UAAU,CAACS,QAAQ,CAACJ,IAAMC,EAAAA,IAAAA,CAAAA;AAC5C,YAAA,IAAI,CAACR,UAAU,CAACa,GAAG,CAACP,IAAM,EAAA;AAACI,gBAAAA,IAAAA;AAAME,gBAAAA;AAAK,aAAA,CAAA;AACxC;AACF;AAEA;;;;;;;;;;MAWAE,mBAAAA,CACER,IAAY,EACZC,IAAmB,EACnBC,IAAoB,EACpBO,cAAwB,EAClB;AACN,QAAA,IAAI,CAAC,IAAI,CAACf,UAAU,CAACS,GAAG,CAACH,IAAO,CAAA,EAAA;;AAE9B,YAAA,MAAMU,cAAc,IAAI,CAACd,UAAU,CAACS,QAAQ,CAACJ,IAAMC,EAAAA,IAAAA,CAAAA;;AAEnD,YAAA,IAAI,CAACR,UAAU,CAACa,GAAG,CAACP,IAAM,EAAA;AAACS,gBAAAA,cAAAA;AAAgBC,gBAAAA;AAAY,aAAA,CAAA;AACzD;AACF;AAEA;;;;;;;;MASAC,UAAAA,CAAWX,IAAY,EAAY;AACjC,QAAA,MAAMY,WAAW,IAAI,CAAClB,UAAU,CAACmB,GAAG,CAACb,IAAAA,CAAAA;AACrC,QAAA,IAAI,CAACY,QAAU,EAAA;AACb,YAAA,MAAM,IAAIE,KAAM,CAAA,CAAC,kBAAkB,EAAEd,IAAAA,CAAK,+CAA+C,CAAC,CAAA;AAC5F;AACA,QAAA,OAAOY,QAAQ,CAAC,IAAI,CAACf,WAAW,GAAG,CAAE,CAAA;AACvC;AAEA;;;;;;;;MASAkB,WAAAA,CAAYf,IAAY,EAAY;AAClC,QAAA,MAAMY,WAAW,IAAI,CAAClB,UAAU,CAACmB,GAAG,CAACb,IAAAA,CAAAA;AACrC,QAAA,IAAI,CAACY,QAAU,EAAA;AACb,YAAA,MAAM,IAAIE,KAAM,CAAA,CAAC,kBAAkB,EAAEd,IAAAA,CAAK,+CAA+C,CAAC,CAAA;AAC5F;QACA,OAAOY,QAAQ,CAAE,CAAA,IAAI,CAACf,WAAW,GAAG,CAAA,IAAK,CAAE,CAAA;AAC7C;AAEA;;;;;MAMAM,GAAAA,CAAIH,IAAY,EAAW;AACzB,QAAA,OAAO,IAAI,CAACN,UAAU,CAACS,GAAG,CAACH,IAAAA,CAAAA;AAC7B;AAEA;;;;;MAMAgB,UAAAA,CAAWhB,IAAY,EAAW;AAChC,QAAA,MAAMY,WAAW,IAAI,CAAClB,UAAU,CAACmB,GAAG,CAACb,IAAAA,CAAAA;AACrC,QAAA,IAAIY,QAAU,EAAA;YACZA,QAASK,CAAAA,OAAO,CAAC,CAACC,GAAAA,GAAQ,IAAI,CAACtB,UAAU,CAACuB,OAAO,CAACD,GAAAA,CAAAA,CAAAA;AAClD,YAAA,IAAI,CAACxB,UAAU,CAAC0B,MAAM,CAACpB,IAAAA,CAAAA;YACvB,OAAO,IAAA;AACT;QACA,OAAO,KAAA;AACT;AAEA;;;;;AAKC,MACDqB,IAAa,GAAA;AACX,QAAA,IAAI,CAACxB,WAAW,EAAA;AAClB;AAEA;;;;AAIC,MACDyB,OAAgB,GAAA;AACd,QAAA,KAAK,MAAMV,QAAY,IAAA,IAAI,CAAClB,UAAU,CAAC6B,MAAM,EAAI,CAAA;YAC/CX,QAASK,CAAAA,OAAO,CAAC,CAACC,GAAAA,GAAQ,IAAI,CAACtB,UAAU,CAACuB,OAAO,CAACD,GAAAA,CAAAA,CAAAA;AACpD;QACA,IAAI,CAACxB,UAAU,CAAC8B,KAAK,EAAA;QACrB,IAAI,CAAC3B,WAAW,GAAG,CAAA;AACrB;AAEA;;;;;;;;AAQC,MACD4B,aAAczB,CAAAA,IAAY,EAAE0B,OAAiB,EAAQ;AACnD,QAAA,MAAMd,WAAW,IAAI,CAAClB,UAAU,CAACmB,GAAG,CAACb,IAAAA,CAAAA;AACrC,QAAA,IAAI,CAACY,QAAU,EAAA;AACb,YAAA,MAAM,IAAIE,KAAM,CAAA,CAAC,kBAAkB,EAAEd,IAAAA,CAAK,+CAA+C,CAAC,CAAA;AAC5F;;AAGA,QAAA,MAAM2B,aAAaf,QAAQ,CAAC,IAAI,CAACf,WAAW,GAAG,CAAE,CAAA;AACjD,QAAA,IAAI,CAACD,UAAU,CAACuB,OAAO,CAACQ,UAAAA,CAAAA;;AAGxBf,QAAAA,QAAQ,CAAC,IAAI,CAACf,WAAW,GAAG,EAAE,GAAG6B,OAAAA;AACnC;AAEA;;AAEC,MACD,IAAIxB,IAAe,GAAA;AACjB,QAAA,OAAO,IAAI,CAACR,UAAU,CAACQ,IAAI;AAC7B;AACF;;;;"}
@@ -139,6 +139,10 @@ import { RGHandle, RGPass, RGResource } from './types.js';
139
139
  if (!res) {
140
140
  throw new Error(`RenderGraph: unknown resource "${handle.name}" (id=${handle._id})`);
141
141
  }
142
+ // Validate that transient resources have a producer
143
+ if (res.kind === 'transient' && !res.producer) {
144
+ throw new Error(`RenderGraph: pass "${pass.name}" attempts to read transient resource "${res.name}" ` + `which has no producer. Ensure the resource is created before being read.`);
145
+ }
142
146
  pass.reads.push(res);
143
147
  res.consumers.push(pass);
144
148
  },
@@ -261,7 +265,14 @@ import { RGHandle, RGPass, RGResource } from './types.js';
261
265
  }
262
266
  }
263
267
  if (result.length !== alivePasses.length) {
264
- throw new Error(`RenderGraph: circular dependency detected. ` + `Sorted ${result.length} of ${alivePasses.length} alive passes.`);
268
+ // Find passes that are part of the cycle (those with non-zero in-degree)
269
+ const cycleParticipants = [];
270
+ for (const [pass, degree] of inDegree){
271
+ if (degree > 0) {
272
+ cycleParticipants.push(pass.name);
273
+ }
274
+ }
275
+ throw new Error(`RenderGraph: circular dependency detected. ` + `Sorted ${result.length} of ${alivePasses.length} alive passes. ` + `Passes in cycle: [${cycleParticipants.join(', ')}]`);
265
276
  }
266
277
  return result;
267
278
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rendergraph.js","sources":["../../../src/render/rendergraph/rendergraph.ts"],"sourcesContent":["import {\r\n RGHandle,\r\n RGResource,\r\n RGPass,\r\n type RGTextureDesc,\r\n type RGPassBuilder,\r\n type RGExecuteFn,\r\n type RGExecuteContext,\r\n type CompiledRenderGraph,\r\n type RGResourceLifetime\r\n} from './types';\r\n\r\n/**\r\n * Render Graph — declarative, configurable render pipeline.\r\n *\r\n * Usage:\r\n * ```ts\r\n * const graph = new RenderGraph();\r\n * const backbuffer = graph.importTexture('backbuffer');\r\n *\r\n * let linearDepth: RGHandle;\r\n * graph.addPass('DepthPrepass', (builder) => {\r\n * linearDepth = builder.createTexture({ format: 'r32f', label: 'linearDepth' });\r\n * builder.setExecute(() => { ... });\r\n * });\r\n *\r\n * graph.addPass('LightPass', (builder) => {\r\n * builder.read(linearDepth);\r\n * builder.write(backbuffer);\r\n * builder.setExecute(() => { ... });\r\n * });\r\n *\r\n * const compiled = graph.compile([backbuffer]);\r\n * graph.execute(compiled);\r\n * graph.reset();\r\n * ```\r\n *\r\n * @public\r\n */\r\nexport class RenderGraph {\r\n /** @internal */\r\n private _nextResourceId = 0;\r\n /** @internal */\r\n private _resources: Map<number, RGResource> = new Map();\r\n /** @internal */\r\n private _passes: RGPass[] = [];\r\n /** @internal */\r\n private _compiled: CompiledRenderGraph | null = null;\r\n\r\n // ─── Graph Building ─────────────────────────────────────────────────\r\n\r\n /**\r\n * Import an external (persistent) texture into the graph.\r\n *\r\n * Imported resources are not allocated or released by the graph.\r\n * Typically used for the backbuffer or any texture that outlives a single frame.\r\n *\r\n * @param name - Debug label for the imported resource.\r\n * @returns A handle referencing the imported resource.\r\n */\r\n importTexture(name: string): RGHandle {\r\n const id = this._nextResourceId++;\r\n const resource = new RGResource(id, name, 'imported', null);\r\n this._resources.set(id, resource);\r\n this._compiled = null;\r\n return new RGHandle(id, name);\r\n }\r\n\r\n /**\r\n * Add a render pass to the graph.\r\n *\r\n * The setup callback receives a {@link RGPassBuilder} to declare resource\r\n * dependencies. Call `builder.setExecute(fn)` inside setup to provide the\r\n * execution callback.\r\n *\r\n * @param name - Debug label for the pass.\r\n * @param setup - Setup callback that declares resources and sets the execute function.\r\n */\r\n addPass<T = void>(name: string, setup: (builder: RGPassBuilder) => T): T {\r\n const pass = new RGPass(this._passes.length, name);\r\n const builder = this._createBuilder(pass);\r\n const data = setup(builder);\r\n pass.data = data;\r\n this._passes.push(pass);\r\n this._compiled = null;\r\n return data;\r\n }\r\n\r\n // ─── Compilation ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Compile the render graph.\r\n *\r\n * Performs dead-pass culling, topological sorting, and resource lifetime analysis.\r\n *\r\n * @param outputs - Handles of resources that must be produced (graph sinks).\r\n * Passes that do not contribute to these outputs (directly or transitively)\r\n * are culled, unless marked as side-effect passes.\r\n * @returns The compiled graph ready for execution.\r\n */\r\n compile(outputs: RGHandle[]): CompiledRenderGraph {\r\n if (this._compiled) {\r\n return this._compiled;\r\n }\r\n // 1. Mark alive passes via backward traversal from outputs + side-effect passes\r\n this._cullDeadPasses(outputs);\r\n // 2. Topological sort of alive passes\r\n const ordered = this._topologicalSort();\r\n // 3. Resource lifetime analysis\r\n const lifetimes = this._analyzeLifetimes(ordered);\r\n\r\n this._compiled = { orderedPasses: ordered, lifetimes };\r\n return this._compiled;\r\n }\r\n\r\n /**\r\n * Execute a compiled render graph (simple mode, no resource management).\r\n *\r\n * For automatic resource allocation/release, use {@link RenderGraphExecutor} instead.\r\n *\r\n * @param compiled - The compiled graph from {@link compile}.\r\n */\r\n execute(compiled: CompiledRenderGraph): void {\r\n const noopCtx: RGExecuteContext = {\r\n getTexture() {\r\n throw new Error(\r\n 'RenderGraph.execute(): resource resolution not available. Use RenderGraphExecutor for managed execution.'\r\n );\r\n }\r\n };\r\n for (const pass of compiled.orderedPasses) {\r\n if (pass.executeFn) {\r\n (pass.executeFn as RGExecuteFn<unknown>)(noopCtx, pass.data);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Reset the graph for the next frame.\r\n *\r\n * Clears all passes, transient resources, and compiled state.\r\n * Imported resources are also cleared — re-import them each frame.\r\n */\r\n reset(): void {\r\n this._passes.length = 0;\r\n this._resources.clear();\r\n this._nextResourceId = 0;\r\n this._compiled = null;\r\n }\r\n\r\n // ─── Accessors (for testing / debugging) ────────────────────────────\r\n\r\n /** @internal */\r\n getResource(handle: RGHandle): RGResource | undefined {\r\n return this._resources.get(handle._id);\r\n }\r\n\r\n /** @internal */\r\n get passes(): ReadonlyArray<RGPass> {\r\n return this._passes;\r\n }\r\n\r\n /** @internal */\r\n get resources(): ReadonlyMap<number, RGResource> {\r\n return this._resources;\r\n }\r\n\r\n // ─── Private: Builder ───────────────────────────────────────────────\r\n\r\n /** @internal */\r\n private _createBuilder(pass: RGPass): RGPassBuilder {\r\n const graph = this;\r\n return {\r\n read(handle: RGHandle): void {\r\n const res = graph._resources.get(handle._id);\r\n if (!res) {\r\n throw new Error(`RenderGraph: unknown resource \"${handle.name}\" (id=${handle._id})`);\r\n }\r\n pass.reads.push(res);\r\n res.consumers.push(pass);\r\n },\r\n write(handle: RGHandle): void {\r\n const res = graph._resources.get(handle._id);\r\n if (!res) {\r\n throw new Error(`RenderGraph: unknown resource \"${handle.name}\" (id=${handle._id})`);\r\n }\r\n if (res.producer && res.producer !== pass) {\r\n throw new Error(\r\n `RenderGraph: resource \"${res.name}\" already produced by pass \"${res.producer.name}\", ` +\r\n `cannot be written by pass \"${pass.name}\"`\r\n );\r\n }\r\n res.producer = pass;\r\n pass.writes.push(res);\r\n },\r\n createTexture(desc: RGTextureDesc): RGHandle {\r\n const id = graph._nextResourceId++;\r\n const name = desc.label ?? `_tex_${id}`;\r\n const res = new RGResource(id, name, 'transient', desc);\r\n res.producer = pass;\r\n graph._resources.set(id, res);\r\n pass.writes.push(res);\r\n return new RGHandle(id, name);\r\n },\r\n sideEffect(): void {\r\n pass.hasSideEffect = true;\r\n },\r\n setExecute<D>(fn: RGExecuteFn<D>): void {\r\n pass.executeFn = fn as RGExecuteFn<unknown>;\r\n }\r\n };\r\n }\r\n\r\n // ─── Private: Dead Pass Culling ─────────────────────────────────────\r\n\r\n /** @internal */\r\n private _cullDeadPasses(outputs: RGHandle[]): void {\r\n // Start with all passes marked dead\r\n for (const pass of this._passes) {\r\n pass.alive = false;\r\n }\r\n\r\n // Seed: resources that are requested outputs\r\n const neededResources = new Set<number>();\r\n const stack: RGResource[] = [];\r\n\r\n for (const handle of outputs) {\r\n const res = this._resources.get(handle._id);\r\n if (res) {\r\n neededResources.add(res.id);\r\n stack.push(res);\r\n }\r\n }\r\n\r\n // Seed: side-effect passes (always alive) — push their read dependencies\r\n for (const pass of this._passes) {\r\n if (pass.hasSideEffect) {\r\n pass.alive = true;\r\n for (const res of pass.reads) {\r\n if (!neededResources.has(res.id)) {\r\n neededResources.add(res.id);\r\n stack.push(res);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Backward traversal: for each needed resource, mark its producer alive\r\n // and recursively mark the producer's read dependencies as needed\r\n while (stack.length > 0) {\r\n const res = stack.pop()!;\r\n const producer = res.producer;\r\n if (producer && !producer.alive) {\r\n producer.alive = true;\r\n for (const dep of producer.reads) {\r\n if (!neededResources.has(dep.id)) {\r\n neededResources.add(dep.id);\r\n stack.push(dep);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ─── Private: Topological Sort (Kahn's Algorithm) ───────────────────\r\n\r\n /** @internal */\r\n private _topologicalSort(): RGPass[] {\r\n const alivePasses = this._passes.filter((p) => p.alive);\r\n if (alivePasses.length === 0) {\r\n return [];\r\n }\r\n\r\n // Build adjacency: producer -> consumers (only among alive passes)\r\n const aliveSet = new Set(alivePasses);\r\n const inDegree = new Map<RGPass, number>();\r\n const adjacency = new Map<RGPass, RGPass[]>();\r\n\r\n for (const pass of alivePasses) {\r\n inDegree.set(pass, 0);\r\n adjacency.set(pass, []);\r\n }\r\n\r\n // For each resource, its producer has an edge to each of its consumers\r\n for (const res of this._resources.values()) {\r\n if (!res.producer || !aliveSet.has(res.producer)) {\r\n continue;\r\n }\r\n for (const consumer of res.consumers) {\r\n if (!aliveSet.has(consumer)) {\r\n continue;\r\n }\r\n adjacency.get(res.producer)!.push(consumer);\r\n inDegree.set(consumer, inDegree.get(consumer)! + 1);\r\n }\r\n }\r\n\r\n // Kahn's algorithm\r\n const queue: RGPass[] = [];\r\n for (const pass of alivePasses) {\r\n if (inDegree.get(pass) === 0) {\r\n queue.push(pass);\r\n }\r\n }\r\n\r\n const result: RGPass[] = [];\r\n while (queue.length > 0) {\r\n const pass = queue.shift()!;\r\n result.push(pass);\r\n for (const neighbor of adjacency.get(pass)!) {\r\n const deg = inDegree.get(neighbor)! - 1;\r\n inDegree.set(neighbor, deg);\r\n if (deg === 0) {\r\n queue.push(neighbor);\r\n }\r\n }\r\n }\r\n\r\n if (result.length !== alivePasses.length) {\r\n throw new Error(\r\n `RenderGraph: circular dependency detected. ` +\r\n `Sorted ${result.length} of ${alivePasses.length} alive passes.`\r\n );\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // ─── Private: Resource Lifetime Analysis ────────────────────────────\r\n\r\n /** @internal */\r\n private _analyzeLifetimes(orderedPasses: RGPass[]): Map<number, RGResourceLifetime> {\r\n const lifetimes = new Map<number, RGResourceLifetime>();\r\n\r\n // Build pass -> order index map\r\n const orderMap = new Map<RGPass, number>();\r\n for (let i = 0; i < orderedPasses.length; i++) {\r\n orderMap.set(orderedPasses[i], i);\r\n }\r\n\r\n for (const res of this._resources.values()) {\r\n let first = Infinity;\r\n let last = -Infinity;\r\n\r\n // Producer\r\n if (res.producer && orderMap.has(res.producer)) {\r\n const idx = orderMap.get(res.producer)!;\r\n first = Math.min(first, idx);\r\n last = Math.max(last, idx);\r\n }\r\n\r\n // Consumers\r\n for (const consumer of res.consumers) {\r\n if (orderMap.has(consumer)) {\r\n const idx = orderMap.get(consumer)!;\r\n first = Math.min(first, idx);\r\n last = Math.max(last, idx);\r\n }\r\n }\r\n\r\n if (first !== Infinity) {\r\n lifetimes.set(res.id, { resource: res, firstUse: first, lastUse: last });\r\n }\r\n }\r\n\r\n return lifetimes;\r\n }\r\n}\r\n"],"names":["RenderGraph","_nextResourceId","_resources","Map","_passes","_compiled","importTexture","name","id","resource","RGResource","set","RGHandle","addPass","setup","pass","RGPass","length","builder","_createBuilder","data","push","compile","outputs","_cullDeadPasses","ordered","_topologicalSort","lifetimes","_analyzeLifetimes","orderedPasses","execute","compiled","noopCtx","getTexture","Error","executeFn","reset","clear","getResource","handle","get","_id","passes","resources","graph","read","res","reads","consumers","write","producer","writes","createTexture","desc","label","sideEffect","hasSideEffect","setExecute","fn","alive","neededResources","Set","stack","add","has","pop","dep","alivePasses","filter","p","aliveSet","inDegree","adjacency","values","consumer","queue","result","shift","neighbor","deg","orderMap","i","first","Infinity","last","idx","Math","min","max","firstUse","lastUse"],"mappings":"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"}
1
+ {"version":3,"file":"rendergraph.js","sources":["../../../src/render/rendergraph/rendergraph.ts"],"sourcesContent":["import {\r\n RGHandle,\r\n RGResource,\r\n RGPass,\r\n type RGTextureDesc,\r\n type RGPassBuilder,\r\n type RGExecuteFn,\r\n type RGExecuteContext,\r\n type CompiledRenderGraph,\r\n type RGResourceLifetime\r\n} from './types';\r\n\r\n/**\r\n * Render Graph — declarative, configurable render pipeline.\r\n *\r\n * Usage:\r\n * ```ts\r\n * const graph = new RenderGraph();\r\n * const backbuffer = graph.importTexture('backbuffer');\r\n *\r\n * let linearDepth: RGHandle;\r\n * graph.addPass('DepthPrepass', (builder) => {\r\n * linearDepth = builder.createTexture({ format: 'r32f', label: 'linearDepth' });\r\n * builder.setExecute(() => { ... });\r\n * });\r\n *\r\n * graph.addPass('LightPass', (builder) => {\r\n * builder.read(linearDepth);\r\n * builder.write(backbuffer);\r\n * builder.setExecute(() => { ... });\r\n * });\r\n *\r\n * const compiled = graph.compile([backbuffer]);\r\n * graph.execute(compiled);\r\n * graph.reset();\r\n * ```\r\n *\r\n * @public\r\n */\r\nexport class RenderGraph {\r\n /** @internal */\r\n private _nextResourceId = 0;\r\n /** @internal */\r\n private _resources: Map<number, RGResource> = new Map();\r\n /** @internal */\r\n private _passes: RGPass[] = [];\r\n /** @internal */\r\n private _compiled: CompiledRenderGraph | null = null;\r\n\r\n // ─── Graph Building ─────────────────────────────────────────────────\r\n\r\n /**\r\n * Import an external (persistent) texture into the graph.\r\n *\r\n * Imported resources are not allocated or released by the graph.\r\n * Typically used for the backbuffer or any texture that outlives a single frame.\r\n *\r\n * @param name - Debug label for the imported resource.\r\n * @returns A handle referencing the imported resource.\r\n */\r\n importTexture(name: string): RGHandle {\r\n const id = this._nextResourceId++;\r\n const resource = new RGResource(id, name, 'imported', null);\r\n this._resources.set(id, resource);\r\n this._compiled = null;\r\n return new RGHandle(id, name);\r\n }\r\n\r\n /**\r\n * Add a render pass to the graph.\r\n *\r\n * The setup callback receives a {@link RGPassBuilder} to declare resource\r\n * dependencies. Call `builder.setExecute(fn)` inside setup to provide the\r\n * execution callback.\r\n *\r\n * @param name - Debug label for the pass.\r\n * @param setup - Setup callback that declares resources and sets the execute function.\r\n */\r\n addPass<T = void>(name: string, setup: (builder: RGPassBuilder) => T): T {\r\n const pass = new RGPass(this._passes.length, name);\r\n const builder = this._createBuilder(pass);\r\n const data = setup(builder);\r\n pass.data = data;\r\n this._passes.push(pass);\r\n this._compiled = null;\r\n return data;\r\n }\r\n\r\n // ─── Compilation ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Compile the render graph.\r\n *\r\n * Performs dead-pass culling, topological sorting, and resource lifetime analysis.\r\n *\r\n * @param outputs - Handles of resources that must be produced (graph sinks).\r\n * Passes that do not contribute to these outputs (directly or transitively)\r\n * are culled, unless marked as side-effect passes.\r\n * @returns The compiled graph ready for execution.\r\n */\r\n compile(outputs: RGHandle[]): CompiledRenderGraph {\r\n if (this._compiled) {\r\n return this._compiled;\r\n }\r\n // 1. Mark alive passes via backward traversal from outputs + side-effect passes\r\n this._cullDeadPasses(outputs);\r\n // 2. Topological sort of alive passes\r\n const ordered = this._topologicalSort();\r\n // 3. Resource lifetime analysis\r\n const lifetimes = this._analyzeLifetimes(ordered);\r\n\r\n this._compiled = { orderedPasses: ordered, lifetimes };\r\n return this._compiled;\r\n }\r\n\r\n /**\r\n * Execute a compiled render graph (simple mode, no resource management).\r\n *\r\n * For automatic resource allocation/release, use {@link RenderGraphExecutor} instead.\r\n *\r\n * @param compiled - The compiled graph from {@link compile}.\r\n */\r\n execute(compiled: CompiledRenderGraph): void {\r\n const noopCtx: RGExecuteContext = {\r\n getTexture() {\r\n throw new Error(\r\n 'RenderGraph.execute(): resource resolution not available. Use RenderGraphExecutor for managed execution.'\r\n );\r\n }\r\n };\r\n for (const pass of compiled.orderedPasses) {\r\n if (pass.executeFn) {\r\n (pass.executeFn as RGExecuteFn<unknown>)(noopCtx, pass.data);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Reset the graph for the next frame.\r\n *\r\n * Clears all passes, transient resources, and compiled state.\r\n * Imported resources are also cleared — re-import them each frame.\r\n */\r\n reset(): void {\r\n this._passes.length = 0;\r\n this._resources.clear();\r\n this._nextResourceId = 0;\r\n this._compiled = null;\r\n }\r\n\r\n // ─── Accessors (for testing / debugging) ────────────────────────────\r\n\r\n /** @internal */\r\n getResource(handle: RGHandle): RGResource | undefined {\r\n return this._resources.get(handle._id);\r\n }\r\n\r\n /** @internal */\r\n get passes(): ReadonlyArray<RGPass> {\r\n return this._passes;\r\n }\r\n\r\n /** @internal */\r\n get resources(): ReadonlyMap<number, RGResource> {\r\n return this._resources;\r\n }\r\n\r\n // ─── Private: Builder ───────────────────────────────────────────────\r\n\r\n /** @internal */\r\n private _createBuilder(pass: RGPass): RGPassBuilder {\r\n const graph = this;\r\n return {\r\n read(handle: RGHandle): void {\r\n const res = graph._resources.get(handle._id);\r\n if (!res) {\r\n throw new Error(`RenderGraph: unknown resource \"${handle.name}\" (id=${handle._id})`);\r\n }\r\n // Validate that transient resources have a producer\r\n if (res.kind === 'transient' && !res.producer) {\r\n throw new Error(\r\n `RenderGraph: pass \"${pass.name}\" attempts to read transient resource \"${res.name}\" ` +\r\n `which has no producer. Ensure the resource is created before being read.`\r\n );\r\n }\r\n pass.reads.push(res);\r\n res.consumers.push(pass);\r\n },\r\n write(handle: RGHandle): void {\r\n const res = graph._resources.get(handle._id);\r\n if (!res) {\r\n throw new Error(`RenderGraph: unknown resource \"${handle.name}\" (id=${handle._id})`);\r\n }\r\n if (res.producer && res.producer !== pass) {\r\n throw new Error(\r\n `RenderGraph: resource \"${res.name}\" already produced by pass \"${res.producer.name}\", ` +\r\n `cannot be written by pass \"${pass.name}\"`\r\n );\r\n }\r\n res.producer = pass;\r\n pass.writes.push(res);\r\n },\r\n createTexture(desc: RGTextureDesc): RGHandle {\r\n const id = graph._nextResourceId++;\r\n const name = desc.label ?? `_tex_${id}`;\r\n const res = new RGResource(id, name, 'transient', desc);\r\n res.producer = pass;\r\n graph._resources.set(id, res);\r\n pass.writes.push(res);\r\n return new RGHandle(id, name);\r\n },\r\n sideEffect(): void {\r\n pass.hasSideEffect = true;\r\n },\r\n setExecute<D>(fn: RGExecuteFn<D>): void {\r\n pass.executeFn = fn as RGExecuteFn<unknown>;\r\n }\r\n };\r\n }\r\n\r\n // ─── Private: Dead Pass Culling ─────────────────────────────────────\r\n\r\n /** @internal */\r\n private _cullDeadPasses(outputs: RGHandle[]): void {\r\n // Start with all passes marked dead\r\n for (const pass of this._passes) {\r\n pass.alive = false;\r\n }\r\n\r\n // Seed: resources that are requested outputs\r\n const neededResources = new Set<number>();\r\n const stack: RGResource[] = [];\r\n\r\n for (const handle of outputs) {\r\n const res = this._resources.get(handle._id);\r\n if (res) {\r\n neededResources.add(res.id);\r\n stack.push(res);\r\n }\r\n }\r\n\r\n // Seed: side-effect passes (always alive) — push their read dependencies\r\n for (const pass of this._passes) {\r\n if (pass.hasSideEffect) {\r\n pass.alive = true;\r\n for (const res of pass.reads) {\r\n if (!neededResources.has(res.id)) {\r\n neededResources.add(res.id);\r\n stack.push(res);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Backward traversal: for each needed resource, mark its producer alive\r\n // and recursively mark the producer's read dependencies as needed\r\n while (stack.length > 0) {\r\n const res = stack.pop()!;\r\n const producer = res.producer;\r\n if (producer && !producer.alive) {\r\n producer.alive = true;\r\n for (const dep of producer.reads) {\r\n if (!neededResources.has(dep.id)) {\r\n neededResources.add(dep.id);\r\n stack.push(dep);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ─── Private: Topological Sort (Kahn's Algorithm) ───────────────────\r\n\r\n /** @internal */\r\n private _topologicalSort(): RGPass[] {\r\n const alivePasses = this._passes.filter((p) => p.alive);\r\n if (alivePasses.length === 0) {\r\n return [];\r\n }\r\n\r\n // Build adjacency: producer -> consumers (only among alive passes)\r\n const aliveSet = new Set(alivePasses);\r\n const inDegree = new Map<RGPass, number>();\r\n const adjacency = new Map<RGPass, RGPass[]>();\r\n\r\n for (const pass of alivePasses) {\r\n inDegree.set(pass, 0);\r\n adjacency.set(pass, []);\r\n }\r\n\r\n // For each resource, its producer has an edge to each of its consumers\r\n for (const res of this._resources.values()) {\r\n if (!res.producer || !aliveSet.has(res.producer)) {\r\n continue;\r\n }\r\n for (const consumer of res.consumers) {\r\n if (!aliveSet.has(consumer)) {\r\n continue;\r\n }\r\n adjacency.get(res.producer)!.push(consumer);\r\n inDegree.set(consumer, inDegree.get(consumer)! + 1);\r\n }\r\n }\r\n\r\n // Kahn's algorithm\r\n const queue: RGPass[] = [];\r\n for (const pass of alivePasses) {\r\n if (inDegree.get(pass) === 0) {\r\n queue.push(pass);\r\n }\r\n }\r\n\r\n const result: RGPass[] = [];\r\n while (queue.length > 0) {\r\n const pass = queue.shift()!;\r\n result.push(pass);\r\n for (const neighbor of adjacency.get(pass)!) {\r\n const deg = inDegree.get(neighbor)! - 1;\r\n inDegree.set(neighbor, deg);\r\n if (deg === 0) {\r\n queue.push(neighbor);\r\n }\r\n }\r\n }\r\n\r\n if (result.length !== alivePasses.length) {\r\n // Find passes that are part of the cycle (those with non-zero in-degree)\r\n const cycleParticipants: string[] = [];\r\n for (const [pass, degree] of inDegree) {\r\n if (degree > 0) {\r\n cycleParticipants.push(pass.name);\r\n }\r\n }\r\n throw new Error(\r\n `RenderGraph: circular dependency detected. ` +\r\n `Sorted ${result.length} of ${alivePasses.length} alive passes. ` +\r\n `Passes in cycle: [${cycleParticipants.join(', ')}]`\r\n );\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // ─── Private: Resource Lifetime Analysis ────────────────────────────\r\n\r\n /** @internal */\r\n private _analyzeLifetimes(orderedPasses: RGPass[]): Map<number, RGResourceLifetime> {\r\n const lifetimes = new Map<number, RGResourceLifetime>();\r\n\r\n // Build pass -> order index map\r\n const orderMap = new Map<RGPass, number>();\r\n for (let i = 0; i < orderedPasses.length; i++) {\r\n orderMap.set(orderedPasses[i], i);\r\n }\r\n\r\n for (const res of this._resources.values()) {\r\n let first = Infinity;\r\n let last = -Infinity;\r\n\r\n // Producer\r\n if (res.producer && orderMap.has(res.producer)) {\r\n const idx = orderMap.get(res.producer)!;\r\n first = Math.min(first, idx);\r\n last = Math.max(last, idx);\r\n }\r\n\r\n // Consumers\r\n for (const consumer of res.consumers) {\r\n if (orderMap.has(consumer)) {\r\n const idx = orderMap.get(consumer)!;\r\n first = Math.min(first, idx);\r\n last = Math.max(last, idx);\r\n }\r\n }\r\n\r\n if (first !== Infinity) {\r\n lifetimes.set(res.id, { resource: res, firstUse: first, lastUse: last });\r\n }\r\n }\r\n\r\n return lifetimes;\r\n }\r\n}\r\n"],"names":["RenderGraph","_nextResourceId","_resources","Map","_passes","_compiled","importTexture","name","id","resource","RGResource","set","RGHandle","addPass","setup","pass","RGPass","length","builder","_createBuilder","data","push","compile","outputs","_cullDeadPasses","ordered","_topologicalSort","lifetimes","_analyzeLifetimes","orderedPasses","execute","compiled","noopCtx","getTexture","Error","executeFn","reset","clear","getResource","handle","get","_id","passes","resources","graph","read","res","kind","producer","reads","consumers","write","writes","createTexture","desc","label","sideEffect","hasSideEffect","setExecute","fn","alive","neededResources","Set","stack","add","has","pop","dep","alivePasses","filter","p","aliveSet","inDegree","adjacency","values","consumer","queue","result","shift","neighbor","deg","cycleParticipants","degree","join","orderMap","i","first","Infinity","last","idx","Math","min","max","firstUse","lastUse"],"mappings":"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"}
@@ -20,7 +20,7 @@
20
20
  }
21
21
  /**
22
22
  * Internal bookkeeping for a resource within the render graph.
23
- * @internal
23
+ * @public
24
24
  */ class RGResource {
25
25
  id;
26
26
  name;
@@ -37,7 +37,7 @@
37
37
  }
38
38
  /**
39
39
  * Internal bookkeeping for a pass within the render graph.
40
- * @internal
40
+ * @public
41
41
  */ class RGPass {
42
42
  index;
43
43
  name;