@forgeax/engine-render 0.1.34 → 0.1.35
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/README.md +52 -3
- package/dist/assembly/device-feature-admission.d.ts +2 -2
- package/dist/assembly/host-contract.d.ts +3 -2
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +5 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer.d.ts +1 -0
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -4
- package/dist/authoring.mjs.map +1 -1
- package/dist/chunk-3XUBWRY2.mjs +1842 -0
- package/dist/chunk-3XUBWRY2.mjs.map +1 -0
- package/dist/{chunk-UI5SFODX.mjs → chunk-G6HDNGY7.mjs} +2329 -1776
- package/dist/chunk-G6HDNGY7.mjs.map +1 -0
- package/dist/{chunk-HEB564WF.mjs → chunk-LM5IE7GF.mjs} +4 -4
- package/dist/{chunk-HEB564WF.mjs.map → chunk-LM5IE7GF.mjs.map} +1 -1
- package/dist/{chunk-MKDIT2EM.mjs → chunk-LNIUIKQ7.mjs} +143 -246
- package/dist/chunk-LNIUIKQ7.mjs.map +1 -0
- package/dist/chunk-MXTWKZO4.mjs +3268 -0
- package/dist/chunk-MXTWKZO4.mjs.map +1 -0
- package/dist/{chunk-ODZWR6JQ.mjs → chunk-MZ4C7EHF.mjs} +2042 -27
- package/dist/chunk-MZ4C7EHF.mjs.map +1 -0
- package/dist/chunk-RIPAEGI6.mjs +48 -0
- package/dist/chunk-RIPAEGI6.mjs.map +1 -0
- package/dist/{chunk-OCDLEI6I.mjs → chunk-SGPUJW3F.mjs} +117 -5
- package/dist/chunk-SGPUJW3F.mjs.map +1 -0
- package/dist/{chunk-ELJFJ2BU.mjs → chunk-X2KA6WHM.mjs} +29 -4
- package/dist/chunk-X2KA6WHM.mjs.map +1 -0
- package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
- package/dist/chunk-XSFB7XXQ.mjs.map +1 -0
- package/dist/cloud/frame-context.d.ts +2 -2
- package/dist/cloud/frame-context.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +810 -2073
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -19
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/errors/render.d.ts +3 -2
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/material-context.d.ts +7 -0
- package/dist/extract/material-context.d.ts.map +1 -0
- package/dist/features/host.d.ts +5 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/plan.d.ts +2 -0
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/types.d.ts +4 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/glyph-text-layout-system.d.ts +1 -1
- package/dist/glyph-text-layout-system.d.ts.map +1 -1
- package/dist/gpu-driven/shadow-ownership.d.ts +3 -3
- package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -1
- package/dist/ibl/frame-resources.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +4 -4
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +530 -9
- package/dist/index.mjs.map +1 -1
- package/dist/instances.d.ts +3 -4
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -8
- package/dist/internal.mjs.map +1 -1
- package/dist/pbr-pipeline.d.ts +3 -3
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-output/lut-gpu.d.ts +2 -2
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
- package/dist/pipeline/standard-output/resources.d.ts +2 -2
- package/dist/pipeline/standard-output/resources.d.ts.map +1 -1
- package/dist/publication/contract.d.ts +77 -0
- package/dist/publication/contract.d.ts.map +1 -0
- package/dist/publication/dependencies.d.ts +7 -0
- package/dist/publication/dependencies.d.ts.map +1 -0
- package/dist/publication/prepare-geometry.d.ts +9 -0
- package/dist/publication/prepare-geometry.d.ts.map +1 -0
- package/dist/publication/programs.d.ts +5 -0
- package/dist/publication/programs.d.ts.map +1 -0
- package/dist/publication/publisher.d.ts +33 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/receiver.d.ts +29 -0
- package/dist/publication/receiver.d.ts.map +1 -0
- package/dist/publication/resource-scope.d.ts +18 -0
- package/dist/publication/resource-scope.d.ts.map +1 -0
- package/dist/publication/targets.d.ts +33 -0
- package/dist/publication/targets.d.ts.map +1 -0
- package/dist/publication/video.d.ts +5 -0
- package/dist/publication/video.d.ts.map +1 -0
- package/dist/record/fold-buckets.d.ts +3 -3
- package/dist/record/fold-buckets.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +6 -6
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +5 -4
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +2 -2
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +2 -2
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +7 -9
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +3 -16
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/prepared-material-bindings.d.ts +3 -3
- package/dist/record/prepared-material-bindings.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +2 -2
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/sprite-instance-buffer.d.ts +31 -0
- package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
- package/dist/record/target-capture-graph.d.ts +19 -0
- package/dist/record/target-capture-graph.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +2 -13
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/record/volume-params.d.ts +2 -2
- package/dist/record/volume-params.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +5 -5
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/render-contract.d.ts +4 -1
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +2 -0
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-presentation.d.ts +2 -2
- package/dist/render-system-presentation.d.ts.map +1 -1
- package/dist/render-system-projections.d.ts +3 -2
- package/dist/render-system-projections.d.ts.map +1 -1
- package/dist/render-system-residency.d.ts +2 -2
- package/dist/render-system-residency.d.ts.map +1 -1
- package/dist/render-system.d.ts +3 -7
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +8 -4
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/render-source.d.ts +42 -0
- package/dist/scene/render-source.d.ts.map +1 -0
- package/dist/scene/source-systems.d.ts +6 -0
- package/dist/scene/source-systems.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +10 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +2 -2
- package/dist/systems/transparent-dispatch.d.ts.map +1 -1
- package/dist/systems/transparent-sort-config.d.ts +2 -1
- package/dist/systems/transparent-sort-config.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -7
- package/package.json +21 -21
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +4 -9
- package/src/__tests__/device-feature-admission.unit.test.ts +3 -2
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +3 -4
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +0 -1
- package/src/__tests__/materials-standard-contract.unit.test.ts +0 -1
- package/src/__tests__/physical-clearcoat.integration.test.ts +23 -23
- package/src/__tests__/physical-material-budget.unit.test.ts +40 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +1 -1
- package/src/assembly/device-feature-admission.ts +2 -2
- package/src/assembly/host-contract.ts +5 -2
- package/src/assembly/recovery/renderer-recover.ts +9 -0
- package/src/assembly/render-target-host.ts +57 -47
- package/src/assembly/renderer-facade.ts +3 -1
- package/src/assembly/webgpu-ready.ts +1 -1
- package/src/assembly/webgpu-renderer.ts +89 -61
- package/src/cloud/frame-context.ts +2 -2
- package/src/device/gpu-residency.ts +26 -25
- package/src/errors/render.ts +3 -1
- package/src/extract/material-context.ts +21 -0
- package/src/features/host.ts +13 -5
- package/src/features/plan.ts +2 -0
- package/src/features/types.ts +4 -0
- package/src/glyph-text-layout-system.ts +2 -2
- package/src/gpu-driven/shadow-ownership.ts +3 -3
- package/src/ibl/frame-resources.ts +0 -1
- package/src/ibl/skylight-bind-group.ts +13 -25
- package/src/index.ts +9 -0
- package/src/instances.ts +9 -6
- package/src/pbr-pipeline.ts +11 -17
- package/src/pipeline/standard-output/lut-gpu.ts +3 -3
- package/src/pipeline/standard-output/resources.ts +2 -2
- package/src/publication/__tests__/derived-geometry.integration.test.ts +177 -0
- package/src/publication/__tests__/features.integration.test.ts +122 -0
- package/src/publication/__tests__/programs.unit.test.ts +25 -0
- package/src/publication/__tests__/publication.integration.test.ts +370 -0
- package/src/publication/__tests__/targets.integration.test.ts +120 -0
- package/src/publication/__tests__/video.browser.test.ts +50 -0
- package/src/publication/contract.ts +104 -0
- package/src/publication/dependencies.ts +54 -0
- package/src/publication/prepare-geometry.ts +94 -0
- package/src/publication/programs.ts +45 -0
- package/src/publication/publisher.ts +618 -0
- package/src/publication/receiver.ts +297 -0
- package/src/publication/resource-scope.ts +31 -0
- package/src/publication/targets.ts +182 -0
- package/src/publication/video.ts +33 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +8 -10
- package/src/record/__tests__/video-texture-view.unit.test.ts +9 -9
- package/src/record/fold-buckets.ts +8 -5
- package/src/record/frame-snapshot.ts +6 -6
- package/src/record/frame.ts +42 -22
- package/src/record/helpers.ts +2 -2
- package/src/record/main-pass-geometry.ts +21 -2
- package/src/record/main-pass-material.ts +37 -33
- package/src/record/main-pass-sprite-draws.ts +6 -152
- package/src/record/main-pass.ts +8 -7
- package/src/record/prepared-material-bindings.ts +11 -6
- package/src/record/render-context.ts +2 -2
- package/src/record/shadow-pass.ts +0 -3
- package/src/record/sprite-instance-buffer.ts +155 -0
- package/src/record/target-capture-graph.ts +258 -0
- package/src/record/typed-frame-graph.ts +6 -206
- package/src/record/view-ubo.ts +1 -1
- package/src/record/volume-params.ts +6 -6
- package/src/recovery/render-system-candidate.ts +10 -10
- package/src/render-contract.ts +6 -1
- package/src/render-system-extract-tail.ts +33 -17
- package/src/render-system-extract.ts +2 -0
- package/src/render-system-presentation.ts +2 -2
- package/src/render-system-projections.ts +3 -2
- package/src/render-system-residency.ts +2 -2
- package/src/render-system.ts +82 -53
- package/src/scene/render-scene.ts +110 -100
- package/src/scene/render-source.ts +90 -0
- package/src/scene/source-systems.ts +33 -0
- package/src/systems/skin-palette-allocator.ts +1 -0
- package/src/systems/skin-palette-types.ts +11 -0
- package/src/systems/transparent-dispatch.ts +2 -2
- package/src/systems/transparent-sort-config.ts +3 -1
- package/dist/chunk-BLXGONR2.mjs.map +0 -1
- package/dist/chunk-ELJFJ2BU.mjs.map +0 -1
- package/dist/chunk-ILQ5MEZF.mjs +0 -32
- package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
- package/dist/chunk-MKDIT2EM.mjs.map +0 -1
- package/dist/chunk-OCDLEI6I.mjs.map +0 -1
- package/dist/chunk-ODZWR6JQ.mjs.map +0 -1
- package/dist/chunk-RXZ3RGOU.mjs +0 -53
- package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
- package/dist/chunk-SHFUFJ5N.mjs +0 -1781
- package/dist/chunk-SHFUFJ5N.mjs.map +0 -1
- package/dist/chunk-UI5SFODX.mjs.map +0 -1
- package/dist/chunk-UINHLCZA.mjs +0 -2389
- package/dist/chunk-UINHLCZA.mjs.map +0 -1
- package/dist/chunk-WEX45HKH.mjs +0 -1524
- package/dist/chunk-WEX45HKH.mjs.map +0 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { TimeResource } from '@forgeax/engine-ecs';
|
|
2
|
+
import type { MaterialRuntimeArtifact, MaterialShaderEntry } from '@forgeax/engine-shader';
|
|
3
|
+
import type { Asset, Handle } from '@forgeax/engine-types';
|
|
4
|
+
import type { DispatchEntry, ExtractedFrame, RenderableSnapshot } from '../render-system-extract';
|
|
5
|
+
import type { TransparentSortConfig } from '../systems/transparent-sort-config';
|
|
6
|
+
import type { PublishedRenderTarget, PublishedRenderTargetSource } from './targets';
|
|
7
|
+
|
|
8
|
+
/** Chosen by App before creating the receiver; never inferred from the first packet. */
|
|
9
|
+
export interface RenderPublicationIdentity {
|
|
10
|
+
readonly source: string;
|
|
11
|
+
readonly epoch: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type RenderPublicationMetadata = Omit<
|
|
15
|
+
ExtractedFrame,
|
|
16
|
+
| 'renderables'
|
|
17
|
+
| 'dispatch'
|
|
18
|
+
| 'visibilitySnapshots'
|
|
19
|
+
| 'featureVisibilitySnapshots'
|
|
20
|
+
| 'hiddenEntityReports'
|
|
21
|
+
| 'shadowCasterEntityKeys'
|
|
22
|
+
| 'shadowCasterDrawKeys'
|
|
23
|
+
| 'shadowCasterMembership'
|
|
24
|
+
>;
|
|
25
|
+
|
|
26
|
+
export interface RenderPublicationTemplate {
|
|
27
|
+
readonly snapshot: Omit<RenderableSnapshot, 'worldId' | 'entityKey' | 'transform'>;
|
|
28
|
+
readonly dispatch: readonly Omit<DispatchEntry, 'entityIndex' | 'renderableIndex'>[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Numeric storage is publisher-owned; no ECS or asset buffer is transferred. */
|
|
32
|
+
export interface RenderPublication extends RenderPublicationIdentity {
|
|
33
|
+
readonly revision: number;
|
|
34
|
+
readonly base: number;
|
|
35
|
+
readonly baseline: boolean;
|
|
36
|
+
readonly time: TimeResource;
|
|
37
|
+
readonly sampleTimeSeconds: number;
|
|
38
|
+
readonly temporalReset: boolean;
|
|
39
|
+
readonly transparentSort: TransparentSortConfig;
|
|
40
|
+
readonly metadata: RenderPublicationMetadata;
|
|
41
|
+
readonly templates: readonly RenderPublicationTemplate[];
|
|
42
|
+
readonly videoFrames: readonly {
|
|
43
|
+
readonly entity: number;
|
|
44
|
+
readonly clip: number;
|
|
45
|
+
readonly frame: VideoFrame;
|
|
46
|
+
}[];
|
|
47
|
+
readonly targets: readonly PublishedRenderTarget[];
|
|
48
|
+
readonly targetSources: readonly PublishedRenderTargetSource[];
|
|
49
|
+
readonly features: readonly { readonly identity: string; readonly data: unknown }[];
|
|
50
|
+
readonly programs: readonly {
|
|
51
|
+
readonly key: string;
|
|
52
|
+
readonly shader: MaterialShaderEntry;
|
|
53
|
+
readonly artifact?: MaterialRuntimeArtifact;
|
|
54
|
+
}[];
|
|
55
|
+
/** entity, template index pairs. A publication source owns one World. */
|
|
56
|
+
readonly upserts: Uint32Array;
|
|
57
|
+
readonly removed: Uint32Array;
|
|
58
|
+
readonly transformEntities: Uint32Array;
|
|
59
|
+
readonly transforms: Float32Array;
|
|
60
|
+
readonly assets: readonly {
|
|
61
|
+
readonly handle: Handle<string, 'shared'>;
|
|
62
|
+
readonly guid?: string;
|
|
63
|
+
readonly value: Asset;
|
|
64
|
+
}[];
|
|
65
|
+
readonly retiredAssets: readonly Handle<string, 'shared'>[];
|
|
66
|
+
readonly invalidatedAssets: readonly Handle<string, 'shared'>[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface PublishedRenderFrameInput {
|
|
70
|
+
readonly publication: RenderPublication;
|
|
71
|
+
/** Realm-local adapter invoked only after the feature's graph is submitted. */
|
|
72
|
+
readonly onFeatureSourceSubmitted?: (identity: string, feedback: unknown) => void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function renderPublicationTransfers(packet: RenderPublication): ArrayBuffer[] {
|
|
76
|
+
return [
|
|
77
|
+
packet.upserts.buffer,
|
|
78
|
+
packet.removed.buffer,
|
|
79
|
+
packet.transformEntities.buffer,
|
|
80
|
+
packet.transforms.buffer,
|
|
81
|
+
] as ArrayBuffer[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type RenderPublicationFailure =
|
|
85
|
+
| 'identity'
|
|
86
|
+
| 'base'
|
|
87
|
+
| 'revision'
|
|
88
|
+
| 'shape'
|
|
89
|
+
| 'unsupported'
|
|
90
|
+
| 'in-flight'
|
|
91
|
+
| 'disposed';
|
|
92
|
+
|
|
93
|
+
export class RenderPublicationError extends Error {
|
|
94
|
+
readonly code = 'render-publication-invalid' as const;
|
|
95
|
+
readonly expected = 'one valid publication for the bound source session and accepted base';
|
|
96
|
+
readonly hint =
|
|
97
|
+
'inspect detail.reason; repair the source or start a new session with a complete current baseline';
|
|
98
|
+
constructor(
|
|
99
|
+
readonly detail: { readonly reason: RenderPublicationFailure; readonly subject: string },
|
|
100
|
+
) {
|
|
101
|
+
super(`render-publication-invalid: ${detail.reason}: ${detail.subject}`);
|
|
102
|
+
this.name = 'RenderPublicationError';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Handle } from '@forgeax/engine-types';
|
|
2
|
+
import type { ExtractedFrame, RenderableSnapshot } from '../render-system-extract';
|
|
3
|
+
|
|
4
|
+
/** One asset closure for source publication and receiver admission. */
|
|
5
|
+
export function publicationDependencies(
|
|
6
|
+
row: Pick<RenderableSnapshot, 'assetHandle' | 'materials'>,
|
|
7
|
+
): Handle<string, 'shared'>[] {
|
|
8
|
+
const handles = new Set<Handle<string, 'shared'>>([row.assetHandle as Handle<string, 'shared'>]);
|
|
9
|
+
for (const material of row.materials) {
|
|
10
|
+
for (const handle of [
|
|
11
|
+
material.materialHandle,
|
|
12
|
+
material.baseColorTexture,
|
|
13
|
+
material.metallicRoughnessTexture,
|
|
14
|
+
material.normalTexture,
|
|
15
|
+
material.emissiveTexture,
|
|
16
|
+
material.occlusionTexture,
|
|
17
|
+
]) {
|
|
18
|
+
if (handle) handles.add(handle as Handle<string, 'shared'>);
|
|
19
|
+
}
|
|
20
|
+
for (const handle of material.textureHandles?.values() ?? []) handles.add(handle);
|
|
21
|
+
for (const handle of material.samplerHandles?.values() ?? []) handles.add(handle);
|
|
22
|
+
}
|
|
23
|
+
return [...handles];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Resources selected once for the frame rather than attached to geometry. */
|
|
27
|
+
export function publicationFrameDependencies(
|
|
28
|
+
frame: Pick<
|
|
29
|
+
ExtractedFrame,
|
|
30
|
+
'cameras' | 'auxiliaryCameras' | 'skylight' | 'skybox' | 'lights' | 'volumetricFog'
|
|
31
|
+
>,
|
|
32
|
+
): Handle<string, 'shared'>[] {
|
|
33
|
+
const handles = new Set<Handle<string, 'shared'>>();
|
|
34
|
+
const add = (handle: number | undefined) => {
|
|
35
|
+
if (handle) handles.add(handle as Handle<string, 'shared'>);
|
|
36
|
+
};
|
|
37
|
+
add(frame.skylight?.equirectHandle);
|
|
38
|
+
add(frame.skybox?.equirectHandle);
|
|
39
|
+
for (const camera of [...frame.cameras, ...frame.auxiliaryCameras]) add(camera.output?.colorLut);
|
|
40
|
+
for (const light of frame.lights.spot) {
|
|
41
|
+
add(light.iesProfileHandle);
|
|
42
|
+
add(light.cookieHandle);
|
|
43
|
+
add(light.projectorHandle);
|
|
44
|
+
}
|
|
45
|
+
const fogs =
|
|
46
|
+
frame.volumetricFog === undefined
|
|
47
|
+
? []
|
|
48
|
+
: [frame.volumetricFog, ...(frame.volumetricFog.additional ?? [])];
|
|
49
|
+
for (const fog of fogs) {
|
|
50
|
+
add(fog.densityHandle);
|
|
51
|
+
add(fog.projectorHandle);
|
|
52
|
+
}
|
|
53
|
+
return [...handles];
|
|
54
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
2
|
+
import type { Handle, MeshAsset } from '@forgeax/engine-types';
|
|
3
|
+
import { buildGpuDrivenDraws } from '../extract/gpu-driven';
|
|
4
|
+
import type { InstanceProjectionStore } from '../instances';
|
|
5
|
+
import type { extractFrames, RenderableSnapshot } from '../render-system-extract';
|
|
6
|
+
import type { PersistentRenderScene } from '../scene/render-scene';
|
|
7
|
+
import type { SkinPaletteAllocator } from '../systems/skin-palette-allocator';
|
|
8
|
+
import { RenderPublicationError } from './contract';
|
|
9
|
+
import type { PreparedRenderPublication } from './receiver';
|
|
10
|
+
import { renderAssetByGuid } from './resource-scope';
|
|
11
|
+
|
|
12
|
+
/** Resolve GPU ownership after source data has crossed the publication boundary. */
|
|
13
|
+
export function preparePublicationGeometry(
|
|
14
|
+
input: PreparedRenderPublication,
|
|
15
|
+
scene: PersistentRenderScene,
|
|
16
|
+
palette: SkinPaletteAllocator | null | undefined,
|
|
17
|
+
assets: AssetRegistry,
|
|
18
|
+
instances: InstanceProjectionStore,
|
|
19
|
+
getMaterialShaderArtifact?: NonNullable<
|
|
20
|
+
Parameters<typeof extractFrames>[5]
|
|
21
|
+
>['getMaterialShaderArtifact'],
|
|
22
|
+
): PreparedRenderPublication {
|
|
23
|
+
const replacements = new Map<number, RenderableSnapshot>();
|
|
24
|
+
for (const operation of input.operations) {
|
|
25
|
+
if (operation.kind !== 'remove' && operation.snapshot === undefined) continue;
|
|
26
|
+
if (operation.kind === 'remove' || operation.snapshot?.instances === undefined)
|
|
27
|
+
instances.release(input.resources, operation.entityKey);
|
|
28
|
+
const prior = scene.compositionSlot(0, operation.entityKey)?.snapshot.skin;
|
|
29
|
+
const pose = operation.kind === 'remove' ? undefined : operation.snapshot?.skinPose;
|
|
30
|
+
if (prior !== undefined && prior.identity !== pose?.identity)
|
|
31
|
+
palette?.releasePersistentSlice(prior.identity);
|
|
32
|
+
}
|
|
33
|
+
for (const row of input.frame.renderables) {
|
|
34
|
+
const { skinPose, ...source } = row;
|
|
35
|
+
let skin = row.skin;
|
|
36
|
+
if (skinPose !== undefined) {
|
|
37
|
+
if (palette == null)
|
|
38
|
+
throw new RenderPublicationError({
|
|
39
|
+
reason: 'unsupported',
|
|
40
|
+
subject: 'skin palette allocator',
|
|
41
|
+
});
|
|
42
|
+
palette.observePersistentJoints(
|
|
43
|
+
skinPose.identity,
|
|
44
|
+
skinPose.inverseBindMatrices,
|
|
45
|
+
skinPose.jointWorlds,
|
|
46
|
+
);
|
|
47
|
+
skin = palette.allocatePersistentSlice(skinPose);
|
|
48
|
+
palette.writePersistentJointPalette(skin, skinPose.inverseBindMatrices, skinPose.jointWorlds);
|
|
49
|
+
}
|
|
50
|
+
const projected =
|
|
51
|
+
row.instances === undefined
|
|
52
|
+
? undefined
|
|
53
|
+
: instances.project(input.resources, row.entityKey, row.instances.transforms);
|
|
54
|
+
const snapshot: RenderableSnapshot = {
|
|
55
|
+
...source,
|
|
56
|
+
...(skin === undefined ? {} : { skin }),
|
|
57
|
+
...(projected === undefined || row.instances === undefined
|
|
58
|
+
? {}
|
|
59
|
+
: { instances: { ...row.instances, ...projected, archVersion: 0 } }),
|
|
60
|
+
};
|
|
61
|
+
if (projected !== undefined) instances.accept(input.resources, row.entityKey, projected);
|
|
62
|
+
const mesh = input.resources.resolveAsset<MeshAsset>(
|
|
63
|
+
row.assetHandle as Handle<'MeshAsset', 'shared'>,
|
|
64
|
+
);
|
|
65
|
+
if (!mesh.ok) throw mesh.error;
|
|
66
|
+
const gpuDrivenDraws =
|
|
67
|
+
row.morph === undefined
|
|
68
|
+
? buildGpuDrivenDraws({
|
|
69
|
+
mesh: mesh.value,
|
|
70
|
+
materials: row.materials,
|
|
71
|
+
fallbackMaterial: row.material,
|
|
72
|
+
baseSnapshot: snapshot,
|
|
73
|
+
...(getMaterialShaderArtifact === undefined ? {} : { getMaterialShaderArtifact }),
|
|
74
|
+
...(row.lods === undefined
|
|
75
|
+
? {}
|
|
76
|
+
: {
|
|
77
|
+
lodMeshes: row.lods.map((lod) =>
|
|
78
|
+
renderAssetByGuid<MeshAsset>(input.resources, assets, lod.mesh),
|
|
79
|
+
),
|
|
80
|
+
}),
|
|
81
|
+
})
|
|
82
|
+
: [];
|
|
83
|
+
replacements.set(row.entityKey, { ...snapshot, gpuDrivenDraws });
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
...input,
|
|
87
|
+
frame: { ...input.frame, renderables: [...replacements.values()] },
|
|
88
|
+
operations: input.operations.map((operation) =>
|
|
89
|
+
operation.kind !== 'remove' && operation.snapshot !== undefined
|
|
90
|
+
? { ...operation, snapshot: replacements.get(operation.entityKey) as RenderableSnapshot }
|
|
91
|
+
: operation,
|
|
92
|
+
),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
2
|
+
import { MaterialArtifactRegistry, ShaderRegistry } from '@forgeax/engine-shader';
|
|
3
|
+
import { type RenderPublication, RenderPublicationError } from './contract';
|
|
4
|
+
|
|
5
|
+
/** Admit immutable producer artifacts before the full Renderer prepares their pipelines. */
|
|
6
|
+
export function installPublicationPrograms(
|
|
7
|
+
assets: AssetRegistry,
|
|
8
|
+
programs: RenderPublication['programs'],
|
|
9
|
+
): void {
|
|
10
|
+
if (programs.length === 0) return;
|
|
11
|
+
const validation = new MaterialArtifactRegistry();
|
|
12
|
+
const shaders = new ShaderRegistry({ manifestUrl: undefined });
|
|
13
|
+
const keys = new Set<string>();
|
|
14
|
+
for (const row of programs) {
|
|
15
|
+
if (keys.has(row.key) || (row.artifact !== undefined && row.artifact.key !== row.key))
|
|
16
|
+
throw new RenderPublicationError({
|
|
17
|
+
reason: 'shape',
|
|
18
|
+
subject: 'duplicate or mismatched program key',
|
|
19
|
+
});
|
|
20
|
+
keys.add(row.key);
|
|
21
|
+
shaders.installMaterialArtifact(row.key, row.shader);
|
|
22
|
+
const previous = assets.shaderRegistry.findMaterialArtifact(row.key);
|
|
23
|
+
if (
|
|
24
|
+
previous.ok &&
|
|
25
|
+
(previous.value.source !== row.shader.source ||
|
|
26
|
+
JSON.stringify(previous.value.paramSchema) !== JSON.stringify(row.shader.paramSchema) ||
|
|
27
|
+
JSON.stringify(previous.value.receipt) !== JSON.stringify(row.shader.receipt))
|
|
28
|
+
) {
|
|
29
|
+
throw new RenderPublicationError({
|
|
30
|
+
reason: 'shape',
|
|
31
|
+
subject: `conflicting immutable shader ${row.key}`,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (row.artifact !== undefined) {
|
|
35
|
+
const existing = assets.getMaterialArtifact(row.key);
|
|
36
|
+
if (existing !== undefined) validation.register(existing).unwrap();
|
|
37
|
+
validation.register(row.artifact).unwrap();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (const row of programs) {
|
|
41
|
+
if (row.artifact !== undefined) assets.materialArtifactRegistry.register(row.artifact).unwrap();
|
|
42
|
+
if (!assets.shaderRegistry.findMaterialArtifact(row.key).ok)
|
|
43
|
+
assets.shaderRegistry.installMaterialArtifact(row.key, row.shader);
|
|
44
|
+
}
|
|
45
|
+
}
|