@forgeax/engine-render 0.1.19 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/assembly/factory.d.ts +16 -5
  3. package/dist/assembly/factory.d.ts.map +1 -1
  4. package/dist/{chunk-RJRUS55L.mjs → chunk-4XINDLAY.mjs} +267 -186
  5. package/dist/chunk-4XINDLAY.mjs.map +1 -0
  6. package/dist/{chunk-YTQ5C7YQ.mjs → chunk-CDTWTHZR.mjs} +176 -8
  7. package/dist/chunk-CDTWTHZR.mjs.map +1 -0
  8. package/dist/{chunk-IPXCABEP.mjs → chunk-M2MP4ZOU.mjs} +2 -2
  9. package/dist/chunk-M2MP4ZOU.mjs.map +1 -0
  10. package/dist/{chunk-LOSO4CTV.mjs → chunk-TBQJOK2L.mjs} +67 -3
  11. package/dist/chunk-TBQJOK2L.mjs.map +1 -0
  12. package/dist/components/light-helpers.d.ts.map +1 -1
  13. package/dist/components/spot-light.d.ts +12 -0
  14. package/dist/components/spot-light.d.ts.map +1 -1
  15. package/dist/construct-renderer.mjs +2281 -164
  16. package/dist/construct-renderer.mjs.map +1 -1
  17. package/dist/device/gpu-residency.d.ts +19 -2
  18. package/dist/device/gpu-residency.d.ts.map +1 -1
  19. package/dist/errors/render.d.ts +69 -1
  20. package/dist/errors/render.d.ts.map +1 -1
  21. package/dist/gpu-usage.d.ts +2 -0
  22. package/dist/gpu-usage.d.ts.map +1 -1
  23. package/dist/index.d.ts +7 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.mjs +3 -3
  26. package/dist/internal.mjs +1 -1
  27. package/dist/light-buffer-layout.d.ts +20 -12
  28. package/dist/light-buffer-layout.d.ts.map +1 -1
  29. package/dist/pbr-pipeline.d.ts +6 -3
  30. package/dist/pbr-pipeline.d.ts.map +1 -1
  31. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  32. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  33. package/dist/pipeline/standard-profile.d.ts +13 -0
  34. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  35. package/dist/record/frame-lighting.d.ts +2 -0
  36. package/dist/record/frame-lighting.d.ts.map +1 -1
  37. package/dist/record/frame-snapshot.d.ts +37 -1
  38. package/dist/record/frame-snapshot.d.ts.map +1 -1
  39. package/dist/record/frame-targets.d.ts.map +1 -1
  40. package/dist/record/frame.d.ts +3 -2
  41. package/dist/record/frame.d.ts.map +1 -1
  42. package/dist/record/gpu-timing.d.ts +32 -0
  43. package/dist/record/gpu-timing.d.ts.map +1 -0
  44. package/dist/record/main-pass-material.d.ts +1 -1
  45. package/dist/record/main-pass-material.d.ts.map +1 -1
  46. package/dist/record/render-context.d.ts +5 -1
  47. package/dist/record/render-context.d.ts.map +1 -1
  48. package/dist/record/shadow-pass.d.ts.map +1 -1
  49. package/dist/record/typed-frame-graph.d.ts +11 -3
  50. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  51. package/dist/render-contract.d.ts +66 -1
  52. package/dist/render-contract.d.ts.map +1 -1
  53. package/dist/render-data.d.ts +10 -6
  54. package/dist/render-data.d.ts.map +1 -1
  55. package/dist/render-pipeline.d.ts +36 -0
  56. package/dist/render-pipeline.d.ts.map +1 -1
  57. package/dist/render-system-extract.d.ts +55 -3
  58. package/dist/render-system-extract.d.ts.map +1 -1
  59. package/dist/render-system.d.ts +7 -1
  60. package/dist/render-system.d.ts.map +1 -1
  61. package/dist/renderer-inspect.d.ts +29 -0
  62. package/dist/renderer-inspect.d.ts.map +1 -0
  63. package/dist/scene/render-scene.d.ts.map +1 -1
  64. package/dist/temporal/frame.d.ts +44 -0
  65. package/dist/temporal/frame.d.ts.map +1 -0
  66. package/dist/temporal/index.mjs +3 -3
  67. package/dist/typed-render-graph-primitives.d.ts +6 -1
  68. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  69. package/dist/typed-shadow-atlas.d.ts +10 -0
  70. package/dist/typed-shadow-atlas.d.ts.map +1 -0
  71. package/dist/typed-shadow-passes.d.ts.map +1 -1
  72. package/dist/volume/capability.d.ts +57 -0
  73. package/dist/volume/capability.d.ts.map +1 -0
  74. package/dist/volume/component.d.ts +61 -0
  75. package/dist/volume/component.d.ts.map +1 -0
  76. package/dist/volume/extract.d.ts +11 -0
  77. package/dist/volume/extract.d.ts.map +1 -0
  78. package/dist/volume/inspection.d.ts +38 -0
  79. package/dist/volume/inspection.d.ts.map +1 -0
  80. package/dist/volume/passes.d.ts +38 -0
  81. package/dist/volume/passes.d.ts.map +1 -0
  82. package/dist/volume/recovery.d.ts +38 -0
  83. package/dist/volume/recovery.d.ts.map +1 -0
  84. package/dist/volume/resources.d.ts +57 -0
  85. package/dist/volume/resources.d.ts.map +1 -0
  86. package/dist/volume/temporal.d.ts +35 -0
  87. package/dist/volume/temporal.d.ts.map +1 -0
  88. package/package.json +20 -20
  89. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -14
  90. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
  91. package/src/__tests__/render-error-code-owner.test-d.ts +5 -0
  92. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +28 -0
  93. package/src/__tests__/renderer-frame-transaction.integration.test.ts +1 -1
  94. package/src/__tests__/skinned-shadow-caster.test.ts +21 -0
  95. package/src/__tests__/standard-profile-oracle.unit.test.ts +7 -5
  96. package/src/__tests__/volume-optics-oracle.unit.test.ts +85 -0
  97. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +655 -0
  98. package/src/__tests__/volumetric-fog-component.unit.test.ts +71 -0
  99. package/src/__tests__/volumetric-fog-composite-stage-readback.dawn.test.ts +376 -0
  100. package/src/__tests__/volumetric-fog-errors.unit.test.ts +51 -0
  101. package/src/__tests__/volumetric-fog-inspection.unit.test.ts +77 -0
  102. package/src/__tests__/volumetric-fog-light-capability.unit.test.ts +19 -0
  103. package/src/__tests__/volumetric-fog-light-consumers.integration.test.ts +18 -0
  104. package/src/__tests__/volumetric-fog-light-errors.unit.test.ts +17 -0
  105. package/src/__tests__/volumetric-fog-light-topology.unit.test.ts +21 -0
  106. package/src/__tests__/volumetric-fog-light-transaction.integration.test.ts +53 -0
  107. package/src/__tests__/volumetric-fog-m9-watcher.integration.test.ts +27 -0
  108. package/src/__tests__/volumetric-fog-point-light-owner.integration.test.ts +44 -0
  109. package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +49 -0
  110. package/src/__tests__/volumetric-fog-point-spot-contract.unit.test.ts +28 -0
  111. package/src/__tests__/volumetric-fog-point-spot-lkg.integration.test.ts +65 -0
  112. package/src/__tests__/volumetric-fog-point-spot-selection.integration.test.ts +49 -0
  113. package/src/__tests__/volumetric-fog-point-spot-temporal.unit.test.ts +55 -0
  114. package/src/__tests__/volumetric-fog-projector-contract.unit.test.ts +22 -0
  115. package/src/__tests__/volumetric-fog-projector-inspection.unit.test.ts +12 -0
  116. package/src/__tests__/volumetric-fog-projector-surface-volume.integration.test.ts +11 -0
  117. package/src/__tests__/volumetric-fog-projector-transaction.integration.test.ts +26 -0
  118. package/src/__tests__/volumetric-fog-recovery.integration.test.ts +47 -0
  119. package/src/__tests__/volumetric-fog-selected-light-resolution.integration.test.ts +63 -0
  120. package/src/__tests__/volumetric-fog-spot-closure.integration.test.ts +26 -0
  121. package/src/__tests__/volumetric-fog-spot-contract.test-d.ts +21 -0
  122. package/src/__tests__/volumetric-fog-spot-contract.unit.test.ts +27 -0
  123. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +14 -0
  124. package/src/__tests__/volumetric-fog-spot-optics.integration.test.ts +29 -0
  125. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +550 -0
  126. package/src/__tests__/volumetric-fog-temporal-selected-light.unit.test.ts +33 -0
  127. package/src/__tests__/volumetric-fog-temporal.unit.test.ts +45 -0
  128. package/src/__tests__/volumetric-fog-topology.unit.test.ts +237 -0
  129. package/src/__tests__/volumetric-fog-transparent.integration.test.ts +27 -0
  130. package/src/assembly/factory.ts +271 -15
  131. package/src/components/light-helpers.ts +4 -0
  132. package/src/components/spot-light.ts +22 -3
  133. package/src/device/gpu-residency.ts +168 -58
  134. package/src/errors/render.ts +119 -1
  135. package/src/gpu-usage.ts +2 -0
  136. package/src/index.ts +38 -1
  137. package/src/light-buffer-layout.ts +59 -26
  138. package/src/pbr-pipeline.ts +33 -10
  139. package/src/pipeline/standard-forward-lane.ts +20 -0
  140. package/src/pipeline/standard-pipeline.ts +20 -0
  141. package/src/pipeline/standard-profile.ts +23 -0
  142. package/src/record/frame-lighting.ts +103 -89
  143. package/src/record/frame-snapshot.ts +41 -1
  144. package/src/record/frame-targets.ts +6 -2
  145. package/src/record/frame.ts +908 -5
  146. package/src/record/gpu-timing.ts +224 -0
  147. package/src/record/main-pass-material.ts +6 -2
  148. package/src/record/render-context.ts +5 -0
  149. package/src/record/shadow-pass.ts +87 -38
  150. package/src/record/typed-frame-graph.ts +143 -8
  151. package/src/render-contract.ts +72 -0
  152. package/src/render-data.ts +50 -22
  153. package/src/render-pipeline.ts +44 -0
  154. package/src/render-system-extract.ts +329 -3
  155. package/src/render-system.ts +79 -0
  156. package/src/renderer-inspect.ts +66 -0
  157. package/src/scene/render-scene.ts +2 -0
  158. package/src/temporal/frame.ts +128 -0
  159. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +2 -3
  160. package/src/typed-render-graph-primitives.ts +32 -2
  161. package/src/typed-shadow-atlas.ts +17 -0
  162. package/src/typed-shadow-passes.ts +6 -5
  163. package/src/volume/capability.ts +173 -0
  164. package/src/volume/component.ts +110 -0
  165. package/src/volume/extract.ts +21 -0
  166. package/src/volume/inspection.ts +78 -0
  167. package/src/volume/passes.ts +680 -0
  168. package/src/volume/recovery.ts +86 -0
  169. package/src/volume/resources.ts +236 -0
  170. package/src/volume/temporal.ts +89 -0
  171. package/dist/chunk-IPXCABEP.mjs.map +0 -1
  172. package/dist/chunk-LOSO4CTV.mjs.map +0 -1
  173. package/dist/chunk-RJRUS55L.mjs.map +0 -1
  174. package/dist/chunk-YTQ5C7YQ.mjs.map +0 -1
