@forgeax/engine-render 0.1.32 → 0.1.33

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 (250) hide show
  1. package/README.md +379 -33
  2. package/dist/assembly/analytic-fog-registration.d.ts +3 -0
  3. package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
  4. package/dist/assembly/fxaa-registration.d.ts +4 -0
  5. package/dist/assembly/fxaa-registration.d.ts.map +1 -0
  6. package/dist/assembly/lod-observation.d.ts +4 -0
  7. package/dist/assembly/lod-observation.d.ts.map +1 -0
  8. package/dist/assembly/motion-blur-registration.d.ts +3 -0
  9. package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
  10. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  11. package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
  12. package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
  13. package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
  14. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
  15. package/dist/assembly/webgpu-ready.d.ts +1 -1
  16. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  17. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  18. package/dist/bloom-admission.d.ts +13 -0
  19. package/dist/bloom-admission.d.ts.map +1 -0
  20. package/dist/{chunk-DRR7D3KX.mjs → chunk-3RTCJTH4.mjs} +12 -9
  21. package/dist/chunk-3RTCJTH4.mjs.map +1 -0
  22. package/dist/{chunk-S665NJNF.mjs → chunk-LEAXOMYJ.mjs} +3 -3
  23. package/dist/{chunk-S665NJNF.mjs.map → chunk-LEAXOMYJ.mjs.map} +1 -1
  24. package/dist/{chunk-6TFBXLRJ.mjs → chunk-NB2S7ZRX.mjs} +155 -11
  25. package/dist/chunk-NB2S7ZRX.mjs.map +1 -0
  26. package/dist/{chunk-LULCA3OF.mjs → chunk-NNQL7CB3.mjs} +4 -4
  27. package/dist/{chunk-LULCA3OF.mjs.map → chunk-NNQL7CB3.mjs.map} +1 -1
  28. package/dist/{chunk-4NNZQCL3.mjs → chunk-OO3DRYK7.mjs} +66 -200
  29. package/dist/chunk-OO3DRYK7.mjs.map +1 -0
  30. package/dist/{chunk-GWCEMDVR.mjs → chunk-PLAXOOX5.mjs} +232 -7
  31. package/dist/chunk-PLAXOOX5.mjs.map +1 -0
  32. package/dist/{chunk-JRIPCMYC.mjs → chunk-VOZWDM3L.mjs} +283 -193
  33. package/dist/chunk-VOZWDM3L.mjs.map +1 -0
  34. package/dist/{chunk-JCIRYQ4V.mjs → chunk-ZDQWGQW7.mjs} +10 -4
  35. package/dist/chunk-ZDQWGQW7.mjs.map +1 -0
  36. package/dist/components/atmosphere.d.ts +2 -0
  37. package/dist/components/atmosphere.d.ts.map +1 -1
  38. package/dist/components/camera.d.ts +20 -4
  39. package/dist/components/camera.d.ts.map +1 -1
  40. package/dist/components/mesh-filter.d.ts +6 -5
  41. package/dist/components/mesh-filter.d.ts.map +1 -1
  42. package/dist/components/motion-blur.d.ts +1 -0
  43. package/dist/components/motion-blur.d.ts.map +1 -1
  44. package/dist/construct-renderer.mjs +2865 -526
  45. package/dist/construct-renderer.mjs.map +1 -1
  46. package/dist/device/gpu-residency.d.ts +6 -0
  47. package/dist/device/gpu-residency.d.ts.map +1 -1
  48. package/dist/environment/analytic-fog.d.ts +6 -0
  49. package/dist/environment/analytic-fog.d.ts.map +1 -0
  50. package/dist/errors/render.d.ts +6 -2
  51. package/dist/errors/render.d.ts.map +1 -1
  52. package/dist/extract/camera.d.ts.map +1 -1
  53. package/dist/extract/contracts.d.ts +7 -0
  54. package/dist/extract/contracts.d.ts.map +1 -1
  55. package/dist/extract/environment.d.ts +2 -0
  56. package/dist/extract/environment.d.ts.map +1 -1
  57. package/dist/features/error-reporting.d.ts +13 -0
  58. package/dist/features/error-reporting.d.ts.map +1 -0
  59. package/dist/features/host.d.ts +5 -0
  60. package/dist/features/host.d.ts.map +1 -1
  61. package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
  62. package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
  63. package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
  64. package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
  65. package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
  66. package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
  67. package/dist/features/plan.d.ts +7 -4
  68. package/dist/features/plan.d.ts.map +1 -1
  69. package/dist/features/prepared-gpu-work.d.ts +9 -5
  70. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  71. package/dist/features/render-graph-compute.d.ts.map +1 -1
  72. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  73. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  74. package/dist/gpu-driven/prepared-draw.d.ts +7 -0
  75. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  76. package/dist/gpu-driven/production-raster.d.ts +3 -1
  77. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  78. package/dist/gpu-driven/view-gpu.d.ts +9 -0
  79. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  80. package/dist/gpu-scene.d.ts +6 -1
  81. package/dist/gpu-scene.d.ts.map +1 -1
  82. package/dist/index.d.ts +5 -2
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.mjs +5 -5
  85. package/dist/inspection-types.d.ts +43 -2
  86. package/dist/inspection-types.d.ts.map +1 -1
  87. package/dist/instances.d.ts +8 -1
  88. package/dist/instances.d.ts.map +1 -1
  89. package/dist/internal.mjs +6 -6
  90. package/dist/pipeline/standard-post.d.ts +28 -19
  91. package/dist/pipeline/standard-post.d.ts.map +1 -1
  92. package/dist/pipeline-spec.d.ts +2 -2
  93. package/dist/record/frame-snapshot.d.ts +3 -0
  94. package/dist/record/frame-snapshot.d.ts.map +1 -1
  95. package/dist/record/frame-targets.d.ts.map +1 -1
  96. package/dist/record/frame.d.ts +5 -2
  97. package/dist/record/frame.d.ts.map +1 -1
  98. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  99. package/dist/record/mesh-ssbo.d.ts +6 -5
  100. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  101. package/dist/record/render-context.d.ts +12 -28
  102. package/dist/record/render-context.d.ts.map +1 -1
  103. package/dist/record/shadow-pass.d.ts.map +1 -1
  104. package/dist/record/skybox-post-pass.d.ts +5 -3
  105. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  106. package/dist/record/typed-frame-graph.d.ts +1 -1
  107. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  108. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  109. package/dist/render-contract.d.ts +24 -4
  110. package/dist/render-contract.d.ts.map +1 -1
  111. package/dist/render-pipeline.d.ts +3 -1
  112. package/dist/render-pipeline.d.ts.map +1 -1
  113. package/dist/render-system-extract-tail.d.ts.map +1 -1
  114. package/dist/render-system-extract.d.ts +8 -1
  115. package/dist/render-system-extract.d.ts.map +1 -1
  116. package/dist/render-system.d.ts +7 -1
  117. package/dist/render-system.d.ts.map +1 -1
  118. package/dist/scene/render-scene.d.ts +2 -0
  119. package/dist/scene/render-scene.d.ts.map +1 -1
  120. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  121. package/dist/temporal/frame.d.ts +7 -0
  122. package/dist/temporal/frame.d.ts.map +1 -1
  123. package/dist/temporal/index.mjs +5 -5
  124. package/dist/temporal/view.d.ts +6 -1
  125. package/dist/temporal/view.d.ts.map +1 -1
  126. package/dist/typed-render-graph-primitives.d.ts +10 -7
  127. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  128. package/dist/volume/component.d.ts +0 -1
  129. package/dist/volume/component.d.ts.map +1 -1
  130. package/dist/volume/passes.d.ts.map +1 -1
  131. package/dist/volume/temporal.d.ts +3 -1
  132. package/dist/volume/temporal.d.ts.map +1 -1
  133. package/package.json +21 -21
  134. package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
  135. package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
  136. package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
  137. package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
  138. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
  139. package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
  140. package/src/__tests__/environment-selection.unit.test.ts +12 -0
  141. package/src/__tests__/factory-contract.integration.test.ts +331 -68
  142. package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
  143. package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
  144. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
  145. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +1 -1
  146. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
  147. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +11 -0
  148. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
  149. package/src/__tests__/gpu-scene.unit.test.ts +91 -0
  150. package/src/__tests__/instances-store.unit.test.ts +75 -0
  151. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
  152. package/src/__tests__/motion-blur-compute.dawn.test.ts +583 -0
  153. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
  154. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
  155. package/src/__tests__/public-surface.test-d.ts +8 -0
  156. package/src/__tests__/render-error-code-owner.test-d.ts +2 -0
  157. package/src/__tests__/render-feature-error-reporting.unit.test.ts +24 -0
  158. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
  159. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +31 -0
  160. package/src/__tests__/renderer-frame-transaction.integration.test.ts +7 -1
  161. package/src/__tests__/shader-manifest-fixture.ts +4 -4
  162. package/src/__tests__/skinned-shadow-caster.test.ts +2 -0
  163. package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
  164. package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
  165. package/src/__tests__/standard-pipeline.integration.test.ts +18 -8
  166. package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
  167. package/src/__tests__/temporal-view.unit.test.ts +2 -1
  168. package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
  169. package/src/__tests__/volume-optics-oracle.unit.test.ts +3 -1
  170. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +177 -13
  171. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +447 -61
  172. package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
  173. package/src/__tests__/volumetric-fog-topology.unit.test.ts +19 -3
  174. package/src/assembly/analytic-fog-registration.ts +14 -0
  175. package/src/assembly/fxaa-registration.ts +17 -0
  176. package/src/assembly/lod-observation.ts +12 -0
  177. package/src/assembly/motion-blur-registration.ts +17 -0
  178. package/src/assembly/renderer-facade.ts +2 -0
  179. package/src/assembly/temporal-post-process-prewarm.ts +40 -0
  180. package/src/assembly/webgpu-ready-contract.ts +8 -3
  181. package/src/assembly/webgpu-ready.ts +181 -245
  182. package/src/assembly/webgpu-renderer.ts +16 -31
  183. package/src/bloom-admission.ts +21 -0
  184. package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
  185. package/src/components/atmosphere.ts +4 -0
  186. package/src/components/camera.ts +66 -10
  187. package/src/components/mesh-filter.ts +11 -9
  188. package/src/components/motion-blur.ts +1 -0
  189. package/src/device/gpu-residency.ts +56 -12
  190. package/src/environment/analytic-fog.ts +44 -0
  191. package/src/environment/background.ts +2 -2
  192. package/src/errors/render.ts +14 -1
  193. package/src/extract/camera.ts +20 -7
  194. package/src/extract/contracts.ts +7 -0
  195. package/src/extract/environment.ts +4 -0
  196. package/src/features/error-reporting.ts +78 -0
  197. package/src/features/host.ts +25 -12
  198. package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
  199. package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
  200. package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
  201. package/src/features/motion-blur/motion-blur-params.ts +70 -2
  202. package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
  203. package/src/features/plan.ts +25 -8
  204. package/src/features/prepared-gpu-work.ts +86 -35
  205. package/src/features/render-graph-compute.ts +13 -5
  206. package/src/features/render-graph-contribution.ts +2 -0
  207. package/src/gpu-driven/material-artifacts.ts +2 -7
  208. package/src/gpu-driven/prepared-draw.ts +15 -10
  209. package/src/gpu-driven/production-raster.ts +83 -7
  210. package/src/gpu-driven/view-gpu.ts +17 -0
  211. package/src/gpu-scene.ts +188 -21
  212. package/src/index.ts +32 -0
  213. package/src/inspection-types.ts +60 -2
  214. package/src/instances.ts +80 -1
  215. package/src/pipeline/standard-post.ts +307 -78
  216. package/src/pipeline-spec.ts +5 -5
  217. package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
  218. package/src/record/__tests__/temporal-payload.unit.test.ts +2 -1
  219. package/src/record/frame-snapshot.ts +5 -1
  220. package/src/record/frame-targets.ts +10 -6
  221. package/src/record/frame.ts +163 -22
  222. package/src/record/main-pass-geometry.ts +30 -1
  223. package/src/record/main-pass-sprite-draws.ts +6 -1
  224. package/src/record/mesh-ssbo.ts +43 -6
  225. package/src/record/render-context.ts +12 -28
  226. package/src/record/shadow-pass.ts +6 -1
  227. package/src/record/skybox-post-pass.ts +122 -196
  228. package/src/record/typed-frame-graph.ts +153 -9
  229. package/src/recovery/render-system-candidate.ts +22 -10
  230. package/src/render-contract.ts +23 -4
  231. package/src/render-pipeline.ts +6 -1
  232. package/src/render-system-extract-tail.ts +16 -0
  233. package/src/render-system-extract.ts +45 -13
  234. package/src/render-system.ts +255 -120
  235. package/src/scene/render-scene.ts +85 -4
  236. package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
  237. package/src/temporal/frame-coordinator.ts +8 -1
  238. package/src/temporal/frame.ts +20 -0
  239. package/src/temporal/view.ts +13 -2
  240. package/src/typed-render-graph-primitives.ts +121 -48
  241. package/src/volume/component.ts +0 -1
  242. package/src/volume/passes.ts +8 -4
  243. package/src/volume/resources.ts +1 -1
  244. package/src/volume/temporal.ts +11 -0
  245. package/dist/chunk-4NNZQCL3.mjs.map +0 -1
  246. package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
  247. package/dist/chunk-DRR7D3KX.mjs.map +0 -1
  248. package/dist/chunk-GWCEMDVR.mjs.map +0 -1
  249. package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
  250. package/dist/chunk-JRIPCMYC.mjs.map +0 -1
