@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
|
@@ -183,7 +183,7 @@ import {
|
|
|
183
183
|
} from './render-system-extract';
|
|
184
184
|
import { buildShadowFrusta } from './scene/shadow-visibility';
|
|
185
185
|
import { SHADOW_ATLAS_DEFAULT_LAYERS } from './shadow-atlas';
|
|
186
|
-
import type { SkinPaletteReceipt } from './systems/skin-palette-types';
|
|
186
|
+
import type { SkinPaletteReceipt, SkinPose } from './systems/skin-palette-types';
|
|
187
187
|
|
|
188
188
|
function skinPaletteIdentity(world: World, entity: number): string {
|
|
189
189
|
return `skin:${world.identity}:${entity}`;
|
|
@@ -2739,6 +2739,7 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2739
2739
|
// resolve / validate / write chain (D-9 reset already fired at
|
|
2740
2740
|
// extractFrame entry; per-entity allocate + writeJointPalette here).
|
|
2741
2741
|
let skinSlice: SkinPaletteReceipt | undefined;
|
|
2742
|
+
let skinPose: SkinPose | undefined;
|
|
2742
2743
|
const skinIdentity = hasSkin ? skinPaletteIdentity(world, entity) : undefined;
|
|
2743
2744
|
const releaseSkinIdentity = (): void => {
|
|
2744
2745
|
if (skinIdentity !== undefined) {
|
|
@@ -2850,6 +2851,17 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2850
2851
|
});
|
|
2851
2852
|
skinPaletteAllocator.writePersistentJointPalette(receipt, ibms, jointWorlds);
|
|
2852
2853
|
skinSlice = receipt;
|
|
2854
|
+
} else {
|
|
2855
|
+
skinPose = {
|
|
2856
|
+
identity: skinPaletteIdentity(world, entity),
|
|
2857
|
+
generation: ((skeletonHandleRaw >>> 0) ^ skeleton.jointCount) >>> 0,
|
|
2858
|
+
jointCount: skeleton.jointCount,
|
|
2859
|
+
...(hasFiniteOrderedLocalAabb(skeleton.bounds)
|
|
2860
|
+
? { bounds: new Float32Array(skeleton.bounds) }
|
|
2861
|
+
: {}),
|
|
2862
|
+
inverseBindMatrices: ibms,
|
|
2863
|
+
jointWorlds,
|
|
2864
|
+
};
|
|
2853
2865
|
}
|
|
2854
2866
|
}
|
|
2855
2867
|
}
|
|
@@ -2858,7 +2870,7 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2858
2870
|
// projection. Do not publish a renderable or its staged dispatch when
|
|
2859
2871
|
// palette extraction was unavailable; the record stage must never
|
|
2860
2872
|
// reinterpret a skinned vertex stream through an ordinary mesh group.
|
|
2861
|
-
if (skinSlice === undefined && hasSkin) {
|
|
2873
|
+
if (skinSlice === undefined && skinPose === undefined && hasSkin) {
|
|
2862
2874
|
releaseSkinIdentity();
|
|
2863
2875
|
if (
|
|
2864
2876
|
materialSnap.materialShaderId === 'forgeax::pbr-skin' ||
|
|
@@ -3128,6 +3140,7 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
3128
3140
|
entityKey: entity,
|
|
3129
3141
|
...(authorVisible ? {} : { authorVisible: false }),
|
|
3130
3142
|
...(skinSlice !== undefined ? { skin: skinSlice } : {}),
|
|
3143
|
+
...(skinPose === undefined ? {} : { skinPose }),
|
|
3131
3144
|
...(skin?.joints === undefined
|
|
3132
3145
|
? {}
|
|
3133
3146
|
: { skinJointEntities: Array.from(skin.joints, (joint) => Number(joint)) }),
|
|
@@ -3136,21 +3149,24 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
3136
3149
|
...(spriteInstancesSnap !== undefined ? { spriteInstances: spriteInstancesSnap } : {}),
|
|
3137
3150
|
...(pointsLines !== undefined ? { pointsLines } : {}),
|
|
3138
3151
|
};
|
|
3139
|
-
const gpuDrivenDraws =
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3152
|
+
const gpuDrivenDraws =
|
|
3153
|
+
skinPose === undefined
|
|
3154
|
+
? buildGpuDrivenDraws({
|
|
3155
|
+
mesh: gpuDrivenMesh,
|
|
3156
|
+
materials: materialsArr,
|
|
3157
|
+
fallbackMaterial: materialSnap,
|
|
3158
|
+
baseSnapshot: baseRenderable,
|
|
3159
|
+
...(getMaterialShaderArtifact === undefined ? {} : { getMaterialShaderArtifact }),
|
|
3160
|
+
...(lods === undefined
|
|
3161
|
+
? {}
|
|
3162
|
+
: {
|
|
3163
|
+
lodMeshes: lods.map((lod) => {
|
|
3164
|
+
const lower = assets?.lookup<Asset>(lod.mesh);
|
|
3165
|
+
return lower?.kind === 'mesh' ? lower : undefined;
|
|
3166
|
+
}),
|
|
3167
|
+
}),
|
|
3168
|
+
})
|
|
3169
|
+
: [];
|
|
3154
3170
|
for (const draw of gpuDrivenDraws) {
|
|
3155
3171
|
if (draw.preparationError === undefined) continue;
|
|
3156
3172
|
worldInternal._routeError(draw.preparationError, {
|
|
@@ -792,6 +792,8 @@ export interface RenderableSnapshot {
|
|
|
792
792
|
* Absent (`undefined`) means the entity is not skinned.
|
|
793
793
|
*/
|
|
794
794
|
readonly skin?: SkinPaletteReceipt;
|
|
795
|
+
/** Source pose waiting for the receiving Renderer to assign a palette. */
|
|
796
|
+
readonly skinPose?: import('./systems/skin-palette-types').SkinPose;
|
|
795
797
|
/** Joint identities consumed by the retained scene dependency index. */
|
|
796
798
|
readonly skinJointEntities?: readonly number[];
|
|
797
799
|
/** Source pass ownership retained with the scene record across view changes. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RenderResourceScope } from './publication/resource-scope';
|
|
2
2
|
import type { RenderSystemInternals } from './record/render-context';
|
|
3
3
|
import type { FramePresentation } from './render-contract';
|
|
4
4
|
import type { DispatchEntry, RenderableSnapshot } from './render-system-extract';
|
|
@@ -20,7 +20,7 @@ export function projectFramePresentation(input: {
|
|
|
20
20
|
readonly hasEnvironment: boolean;
|
|
21
21
|
readonly submissionRenderables: readonly RenderableSnapshot[];
|
|
22
22
|
readonly submissionDispatch: readonly DispatchEntry[];
|
|
23
|
-
readonly preparedWorlds: readonly
|
|
23
|
+
readonly preparedWorlds: readonly RenderResourceScope[];
|
|
24
24
|
readonly internals: RenderSystemInternals;
|
|
25
25
|
}): FramePresentationProjection {
|
|
26
26
|
const displayRenderableIndices = new Set<number>();
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
LodOcclusionInspectionRow,
|
|
7
7
|
LodOcclusionWorldInspection,
|
|
8
8
|
} from './inspection-types';
|
|
9
|
+
import type { RenderResourceScope } from './publication/resource-scope';
|
|
9
10
|
import { worldEntityKey } from './record/frame-snapshot';
|
|
10
11
|
import type { CameraSnapshot, DrawOwnerOptions } from './render-contract';
|
|
11
12
|
import type { DispatchEntry, RenderableSnapshot } from './render-system-extract';
|
|
@@ -52,7 +53,7 @@ interface LodInspectionQuerySummary {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
export function createLodWorldInspections(
|
|
55
|
-
worlds: readonly
|
|
56
|
+
worlds: readonly RenderResourceScope[],
|
|
56
57
|
renderables: readonly RenderableSnapshot[],
|
|
57
58
|
submittedRenderables: readonly RenderableSnapshot[],
|
|
58
59
|
camera: CameraSnapshot,
|
|
@@ -164,7 +165,7 @@ export function createLodWorldInspections(
|
|
|
164
165
|
/** Apply the configured stable sub-sort to transparent dispatch entries. */
|
|
165
166
|
export function sortTransparentDispatch(
|
|
166
167
|
dispatch: DispatchEntry[],
|
|
167
|
-
world:
|
|
168
|
+
world: RenderResourceScope,
|
|
168
169
|
cameras: readonly CameraSnapshot[],
|
|
169
170
|
renderables: readonly RenderableSnapshot[],
|
|
170
171
|
): DispatchEntry[] {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { resolveAssetHandle } from '@forgeax/engine-assets-runtime';
|
|
2
|
-
import type { World } from '@forgeax/engine-ecs';
|
|
3
2
|
import {
|
|
4
3
|
deriveTextureLayout,
|
|
5
4
|
type MaterialAsset,
|
|
@@ -11,6 +10,7 @@ import type {
|
|
|
11
10
|
MeshMaterialBindingPreparationFailure,
|
|
12
11
|
MeshMaterialBindingResidency,
|
|
13
12
|
} from './mesh-material-bindings';
|
|
13
|
+
import type { RenderResourceScope } from './publication/resource-scope';
|
|
14
14
|
import type { RenderSystemInternals } from './record/render-context';
|
|
15
15
|
import { materialSamplerHandles, materialTextureHandles } from './recovery/render-system-candidate';
|
|
16
16
|
import type { MaterialSnapshot } from './render-system-extract';
|
|
@@ -49,7 +49,7 @@ function preparationFailureFrom(error: unknown): MeshMaterialBindingPreparationF
|
|
|
49
49
|
* already resident resource remains last-known-good.
|
|
50
50
|
*/
|
|
51
51
|
export function observeMaterialResidency(
|
|
52
|
-
world:
|
|
52
|
+
world: RenderResourceScope | undefined,
|
|
53
53
|
material: MaterialSnapshot,
|
|
54
54
|
internals: RenderSystemInternals,
|
|
55
55
|
): MeshMaterialBindingResidency {
|
package/src/render-system.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { projectCaptureScene } from './capture/scene-projection';
|
|
2
|
+
import { renderMaterialContext } from './extract/material-context';
|
|
3
|
+
import { RenderPublicationError } from './publication/contract';
|
|
4
|
+
import { preparePublicationGeometry } from './publication/prepare-geometry';
|
|
5
|
+
import type { PreparedRenderPublication } from './publication/receiver';
|
|
6
|
+
import { type RenderResourceScope, renderTime } from './publication/resource-scope';
|
|
2
7
|
import type { RenderSceneBounds } from './scene/render-scene-types';
|
|
3
8
|
// @forgeax/engine-math is referenced through render-system-record.ts which builds
|
|
4
9
|
// view/proj matrices and worldFromLocal via `mat4.compose / .multiply /
|
|
@@ -6,13 +11,13 @@ import type { RenderSceneBounds } from './scene/render-scene-types';
|
|
|
6
11
|
// asserts `/@forgeax\/engine-math/` shows up in render-system.ts source).
|
|
7
12
|
|
|
8
13
|
import { numMipLevels } from '@forgeax/engine-assets-runtime';
|
|
9
|
-
import {
|
|
14
|
+
import type { World } from '@forgeax/engine-ecs';
|
|
10
15
|
import type { RenderReadLease } from '@forgeax/engine-ecs/projection';
|
|
11
16
|
import type { RecorderSession } from '@forgeax/engine-profiler';
|
|
12
17
|
import type { CompiledRenderGraphInfo } from '@forgeax/engine-render-graph';
|
|
13
18
|
import type { BindGroupLayout, Buffer, RenderPipeline, RhiDevice } from '@forgeax/engine-rhi';
|
|
14
19
|
import { err, ok, type Result, RhiError } from '@forgeax/engine-rhi';
|
|
15
|
-
import { type RenderPipelineAsset, toShared } from '@forgeax/engine-types';
|
|
20
|
+
import { type Handle, type RenderPipelineAsset, toShared } from '@forgeax/engine-types';
|
|
16
21
|
import {
|
|
17
22
|
type DirectionalShadowInspectionSource,
|
|
18
23
|
directionalShadowProfileFromQuality,
|
|
@@ -363,6 +368,7 @@ export interface RenderSystem {
|
|
|
363
368
|
opts: DrawOwnerOptions,
|
|
364
369
|
renderReadLeases?: readonly RenderReadLease[],
|
|
365
370
|
timingCapture?: GpuTimingCapture,
|
|
371
|
+
publication?: PreparedRenderPublication,
|
|
366
372
|
): boolean;
|
|
367
373
|
/**
|
|
368
374
|
* Return the asset binding consumed by the last successful record pass.
|
|
@@ -604,7 +610,7 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
604
610
|
);
|
|
605
611
|
let releaseProfilerCatalog =
|
|
606
612
|
phaseCatalogRegistration?.ok === true ? phaseCatalogRegistration.value : undefined;
|
|
607
|
-
let preparedWorlds: readonly
|
|
613
|
+
let preparedWorlds: readonly RenderResourceScope[] = [];
|
|
608
614
|
const resolveFeatureNoise = createFeatureNoiseResolver({
|
|
609
615
|
scope: internals.deviceScope,
|
|
610
616
|
getDevice: () => internals.device,
|
|
@@ -1497,7 +1503,7 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
1497
1503
|
let orderedDispatchCache:
|
|
1498
1504
|
| {
|
|
1499
1505
|
readonly source: readonly DispatchEntry[];
|
|
1500
|
-
readonly world:
|
|
1506
|
+
readonly world: RenderResourceScope;
|
|
1501
1507
|
readonly camera: readonly CameraSnapshot[];
|
|
1502
1508
|
readonly renderables: readonly RenderableSnapshot[];
|
|
1503
1509
|
readonly value: readonly DispatchEntry[];
|
|
@@ -1628,7 +1634,7 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
1628
1634
|
(
|
|
1629
1635
|
runtime: RenderSystemInternals,
|
|
1630
1636
|
gpuWork: RenderFeatureGpuWorkOwner,
|
|
1631
|
-
worlds: readonly
|
|
1637
|
+
worlds: readonly RenderResourceScope[],
|
|
1632
1638
|
caches: PreparedResolverCaches,
|
|
1633
1639
|
) =>
|
|
1634
1640
|
(input: RenderFeaturePreparedGraphicsResolverInput): PreparedGraphicsResolver => {
|
|
@@ -2198,9 +2204,12 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
2198
2204
|
opts: DrawOwnerOptions,
|
|
2199
2205
|
renderReadLeases?: readonly RenderReadLease[],
|
|
2200
2206
|
timingCapture?: GpuTimingCapture,
|
|
2207
|
+
publication?: PreparedRenderPublication,
|
|
2201
2208
|
): boolean {
|
|
2202
2209
|
const composition = canonicalizeWorldComposition(worlds, opts, renderReadLeases);
|
|
2203
|
-
const
|
|
2210
|
+
const sourceWorlds = composition.worlds;
|
|
2211
|
+
const compositionWorlds: readonly RenderResourceScope[] =
|
|
2212
|
+
publication === undefined ? sourceWorlds : [publication.resources];
|
|
2204
2213
|
const compositionLeases = composition.leases;
|
|
2205
2214
|
preparedWorlds = compositionWorlds;
|
|
2206
2215
|
const profileSession = internals.profiler?.activeSession();
|
|
@@ -2240,21 +2249,45 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
2240
2249
|
// so a hot-swap cannot reuse passes compiled for the retired pipeline.
|
|
2241
2250
|
resetRenderFeatureGraphState(internals);
|
|
2242
2251
|
lastBuiltPipelineHandle = frameState.installedPipelineHandle;
|
|
2243
|
-
persistentRenderScene.invalidate();
|
|
2252
|
+
if (publication === undefined) persistentRenderScene.invalidate();
|
|
2244
2253
|
}
|
|
2245
2254
|
dispatchCounts.unlit = 0;
|
|
2246
2255
|
|
|
2247
|
-
const resourceWorld = compositionWorlds[resourceOwner] as
|
|
2256
|
+
const resourceWorld = compositionWorlds[resourceOwner] as RenderResourceScope;
|
|
2248
2257
|
let frame: ReturnType<PersistentRenderScene['extractComposition']>;
|
|
2249
2258
|
try {
|
|
2250
2259
|
frame = runProfiledRenderPhase(profileSession, 'extract', () => {
|
|
2260
|
+
if (publication !== undefined) {
|
|
2261
|
+
for (const handle of [
|
|
2262
|
+
...publication.packet.invalidatedAssets,
|
|
2263
|
+
...publication.packet.retiredAssets,
|
|
2264
|
+
]) {
|
|
2265
|
+
internals.gpuStore.invalidateMesh(handle, publication.resources);
|
|
2266
|
+
internals.gpuStore.evictTexture(
|
|
2267
|
+
handle as Handle<'TextureAsset', 'shared'>,
|
|
2268
|
+
publication.resources,
|
|
2269
|
+
);
|
|
2270
|
+
}
|
|
2271
|
+
return persistentRenderScene.consumePublication(
|
|
2272
|
+
preparePublicationGeometry(
|
|
2273
|
+
publication,
|
|
2274
|
+
persistentRenderScene,
|
|
2275
|
+
internals.getPipelineState()?.skinPaletteAllocator,
|
|
2276
|
+
internals.assets,
|
|
2277
|
+
instanceCollections,
|
|
2278
|
+
internals.device.caps.storageBuffer
|
|
2279
|
+
? internals.getMaterialShaderArtifact
|
|
2280
|
+
: undefined,
|
|
2281
|
+
),
|
|
2282
|
+
);
|
|
2283
|
+
}
|
|
2251
2284
|
return persistentRenderScene.extractComposition(
|
|
2252
|
-
|
|
2285
|
+
sourceWorlds,
|
|
2253
2286
|
{ cameraOwner, resourceOwner },
|
|
2254
2287
|
internals.assets.catalogEpoch,
|
|
2255
2288
|
(renderables) =>
|
|
2256
2289
|
extractFrames(
|
|
2257
|
-
|
|
2290
|
+
sourceWorlds,
|
|
2258
2291
|
{
|
|
2259
2292
|
cameraOwner,
|
|
2260
2293
|
resourceOwner,
|
|
@@ -2264,25 +2297,7 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
2264
2297
|
internals.getPipelineState(),
|
|
2265
2298
|
persistentRenderScene.materialSnapshotCacheStore(),
|
|
2266
2299
|
{
|
|
2267
|
-
...(internals.device.caps
|
|
2268
|
-
? {}
|
|
2269
|
-
: {
|
|
2270
|
-
materialContext: {
|
|
2271
|
-
backend:
|
|
2272
|
-
internals.device.caps.backendKind === 'wgpu-webgl2'
|
|
2273
|
-
? ('webgl2' as const)
|
|
2274
|
-
: internals.device.caps.backendKind,
|
|
2275
|
-
capability: internals.device.caps.storageBuffer
|
|
2276
|
-
? ('storage-buffer' as const)
|
|
2277
|
-
: ('uniform-fallback' as const),
|
|
2278
|
-
pipeline: 'forward' as const,
|
|
2279
|
-
geometry: 'mesh' as const,
|
|
2280
|
-
pass: 'forward' as const,
|
|
2281
|
-
profile: 'forgeax-material-wgsl-v1' as const,
|
|
2282
|
-
toolchain: 'naga-oil' as const,
|
|
2283
|
-
instrumentation: 'none' as const,
|
|
2284
|
-
},
|
|
2285
|
-
}),
|
|
2300
|
+
...renderMaterialContext(internals.device.caps),
|
|
2286
2301
|
cull: 'none',
|
|
2287
2302
|
retainHidden: true,
|
|
2288
2303
|
renderables,
|
|
@@ -2308,6 +2323,7 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
2308
2323
|
lastMotionBlurInvalidParams = undefined;
|
|
2309
2324
|
const {
|
|
2310
2325
|
cameras: extractedCameras,
|
|
2326
|
+
auxiliaryCameras,
|
|
2311
2327
|
cubeCameras,
|
|
2312
2328
|
lights,
|
|
2313
2329
|
environment,
|
|
@@ -2333,7 +2349,7 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
2333
2349
|
frameState,
|
|
2334
2350
|
internals,
|
|
2335
2351
|
cameras[0],
|
|
2336
|
-
compositionWorlds[cameraOwner] as
|
|
2352
|
+
compositionWorlds[cameraOwner] as RenderResourceScope,
|
|
2337
2353
|
);
|
|
2338
2354
|
if (!preparedOutput.ok) {
|
|
2339
2355
|
internals.errorRegistry.fire(preparedOutput.error);
|
|
@@ -2814,7 +2830,7 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
2814
2830
|
const motionBlurParams = cameras[0]?.motionBlur;
|
|
2815
2831
|
let motionBlurDelta = 0;
|
|
2816
2832
|
try {
|
|
2817
|
-
const delta = (compositionWorlds[cameraOwner] as
|
|
2833
|
+
const delta = renderTime(compositionWorlds[cameraOwner] as RenderResourceScope).delta;
|
|
2818
2834
|
motionBlurDelta = Number.isFinite(delta) ? Math.max(0, delta) : 0;
|
|
2819
2835
|
} catch {
|
|
2820
2836
|
motionBlurDelta = 0;
|
|
@@ -2856,9 +2872,29 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
2856
2872
|
.skylightResources;
|
|
2857
2873
|
let featureGraphCandidate: RenderFeatureGraphCandidate | undefined;
|
|
2858
2874
|
const preparedResourceBatches = runProfiledRenderPhase(profileSession, 'features', () => {
|
|
2875
|
+
if (
|
|
2876
|
+
publication?.packet.features.some(
|
|
2877
|
+
(row) =>
|
|
2878
|
+
!internals.featureHost?.features.some(
|
|
2879
|
+
(feature) => feature.identity === row.identity,
|
|
2880
|
+
),
|
|
2881
|
+
)
|
|
2882
|
+
)
|
|
2883
|
+
throw new RenderPublicationError({
|
|
2884
|
+
reason: 'shape',
|
|
2885
|
+
subject: 'published feature has no receiver implementation',
|
|
2886
|
+
});
|
|
2859
2887
|
if (internals.featureHost === undefined) return [];
|
|
2860
2888
|
const featureFrame = runRenderFeatureFrame(internals.featureHost, {
|
|
2861
|
-
worlds:
|
|
2889
|
+
worlds: sourceWorlds,
|
|
2890
|
+
...(publication === undefined
|
|
2891
|
+
? {}
|
|
2892
|
+
: {
|
|
2893
|
+
publishedFeatures: publication.packet.features,
|
|
2894
|
+
...(publication.onFeatureSourceSubmitted === undefined
|
|
2895
|
+
? {}
|
|
2896
|
+
: { onFeatureSourceSubmitted: publication.onFeatureSourceSubmitted }),
|
|
2897
|
+
}),
|
|
2862
2898
|
owner: resourceOwner,
|
|
2863
2899
|
frameNumber: frameState.frameNumber,
|
|
2864
2900
|
...(cameras[0] === undefined ? {} : { selectedCamera: cameras[0] }),
|
|
@@ -3053,8 +3089,8 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
3053
3089
|
frameState.standardLutState.resident !== null ||
|
|
3054
3090
|
frameState.pendingStandardLutState !== undefined;
|
|
3055
3091
|
if (hasLiveFeatureState) {
|
|
3056
|
-
const cameraWorld = compositionWorlds[cameraOwner] as
|
|
3057
|
-
const deltaTime = cameraWorld
|
|
3092
|
+
const cameraWorld = compositionWorlds[cameraOwner] as RenderResourceScope;
|
|
3093
|
+
const deltaTime = renderTime(cameraWorld).delta;
|
|
3058
3094
|
stageLiveFeatureState(
|
|
3059
3095
|
cameras[0],
|
|
3060
3096
|
Number.isFinite(deltaTime) ? Math.max(0, deltaTime) : 0,
|
|
@@ -3071,16 +3107,15 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
3071
3107
|
frameState.surfaceSubmissionObservation = surfaceSubmissionCandidate;
|
|
3072
3108
|
const probeCaptureScene =
|
|
3073
3109
|
shadowCasterProjection !== undefined &&
|
|
3074
|
-
|
|
3110
|
+
(auxiliaryCameras.length > 0 ||
|
|
3111
|
+
cubeCameras.length > 0 ||
|
|
3112
|
+
reflectionProbeRecord.graph.work.some((work) => work.rawCaptureFace !== undefined))
|
|
3075
3113
|
? projectCaptureScene(shadowCasterProjection, submissionRenderables, orderedDispatch)
|
|
3076
3114
|
: undefined;
|
|
3077
|
-
//
|
|
3078
|
-
// draws. It lets the presentation fact distinguish a clear/submit
|
|
3079
|
-
// from a frame where geometry or its pipeline was skipped, without
|
|
3080
|
-
// retaining a second readiness registry or per-asset counter.
|
|
3115
|
+
// Track actual draws so a clear/submit cannot claim visible geometry was presented.
|
|
3081
3116
|
const presentedRenderableKeys = new Set<number>();
|
|
3082
3117
|
const presentedSubmeshKeys = new Set<string>();
|
|
3083
|
-
const consumeDynamicGeometry = dynamicGeometryFrames.onRenderableDraw(
|
|
3118
|
+
const consumeDynamicGeometry = dynamicGeometryFrames.onRenderableDraw(sourceWorlds);
|
|
3084
3119
|
const markPresentedRenderable = (
|
|
3085
3120
|
entry: Parameters<typeof consumeDynamicGeometry>[0],
|
|
3086
3121
|
submeshIndex?: number,
|
|
@@ -3131,7 +3166,9 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
3131
3166
|
},
|
|
3132
3167
|
...(occlusionProjection === undefined ? {} : { occlusion: occlusionProjection }),
|
|
3133
3168
|
frameTime: (() => {
|
|
3134
|
-
const elapsed = (
|
|
3169
|
+
const elapsed = renderTime(
|
|
3170
|
+
compositionWorlds[cameraOwner] as RenderResourceScope,
|
|
3171
|
+
).elapsed;
|
|
3135
3172
|
return Number.isFinite(elapsed) ? elapsed : 0;
|
|
3136
3173
|
})(),
|
|
3137
3174
|
deviceGeneration: internals.deviceScope.generation,
|
|
@@ -3145,6 +3182,7 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
3145
3182
|
pointsLinesOwner,
|
|
3146
3183
|
{
|
|
3147
3184
|
snapshots: cubeCameras,
|
|
3185
|
+
auxiliaryCameras,
|
|
3148
3186
|
scheduler: cubeCaptureScheduler,
|
|
3149
3187
|
state: cubeCaptureState,
|
|
3150
3188
|
reflectionProbes: reflectionProbeRecord,
|
|
@@ -3329,7 +3367,9 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
3329
3367
|
width: Math.max(1, internals.canvas.width),
|
|
3330
3368
|
height: Math.max(1, internals.canvas.height),
|
|
3331
3369
|
frameTime: (() => {
|
|
3332
|
-
const elapsed = (
|
|
3370
|
+
const elapsed = renderTime(
|
|
3371
|
+
compositionWorlds[cameraOwner] as RenderResourceScope,
|
|
3372
|
+
).elapsed;
|
|
3333
3373
|
return Number.isFinite(elapsed) ? elapsed : 0;
|
|
3334
3374
|
})(),
|
|
3335
3375
|
...(surfaceDynamicInputFrame === undefined
|
|
@@ -4054,14 +4094,3 @@ export function createRenderSystem(internals: RenderSystemInternals): RenderSyst
|
|
|
4054
4094
|
export function resolveInspectionBuild(internals: Pick<RenderSystemInternals, 'build'>): string {
|
|
4055
4095
|
return internals.build ?? 'render-system';
|
|
4056
4096
|
}
|
|
4057
|
-
|
|
4058
|
-
// @forgeax/engine-render - built-in record context extension.
|
|
4059
|
-
//
|
|
4060
|
-
// The public RenderPipelineContext is canonical in render-contract.ts. This
|
|
4061
|
-
// owner adds only concrete assembly state for built-in record closures.
|
|
4062
|
-
|
|
4063
|
-
/**
|
|
4064
|
-
* Package-private extension consumed by the built-in record closures only.
|
|
4065
|
-
* Custom pipeline authors see the leaf RenderPipelineContext contract and
|
|
4066
|
-
* never this surface.
|
|
4067
|
-
*/
|