@forgeax/engine-render 0.1.34 → 0.1.36
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 +69 -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/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -4
- package/dist/authoring.mjs.map +1 -1
- package/dist/chunk-2OZAS3WU.mjs +3489 -0
- package/dist/chunk-2OZAS3WU.mjs.map +1 -0
- package/dist/{chunk-UI5SFODX.mjs → chunk-BZQ4CDRF.mjs} +2338 -1991
- package/dist/chunk-BZQ4CDRF.mjs.map +1 -0
- package/dist/{chunk-MKDIT2EM.mjs → chunk-CJOV2XLO.mjs} +216 -261
- package/dist/chunk-CJOV2XLO.mjs.map +1 -0
- package/dist/chunk-D6WSBXJ2.mjs +1842 -0
- package/dist/chunk-D6WSBXJ2.mjs.map +1 -0
- package/dist/{chunk-HEB564WF.mjs → chunk-DRF6OULX.mjs} +4 -4
- package/dist/{chunk-HEB564WF.mjs.map → chunk-DRF6OULX.mjs.map} +1 -1
- package/dist/{chunk-OCDLEI6I.mjs → chunk-OB5WAFYH.mjs} +117 -5
- package/dist/chunk-OB5WAFYH.mjs.map +1 -0
- package/dist/{chunk-ODZWR6JQ.mjs → chunk-OEYKKMXG.mjs} +2042 -27
- package/dist/chunk-OEYKKMXG.mjs.map +1 -0
- package/dist/chunk-RIPAEGI6.mjs +48 -0
- package/dist/chunk-RIPAEGI6.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 +936 -2140
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/device-scope.d.ts.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/particle-mesh-layout.d.ts +19 -0
- package/dist/features/particle-mesh-layout.d.ts.map +1 -0
- package/dist/features/plan.d.ts +2 -0
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/types.d.ts +8 -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/production-raster.d.ts +1 -1
- package/dist/gpu-driven/production-raster.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/gpu-driven/shadow-views.d.ts +1 -1
- package/dist/gpu-driven/shadow-views.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +1 -1
- package/dist/gpu-driven/view-gpu.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 +542 -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 +34 -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 +2 -3
- package/dist/record/prepared-material-bindings.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +4 -2
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +2 -2
- package/dist/record/shadow-pass.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 -12
- 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/dist/typed-shadow-passes.d.ts.map +1 -1
- 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__/device-scope-lifecycle.unit.test.ts +26 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +3 -4
- package/src/__tests__/gpu-driven-production.integration.test.ts +18 -1
- package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +23 -0
- 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__/material-vertex-texture.browser.test.ts +7 -0
- package/src/__tests__/material-vertex-texture.dawn.test.ts +7 -0
- package/src/__tests__/material-vertex-texture.fixture.ts +31 -0
- 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__/recovery-candidate-prepare.contract.test.ts +5 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +107 -5
- package/src/__tests__/runtime-material-program.integration.test.ts +79 -0
- package/src/__tests__/vertex-layouts-ssot.unit.test.ts +23 -3
- 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 +101 -70
- package/src/assembly/webgpu-vertex-layouts.ts +2 -9
- package/src/cloud/frame-context.ts +2 -2
- package/src/device/device-scope.ts +3 -0
- 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/particle-mesh-layout.ts +25 -0
- package/src/features/plan.ts +2 -0
- package/src/features/types.ts +8 -0
- package/src/glyph-text-layout-system.ts +2 -2
- package/src/gpu-driven/production-raster.ts +9 -3
- package/src/gpu-driven/shadow-ownership.ts +3 -3
- package/src/gpu-driven/shadow-views.ts +27 -2
- package/src/gpu-driven/view-gpu.ts +5 -0
- 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 +15 -18
- 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 +173 -0
- package/src/publication/__tests__/programs.unit.test.ts +25 -0
- package/src/publication/__tests__/publication.integration.test.ts +415 -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 +645 -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__/prepared-runtime-material.integration.test.ts +134 -0
- 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 +87 -28
- 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 +16 -37
- package/src/record/render-context.ts +4 -2
- package/src/record/shadow-pass.ts +65 -7
- 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 +11 -207
- package/src/record/view-ubo.ts +1 -1
- package/src/record/volume-params.ts +6 -6
- package/src/recovery/render-system-candidate.ts +10 -18
- package/src/render-contract.ts +6 -1
- package/src/render-system-extract-tail.ts +48 -23
- package/src/render-system-extract.ts +11 -2
- 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 -54
- 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/src/typed-shadow-passes.ts +36 -5
- 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
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { addTargetCaptureGraphPasses, type CubeCaptureGraphState } from './target-capture-graph';
|
|
2
|
+
|
|
3
|
+
export type { CubeCaptureGraphState, CubeCaptureGraphWork } from './target-capture-graph';
|
|
4
|
+
|
|
1
5
|
import { encodeMipmapLevel } from '@forgeax/engine-assets-runtime';
|
|
2
6
|
import {
|
|
3
7
|
type CompiledRenderGraph,
|
|
@@ -95,8 +99,6 @@ import type {
|
|
|
95
99
|
import type { ExtractedLights, ExtractedVolumetricFog } from '../render-system-extract';
|
|
96
100
|
import { SHADOW_ATLAS_DEFAULT_FACE_SIZE, SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';
|
|
97
101
|
import type { SsrAdmissionResult, SsrSpatialAdmission } from '../ssr/admission';
|
|
98
|
-
import type { RenderTarget } from '../targets/contracts';
|
|
99
|
-
import type { RenderTargetPhysical } from '../targets/physical';
|
|
100
102
|
import {
|
|
101
103
|
abortTemporalGpuSubmit,
|
|
102
104
|
CLOUD_HISTORY_FORMATS,
|
|
@@ -607,19 +609,6 @@ export function createTemporalGraphRoster(input: {
|
|
|
607
609
|
};
|
|
608
610
|
}
|
|
609
611
|
|
|
610
|
-
export interface CubeCaptureGraphWork {
|
|
611
|
-
readonly target: RenderTarget;
|
|
612
|
-
readonly faceIndex: number;
|
|
613
|
-
readonly physical: RenderTargetPhysical;
|
|
614
|
-
readonly faceCamera: import('../render-contract').CameraSnapshot;
|
|
615
|
-
readonly viewBindGroupDynamicOffset: number;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
export interface CubeCaptureGraphState {
|
|
619
|
-
work: readonly CubeCaptureGraphWork[];
|
|
620
|
-
reflectionProbes?: ReflectionProbeGraphState;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
612
|
export interface ReflectionProbeFilterGraphWork {
|
|
624
613
|
readonly probeIndex: number;
|
|
625
614
|
readonly faceIndex: number;
|
|
@@ -666,195 +655,6 @@ export function boundedReflectionProbeFilterWork(
|
|
|
666
655
|
return state.work.slice(0, Math.max(0, state.maxStepsPerFrame));
|
|
667
656
|
}
|
|
668
657
|
|
|
669
|
-
function renderTargetMipCount(work: CubeCaptureGraphWork): number {
|
|
670
|
-
const { descriptor } = work.physical;
|
|
671
|
-
return descriptor.mipLevels === 1
|
|
672
|
-
? 1
|
|
673
|
-
: Math.floor(Math.log2(Math.max(descriptor.width, descriptor.height))) + 1;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
function addCubeCaptureGraphPasses(
|
|
677
|
-
builder: RenderGraphBuilder<RenderPipelineFrame>,
|
|
678
|
-
state: CubeCaptureGraphState,
|
|
679
|
-
): Result<void, RenderGraphError> {
|
|
680
|
-
for (let index = 0; index < state.work.length; index += 1) {
|
|
681
|
-
const slot = index;
|
|
682
|
-
const initial = state.work[slot];
|
|
683
|
-
if (initial === undefined) continue;
|
|
684
|
-
const current = (): CubeCaptureGraphWork => state.work[slot] ?? initial;
|
|
685
|
-
const texture = builder.importTexture(
|
|
686
|
-
`cube-capture.${slot}.texture`,
|
|
687
|
-
{
|
|
688
|
-
format: initial.physical.descriptor.format,
|
|
689
|
-
size: {
|
|
690
|
-
width: initial.physical.descriptor.width,
|
|
691
|
-
height: initial.physical.descriptor.height,
|
|
692
|
-
depthOrArrayLayers: initial.physical.descriptor.sampleCount === 4 ? 1 : 6,
|
|
693
|
-
},
|
|
694
|
-
mipLevelCount:
|
|
695
|
-
initial.physical.descriptor.sampleCount === 4 ? 1 : renderTargetMipCount(initial),
|
|
696
|
-
sampleCount: initial.physical.descriptor.sampleCount,
|
|
697
|
-
dimension: '2d',
|
|
698
|
-
usage: 0x10 | 0x04 | 0x01,
|
|
699
|
-
},
|
|
700
|
-
() => current().physical.colorTextures[current().faceIndex] ?? initial.physical.texture,
|
|
701
|
-
);
|
|
702
|
-
if (!texture.ok) return texture;
|
|
703
|
-
const color = builder.importView(
|
|
704
|
-
texture.value,
|
|
705
|
-
{
|
|
706
|
-
label: `cube-capture.${slot}.color`,
|
|
707
|
-
dimension: '2d',
|
|
708
|
-
baseMipLevel: 0,
|
|
709
|
-
mipLevelCount: 1,
|
|
710
|
-
baseArrayLayer: initial.physical.descriptor.sampleCount === 4 ? 0 : initial.faceIndex,
|
|
711
|
-
arrayLayerCount: 1,
|
|
712
|
-
},
|
|
713
|
-
() =>
|
|
714
|
-
current().physical.faceViews[current().faceIndex] ??
|
|
715
|
-
initial.physical.faceViews[initial.faceIndex] ??
|
|
716
|
-
initial.physical.view,
|
|
717
|
-
);
|
|
718
|
-
if (!color.ok) return color;
|
|
719
|
-
const depthTexture = builder.importTexture(
|
|
720
|
-
`cube-capture.${slot}.depth-texture`,
|
|
721
|
-
{
|
|
722
|
-
format: 'depth24plus-stencil8',
|
|
723
|
-
size: {
|
|
724
|
-
width: initial.physical.descriptor.width,
|
|
725
|
-
height: initial.physical.descriptor.height,
|
|
726
|
-
depthOrArrayLayers: initial.physical.descriptor.sampleCount === 4 ? 1 : 6,
|
|
727
|
-
},
|
|
728
|
-
mipLevelCount: 1,
|
|
729
|
-
sampleCount: initial.physical.descriptor.sampleCount,
|
|
730
|
-
dimension: '2d',
|
|
731
|
-
usage: 0x10,
|
|
732
|
-
},
|
|
733
|
-
() => current().physical.depthTextures[current().faceIndex] as Texture,
|
|
734
|
-
);
|
|
735
|
-
if (!depthTexture.ok) return depthTexture;
|
|
736
|
-
const depth = builder.importView(
|
|
737
|
-
depthTexture.value,
|
|
738
|
-
{
|
|
739
|
-
label: `cube-capture.${slot}.depth`,
|
|
740
|
-
dimension: '2d',
|
|
741
|
-
baseArrayLayer: initial.physical.descriptor.sampleCount === 4 ? 0 : initial.faceIndex,
|
|
742
|
-
arrayLayerCount: 1,
|
|
743
|
-
},
|
|
744
|
-
() => current().physical.depthViews[current().faceIndex] as TextureView,
|
|
745
|
-
);
|
|
746
|
-
if (!depth.ok) return depth;
|
|
747
|
-
const resolveTexture =
|
|
748
|
-
initial.physical.descriptor.sampleCount === 4
|
|
749
|
-
? builder.importTexture(
|
|
750
|
-
`cube-capture.${slot}.resolve-texture`,
|
|
751
|
-
{
|
|
752
|
-
format: initial.physical.descriptor.format,
|
|
753
|
-
size: {
|
|
754
|
-
width: initial.physical.descriptor.width,
|
|
755
|
-
height: initial.physical.descriptor.height,
|
|
756
|
-
depthOrArrayLayers: 6,
|
|
757
|
-
},
|
|
758
|
-
mipLevelCount: renderTargetMipCount(initial),
|
|
759
|
-
sampleCount: 1,
|
|
760
|
-
dimension: '2d',
|
|
761
|
-
usage: 0x10 | 0x04 | 0x01,
|
|
762
|
-
},
|
|
763
|
-
() =>
|
|
764
|
-
current().physical.resolveTexture ??
|
|
765
|
-
initial.physical.resolveTexture ??
|
|
766
|
-
initial.physical.texture,
|
|
767
|
-
)
|
|
768
|
-
: undefined;
|
|
769
|
-
if (resolveTexture !== undefined && !resolveTexture.ok) return resolveTexture;
|
|
770
|
-
const resolve =
|
|
771
|
-
resolveTexture === undefined
|
|
772
|
-
? undefined
|
|
773
|
-
: builder.importView(
|
|
774
|
-
resolveTexture.value,
|
|
775
|
-
{
|
|
776
|
-
label: `cube-capture.${slot}.resolve`,
|
|
777
|
-
dimension: '2d',
|
|
778
|
-
baseMipLevel: 0,
|
|
779
|
-
mipLevelCount: 1,
|
|
780
|
-
baseArrayLayer: initial.faceIndex,
|
|
781
|
-
arrayLayerCount: 1,
|
|
782
|
-
},
|
|
783
|
-
() =>
|
|
784
|
-
current().physical.resolveFaceViews[current().faceIndex] ??
|
|
785
|
-
initial.physical.resolveFaceViews[initial.faceIndex] ??
|
|
786
|
-
initial.physical.resolveView,
|
|
787
|
-
);
|
|
788
|
-
if (resolve !== undefined && !resolve.ok) return resolve;
|
|
789
|
-
const added = builder.addRasterPass(`cube-capture-face.${slot}`, {
|
|
790
|
-
accesses: [
|
|
791
|
-
{ resource: color.value, usage: 'color-attachment' },
|
|
792
|
-
{ resource: depth.value, usage: 'depth-stencil-write' },
|
|
793
|
-
...(resolve === undefined
|
|
794
|
-
? []
|
|
795
|
-
: [{ resource: resolve.value, usage: 'color-attachment' as const }]),
|
|
796
|
-
],
|
|
797
|
-
colorAttachments: [
|
|
798
|
-
{
|
|
799
|
-
view: color.value,
|
|
800
|
-
...(resolve === undefined ? {} : { resolveTarget: resolve.value }),
|
|
801
|
-
loadOp: 'clear',
|
|
802
|
-
storeOp: 'store',
|
|
803
|
-
clearValue: () => {
|
|
804
|
-
return { r: 0, g: 0, b: 0, a: 1 };
|
|
805
|
-
},
|
|
806
|
-
},
|
|
807
|
-
],
|
|
808
|
-
depthStencilAttachment: {
|
|
809
|
-
view: depth.value,
|
|
810
|
-
depthClearValue: 1,
|
|
811
|
-
depthLoadOp: 'clear',
|
|
812
|
-
depthStoreOp: 'store',
|
|
813
|
-
stencilClearValue: 0,
|
|
814
|
-
stencilLoadOp: 'clear',
|
|
815
|
-
stencilStoreOp: 'store',
|
|
816
|
-
},
|
|
817
|
-
encode: ({ pass, frame, resources }) => {
|
|
818
|
-
const internal = frame as _InternalRenderPipelineContext;
|
|
819
|
-
const captureColor = resources.textureView(color.value);
|
|
820
|
-
if (!captureColor.ok) return;
|
|
821
|
-
const captureDepth = resources.textureView(depth.value);
|
|
822
|
-
if (!captureDepth.ok) return;
|
|
823
|
-
const captureResolve =
|
|
824
|
-
resolve === undefined ? undefined : resources.textureView(resolve.value);
|
|
825
|
-
if (resolve !== undefined && (captureResolve === undefined || !captureResolve.ok)) return;
|
|
826
|
-
const captureResolveView = captureResolve?.ok ? captureResolve.value : null;
|
|
827
|
-
const captureContext = {
|
|
828
|
-
...internal,
|
|
829
|
-
camera: current().faceCamera,
|
|
830
|
-
// Cube faces are raw scene captures, not display-camera HDR output.
|
|
831
|
-
// Select the PSO against the actual target attachment so an LDR
|
|
832
|
-
// cube target is rendered by a compatible forward pipeline.
|
|
833
|
-
tonemapActive: false,
|
|
834
|
-
skyboxActive: false,
|
|
835
|
-
transparentColorFormat: initial.physical.descriptor.format as GPUTextureFormat,
|
|
836
|
-
msaaActive: initial.physical.descriptor.sampleCount === 4,
|
|
837
|
-
viewBindGroupDynamicOffset: current().viewBindGroupDynamicOffset,
|
|
838
|
-
geometryColorView: captureColor.value,
|
|
839
|
-
geometryDepthView: captureDepth.value,
|
|
840
|
-
geometryColorResolveView: captureResolveView,
|
|
841
|
-
splitLdrSprite: false,
|
|
842
|
-
ldrSpritePassView: null,
|
|
843
|
-
};
|
|
844
|
-
encodeMainPass(captureContext, pass, undefined, {
|
|
845
|
-
colorViews: [captureColor.value],
|
|
846
|
-
colorFormats: [initial.physical.descriptor.format as GPUTextureFormat],
|
|
847
|
-
depthView: captureDepth.value,
|
|
848
|
-
passKind: 'forward',
|
|
849
|
-
clearColor: [0, 0, 0, 1],
|
|
850
|
-
});
|
|
851
|
-
},
|
|
852
|
-
});
|
|
853
|
-
if (!added.ok) return added;
|
|
854
|
-
}
|
|
855
|
-
return ok(undefined);
|
|
856
|
-
}
|
|
857
|
-
|
|
858
658
|
export function addReflectionProbeGraphPasses(
|
|
859
659
|
builder: RenderGraphBuilder<RenderPipelineFrame>,
|
|
860
660
|
state: ReflectionProbeGraphState,
|
|
@@ -2669,7 +2469,7 @@ export function ensureCompiledFrameGraph(
|
|
|
2669
2469
|
// rotation must not invalidate the graph or its cached bind groups.
|
|
2670
2470
|
occlusionQuery:
|
|
2671
2471
|
occlusion === undefined ? undefined : { active: true, sampleCount: occlusion.sampleCount },
|
|
2672
|
-
cubeCaptureSlots: cubeCaptureState?.work.
|
|
2472
|
+
cubeCaptureSlots: cubeCaptureState?.work.map((work) => work.physical.descriptor),
|
|
2673
2473
|
reflectionProbeSlots: cubeCaptureState?.reflectionProbes?.work.map((work) => [
|
|
2674
2474
|
work.probeIndex,
|
|
2675
2475
|
work.rawCaptureFace ?? -1,
|
|
@@ -2839,7 +2639,11 @@ export function ensureCompiledFrameGraph(
|
|
|
2839
2639
|
? {}
|
|
2840
2640
|
: {
|
|
2841
2641
|
projectGpuDrivenShadow: (identity) =>
|
|
2842
|
-
|
|
2642
|
+
// A newly compiled graph must include the shadow compute passes
|
|
2643
|
+
// even when the producer cache hit. The graph owns its pass
|
|
2644
|
+
// list; importing only the cached view resources would reuse
|
|
2645
|
+
// stale indirect arguments after a topology replacement.
|
|
2646
|
+
gpuDriven.projectShadow?.(builder, identity, true) ?? ok(undefined),
|
|
2843
2647
|
}),
|
|
2844
2648
|
contributeShadowFeatures: () =>
|
|
2845
2649
|
(featureShadows ??= projectRenderFeatureShadows(
|
|
@@ -2924,7 +2728,7 @@ export function ensureCompiledFrameGraph(
|
|
|
2924
2728
|
if (!reflectionProbes.ok) return reflectionProbes;
|
|
2925
2729
|
return cubeCaptureState === undefined
|
|
2926
2730
|
? ok(undefined)
|
|
2927
|
-
:
|
|
2731
|
+
: addTargetCaptureGraphPasses(builder, cubeCaptureState);
|
|
2928
2732
|
},
|
|
2929
2733
|
hasFeature: (identity) =>
|
|
2930
2734
|
projectedFeaturePlans.value.some((execution) => execution.featureIdentity === identity),
|
package/src/record/view-ubo.ts
CHANGED
|
@@ -30,7 +30,7 @@ export const POINTS_LINES_VIEW_BUFFER_SIZE =
|
|
|
30
30
|
export const VIEW_UNIFORM_SLOT_STRIDE = 1024;
|
|
31
31
|
export const POINT_SHADOW_VIEW_SLOT_COUNT = 24;
|
|
32
32
|
export const CUBE_CAPTURE_VIEW_SLOT_BASE = 1 + POINT_SHADOW_VIEW_SLOT_COUNT;
|
|
33
|
-
export const REFLECTION_PROBE_VIEW_SLOT_BASE = CUBE_CAPTURE_VIEW_SLOT_BASE + 6;
|
|
33
|
+
export const REFLECTION_PROBE_VIEW_SLOT_BASE = CUBE_CAPTURE_VIEW_SLOT_BASE + 6 + 1;
|
|
34
34
|
export const REFLECTION_PROBE_VIEW_SLOT_COUNT = 16;
|
|
35
35
|
export const VIEW_UNIFORM_BUFFER_SIZE =
|
|
36
36
|
VIEW_UNIFORM_SLOT_STRIDE * (REFLECTION_PROBE_VIEW_SLOT_BASE + REFLECTION_PROBE_VIEW_SLOT_COUNT);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { World } from '@forgeax/engine-ecs';
|
|
2
1
|
import { vec3 } from '@forgeax/engine-math';
|
|
3
2
|
import { type Buffer, RhiError } from '@forgeax/engine-rhi';
|
|
4
3
|
import { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';
|
|
4
|
+
import type { RenderResourceScope } from '../publication/resource-scope';
|
|
5
5
|
import type { SpotLightProjectorFrameContext, VolumetricFogFrameContext } from '../render-contract';
|
|
6
6
|
import type { ExtractedLights, ExtractedVolumetricFog } from '../render-system-extract';
|
|
7
7
|
import { VOLUMETRIC_FOG_PARAMS_BYTES } from '../volume/resources';
|
|
@@ -57,8 +57,8 @@ export function stageVolumetricFogParams(
|
|
|
57
57
|
function prepareVolumetricFogMember(
|
|
58
58
|
internals: RenderSystemInternals,
|
|
59
59
|
frameState: RenderFrameState,
|
|
60
|
-
world:
|
|
61
|
-
worlds: readonly
|
|
60
|
+
world: RenderResourceScope,
|
|
61
|
+
worlds: readonly RenderResourceScope[],
|
|
62
62
|
fog: ExtractedVolumetricFog | undefined,
|
|
63
63
|
lights: ExtractedLights,
|
|
64
64
|
volumeCapability: boolean,
|
|
@@ -157,7 +157,7 @@ function prepareVolumetricFogMember(
|
|
|
157
157
|
frameState.temporalFrame !== undefined && frameState.temporalFrame.resetReason === 'none'
|
|
158
158
|
? 1
|
|
159
159
|
: 0;
|
|
160
|
-
//
|
|
160
|
+
// RenderResourceScope elapsed time is the sole authored-medium clock.
|
|
161
161
|
params[32] = fog.worldTimeSeconds ?? 0;
|
|
162
162
|
return {
|
|
163
163
|
densityTexture: resident.value.texture.handle,
|
|
@@ -180,8 +180,8 @@ function prepareVolumetricFogMember(
|
|
|
180
180
|
export function prepareVolumetricFogFrame(
|
|
181
181
|
internals: RenderSystemInternals,
|
|
182
182
|
frameState: RenderFrameState,
|
|
183
|
-
world:
|
|
184
|
-
worlds: readonly
|
|
183
|
+
world: RenderResourceScope,
|
|
184
|
+
worlds: readonly RenderResourceScope[],
|
|
185
185
|
fog: ExtractedVolumetricFog | undefined,
|
|
186
186
|
lights: ExtractedLights,
|
|
187
187
|
volumeCapability: boolean,
|
|
@@ -47,11 +47,13 @@ import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
|
|
|
47
47
|
import { standardTopologyVariantSet } from '../pipeline-spec';
|
|
48
48
|
import { inspectPointShadow } from '../point-shadow-inspection';
|
|
49
49
|
import type { PreparedGraphicsResolver } from '../prepare/prepared-graphics-resolver';
|
|
50
|
+
import type { RenderResourceScope } from '../publication/resource-scope';
|
|
50
51
|
import { gpuDrivenMeshesForFrame, validateRenderables } from '../record/frame';
|
|
51
52
|
import { prepareFrameLighting } from '../record/frame-lighting';
|
|
52
53
|
import type { RenderFrameState, ValidatedRenderable } from '../record/frame-snapshot';
|
|
53
54
|
import { resolveGeometryInstanceBuffer } from '../record/main-pass-geometry';
|
|
54
55
|
import { computeSplitLdrSprite } from '../record/main-pass-sprite-draws';
|
|
56
|
+
import type { PreparedResolverCaches } from '../record/prepared-material-bindings';
|
|
55
57
|
import { ensureProbeBlendRecordBuffer } from '../record/probe-blend-buffer';
|
|
56
58
|
import {
|
|
57
59
|
prepareRecoveryPipelineReadiness,
|
|
@@ -89,25 +91,16 @@ import type {
|
|
|
89
91
|
RecoveryPointsLinesCandidate,
|
|
90
92
|
} from './types';
|
|
91
93
|
|
|
92
|
-
export interface PreparedResolverCaches {
|
|
93
|
-
readonly preparedPipelineIds: WeakMap<object, string>;
|
|
94
|
-
readonly preparedMaterialPipelineShaders: WeakMap<object, string>;
|
|
95
|
-
readonly preparedGroup0Pipelines: WeakSet<object>;
|
|
96
|
-
readonly preparedViewOnlyPipelines: WeakSet<object>;
|
|
97
|
-
readonly preparedRenderMaterialPipelines: WeakSet<object>;
|
|
98
|
-
readonly preparedAssetHandles: WeakMap<World, Map<string, number>>;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
94
|
export interface RecoveryFrameSeed {
|
|
102
95
|
readonly frame: ExtractedFrame;
|
|
103
|
-
readonly worlds: readonly
|
|
96
|
+
readonly worlds: readonly RenderResourceScope[];
|
|
104
97
|
readonly cameraOwner: number;
|
|
105
98
|
readonly resourceOwner: number;
|
|
106
99
|
readonly width: number;
|
|
107
100
|
readonly height: number;
|
|
108
101
|
/** Last submitted Surface page is reused while the replacement device warms. */
|
|
109
102
|
readonly surfaceDynamicInput?: SurfaceDynamicInputFrame;
|
|
110
|
-
/** Last submitted
|
|
103
|
+
/** Last submitted RenderResourceScope/App time snapshot for the Surface frame ABI. */
|
|
111
104
|
readonly frameTime?: number;
|
|
112
105
|
/** Exact forward artifacts accepted by the submitted frame. */
|
|
113
106
|
readonly materialArtifacts?: ReadonlyMap<string, MaterialShaderArtifact>;
|
|
@@ -144,7 +137,7 @@ export interface RenderSystemRecoveryDependencies {
|
|
|
144
137
|
readonly createPreparedResolverFactory: (
|
|
145
138
|
runtime: RenderSystemInternals,
|
|
146
139
|
gpuWork: RenderFeatureGpuWorkOwner,
|
|
147
|
-
worlds: readonly
|
|
140
|
+
worlds: readonly RenderResourceScope[],
|
|
148
141
|
caches: PreparedResolverCaches,
|
|
149
142
|
) => (input: RenderFeaturePreparedGraphicsResolverInput) => PreparedGraphicsResolver;
|
|
150
143
|
readonly createPreparedResolverCaches: () => PreparedResolverCaches;
|
|
@@ -229,7 +222,7 @@ export function createRenderSystemRecovery(
|
|
|
229
222
|
} = deps;
|
|
230
223
|
|
|
231
224
|
// This is a detached CPU projection, retained only after queue submission.
|
|
232
|
-
// It is not a
|
|
225
|
+
// It is not a RenderResourceScope/lease cache and it never carries target or scheduler state.
|
|
233
226
|
let lastSuccessfulFrameSeed: RecoveryFrameSeed | undefined;
|
|
234
227
|
|
|
235
228
|
const createRecoveryCandidateFrameState = (): RenderFrameState => {
|
|
@@ -406,7 +399,7 @@ export function createRenderSystemRecovery(
|
|
|
406
399
|
// A successful clear-only draw can have no display camera. There is no
|
|
407
400
|
// frame graph to rehydrate in that case, but the device generation is
|
|
408
401
|
// still recoverable; the next camera-bearing draw will build its graph
|
|
409
|
-
// from the current
|
|
402
|
+
// from the current RenderResourceScope composition.
|
|
410
403
|
if (camera === undefined) return { kind: 'no-seed' };
|
|
411
404
|
|
|
412
405
|
const candidateFrameState = createRecoveryCandidateFrameState();
|
|
@@ -445,7 +438,6 @@ export function createRenderSystemRecovery(
|
|
|
445
438
|
if (pendingOutput !== undefined) retireAutoExposureGpuResources(pendingOutput);
|
|
446
439
|
candidateFrameState.pendingAutoExposureGpuResources = undefined;
|
|
447
440
|
for (const work of setupWorks) work.discard();
|
|
448
|
-
setupWorks.length = 0;
|
|
449
441
|
const graph = candidateFrameState.compiledFrameGraph;
|
|
450
442
|
candidateFrameState.compiledFrameGraph = null;
|
|
451
443
|
candidateFrameState.perFrameGraph = null;
|
|
@@ -504,7 +496,7 @@ export function createRenderSystemRecovery(
|
|
|
504
496
|
candidateFrameState,
|
|
505
497
|
runtime.internals,
|
|
506
498
|
camera,
|
|
507
|
-
seed.worlds[seed.cameraOwner] as
|
|
499
|
+
seed.worlds[seed.cameraOwner] as RenderResourceScope,
|
|
508
500
|
);
|
|
509
501
|
if (!output.ok) return failed('candidate Standard output preparation failed', output.error);
|
|
510
502
|
const gpuScene = persistentRenderScene.prepareRecoveryGpuDrivenCandidate(
|
|
@@ -514,7 +506,7 @@ export function createRenderSystemRecovery(
|
|
|
514
506
|
candidateGpuDrivenScene = gpuScene.value;
|
|
515
507
|
candidateValidated = validateRenderables(
|
|
516
508
|
runtime.internals,
|
|
517
|
-
seed.worlds[seed.cameraOwner] as
|
|
509
|
+
seed.worlds[seed.cameraOwner] as RenderResourceScope,
|
|
518
510
|
seed.worlds,
|
|
519
511
|
runtime.pipelineState,
|
|
520
512
|
candidateFrameState,
|
|
@@ -731,7 +723,7 @@ export function createRenderSystemRecovery(
|
|
|
731
723
|
cloudHistory: seed.frame.cloudLayer !== undefined,
|
|
732
724
|
});
|
|
733
725
|
const featureFrame = runRenderFeatureFrame(candidateFeatureHost, {
|
|
734
|
-
worlds: seed.worlds,
|
|
726
|
+
worlds: seed.worlds.filter((world): world is World => !('resolveAsset' in world)),
|
|
735
727
|
owner: seed.resourceOwner,
|
|
736
728
|
frameNumber: candidateFrameState.frameNumber,
|
|
737
729
|
selectedCamera: camera,
|
package/src/render-contract.ts
CHANGED
|
@@ -62,6 +62,7 @@ import type {
|
|
|
62
62
|
} from './inspection-types.js';
|
|
63
63
|
import type { InstanceCollectionInspection } from './instances.js';
|
|
64
64
|
import type { RenderExtent } from './pipeline/render-extent.js';
|
|
65
|
+
import type { PublishedRenderFrameInput, RenderPublicationIdentity } from './publication/contract';
|
|
65
66
|
import type { RenderSceneBounds } from './scene/render-scene-types.js';
|
|
66
67
|
import type { SsrAdmissionIdentity } from './ssr/identity.js';
|
|
67
68
|
import type {
|
|
@@ -446,7 +447,9 @@ export interface Renderer {
|
|
|
446
447
|
dynamicGeometryReceipt(candidate: DynamicGeometryCandidate): DynamicGeometryReceipt | undefined;
|
|
447
448
|
cancelDynamicGeometry(candidate: DynamicGeometryCandidate): Result<void, DynamicGeometryError>;
|
|
448
449
|
retireDynamicGeometry(candidate: DynamicGeometryCandidate): Result<void, DynamicGeometryError>;
|
|
449
|
-
draw(
|
|
450
|
+
draw(
|
|
451
|
+
input: RenderFrameInput | PublishedRenderFrameInput,
|
|
452
|
+
): RenderResult<FrameReceipt, RenderError>;
|
|
450
453
|
/**
|
|
451
454
|
* Arm one upcoming submitted frame for explicit color-domain observation.
|
|
452
455
|
* Observation buffers are not created, copied, mapped, or retained until a
|
|
@@ -1062,6 +1065,8 @@ export type RenderPhaseSkipReason =
|
|
|
1062
1065
|
|
|
1063
1066
|
/** First-version options bag (intentionally empty; reserved for v0.1). */
|
|
1064
1067
|
export interface RendererOptions {
|
|
1068
|
+
/** Bind a source session before receiving any publication. */
|
|
1069
|
+
readonly publicationSource?: RenderPublicationIdentity;
|
|
1065
1070
|
/** Producer-owned features installed by the renderer host. */
|
|
1066
1071
|
readonly features?: readonly RenderFeature<unknown>[] | undefined;
|
|
1067
1072
|
/** Standard profile consumed by the single renderer-owned pipeline. */
|
|
@@ -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}`;
|
|
@@ -2137,6 +2137,11 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2137
2137
|
if (asset.kind !== 'material') {
|
|
2138
2138
|
materialSnap = defaultMaterialSnapshot(handleRaw);
|
|
2139
2139
|
} else {
|
|
2140
|
+
// Program selection belongs to the shared source; RuntimeMaterialValue
|
|
2141
|
+
// only projects the numeric parameter content resolved below.
|
|
2142
|
+
const source = world.sharedRefs.resolve<string, Asset>(tagged);
|
|
2143
|
+
const programOwner =
|
|
2144
|
+
source.ok && source.value.kind === 'material' ? source.value : asset;
|
|
2140
2145
|
// feat-20260529 M3 / w11: material parent chain inheritance via
|
|
2141
2146
|
// read-through _materialWalk accessor (plan-strategy D-6).
|
|
2142
2147
|
// The old direct asset.passes / asset.values read never
|
|
@@ -2186,7 +2191,7 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2186
2191
|
};
|
|
2187
2192
|
try {
|
|
2188
2193
|
materialProgramSelections = materialProgramSelectionsForMaterial(
|
|
2189
|
-
|
|
2194
|
+
programOwner,
|
|
2190
2195
|
assets,
|
|
2191
2196
|
materialContext,
|
|
2192
2197
|
);
|
|
@@ -2198,10 +2203,14 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2198
2203
|
// publication error instead of guessing from module names/order.
|
|
2199
2204
|
if (isMissingMaterialProgram(error) && materialContext?.geometry === 'mesh') {
|
|
2200
2205
|
try {
|
|
2201
|
-
const skinnedSelections = materialProgramSelectionsForMaterial(
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2206
|
+
const skinnedSelections = materialProgramSelectionsForMaterial(
|
|
2207
|
+
programOwner,
|
|
2208
|
+
assets,
|
|
2209
|
+
{
|
|
2210
|
+
...materialContext,
|
|
2211
|
+
geometry: 'skinned',
|
|
2212
|
+
},
|
|
2213
|
+
);
|
|
2205
2214
|
if (
|
|
2206
2215
|
skinnedSelections?.some(materialProgramSelectionRequiresSkin) === true &&
|
|
2207
2216
|
gpuDrivenMesh !== undefined
|
|
@@ -2238,7 +2247,7 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2238
2247
|
]),
|
|
2239
2248
|
);
|
|
2240
2249
|
const materialSceneIndexProgramKeys = materialSceneIndexProgramKeysForMaterial(
|
|
2241
|
-
|
|
2250
|
+
programOwner,
|
|
2242
2251
|
assets,
|
|
2243
2252
|
materialContext,
|
|
2244
2253
|
);
|
|
@@ -2739,6 +2748,7 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2739
2748
|
// resolve / validate / write chain (D-9 reset already fired at
|
|
2740
2749
|
// extractFrame entry; per-entity allocate + writeJointPalette here).
|
|
2741
2750
|
let skinSlice: SkinPaletteReceipt | undefined;
|
|
2751
|
+
let skinPose: SkinPose | undefined;
|
|
2742
2752
|
const skinIdentity = hasSkin ? skinPaletteIdentity(world, entity) : undefined;
|
|
2743
2753
|
const releaseSkinIdentity = (): void => {
|
|
2744
2754
|
if (skinIdentity !== undefined) {
|
|
@@ -2850,6 +2860,17 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2850
2860
|
});
|
|
2851
2861
|
skinPaletteAllocator.writePersistentJointPalette(receipt, ibms, jointWorlds);
|
|
2852
2862
|
skinSlice = receipt;
|
|
2863
|
+
} else {
|
|
2864
|
+
skinPose = {
|
|
2865
|
+
identity: skinPaletteIdentity(world, entity),
|
|
2866
|
+
generation: ((skeletonHandleRaw >>> 0) ^ skeleton.jointCount) >>> 0,
|
|
2867
|
+
jointCount: skeleton.jointCount,
|
|
2868
|
+
...(hasFiniteOrderedLocalAabb(skeleton.bounds)
|
|
2869
|
+
? { bounds: new Float32Array(skeleton.bounds) }
|
|
2870
|
+
: {}),
|
|
2871
|
+
inverseBindMatrices: ibms,
|
|
2872
|
+
jointWorlds,
|
|
2873
|
+
};
|
|
2853
2874
|
}
|
|
2854
2875
|
}
|
|
2855
2876
|
}
|
|
@@ -2858,7 +2879,7 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
2858
2879
|
// projection. Do not publish a renderable or its staged dispatch when
|
|
2859
2880
|
// palette extraction was unavailable; the record stage must never
|
|
2860
2881
|
// reinterpret a skinned vertex stream through an ordinary mesh group.
|
|
2861
|
-
if (skinSlice === undefined && hasSkin) {
|
|
2882
|
+
if (skinSlice === undefined && skinPose === undefined && hasSkin) {
|
|
2862
2883
|
releaseSkinIdentity();
|
|
2863
2884
|
if (
|
|
2864
2885
|
materialSnap.materialShaderId === 'forgeax::pbr-skin' ||
|
|
@@ -3128,6 +3149,7 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
3128
3149
|
entityKey: entity,
|
|
3129
3150
|
...(authorVisible ? {} : { authorVisible: false }),
|
|
3130
3151
|
...(skinSlice !== undefined ? { skin: skinSlice } : {}),
|
|
3152
|
+
...(skinPose === undefined ? {} : { skinPose }),
|
|
3131
3153
|
...(skin?.joints === undefined
|
|
3132
3154
|
? {}
|
|
3133
3155
|
: { skinJointEntities: Array.from(skin.joints, (joint) => Number(joint)) }),
|
|
@@ -3136,21 +3158,24 @@ export function extractFrame(world: World, context: PreparedExtractContext): Ext
|
|
|
3136
3158
|
...(spriteInstancesSnap !== undefined ? { spriteInstances: spriteInstancesSnap } : {}),
|
|
3137
3159
|
...(pointsLines !== undefined ? { pointsLines } : {}),
|
|
3138
3160
|
};
|
|
3139
|
-
const gpuDrivenDraws =
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3161
|
+
const gpuDrivenDraws =
|
|
3162
|
+
skinPose === undefined
|
|
3163
|
+
? buildGpuDrivenDraws({
|
|
3164
|
+
mesh: gpuDrivenMesh,
|
|
3165
|
+
materials: materialsArr,
|
|
3166
|
+
fallbackMaterial: materialSnap,
|
|
3167
|
+
baseSnapshot: baseRenderable,
|
|
3168
|
+
...(getMaterialShaderArtifact === undefined ? {} : { getMaterialShaderArtifact }),
|
|
3169
|
+
...(lods === undefined
|
|
3170
|
+
? {}
|
|
3171
|
+
: {
|
|
3172
|
+
lodMeshes: lods.map((lod) => {
|
|
3173
|
+
const lower = assets?.lookup<Asset>(lod.mesh);
|
|
3174
|
+
return lower?.kind === 'mesh' ? lower : undefined;
|
|
3175
|
+
}),
|
|
3176
|
+
}),
|
|
3177
|
+
})
|
|
3178
|
+
: [];
|
|
3154
3179
|
for (const draw of gpuDrivenDraws) {
|
|
3155
3180
|
if (draw.preparationError === undefined) continue;
|
|
3156
3181
|
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. */
|
|
@@ -2360,9 +2362,16 @@ export function resolveMaterialSnapshot(
|
|
|
2360
2362
|
if (!resolvedResult.ok) return defaultMaterialSnapshot(handleRaw);
|
|
2361
2363
|
const resolved = resolvedResult.value;
|
|
2362
2364
|
const allPasses = resolved.passes;
|
|
2363
|
-
|
|
2365
|
+
// Numeric World content changes values, never the immutable program owner.
|
|
2366
|
+
const source = world.sharedRefs.resolve<string, Asset>(tagged);
|
|
2367
|
+
const programOwner = source.ok && source.value.kind === 'material' ? source.value : asset;
|
|
2368
|
+
const materialProgramKeys = materialProgramKeysForMaterial(
|
|
2369
|
+
programOwner,
|
|
2370
|
+
assetsRef,
|
|
2371
|
+
materialContext,
|
|
2372
|
+
);
|
|
2364
2373
|
const materialSceneIndexProgramKeys = materialSceneIndexProgramKeysForMaterial(
|
|
2365
|
-
|
|
2374
|
+
programOwner,
|
|
2366
2375
|
assetsRef,
|
|
2367
2376
|
materialContext,
|
|
2368
2377
|
);
|
|
@@ -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[] {
|