@@ -0,0 +1,57 @@
1
+ import { type EntityHandle, type World } from '@forgeax/engine-ecs';
2
+ import type { RhiCaps } from '@forgeax/engine-rhi';
3
+ /**
4
+ * The single capability predicate for the authored volumetric-fog producer.
5
+ * Shader sources are part of the device-bound bundle: compute/storage alone
6
+ * is not enough to claim that the three fused graph passes can execute.
7
+ */
8
+ export declare function hasVolumetricFogCapability(caps: Pick<RhiCaps, 'compute' | 'storageTexture'>, shaders: unknown): boolean;
9
+ export type VolumetricFogLightKind = 'directional' | 'point' | 'spot';
10
+ export type VolumetricFogLightResolution = {
11
+ readonly status: 'available';
12
+ readonly entity: EntityHandle;
13
+ readonly kind: VolumetricFogLightKind;
14
+ } | {
15
+ readonly status: 'unresolved';
16
+ readonly reason: 'missing-entity' | 'wrong-component' | 'ambiguous';
17
+ readonly entity: EntityHandle;
18
+ readonly expected: 'DirectionalLight | PointLight | SpotLight';
19
+ readonly actual: string;
20
+ readonly hint: string;
21
+ };
22
+ export type VolumetricFogLightPairResolution = {
23
+ readonly status: 'available';
24
+ readonly mode: 'point-spot';
25
+ readonly point: EntityHandle;
26
+ readonly spot: EntityHandle;
27
+ } | {
28
+ readonly status: 'unresolved';
29
+ readonly reason: 'missing-entity' | 'same-entity' | 'wrong-component';
30
+ readonly point: EntityHandle;
31
+ readonly spot: EntityHandle;
32
+ readonly expected: 'PointLight + SpotLight in the same World';
33
+ readonly actual: string;
34
+ readonly hint: string;
35
+ };
36
+ /** Resolve the narrow official Point+Spot pair without creating a light owner. */
37
+ export declare function resolveVolumetricFogLightPair(world: World, point: EntityHandle, spot: EntityHandle): VolumetricFogLightPairResolution;
38
+ /**
39
+ * Resolve the required VolumetricFog.light reference in its owning World.
40
+ * PointLight is a valid primary selection for the exact Point+Spot pair.
41
+ * EntityHandle has no portable world tag, so a handle absent from this World
42
+ * (the same World contract) is reported as missing-entity;
43
+ * is reported as missing-entity; callers must not manufacture a light.
44
+ */
45
+ export declare function resolveSelectedVolumetricLight(world: World, entity: EntityHandle): VolumetricFogLightResolution;
46
+ export interface IntegratedVolumeResource {
47
+ /** Logical resolved-volume identity; this is not a physical graph resource. */
48
+ readonly identity: 'volume-integrated';
49
+ readonly format: 'rgba16float';
50
+ readonly stage: 'resolved';
51
+ }
52
+ export type VolumeConsumer = 'opaque' | 'transparent' | 'sprite' | 'vfx' | 'custom';
53
+ export declare function resolveIntegratedVolumeConsumer(resource: IntegratedVolumeResource, consumer: VolumeConsumer): {
54
+ readonly consumer: VolumeConsumer;
55
+ readonly resource: IntegratedVolumeResource;
56
+ };
57
+ //# sourceMappingURL=capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/volume/capability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,YAAY,EAAE,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,gBAAgB,CAAC,EACjD,OAAO,EAAE,OAAO,GACf,OAAO,CAET;AAED,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AAGtE,MAAM,MAAM,4BAA4B,GACpC;IACE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;CACvC,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,WAAW,CAAC;IACpE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,2CAA2C,CAAC;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN,MAAM,MAAM,gCAAgC,GACxC;IACE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;CAC7B,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa,GAAG,iBAAiB,CAAC;IACtE,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,0CAA0C,CAAC;IAC9D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN,kFAAkF;AAClF,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,YAAY,GACjB,gCAAgC,CAsClC;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,YAAY,GACnB,4BAA4B,CA4C9B;AAED,MAAM,WAAW,wBAAwB;IACvC,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,aAAa,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEpF,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,wBAAwB,EAClC,QAAQ,EAAE,cAAc,GACvB;IAAE,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAA;CAAE,CAKpF"}
@@ -0,0 +1,61 @@
1
+ import { type EntityHandle } from '@forgeax/engine-ecs';
2
+ import { type Result } from '@forgeax/engine-types';
3
+ import { type VolumeError } from '../errors/render';
4
+ export interface VolumeDensityBinding {
5
+ readonly guid: string;
6
+ readonly generation: number;
7
+ readonly shape: {
8
+ readonly viewDimension: '2d' | '2d-array' | '3d';
9
+ readonly extent: {
10
+ readonly width: number;
11
+ readonly height: number;
12
+ readonly depth?: number;
13
+ readonly layers?: number;
14
+ };
15
+ };
16
+ readonly format: string;
17
+ readonly colorSpace?: 'linear' | 'srgb';
18
+ }
19
+ export interface VolumeBounds {
20
+ readonly min: readonly [number, number, number];
21
+ readonly max: readonly [number, number, number];
22
+ }
23
+ export interface VolumetricFogAuthoring {
24
+ /** Invalid authoring reports closed code, expected, hint, and detail fields. */
25
+ /** The selected DirectionalLight or PointLight in this World. */
26
+ readonly light: EntityHandle;
27
+ /** The optional same-World SpotLight paired with a PointLight. */
28
+ readonly spotLight?: EntityHandle;
29
+ readonly density: VolumeDensityBinding;
30
+ readonly bounds: VolumeBounds;
31
+ readonly extinction: readonly [number, number, number];
32
+ readonly albedo: readonly [number, number, number];
33
+ readonly emission: readonly [number, number, number];
34
+ readonly anisotropy: number;
35
+ readonly maxDistance: number;
36
+ readonly ownerCount?: number;
37
+ }
38
+ export type VolumetricFogLightSelection = {
39
+ readonly light: EntityHandle;
40
+ readonly spotLight?: undefined;
41
+ } | {
42
+ readonly light: EntityHandle;
43
+ readonly spotLight: EntityHandle;
44
+ };
45
+ export interface ValidatedVolumetricFog extends VolumetricFogAuthoring {
46
+ readonly ownerCount: 1;
47
+ }
48
+ export declare const VolumetricFog: import("@forgeax/engine-ecs").Component<"VolumetricFog", {
49
+ readonly light: "entity";
50
+ readonly spotLight: "entity";
51
+ readonly density: "shared<TextureAsset>";
52
+ readonly boundsMin: "array<f32, 3>";
53
+ readonly boundsMax: "array<f32, 3>";
54
+ readonly extinction: "array<f32, 3>";
55
+ readonly albedo: "array<f32, 3>";
56
+ readonly emission: "array<f32, 3>";
57
+ readonly anisotropy: "f32";
58
+ readonly maxDistance: "f32";
59
+ }>;
60
+ export declare function validateVolumetricFog(input: VolumetricFogAuthoring): Result<ValidatedVolumetricFog, VolumeError>;
61
+ //# sourceMappingURL=component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/volume/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAEL,KAAK,WAAW,EAIjB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,aAAa,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CAAC;QACjD,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;SAC1B,CAAC;KACH,CAAC;IACF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,sBAAsB;IACrC,gFAAgF;IAChF,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,2BAA2B,GACnC;IAAE,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,GAChE;IAAE,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;CAAE,CAAC;AAEvE,MAAM,WAAW,sBAAuB,SAAQ,sBAAsB;IACpE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;CACxB;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;EAWxB,CAAC;AAmBH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,sBAAsB,GAC5B,MAAM,CAAC,sBAAsB,EAAE,WAAW,CAAC,CAsB7C"}
@@ -0,0 +1,11 @@
1
+ import { type Result } from '@forgeax/engine-types';
2
+ import { type VolumeError } from '../errors/render';
3
+ import { type ValidatedVolumetricFog, type VolumetricFogAuthoring } from './component';
4
+ export type VolumetricFogExtract = {
5
+ readonly status: 'off';
6
+ } | {
7
+ readonly status: 'available';
8
+ readonly fog: ValidatedVolumetricFog;
9
+ };
10
+ export declare function extractVolumetricFog(inputs: readonly VolumetricFogAuthoring[]): Result<VolumetricFogExtract, VolumeError>;
11
+ //# sourceMappingURL=extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/volume/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,KAAK,WAAW,EAA4B,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAE5B,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAE3E,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,sBAAsB,EAAE,GACxC,MAAM,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAM3C"}
@@ -0,0 +1,38 @@
1
+ import type { TextureFormat } from '@forgeax/engine-rhi';
2
+ import type { VolumeRecoveryState, VolumeSelectedLightFacts } from './recovery';
3
+ import type { VolumetricFogResourceFacts } from './resources';
4
+ export type VolumetricFogInspectionStatus = 'off' | 'available' | 'unavailable' | 'degraded';
5
+ export type VolumetricFogResourceStage = 'none' | 'candidate' | 'accepted' | 'lkg' | 'recovering';
6
+ export interface VolumetricFogInspection {
7
+ readonly status: VolumetricFogInspectionStatus;
8
+ readonly resourceStage: VolumetricFogResourceStage;
9
+ readonly guid: string | undefined;
10
+ readonly generation: number | undefined;
11
+ readonly digest: string | undefined;
12
+ readonly candidateGeneration: number | undefined;
13
+ readonly candidateDigest: string | undefined;
14
+ readonly lkgGeneration: number | undefined;
15
+ readonly candidateFailure: VolumeRecoveryState['candidateFailure'];
16
+ readonly deviceEpoch: number;
17
+ readonly format: TextureFormat | undefined;
18
+ readonly passCount: number;
19
+ readonly sampleCount: number;
20
+ readonly memoryBytes: number;
21
+ readonly resourceFacts: VolumetricFogResourceFacts | undefined;
22
+ readonly selectedLight: VolumeSelectedLightFacts | undefined;
23
+ readonly candidateSelectedLight: VolumeSelectedLightFacts | undefined;
24
+ }
25
+ export interface VolumetricFogInspectionInput {
26
+ readonly authored: boolean;
27
+ readonly capability: 'available' | 'unavailable';
28
+ readonly degraded?: boolean;
29
+ readonly recovery?: VolumeRecoveryState;
30
+ readonly acceptedDigest?: string;
31
+ readonly format?: TextureFormat;
32
+ readonly passCount?: number;
33
+ readonly sampleCount?: number;
34
+ readonly memoryBytes?: number;
35
+ readonly resourceFacts?: VolumetricFogResourceFacts;
36
+ }
37
+ export declare function inspectVolumetricFog(input: VolumetricFogInspectionInput): VolumetricFogInspection;
38
+ //# sourceMappingURL=inspection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspection.d.ts","sourceRoot":"","sources":["../../src/volume/inspection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,MAAM,6BAA6B,GAAG,KAAK,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAE7F,MAAM,MAAM,0BAA0B,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,KAAK,GAAG,YAAY,CAAC;AAElG,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,6BAA6B,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,0BAA0B,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,0BAA0B,GAAG,SAAS,CAAC;IAC/D,QAAQ,CAAC,aAAa,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC7D,QAAQ,CAAC,sBAAsB,EAAE,wBAAwB,GAAG,SAAS,CAAC;CACvE;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,WAAW,GAAG,aAAa,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,0BAA0B,CAAC;CACrD;AAUD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,4BAA4B,GAAG,uBAAuB,CA4BjG"}
@@ -0,0 +1,38 @@
1
+ import type { GraphBuffer, GraphTextureView, RenderGraphBuilder, RenderGraphError } from '@forgeax/engine-render-graph';
2
+ import { type Result } from '@forgeax/engine-types';
3
+ import type { RenderPipelineFrame, RenderPipelineTarget, RenderPipelineTopology } from '../render-pipeline';
4
+ import type { VolumetricFogResources } from './resources';
5
+ import type { VolumeProjectorTuple } from './temporal';
6
+ export declare const VOLUMETRIC_FOG_PASS_ORDER: readonly ["volume-inject", "volume-integrate", "volume-temporal", "volume-composite"];
7
+ export interface VolumetricFogTopology {
8
+ readonly passes: readonly string[];
9
+ readonly resources: readonly string[];
10
+ readonly colorInput: 'linear-hdr';
11
+ readonly depthInput: 'scene-depth';
12
+ readonly lightKind?: 'directional' | 'point' | 'spot';
13
+ readonly lightEntity?: number;
14
+ readonly lightRevision?: number;
15
+ readonly projector?: Pick<VolumeProjectorTuple, 'guid' | 'generation' | 'revision'>;
16
+ }
17
+ export declare function volumetricFogTopology(enabled: boolean, selectedLight?: {
18
+ readonly lightKind: 'directional' | 'point' | 'spot';
19
+ readonly lightEntity: number;
20
+ readonly lightRevision: number;
21
+ }): VolumetricFogTopology;
22
+ export interface VolumetricFogPassInputs {
23
+ readonly resources: VolumetricFogResources;
24
+ readonly linearHdr: RenderPipelineTarget;
25
+ readonly sceneDepth: GraphTextureView;
26
+ readonly density: GraphTextureView;
27
+ readonly params: GraphBuffer;
28
+ readonly view: GraphBuffer;
29
+ readonly directionalShadow: GraphTextureView;
30
+ readonly spotShadow: GraphTextureView;
31
+ readonly pointLights: GraphBuffer;
32
+ readonly spotLights: GraphBuffer;
33
+ readonly selectedLightKind: 'directional' | 'point' | 'spot';
34
+ readonly projector?: GraphTextureView;
35
+ }
36
+ export declare function addAuthoredVolumetricFogPasses(graph: RenderGraphBuilder<RenderPipelineFrame>, topology: RenderPipelineTopology, linearHdr: RenderPipelineTarget, sceneDepth: GraphTextureView, directionalShadow: GraphTextureView, spotShadow: GraphTextureView): Result<void, RenderGraphError>;
37
+ export declare function addVolumetricFogPasses(graph: RenderGraphBuilder<RenderPipelineFrame>, inputs: VolumetricFogPassInputs): Result<void, RenderGraphError>;
38
+ //# sourceMappingURL=passes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passes.d.ts","sourceRoot":"","sources":["../../src/volume/passes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAWtC,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAcxD,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAQ1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,yBAAyB,uFAK5B,CAAC;AACX,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,CAAC,CAAC;CACrF;AACD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE;IACd,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,GACA,qBAAqB,CAevB;AACD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,iBAAiB,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7D,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;CACvC;AAqLD,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,EAC9C,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,oBAAoB,EAC/B,UAAU,EAAE,gBAAgB,EAC5B,iBAAiB,EAAE,gBAAgB,EACnC,UAAU,EAAE,gBAAgB,GAC3B,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,CA2BhC;AACD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,EAC9C,MAAM,EAAE,uBAAuB,GAC9B,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,CA2WhC"}
@@ -0,0 +1,38 @@
1
+ import type { VolumeProjectorTuple } from './temporal';
2
+ export interface VolumeSelectedLightFacts {
3
+ readonly entity: number;
4
+ readonly kind: 'directional' | 'point' | 'spot';
5
+ readonly revision: number;
6
+ readonly shadowTile: number;
7
+ readonly pointLightEntity?: number;
8
+ readonly spotLightEntity?: number;
9
+ readonly projector?: VolumeProjectorTuple;
10
+ }
11
+ export interface VolumeRecoveryState {
12
+ readonly guid: string;
13
+ readonly generation: number;
14
+ readonly deviceEpoch: number;
15
+ readonly status: 'accepted' | 'candidate' | 'degraded' | 'recovering';
16
+ readonly candidateGeneration?: number;
17
+ readonly candidateDigest?: string;
18
+ readonly lkgGeneration?: number;
19
+ readonly candidateFailure?: 'submit-failed' | 'stale-generation' | 'missing-selected-light' | 'missing-shadow';
20
+ readonly selectedLight?: VolumeSelectedLightFacts;
21
+ readonly candidateSelectedLight?: VolumeSelectedLightFacts;
22
+ }
23
+ export type VolumeRecoveryEvent = {
24
+ readonly kind: 'submit-failed';
25
+ } | {
26
+ readonly kind: 'device-lost';
27
+ readonly deviceEpoch: number;
28
+ } | {
29
+ readonly kind: 'accepted';
30
+ readonly generation: number;
31
+ };
32
+ export declare function stageVolumetricFog(state: VolumeRecoveryState, candidate: {
33
+ readonly generation: number;
34
+ readonly digest: string;
35
+ readonly selectedLight?: VolumeSelectedLightFacts;
36
+ }): VolumeRecoveryState;
37
+ export declare function recoverVolumetricFog(state: VolumeRecoveryState, event: VolumeRecoveryEvent): VolumeRecoveryState;
38
+ //# sourceMappingURL=recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../../src/volume/recovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAC3C;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;IACtE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,CAAC,EACtB,eAAe,GACf,kBAAkB,GAClB,wBAAwB,GACxB,gBAAgB,CAAC;IACrB,QAAQ,CAAC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IAClD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,wBAAwB,CAAC;CAC5D;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE;IACT,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,wBAAwB,CAAC;CACnD,GACA,mBAAmB,CAUrB;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,mBAAmB,GACzB,mBAAmB,CA6BrB"}
@@ -0,0 +1,57 @@
1
+ import type { CompiledRenderGraphInfo, GraphTexture, GraphTextureView, RenderGraphBuilder, RenderGraphError } from '@forgeax/engine-render-graph';
2
+ import { type Result } from '@forgeax/engine-types';
3
+ import type { RenderPipelineFrame } from '../render-pipeline';
4
+ export declare const VOLUME_FROXEL_FORMAT: "rgba8unorm";
5
+ export declare const VOLUME_HISTORY_FORMAT: "rgba16float";
6
+ export declare const VOLUME_RESOLVED_FORMAT: "rgba16float";
7
+ export declare const VOLUME_DEPTH_FORMAT: "r32float";
8
+ export declare const VOLUME_PACKING_Z = 4;
9
+ /** Renderer-owned parameter allocation shared by staging and inspection. */
10
+ export declare const VOLUMETRIC_FOG_PARAMS_BYTES: number;
11
+ export interface VolumetricFogExtent {
12
+ readonly width: number;
13
+ readonly height: number;
14
+ readonly depth: number;
15
+ }
16
+ /** Derive the renderer's high profile grid from the actual surface descriptor. */
17
+ export declare function deriveVolumetricFogExtent(surface: {
18
+ readonly width: number;
19
+ readonly height: number;
20
+ }, depth?: number, tileSize?: number): VolumetricFogExtent;
21
+ /** Derive the 2D resolve extent from the same profile tile without a second profile. */
22
+ export declare function deriveVolumetricFogResolvedExtent(surface: {
23
+ readonly width: number;
24
+ readonly height: number;
25
+ }, froxelTileSize?: number): VolumetricFogExtent;
26
+ export interface VolumetricFogResources {
27
+ readonly extent: VolumetricFogExtent;
28
+ readonly resolvedExtent: VolumetricFogExtent;
29
+ readonly froxel: GraphTexture;
30
+ readonly froxelView: GraphTextureView;
31
+ readonly resolved: GraphTexture;
32
+ readonly resolvedView: GraphTextureView;
33
+ readonly history: GraphTexture;
34
+ readonly historyView: GraphTextureView;
35
+ readonly temporal: GraphTexture;
36
+ readonly temporalView: GraphTextureView;
37
+ }
38
+ export interface VolumetricFogResourceFacts {
39
+ readonly generation: number;
40
+ readonly liveResourceCount: number;
41
+ readonly currentBytes: number;
42
+ readonly historyBytes: number;
43
+ readonly scratchBytes: number;
44
+ readonly bufferBytes: number;
45
+ readonly totalBytes: number;
46
+ readonly physicalResourceCount: number;
47
+ readonly sampleCount: number;
48
+ readonly resolvedPixelCount: number;
49
+ }
50
+ /** Project graph descriptors into the volume inspection without a second ledger. */
51
+ export interface VolumetricFogResourceInspectionOptions {
52
+ /** Number of non-null parameter buffers retained by the frame owner. */
53
+ readonly parameterBufferCount?: number;
54
+ }
55
+ export declare function inspectVolumetricFogResources(graph: CompiledRenderGraphInfo, options?: VolumetricFogResourceInspectionOptions): VolumetricFogResourceFacts;
56
+ export declare function createVolumetricFogResources(graph: RenderGraphBuilder<RenderPipelineFrame>, extent?: VolumetricFogExtent, resolvedExtent?: VolumetricFogExtent): Result<VolumetricFogResources, RenderGraphError>;
57
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/volume/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface VolumeTemporalSignature {
2
+ readonly cameraRevision: number;
3
+ readonly fogRevision: number;
4
+ readonly lightRevision: number;
5
+ readonly densityGeneration: number;
6
+ readonly width: number;
7
+ readonly height: number;
8
+ readonly lightKind?: 'directional' | 'point' | 'spot';
9
+ readonly lightEntity?: number;
10
+ readonly pointLightEntity?: number;
11
+ readonly spotLightEntity?: number;
12
+ readonly projector?: VolumeProjectorTuple;
13
+ readonly lightShadowRevision?: number;
14
+ }
15
+ /** Accepted projector facts shared by surface and volume consumers. */
16
+ export interface VolumeProjectorTuple {
17
+ readonly guid: string;
18
+ readonly generation: number;
19
+ readonly view: string;
20
+ readonly sampler: string;
21
+ readonly projection: string;
22
+ readonly revision: number;
23
+ }
24
+ export type VolumeTemporalResetReason = 'camera-cut' | 'fog-revision' | 'light-revision' | 'density-generation' | 'resize' | 'reprojection-out-of-screen' | 'reprojection-depth-discontinuity';
25
+ export type VolumeTemporalReset = {
26
+ readonly reset: false;
27
+ } | {
28
+ readonly reset: true;
29
+ readonly reason: VolumeTemporalResetReason;
30
+ };
31
+ export declare function resolveVolumeTemporalReset(previous: VolumeTemporalSignature, next: VolumeTemporalSignature, options?: {
32
+ readonly taaEnabled?: boolean;
33
+ readonly reprojection?: 'out-of-screen' | 'depth-discontinuity';
34
+ }): VolumeTemporalReset;
35
+ //# sourceMappingURL=temporal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal.d.ts","sourceRoot":"","sources":["../../src/volume/temporal.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,yBAAyB,GACjC,YAAY,GACZ,cAAc,GACd,gBAAgB,GAChB,oBAAoB,GACpB,QAAQ,GACR,4BAA4B,GAC5B,kCAAkC,CAAC;AAEvC,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAA;CAAE,CAAC;AAEzE,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,uBAAuB,EACjC,IAAI,EAAE,uBAAuB,EAC7B,OAAO,GAAE;IACP,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,GAAG,qBAAqB,CAAC;CAC5D,GACL,mBAAmB,CA2CrB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeax/engine-render",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "description": "Canonical ECS render schemas and renderer boundary.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -37,27 +37,27 @@
37
37
  "LICENSE"