@@ -8,6 +8,10 @@ const pipelineSource = readFileSync(
8
8
  fileURLToPath(new URL('../pipeline/standard-pipeline.ts', import.meta.url)),
9
9
  'utf8',
10
10
  );
11
+ const forwardPipelineSource = readFileSync(
12
+ fileURLToPath(new URL('../pipeline/standard-forward-lane.ts', import.meta.url)),
13
+ 'utf8',
14
+ );
11
15
  const shaderSource = (name: string): string =>
12
16
  readFileSync(
13
17
  fileURLToPath(new URL(`../../../shader/src/volume/${name}`, import.meta.url)),
@@ -34,9 +38,8 @@ describe('volumetric fog RenderGraph topology', () => {
34
38
  expect(composite).toContain('abs(neighbor.a - center.a) * 6.0');
35
39
  });
36
40
 
37
- it('derives deterministic integration density from the authored froxel depth', () => {
41
+ it('integrates the ray independently of packed visibility depth', () => {
38
42
  const integrate = shaderSource('volume-integrate.wgsl');
39
- expect(integrate).toContain('let ray_step_count = visibility_depth;');
40
43
  expect(integrate).toContain('for (var step = 0u; step < ray_step_count; step = step + 1u)');
41
44
  expect(integrate).toContain('let visibility_depth = max(textureNumLayers(froxel) * 4u, 1u);');
42
45
  });
@@ -44,7 +47,7 @@ describe('volumetric fog RenderGraph topology', () => {
44
47
  it('keeps the Beer-Lambert extinction input physically non-negative', () => {
45
48
  const integrate = shaderSource('volume-integrate.wgsl');
46
49
  expect(integrate).toContain(
47
- 'let density_value = max(volume_scattering_density(world_position), 0.0);',
50
+ 'let density_value = max(volume_scattering_density(world_position, volume_params.simulation.x), 0.0);',
48
51
  );
49
52
  });
50
53
 
@@ -114,6 +117,15 @@ describe('volumetric fog RenderGraph topology', () => {
114
117
  );
115
118
  });
116
119
 
120
+ it('keeps mesh CSM visibility on the shared volume owner in both Standard lanes', () => {
121
+ for (const source of [pipelineSource, forwardPipelineSource]) {
122
+ expect(source).toContain('addAuthoredVolumetricFogPasses');
123
+ expect(source).toContain('shadows.value.directional?.view');
124
+ }
125
+ expect(shaderSource('volume-inject.wgsl')).toContain('fn volume_cascade');
126
+ expect(shaderSource('volume-inject.wgsl')).toContain('sample_shadow_2d_kernel');
127
+ });
128
+
117
129
  it('encodes real volume work and non-constant optical semantics', () => {
118
130
  const passes = readFileSync(
119
131
  fileURLToPath(new URL('../volume/passes.ts', import.meta.url)),
@@ -182,6 +194,10 @@ describe('volumetric fog RenderGraph topology', () => {
182
194
  expect(frameSource).toContain('volumetricFogHistorySlot');
183
195
  expect(frameSource).toContain('volumetricFogHistorySignature');
184
196
  expect(frameSource).toContain('activeVolumetricFogSignature');
197
+ expect(frameSource).toContain('params[32] = fog.worldTimeSeconds ?? 0');
198
+ expect(
199
+ readFileSync(fileURLToPath(new URL('../volume/temporal.ts', import.meta.url)), 'utf8'),
200
+ ).toContain("reason: 'simulation-time'");
185
201
  });
186
202
 
187
203
  it('advances temporal history only after the accepted queue submit', () => {
@@ -0,0 +1,14 @@
1
+ import type { RenderSystem } from '../render-system';
2
+
3
+ export function registerAnalyticFogPostProcess(
4
+ renderSystem: Pick<RenderSystem, 'registerBuiltinPostProcess'>,
5
+ source: string,
6
+ candidate: boolean,
7
+ ): void {
8
+ if (candidate) return;
9
+ renderSystem.registerBuiltinPostProcess('forgeax.analytic-fog', {
10
+ source,
11
+ params: { byteSize: 112, defaultValue: new Uint8Array(112) },
12
+ reads: ['scene-color', { key: 'scene-depth', sampleType: 'depth' }],
13
+ });
14
+ }
@@ -0,0 +1,17 @@
1
+ import { FXAA_POST_PROCESS_ID } from '../render-contract';
2
+ import type { RenderSystem } from '../render-system';
3
+
4
+ /** Register the built-in FXAA post-process once for the active generation. */
5
+ export function registerFxaaPostProcess(
6
+ renderSystem: Pick<RenderSystem, 'registerBuiltinPostProcess'>,
7
+ source: string,
8
+ registered: boolean,
9
+ ): boolean {
10
+ if (registered) return true;
11
+ renderSystem.registerBuiltinPostProcess(FXAA_POST_PROCESS_ID, {
12
+ source,
13
+ params: { byteSize: 16, defaultValue: new Uint8Array(16) },
14
+ reads: ['ldrColor'],
15
+ });
16
+ return true;
17
+ }
@@ -0,0 +1,12 @@
1
+ import type { FrameReceipt } from '../render-contract';
2
+ import type { RenderSystem } from '../render-system';
3
+
4
+ export function observeLodOcclusionForReceipt(
5
+ renderSystem: Pick<RenderSystem, 'observeLodOcclusion'>,
6
+ receipt: Pick<FrameReceipt, 'frameId' | 'deviceGeneration'>,
7
+ ): Promise<void> {
8
+ return renderSystem.observeLodOcclusion({
9
+ frameId: receipt.frameId,
10
+ deviceGeneration: receipt.deviceGeneration,
11
+ });
12
+ }
@@ -0,0 +1,17 @@
1
+ import { MOTION_BLUR_PARAMS_BYTE_SIZE } from '../features/motion-blur/motion-blur-params';
2
+ import type { PostProcessShaderEntry } from '../fullscreen-post-process-pass';
3
+ import type { RenderSystem } from '../render-system';
4
+
5
+ export function registerMotionBlurPostProcess(
6
+ renderSystem: Pick<RenderSystem, 'registerBuiltinPostProcess'>,
7
+ source: string,
8
+ ): void {
9
+ renderSystem.registerBuiltinPostProcess('forgeax.motion-blur', {
10
+ source,
11
+ params: {
12
+ byteSize: MOTION_BLUR_PARAMS_BYTE_SIZE,
13
+ defaultValue: new Uint8Array(MOTION_BLUR_PARAMS_BYTE_SIZE),
14
+ },
15
+ reads: ['scene-color', 'scene-temporal'],
16
+ } satisfies PostProcessShaderEntry);
17
+ }
@@ -15,6 +15,7 @@ import {
15
15
  type RendererOperationCause,
16
16
  RendererOperationError,
17
17
  } from '../errors/render';
18
+ import { MotionBlurValidationError } from '../features/motion-blur/motion-blur-params';
18
19
  import {
19
20
  STANDARD_LIGHT_COUNTS,
20
21
  STANDARD_PIPELINE_ID,
@@ -63,6 +64,7 @@ export function exposeRenderer(renderer: RendererHostImplementation): Renderer {
63
64
  cause: structuredRendererCause(cause, 'renderer-event'),
64
65
  });
65
66
  const drawError = (cause: RhiError | RenderError): RenderError => {
67
+ if (cause instanceof MotionBlurValidationError) return cause;
66
68
  if (cause instanceof RendererOperationError) return cause;
67
69
  if (cause instanceof RendererContractFailureError) {
68
70
  return new RendererOperationError('device-operation-failed', {
@@ -0,0 +1,40 @@
1
+ import type { Result, RhiDevice, RhiError, ShaderModule } from '@forgeax/engine-rhi';
2
+ import type { ManifestEntry } from '@forgeax/engine-types';
3
+ import { postProcessShaderModuleLabel } from '../fullscreen-post-process-pass';
4
+ import { invokeDeviceCreateShaderModule } from './material-shader-policy';
5
+ import { runShimStep } from './renderer-helpers';
6
+
7
+ export type AsyncShaderModuleFactory =
8
+ | ((
9
+ device: RhiDevice,
10
+ desc: { readonly code: string; readonly label?: string },
11
+ ) => Promise<Result<ShaderModule, RhiError>>)
12
+ | undefined;
13
+
14
+ /** Create the shared readiness prewarmer for temporal/fullscreen shader entries. */
15
+ export function createTemporalShaderPrewarmer(input: {
16
+ readonly device: RhiDevice;
17
+ readonly asyncCreateShaderModule: AsyncShaderModuleFactory;
18
+ readonly seedShaderModule: (label: string, module: ShaderModule) => void;
19
+ }): (entry: ManifestEntry | undefined, id: string) => Promise<void> {
20
+ return async (entry, id): Promise<void> => {
21
+ if (entry === undefined) return;
22
+ const prewarm = await runShimStep(
23
+ () =>
24
+ input.asyncCreateShaderModule
25
+ ? input.asyncCreateShaderModule(input.device, {
26
+ code: entry.wgsl,
27
+ label: postProcessShaderModuleLabel(id, entry.wgsl),
28
+ })
29
+ : invokeDeviceCreateShaderModule(input.device, {
30
+ code: entry.wgsl,
31
+ label: postProcessShaderModuleLabel(id, entry.wgsl),
32
+ }),
33
+ 'shader-compile-failed',
34
+ `${id} shader module compiled (unified post-process prewarm)`,
35
+ `inspect manifest ${id} entry composed wgsl; check device.features`,
36
+ );
37
+ if (!prewarm.ok) throw prewarm.error;
38
+ input.seedShaderModule(postProcessShaderModuleLabel(id, entry.wgsl), prewarm.value);
39
+ };
40
+ }
@@ -7,8 +7,13 @@ export const MIPMAP_PREWARM_FORMATS: readonly GPUTextureFormat[] = [
7
7
  'rgba8unorm',
8
8
  'rgba16float',
9
9
  ];
10
- export const BRIGHT_PARAMS_BYTES = 16;
11
- export const BLUR_PARAMS_BYTES = 16;
12
- export const COMPOSITE_PARAMS_BYTES = 16;
10
+ // WebGPU requires every dynamic uniform-buffer binding offset to satisfy the
11
+ // device's minimum uniform-buffer offset alignment. Keep one shared buffer
12
+ // per pass family, with the small POD payload at the start of each 256-byte
13
+ // slice so every level remains a single production path.
14
+ export const BLOOM_UNIFORM_PARAMS_STRIDE_BYTES = 256;
15
+ export const BLOOM_DOWNSAMPLE_PARAMS_BYTES = 5 * BLOOM_UNIFORM_PARAMS_STRIDE_BYTES;
16
+ export const BLOOM_UPSAMPLE_PARAMS_BYTES = 4 * BLOOM_UNIFORM_PARAMS_STRIDE_BYTES;
17
+ export const BLOOM_COMPOSITE_PARAMS_BYTES = 16;
13
18
  export const HDR_COLOR_ATTACHMENT_FORMAT: GPUTextureFormat = 'rgba16float';
14
19
  export const DEPTH_TEXTURE_FORMAT: GPUTextureFormat = 'depth24plus-stencil8';