@forgeax/engine-render 0.1.19 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/assembly/factory.d.ts +16 -5
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/{chunk-RJRUS55L.mjs → chunk-4XINDLAY.mjs} +267 -186
- package/dist/chunk-4XINDLAY.mjs.map +1 -0
- package/dist/{chunk-YTQ5C7YQ.mjs → chunk-CDTWTHZR.mjs} +176 -8
- package/dist/chunk-CDTWTHZR.mjs.map +1 -0
- package/dist/{chunk-IPXCABEP.mjs → chunk-M2MP4ZOU.mjs} +2 -2
- package/dist/chunk-M2MP4ZOU.mjs.map +1 -0
- package/dist/{chunk-LOSO4CTV.mjs → chunk-TBQJOK2L.mjs} +67 -3
- package/dist/chunk-TBQJOK2L.mjs.map +1 -0
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/spot-light.d.ts +12 -0
- package/dist/components/spot-light.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +2281 -164
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -2
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/errors/render.d.ts +69 -1
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/gpu-usage.d.ts +2 -0
- package/dist/gpu-usage.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/internal.mjs +1 -1
- package/dist/light-buffer-layout.d.ts +20 -12
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +6 -3
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +13 -0
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/record/frame-lighting.d.ts +2 -0
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +37 -1
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +3 -2
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-timing.d.ts +32 -0
- package/dist/record/gpu-timing.d.ts.map +1 -0
- package/dist/record/main-pass-material.d.ts +1 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +5 -1
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +11 -3
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/render-contract.d.ts +66 -1
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-data.d.ts +10 -6
- package/dist/render-data.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +36 -0
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +55 -3
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +7 -1
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer-inspect.d.ts +29 -0
- package/dist/renderer-inspect.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +44 -0
- package/dist/temporal/frame.d.ts.map +1 -0
- package/dist/temporal/index.mjs +3 -3
- package/dist/typed-render-graph-primitives.d.ts +6 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-atlas.d.ts +10 -0
- package/dist/typed-shadow-atlas.d.ts.map +1 -0
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/capability.d.ts +57 -0
- package/dist/volume/capability.d.ts.map +1 -0
- package/dist/volume/component.d.ts +61 -0
- package/dist/volume/component.d.ts.map +1 -0
- package/dist/volume/extract.d.ts +11 -0
- package/dist/volume/extract.d.ts.map +1 -0
- package/dist/volume/inspection.d.ts +38 -0
- package/dist/volume/inspection.d.ts.map +1 -0
- package/dist/volume/passes.d.ts +38 -0
- package/dist/volume/passes.d.ts.map +1 -0
- package/dist/volume/recovery.d.ts +38 -0
- package/dist/volume/recovery.d.ts.map +1 -0
- package/dist/volume/resources.d.ts +57 -0
- package/dist/volume/resources.d.ts.map +1 -0
- package/dist/volume/temporal.d.ts +35 -0
- package/dist/volume/temporal.d.ts.map +1 -0
- package/package.json +20 -20
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -14
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
- package/src/__tests__/render-error-code-owner.test-d.ts +5 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +28 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +1 -1
- package/src/__tests__/skinned-shadow-caster.test.ts +21 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +7 -5
- package/src/__tests__/volume-optics-oracle.unit.test.ts +85 -0
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +655 -0
- package/src/__tests__/volumetric-fog-component.unit.test.ts +71 -0
- package/src/__tests__/volumetric-fog-composite-stage-readback.dawn.test.ts +376 -0
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +51 -0
- package/src/__tests__/volumetric-fog-inspection.unit.test.ts +77 -0
- package/src/__tests__/volumetric-fog-light-capability.unit.test.ts +19 -0
- package/src/__tests__/volumetric-fog-light-consumers.integration.test.ts +18 -0
- package/src/__tests__/volumetric-fog-light-errors.unit.test.ts +17 -0
- package/src/__tests__/volumetric-fog-light-topology.unit.test.ts +21 -0
- package/src/__tests__/volumetric-fog-light-transaction.integration.test.ts +53 -0
- package/src/__tests__/volumetric-fog-m9-watcher.integration.test.ts +27 -0
- package/src/__tests__/volumetric-fog-point-light-owner.integration.test.ts +44 -0
- package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +49 -0
- package/src/__tests__/volumetric-fog-point-spot-contract.unit.test.ts +28 -0
- package/src/__tests__/volumetric-fog-point-spot-lkg.integration.test.ts +65 -0
- package/src/__tests__/volumetric-fog-point-spot-selection.integration.test.ts +49 -0
- package/src/__tests__/volumetric-fog-point-spot-temporal.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-projector-contract.unit.test.ts +22 -0
- package/src/__tests__/volumetric-fog-projector-inspection.unit.test.ts +12 -0
- package/src/__tests__/volumetric-fog-projector-surface-volume.integration.test.ts +11 -0
- package/src/__tests__/volumetric-fog-projector-transaction.integration.test.ts +26 -0
- package/src/__tests__/volumetric-fog-recovery.integration.test.ts +47 -0
- package/src/__tests__/volumetric-fog-selected-light-resolution.integration.test.ts +63 -0
- package/src/__tests__/volumetric-fog-spot-closure.integration.test.ts +26 -0
- package/src/__tests__/volumetric-fog-spot-contract.test-d.ts +21 -0
- package/src/__tests__/volumetric-fog-spot-contract.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +14 -0
- package/src/__tests__/volumetric-fog-spot-optics.integration.test.ts +29 -0
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +550 -0
- package/src/__tests__/volumetric-fog-temporal-selected-light.unit.test.ts +33 -0
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +45 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +237 -0
- package/src/__tests__/volumetric-fog-transparent.integration.test.ts +27 -0
- package/src/assembly/factory.ts +271 -15
- package/src/components/light-helpers.ts +4 -0
- package/src/components/spot-light.ts +22 -3
- package/src/device/gpu-residency.ts +168 -58
- package/src/errors/render.ts +119 -1
- package/src/gpu-usage.ts +2 -0
- package/src/index.ts +38 -1
- package/src/light-buffer-layout.ts +59 -26
- package/src/pbr-pipeline.ts +33 -10
- package/src/pipeline/standard-forward-lane.ts +20 -0
- package/src/pipeline/standard-pipeline.ts +20 -0
- package/src/pipeline/standard-profile.ts +23 -0
- package/src/record/frame-lighting.ts +103 -89
- package/src/record/frame-snapshot.ts +41 -1
- package/src/record/frame-targets.ts +6 -2
- package/src/record/frame.ts +908 -5
- package/src/record/gpu-timing.ts +224 -0
- package/src/record/main-pass-material.ts +6 -2
- package/src/record/render-context.ts +5 -0
- package/src/record/shadow-pass.ts +87 -38
- package/src/record/typed-frame-graph.ts +143 -8
- package/src/render-contract.ts +72 -0
- package/src/render-data.ts +50 -22
- package/src/render-pipeline.ts +44 -0
- package/src/render-system-extract.ts +329 -3
- package/src/render-system.ts +79 -0
- package/src/renderer-inspect.ts +66 -0
- package/src/scene/render-scene.ts +2 -0
- package/src/temporal/frame.ts +128 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +2 -3
- package/src/typed-render-graph-primitives.ts +32 -2
- package/src/typed-shadow-atlas.ts +17 -0
- package/src/typed-shadow-passes.ts +6 -5
- package/src/volume/capability.ts +173 -0
- package/src/volume/component.ts +110 -0
- package/src/volume/extract.ts +21 -0
- package/src/volume/inspection.ts +78 -0
- package/src/volume/passes.ts +680 -0
- package/src/volume/recovery.ts +86 -0
- package/src/volume/resources.ts +236 -0
- package/src/volume/temporal.ts +89 -0
- package/dist/chunk-IPXCABEP.mjs.map +0 -1
- package/dist/chunk-LOSO4CTV.mjs.map +0 -1
- package/dist/chunk-RJRUS55L.mjs.map +0 -1
- package/dist/chunk-YTQ5C7YQ.mjs.map +0 -1
|
@@ -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":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,YAAY,EAEZ,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,eAAO,MAAM,oBAAoB,EAAG,YAAqB,CAAC;AAC1D,eAAO,MAAM,qBAAqB,EAAG,aAAsB,CAAC;AAC5D,eAAO,MAAM,sBAAsB,EAAG,aAAsB,CAAC;AAC7D,eAAO,MAAM,mBAAmB,EAAG,UAAmB,CAAC;AACvD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,4EAA4E;AAC5E,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAElD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,kFAAkF;AAClF,wBAAgB,yBAAyB,CACvC,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC5D,KAAK,SAAK,EACV,QAAQ,SAAI,GACX,mBAAmB,CASrB;AAED,wFAAwF;AACxF,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC5D,cAAc,SAAI,GACjB,mBAAmB,CAOrB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;CACzC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,oFAAoF;AACpF,MAAM,WAAW,sCAAsC;IACrD,wEAAwE;IACxE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACxC;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,sCAA2C,GACnD,0BAA0B,CA4D5B;AAyBD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,EAC9C,MAAM,GAAE,mBAA0D,EAClE,cAAc,CAAC,EAAE,mBAAmB,GACnC,MAAM,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,CAyDlD"}
|
|
@@ -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.
|
|
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.
|
|
41
|
-
"@forgeax/engine-audio-webaudio": "0.1.
|
|
42
|
-
"@forgeax/engine-codec": "0.1.
|
|
43
|
-
"@forgeax/engine-ecs": "0.1.
|
|
44
|
-
"@forgeax/engine-geometry": "0.1.
|
|
45
|
-
"@forgeax/engine-graphics-extras": "0.1.
|
|
46
|
-
"@forgeax/engine-math": "0.1.
|
|
47
|
-
"@forgeax/engine-pack": "0.1.
|
|
48
|
-
"@forgeax/engine-plugin": "0.1.
|
|
49
|
-
"@forgeax/engine-profiler": "0.1.
|
|
50
|
-
"@forgeax/engine-render-graph": "0.1.
|
|
51
|
-
"@forgeax/engine-rhi": "0.1.
|
|
52
|
-
"@forgeax/engine-scene": "0.1.
|
|
53
|
-
"@forgeax/engine-shader": "0.1.
|
|
54
|
-
"@forgeax/engine-skinning": "0.1.
|
|
55
|
-
"@forgeax/engine-types": "0.1.
|
|
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.
|
|
59
|
-
"@forgeax/engine-rhi-webgpu": "0.1.
|
|
60
|
-
"@forgeax/engine-vite-plugin-shader": "0.1.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 *
|
|
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:
|
|
486
|
+
rowsPerImage: height,
|
|
487
487
|
},
|
|
488
|
-
{ width
|
|
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(
|
|
501
|
-
for (let row = 0; row <
|
|
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 +
|
|
504
|
-
row *
|
|
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(
|
|
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',
|
|
@@ -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
|
});
|