38
38
  ],
39
39
  "dependencies": {
40
- "@forgeax/engine-assets-runtime": "0.1.19",
41
- "@forgeax/engine-audio-webaudio": "0.1.19",
42
- "@forgeax/engine-codec": "0.1.19",
43
- "@forgeax/engine-ecs": "0.1.19",
44
- "@forgeax/engine-geometry": "0.1.19",
45
- "@forgeax/engine-graphics-extras": "0.1.19",
46
- "@forgeax/engine-math": "0.1.19",
47
- "@forgeax/engine-pack": "0.1.19",
48
- "@forgeax/engine-plugin": "0.1.19",
49
- "@forgeax/engine-profiler": "0.1.19",
50
- "@forgeax/engine-render-graph": "0.1.19",
51
- "@forgeax/engine-rhi": "0.1.19",
52
- "@forgeax/engine-scene": "0.1.19",
53
- "@forgeax/engine-shader": "0.1.19",
54
- "@forgeax/engine-skinning": "0.1.19",
55
- "@forgeax/engine-types": "0.1.19"
40
+ "@forgeax/engine-assets-runtime": "0.1.20",
41
+ "@forgeax/engine-audio-webaudio": "0.1.20",
42
+ "@forgeax/engine-codec": "0.1.20",
43
+ "@forgeax/engine-ecs": "0.1.20",
44
+ "@forgeax/engine-geometry": "0.1.20",
45
+ "@forgeax/engine-graphics-extras": "0.1.20",
46
+ "@forgeax/engine-math": "0.1.20",
47
+ "@forgeax/engine-pack": "0.1.20",
48
+ "@forgeax/engine-plugin": "0.1.20",
49
+ "@forgeax/engine-profiler": "0.1.20",
50
+ "@forgeax/engine-render-graph": "0.1.20",
51
+ "@forgeax/engine-rhi": "0.1.20",
52
+ "@forgeax/engine-scene": "0.1.20",
53
+ "@forgeax/engine-shader": "0.1.20",
54
+ "@forgeax/engine-skinning": "0.1.20",
55
+ "@forgeax/engine-types": "0.1.20"
56
56
  },
57
57
  "devDependencies": {
58
- "@forgeax/engine-rhi-null": "0.1.19",
59
- "@forgeax/engine-rhi-webgpu": "0.1.19",
60
- "@forgeax/engine-vite-plugin-shader": "0.1.19"
58
+ "@forgeax/engine-rhi-null": "0.1.20",
59
+ "@forgeax/engine-rhi-webgpu": "0.1.20",
60
+ "@forgeax/engine-vite-plugin-shader": "0.1.20"
61
61
  },
62
62
  "forgeax": {
63
63
  "metrics": {
@@ -343,12 +343,11 @@ async function textureFor(
343
343
  selected,
344
344
  texture: {
345
345
  kind: 'texture',
346
- width: mip.width,
347
- height: mip.height,
346
+ shape: { viewDimension: '2d', extent: { width: mip.width, height: mip.height } },
348
347
  format: selected,
349
348
  data: mip.data,
350
349
  colorSpace: input.colorSpace,
351
- mipmap: false,
350
+ mips: { kind: 'none' },
352
351
  },
353
352
  };
354
353
  }
@@ -377,12 +376,11 @@ async function textureFor(
377
376
  selected,
378
377
  texture: {
379
378
  kind: 'texture',
380
- width: mip.width,
381
- height: mip.height,
379
+ shape: { viewDimension: '2d', extent: { width: mip.width, height: mip.height } },
382
380
  format: selected,
383
381
  data: mip.data,
384
382
  colorSpace: input.colorSpace,
385
- mipmap: false,
383
+ mips: { kind: 'none' },
386
384
  },
387
385
  };
388
386
  }
@@ -392,6 +390,8 @@ async function readbackTexture(
392
390
  texture: TextureAsset,
393
391
  gpuTexture: { readonly handle: Texture },
394
392
  ): Promise<Uint8Array> {
393
+ const width = texture.shape.extent.width;
394
+ const height = texture.shape.extent.height;
395
395
  const hdr = texture.format === 'rgba16float' || texture.format.startsWith('bc6h');
396
396
  const outputFormat: GPUTextureFormat = hdr ? 'rgba16float' : 'rgba8unorm-srgb';
397
397
  const outputBytesPerPixel = hdr ? 8 : 4;
@@ -447,7 +447,7 @@ async function readbackTexture(
447
447
  });
448
448
  if (!bindings.ok) throw new Error(`${bindings.error.code}:${bindings.error.hint}`);
449
449
  const normalizedTexture = device.createTexture({
450
- size: { width: texture.width, height: texture.height, depthOrArrayLayers: 1 },
450
+ size: { width, height, depthOrArrayLayers: 1 },
451
451
  format: outputFormat,
452
452
  usage: 0x10 | 0x01,
453
453
  } as never);
@@ -457,7 +457,7 @@ async function readbackTexture(
457
457
  if (!normalizedView.ok)
458
458
  throw new Error(`${normalizedView.error.code}:${normalizedView.error.hint}`);
459
459
  const readback = device.createBuffer({
460
- size: 256 * texture.height,
460
+ size: 256 * height,
461
461
  usage: GPU_BUFFER_USAGE_COPY_DST | GPU_BUFFER_USAGE_MAP_READ,
462
462
  });
463
463
  if (!readback.ok) throw new Error(`${readback.error.code}:${readback.error.hint}`);
@@ -483,9 +483,9 @@ async function readbackTexture(
483
483
  buffer: readback.value as unknown as GPUBuffer,
484
484
  offset: 0,
485
485
  bytesPerRow: 256,
486
- rowsPerImage: texture.height,
486
+ rowsPerImage: height,
487
487
  },
488
- { width: texture.width, height: texture.height, depthOrArrayLayers: 1 },
488
+ { width, height, depthOrArrayLayers: 1 },
489
489
  );
490
490
  const command = encoder.value.finish();
491
491
  if (!command.ok) throw new Error(`${command.error.code}:${command.error.hint}`);
@@ -497,11 +497,11 @@ async function readbackTexture(
497
497
  const range = mapped.value.getMappedRange();
498
498
  if (!range.ok) throw new Error(`${range.error.code}:${range.error.hint}`);
499
499
  const mappedBytes = new Uint8Array(range.value);
500
- const bytes = new Uint8Array(texture.width * texture.height * outputBytesPerPixel);
501
- for (let row = 0; row < texture.height; row += 1) {
500
+ const bytes = new Uint8Array(width * height * outputBytesPerPixel);
501
+ for (let row = 0; row < height; row += 1) {
502
502
  bytes.set(
503
- mappedBytes.subarray(row * 256, row * 256 + texture.width * outputBytesPerPixel),
504
- row * texture.width * outputBytesPerPixel,
503
+ mappedBytes.subarray(row * 256, row * 256 + width * outputBytesPerPixel),
504
+ row * width * outputBytesPerPixel,
505
505
  );
506
506
  }
507
507
  mapped.value.unmap();
@@ -71,7 +71,7 @@ describe('render buffer usage owner', () => {
71
71
  expect(GPU_BUFFER_USAGE_UNIFORM).toBe(0x40);
72
72
  expect(GPU_BUFFER_USAGE_STORAGE).toBe(0x80);
73
73
  expect(GPU_BUFFER_USAGE_MAP_READ).toBe(0x01);
74
- expect(ownerSource.match(/export const GPU_BUFFER_USAGE_/g)).toHaveLength(8);
74
+ expect(ownerSource.match(/export const GPU_BUFFER_USAGE_/g)).toHaveLength(9);
75
75
  });
76
76
 
77
77
  it('routes mesh descriptor, update, and bootstrap consumers through the owner', () => {
@@ -64,6 +64,11 @@ const expectedCodes = [
64
64
  'points-lines-material-unsupported',
65
65
  'points-lines-budget-exceeded',
66
66
  'points-lines-prepare-failed',
67
+ 'volume-owner-conflict',
68
+ 'volume-density-shape-mismatch',
69
+ 'volume-invalid-bounds',
70
+ 'volume-invalid-parameters',
71
+ 'projector-binding-failed',
67
72
  ] as const satisfies readonly RenderErrorCode[];
68
73
  type ExpectedCodeUnion = (typeof expectedCodes)[number];
69
74
 
@@ -187,6 +187,34 @@ describe('material shader variant identity', () => {
187
187
  ).toBe('STORAGE_BUFFER_AVAILABLE=true+VERTEX_COLOR_AVAILABLE=false');
188
188
  });
189
189
 
190
+ it('selects the projector-disabled PBR variant when the device exposes only 16 sampled textures', () => {
191
+ const variants = [
192
+ {
193
+ defines: {
194
+ CLUSTER_FORWARD_AVAILABLE: false,
195
+ PROJECTOR_AVAILABLE: false,
196
+ STORAGE_BUFFER_AVAILABLE: true,
197
+ VERTEX_COLOR_AVAILABLE: false,
198
+ },
199
+ },
200
+ {
201
+ defines: {
202
+ CLUSTER_FORWARD_AVAILABLE: false,
203
+ PROJECTOR_AVAILABLE: true,
204
+ STORAGE_BUFFER_AVAILABLE: true,
205
+ VERTEX_COLOR_AVAILABLE: false,
206
+ },
207
+ },
208
+ ];
209
+
210
+ expect(resolveMaterialShaderVariantSet(undefined, variants, 'webgpu', true, false)).toBe(
211
+ 'CLUSTER_FORWARD_AVAILABLE=false+PROJECTOR_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true+VERTEX_COLOR_AVAILABLE=false',
212
+ );
213
+ expect(resolveMaterialShaderVariantSet(undefined, variants, 'webgpu', true, true)).toBe(
214
+ 'CLUSTER_FORWARD_AVAILABLE=false+PROJECTOR_AVAILABLE=true+STORAGE_BUFFER_AVAILABLE=true+VERTEX_COLOR_AVAILABLE=false',
215
+ );
216
+ });
217
+
190
218
  it('keeps single-source manifests on the canonical module key', () => {
191
219
  const singleSourceManifest = {
192
220
  identifier: 'forgeax::points-lines',
@@ -83,7 +83,7 @@ function temporalResolveFrame(
83
83
  msaaActive: false,
84
84
  geometryColorResolveView: null,
85
85
  ldrSpriteColorView: null,
86
- } as RenderPipelineFrame;
86
+ } as unknown as RenderPipelineFrame;
87
87
  }
88
88
 
89
89
  async function buildTemporalResolveGraph(device: RhiDevice) {
@@ -99,4 +99,25 @@ describe('skinned shadow caster', () => {
99
99
  expect(recordSource).toContain('shadowPass.setBindGroup(2, skinMeshBindGroup, [');
100
100
  expect(recordSource).toContain('entry.source.skin.byteOffset');
101
101
  });
102
+
103
+ it('keeps low-limit shadow view bindings paired with the optional projector layout', () => {
104
+ const recordSource = readFileSync(
105
+ fileURLToPath(new URL('../record/shadow-pass.ts', import.meta.url)),
106
+ 'utf8',
107
+ );
108
+
109
+ // A 16-sampled-texture device removes bindings 11/12 from pbr-view-bgl.
110
+ // The shadow-view helper must use the same capability bit as the main
111
+ // view helper or it recreates the browser-only bind-group mismatch.
112
+ expect(recordSource).toContain(
113
+ 'const projectorAvailable = pipelineState.projectorAvailable !== false;',
114
+ );
115
+ expect(recordSource).toContain(
116
+ '...(projectorAvailable\n ? [pipelineState.defaultWhiteTextureView, pipelineState.defaultSampler]',
117
+ );
118
+ expect(recordSource).toContain(
119
+ '...(projectorAvailable\n ? [\n {\n binding: 11,',
120
+ );
121
+ expect(recordSource).toContain('binding: 12');
122
+ });
102
123
  });