@forgeax/engine-render 0.1.23 → 0.1.24
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 +131 -9
- package/dist/assembly/bundler-contract.d.ts +9 -0
- package/dist/assembly/bundler-contract.d.ts.map +1 -0
- package/dist/assembly/device-feature-admission.d.ts +8 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -1
- package/dist/assembly/extended-lighting-fallback.d.ts +13 -0
- package/dist/assembly/extended-lighting-fallback.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +7 -243
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +3 -2
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/standard-layer-projection.d.ts +10 -0
- package/dist/assembly/material/standard-layer-projection.d.ts.map +1 -0
- package/dist/assembly/material-shader-policy.d.ts +168 -0
- package/dist/assembly/material-shader-policy.d.ts.map +1 -0
- package/dist/assembly/material-shader-prewarm.d.ts +21 -0
- package/dist/assembly/material-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/mesh-ssbo-grow.d.ts +88 -0
- package/dist/assembly/mesh-ssbo-grow.d.ts.map +1 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts +14 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -0
- package/dist/assembly/recovery/generation.d.ts +46 -0
- package/dist/assembly/recovery/generation.d.ts.map +1 -0
- package/dist/assembly/recovery/recovery-attempt.d.ts +63 -0
- package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -0
- package/dist/assembly/recovery/renderer-recover.d.ts +115 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -0
- package/dist/assembly/renderer-facade.d.ts +10 -0
- package/dist/assembly/renderer-facade.d.ts.map +1 -0
- package/dist/assembly/renderer-frame-transaction.d.ts +17 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-helpers.d.ts +19 -0
- package/dist/assembly/renderer-helpers.d.ts.map +1 -0
- package/dist/assembly/renderer-lifecycle.d.ts +34 -0
- package/dist/assembly/renderer-lifecycle.d.ts.map +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts +15 -0
- package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready-contract.d.ts +9 -0
- package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +55 -0
- package/dist/assembly/webgpu-ready.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +152 -0
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -0
- package/dist/authoring.mjs +1 -1
- package/dist/{chunk-4L3P6DT5.mjs → chunk-GE3SDD72.mjs} +37 -5
- package/dist/chunk-GE3SDD72.mjs.map +1 -0
- package/dist/{chunk-HZUPSYW7.mjs → chunk-KZFTK6DO.mjs} +102 -15
- package/dist/chunk-KZFTK6DO.mjs.map +1 -0
- package/dist/{chunk-FF7K3FSO.mjs → chunk-Q752SHI5.mjs} +89 -89
- package/dist/{chunk-FF7K3FSO.mjs.map → chunk-Q752SHI5.mjs.map} +1 -1
- package/dist/{chunk-QODA5UKU.mjs → chunk-RR5L4SRS.mjs} +2 -2
- package/dist/chunk-RR5L4SRS.mjs.map +1 -0
- package/dist/{chunk-YALPS44A.mjs → chunk-TFH5I7JJ.mjs} +47 -47
- package/dist/chunk-TFH5I7JJ.mjs.map +1 -0
- package/dist/{chunk-FBC4R44J.mjs → chunk-UQYS7FRM.mjs} +57 -57
- package/dist/chunk-UQYS7FRM.mjs.map +1 -0
- package/dist/{chunk-4NPUASZR.mjs → chunk-YKB5DQV7.mjs} +161 -19
- package/dist/chunk-YKB5DQV7.mjs.map +1 -0
- package/dist/{chunk-ZUWKAZ2I.mjs → chunk-YRUYGA4A.mjs} +615 -237
- package/dist/chunk-YRUYGA4A.mjs.map +1 -0
- package/dist/{chunk-DIYW3M5D.mjs → chunk-Z3YYH2MB.mjs} +2210 -2213
- package/dist/chunk-Z3YYH2MB.mjs.map +1 -0
- package/dist/construct-renderer.mjs +19841 -16190
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/device-scope.d.ts +2 -0
- package/dist/device/device-scope.d.ts.map +1 -1
- package/dist/device/gpu-residency.d.ts +24 -4
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/environment/frame.d.ts +5 -0
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/inspection.d.ts +7 -0
- package/dist/environment/inspection.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +20 -2
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/recover.d.ts +58 -2
- package/dist/errors/recover.d.ts.map +1 -1
- package/dist/errors/render.d.ts +13 -0
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +899 -0
- package/dist/extract/contracts.d.ts.map +1 -0
- package/dist/features/host.d.ts +2 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +3 -0
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts +2 -0
- package/dist/features/prepared-graphics-store.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +28 -0
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +1 -0
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +7 -6
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +7 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +6 -6
- package/dist/internal.mjs +6 -6
- package/dist/light-buffer-layout.d.ts +3 -0
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/materials.d.ts +34 -10
- package/dist/materials.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +56 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/occlusion-proxy.d.ts +4 -0
- package/dist/occlusion-proxy.d.ts.map +1 -0
- package/dist/pbr-pipeline.d.ts +32 -9
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/points-lines/prepare.d.ts +3 -0
- package/dist/points-lines/prepare.d.ts.map +1 -1
- package/dist/points-lines/standard-owner.d.ts +33 -0
- package/dist/points-lines/standard-owner.d.ts.map +1 -0
- package/dist/record/frame-snapshot.d.ts +5 -0
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +14 -2
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +14 -1
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +7 -17
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +11 -3
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/recovery-pipeline.d.ts +30 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -0
- package/dist/record/render-context.d.ts +26 -4
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +1 -1
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +65 -0
- package/dist/recovery/render-system-candidate.d.ts.map +1 -0
- package/dist/render-contract.d.ts +64 -7
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +12 -0
- package/dist/render-system-extract-tail.d.ts.map +1 -0
- package/dist/render-system-extract.d.ts +156 -22
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +128 -4
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +19 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -6
- package/dist/temporal/taa-history-store.d.ts +15 -1
- package/dist/temporal/taa-history-store.d.ts.map +1 -1
- package/dist/temporal/transaction.d.ts +5 -0
- package/dist/temporal/transaction.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/device-feature-admission.unit.test.ts +6 -0
- package/src/__tests__/device-loss-fanout.unit.test.ts +107 -0
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +21 -0
- package/src/__tests__/environment-generation.integration.test.ts +23 -0
- package/src/__tests__/expose-renderer-errors.unit.test.ts +34 -0
- package/src/__tests__/factory-contract.integration.test.ts +122 -7
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +4 -1
- package/src/__tests__/ibl/face-uniforms.unit.test.ts +2 -0
- package/src/__tests__/ibl-residency-publication.unit.test.ts +113 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +24 -9
- package/src/__tests__/material-cooked-projection.unit.test.ts +19 -1
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +29 -0
- package/src/__tests__/material-stride-surface.unit.test.ts +7 -3
- package/src/__tests__/materials-standard-contract.unit.test.ts +104 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
- package/src/__tests__/physical-clearcoat.integration.test.ts +89 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +1 -1
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +1 -1
- package/src/__tests__/recover-error-policy-owner.unit.test.ts +6 -3
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +140 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +85 -18
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +47 -0
- package/src/__tests__/renderer-generation-assembly.unit.test.ts +77 -0
- package/src/__tests__/renderer-generation-failure.unit.test.ts +108 -0
- package/src/__tests__/renderer-producer-root-matrix.integration.test.ts +33 -0
- package/src/__tests__/renderer-recovery-capability-matrix.unit.test.ts +59 -0
- package/src/__tests__/renderer-recovery-contract.unit.test.ts +73 -0
- package/src/__tests__/renderer-recovery-lifecycle.unit.test.ts +216 -0
- package/src/__tests__/renderer-target-history-recovery.integration.test.ts +80 -0
- package/src/__tests__/shader-manifest-fixture.ts +13 -16
- package/src/__tests__/shader-stage-surface.unit.test.ts +1 -1
- package/src/__tests__/standard-layer-projection.unit.test.ts +23 -0
- package/src/__tests__/transmission-prewarm.unit.test.ts +95 -85
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +3 -1
- package/src/assembly/bundler-contract.ts +9 -0
- package/src/assembly/device-feature-admission.ts +15 -5
- package/src/assembly/extended-lighting-fallback.ts +216 -0
- package/src/assembly/factory.ts +81 -10088
- package/src/assembly/material/assembly.ts +18 -2
- package/src/assembly/material/standard-layer-projection.ts +16 -0
- package/src/assembly/material-shader-policy.ts +854 -0
- package/src/assembly/material-shader-prewarm.ts +88 -0
- package/src/assembly/mesh-ssbo-grow.ts +270 -0
- package/src/assembly/recovery/device-loss-fanout.ts +89 -0
- package/src/assembly/recovery/generation.ts +141 -0
- package/src/assembly/recovery/recovery-attempt.ts +800 -0
- package/src/assembly/recovery/renderer-recover.ts +906 -0
- package/src/assembly/renderer-facade.ts +342 -0
- package/src/assembly/renderer-frame-transaction.ts +45 -0
- package/src/assembly/renderer-helpers.ts +99 -0
- package/src/assembly/renderer-lifecycle.ts +159 -0
- package/src/assembly/shader-prewarm-policy.ts +157 -0
- package/src/assembly/webgpu-ready-contract.ts +14 -0
- package/src/assembly/webgpu-ready.ts +4079 -0
- package/src/assembly/webgpu-renderer.ts +4095 -0
- package/src/components/camera.ts +1 -1
- package/src/debug-draw-glue.ts +1 -1
- package/src/device/device-scope.ts +35 -6
- package/src/device/gpu-residency.ts +194 -26
- package/src/environment/frame.ts +6 -0
- package/src/environment/inspection.ts +10 -0
- package/src/environment/lifecycle.ts +114 -8
- package/src/errors/recover.ts +76 -5
- package/src/errors/render.ts +17 -0
- package/src/extract/contracts.ts +974 -0
- package/src/features/host.ts +16 -0
- package/src/features/prepared-gpu-work.ts +20 -2
- package/src/features/prepared-graphics-store.ts +17 -0
- package/src/gpu-driven/production-raster.ts +97 -2
- package/src/gpu-scene.ts +3 -2
- package/src/ibl/IblPipelineCache.ts +134 -50
- package/src/ibl/skylight-bind-group.ts +26 -0
- package/src/index.ts +9 -1
- package/src/light-buffer-layout.ts +3 -0
- package/src/materials.ts +262 -45
- package/src/mesh-material-bindings.ts +59 -0
- package/src/occlusion-proxy.ts +64 -0
- package/src/pbr-pipeline.ts +139 -15
- package/src/points-lines/__tests__/cache-recovery.unit.test.ts +22 -0
- package/src/points-lines/prepare.ts +9 -0
- package/src/points-lines/standard-owner.ts +403 -0
- package/src/record/__tests__/frame-targets-recovery.unit.test.ts +60 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +26 -1
- package/src/record/__tests__/mesh-ssbo.unit.test.ts +38 -0
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +124 -0
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +28 -13
- package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +47 -4
- package/src/record/__tests__/temporal-payload.unit.test.ts +22 -43
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -1
- package/src/record/frame-snapshot.ts +15 -0
- package/src/record/frame-targets.ts +11 -1
- package/src/record/frame.ts +6 -2
- package/src/record/helpers.ts +1 -1
- package/src/record/main-pass-geometry.ts +230 -5
- package/src/record/main-pass-material.ts +316 -209
- package/src/record/main-pass-sprite-draws.ts +6 -7
- package/src/record/main-pass.ts +94 -6
- package/src/record/mesh-ssbo.ts +32 -10
- package/src/record/recovery-pipeline.ts +695 -0
- package/src/record/render-context.ts +35 -4
- package/src/record/typed-frame-graph.ts +45 -1
- package/src/record/view-ubo.ts +3 -3
- package/src/recovery/render-system-candidate.ts +839 -0
- package/src/render-contract.ts +65 -7
- package/src/render-system-extract-tail.ts +2983 -0
- package/src/render-system-extract.ts +124 -2977
- package/src/render-system.ts +868 -659
- package/src/scene/render-scene.ts +124 -1
- package/src/temporal/frame-coordinator.ts +4 -1
- package/src/temporal/taa-history-store.ts +46 -2
- package/src/temporal/temporal-view.ts +1 -1
- package/src/temporal/transaction.ts +9 -0
- package/src/tilemap-chunk-extract-system.ts +1 -1
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +19 -12
- package/dist/chunk-4L3P6DT5.mjs.map +0 -1
- package/dist/chunk-4NPUASZR.mjs.map +0 -1
- package/dist/chunk-DIYW3M5D.mjs.map +0 -1
- package/dist/chunk-FBC4R44J.mjs.map +0 -1
- package/dist/chunk-HZUPSYW7.mjs.map +0 -1
- package/dist/chunk-QODA5UKU.mjs.map +0 -1
- package/dist/chunk-YALPS44A.mjs.map +0 -1
- package/dist/chunk-ZUWKAZ2I.mjs.map +0 -1
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
RhiError,
|
|
11
11
|
type RhiRenderPassEncoder,
|
|
12
12
|
} from '@forgeax/engine-rhi';
|
|
13
|
-
import type { PassKind, PrimitiveTopology } from '@forgeax/engine-types';
|
|
13
|
+
import type { ParamSchemaEntry, PassKind, PrimitiveTopology } from '@forgeax/engine-types';
|
|
14
14
|
import { GpuBuffer } from '../gpu-resource';
|
|
15
15
|
import {
|
|
16
16
|
GPU_BUFFER_USAGE_COPY_DST,
|
|
@@ -22,8 +22,12 @@ import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
|
|
|
22
22
|
import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';
|
|
23
23
|
import {
|
|
24
24
|
createPbrSkinMeshBindGroupEntries,
|
|
25
|
+
isCanonicalStandardPbrMaterialShader,
|
|
25
26
|
isStandardPbrMaterialShader,
|
|
27
|
+
isStandardPbrSkinMaterialShader,
|
|
28
|
+
materialBindGroupLayoutIdentity,
|
|
26
29
|
pbrSkinMeshDynamicOffsets,
|
|
30
|
+
physicalTextureFields,
|
|
27
31
|
SKIN_MATERIAL_SHADER_ID,
|
|
28
32
|
} from '../pbr-pipeline';
|
|
29
33
|
import {
|
|
@@ -41,7 +45,7 @@ import {
|
|
|
41
45
|
PROBE_BLEND_RECORD_STRIDE,
|
|
42
46
|
probeBlendRecordOffset,
|
|
43
47
|
} from '../scene/probe-blend-record';
|
|
44
|
-
import { worldEntityKey } from './frame-snapshot';
|
|
48
|
+
import { getOpaqueResourceIdentity, worldEntityKey } from './frame-snapshot';
|
|
45
49
|
import {
|
|
46
50
|
geometryRenderStateForTopology,
|
|
47
51
|
isEntityFullyTransparent,
|
|
@@ -75,6 +79,18 @@ type GeometryBindingState = {
|
|
|
75
79
|
probeOffset: number;
|
|
76
80
|
};
|
|
77
81
|
|
|
82
|
+
function materialDiagnosticsEnabled(): boolean {
|
|
83
|
+
if (typeof globalThis !== 'object' || globalThis === null || !('process' in globalThis)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const processValue = (
|
|
87
|
+
globalThis as {
|
|
88
|
+
readonly process?: { readonly env?: Record<string, string | undefined> };
|
|
89
|
+
}
|
|
90
|
+
).process;
|
|
91
|
+
return processValue?.env?.FORGEAX_MATERIAL_DIAGNOSTICS === '1';
|
|
92
|
+
}
|
|
93
|
+
|
|
78
94
|
type MaterialPipelineLookup = {
|
|
79
95
|
readonly materialShaderId: string;
|
|
80
96
|
readonly isHdrTarget: boolean;
|
|
@@ -94,6 +110,121 @@ type GeometryRecordProfileSegment = 'material-bind-groups' | 'pipeline-selection
|
|
|
94
110
|
|
|
95
111
|
type GeometryRenderState = ReturnType<typeof geometryRenderStateForTopology>;
|
|
96
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Select the transmission shader axis from authored material data, not the
|
|
115
|
+
* canonical boot schema. The latter reserves transmission fields for the
|
|
116
|
+
* shared Standard ABI even when a material remains base-only.
|
|
117
|
+
*/
|
|
118
|
+
export function requestsStandardTransmissionVariant(
|
|
119
|
+
material: Pick<MaterialSnapshot, 'materialShaderId' | 'paramSnapshot'>,
|
|
120
|
+
): boolean {
|
|
121
|
+
return (
|
|
122
|
+
material.materialShaderId === 'forgeax::default-standard-pbr' &&
|
|
123
|
+
material.paramSnapshot?.transmission !== undefined
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function recordIblPipelineBinding(
|
|
128
|
+
c: _InternalRenderPipelineContext,
|
|
129
|
+
material: MaterialSnapshot,
|
|
130
|
+
pipeline: RenderPipeline,
|
|
131
|
+
materialGroup: BindGroup,
|
|
132
|
+
): void {
|
|
133
|
+
const receipt = c.frameState.iblBindingInspection;
|
|
134
|
+
if (receipt === undefined || !isStandardPbrMaterialShader(material.materialShaderId)) return;
|
|
135
|
+
const materialBgl =
|
|
136
|
+
c.runtime.getMaterialBindGroupLayout?.(
|
|
137
|
+
material.materialShaderId ?? 'forgeax::default-standard-pbr',
|
|
138
|
+
) ?? c.pipelineState.materialBindGroupLayout;
|
|
139
|
+
c.frameState.iblBindingInspection = {
|
|
140
|
+
...receipt,
|
|
141
|
+
pipeline: {
|
|
142
|
+
pipelineIdentity: getOpaqueResourceIdentity(pipeline as object),
|
|
143
|
+
effectiveMaterialLayoutIdentity: effectiveMaterialLayoutIdentity(
|
|
144
|
+
material.materialShaderId ?? 'forgeax::default-standard-pbr',
|
|
145
|
+
material.materialParamSchema,
|
|
146
|
+
),
|
|
147
|
+
materialBglIdentity: getOpaqueResourceIdentity(materialBgl as object),
|
|
148
|
+
bindGroupIdentity: getOpaqueResourceIdentity(materialGroup as object),
|
|
149
|
+
drawFrameId: c.frameState.frameNumber,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
const materialReceipt = c.frameState.iblBindingInspection.material;
|
|
153
|
+
const errors: string[] = [];
|
|
154
|
+
if (
|
|
155
|
+
materialReceipt !== undefined &&
|
|
156
|
+
materialReceipt.materialBglIdentity !== getOpaqueResourceIdentity(materialBgl as object)
|
|
157
|
+
) {
|
|
158
|
+
errors.push('material-pipeline-bgl-identity-mismatch');
|
|
159
|
+
}
|
|
160
|
+
if (
|
|
161
|
+
materialReceipt !== undefined &&
|
|
162
|
+
materialReceipt.bindGroupIdentity !== getOpaqueResourceIdentity(materialGroup as object)
|
|
163
|
+
) {
|
|
164
|
+
errors.push('material-bind-group-identity-mismatch');
|
|
165
|
+
}
|
|
166
|
+
if (materialReceipt !== undefined) {
|
|
167
|
+
const expectedResourceIdentities = [
|
|
168
|
+
receipt.resources.irradiance.viewIdentity,
|
|
169
|
+
receipt.resources.irradiance.samplerIdentity,
|
|
170
|
+
receipt.resources.prefilter.viewIdentity,
|
|
171
|
+
receipt.resources.prefilter.samplerIdentity,
|
|
172
|
+
receipt.resources.brdfLut.viewIdentity,
|
|
173
|
+
receipt.resources.brdfLut.samplerIdentity,
|
|
174
|
+
receipt.resources.intensityBufferIdentity,
|
|
175
|
+
];
|
|
176
|
+
const actualResourceIdentities = materialReceipt.entries
|
|
177
|
+
.filter((entry) => entry.binding >= materialReceipt.skylightBindingStart)
|
|
178
|
+
.slice(0, expectedResourceIdentities.length)
|
|
179
|
+
.map((entry) => entry.resourceIdentity);
|
|
180
|
+
if (
|
|
181
|
+
actualResourceIdentities.length !== expectedResourceIdentities.length ||
|
|
182
|
+
actualResourceIdentities.some(
|
|
183
|
+
(identity, index) => identity !== expectedResourceIdentities[index],
|
|
184
|
+
)
|
|
185
|
+
) {
|
|
186
|
+
errors.push('material-ibl-resource-identity-mismatch');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
c.frameState.iblBindingInspection = {
|
|
190
|
+
...c.frameState.iblBindingInspection,
|
|
191
|
+
status: errors.length === 0 ? 'binding-chain-consistent' : 'binding-chain-mismatch',
|
|
192
|
+
errors,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const SHARED_BOOT_MATERIAL_SHADER_IDS = new Set([
|
|
197
|
+
'forgeax::default-unlit',
|
|
198
|
+
'forgeax::default-shadow-caster',
|
|
199
|
+
'forgeax::sprite',
|
|
200
|
+
'forgeax::sprite-lit',
|
|
201
|
+
'forgeax::default-sprite',
|
|
202
|
+
'forgeax::msdf-text',
|
|
203
|
+
'forgeax::default-standard-pbr',
|
|
204
|
+
'forgeax::pbr-skin',
|
|
205
|
+
'forgeax::default-standard-pbr-skin',
|
|
206
|
+
]);
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Returns the layout identity that can distinguish a material PSO in the
|
|
210
|
+
* record cache. Shared boot shaders keep the boot layout identity even when a
|
|
211
|
+
* manifest exposes a schema; Standard PBR only opts into a schema-derived
|
|
212
|
+
* identity when authored clearcoat texture bindings extend that layout.
|
|
213
|
+
*/
|
|
214
|
+
export function effectiveMaterialLayoutIdentity(
|
|
215
|
+
materialShaderId: string,
|
|
216
|
+
materialParamSchema?: readonly ParamSchemaEntry[],
|
|
217
|
+
): string | undefined {
|
|
218
|
+
if (materialParamSchema === undefined) return undefined;
|
|
219
|
+
const hasStandardPhysicalMaps =
|
|
220
|
+
isStandardPbrMaterialShader(materialShaderId) &&
|
|
221
|
+
physicalTextureFields(materialParamSchema).length > 0;
|
|
222
|
+
if (SHARED_BOOT_MATERIAL_SHADER_IDS.has(materialShaderId) && !hasStandardPhysicalMaps) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
return materialBindGroupLayoutIdentity(materialShaderId, materialParamSchema);
|
|
226
|
+
}
|
|
227
|
+
|
|
97
228
|
/**
|
|
98
229
|
* Resolve the depth contract for a geometry pass without changing the base
|
|
99
230
|
* material state. Temporal scene-data shares the main pass depth attachment:
|
|
@@ -228,6 +359,7 @@ export function recordGeometryDraws(
|
|
|
228
359
|
viewBindGroup,
|
|
229
360
|
viewBindGroupDynamicOffset = 0,
|
|
230
361
|
} = c;
|
|
362
|
+
const diagnosticsEnabled = materialDiagnosticsEnabled();
|
|
231
363
|
const colorFormatOverride = c.transparentColorFormat as GPUTextureFormat | undefined;
|
|
232
364
|
// The prepared Standard topology is the frame authority. A bind-group
|
|
233
365
|
// identity is only a resource result; using it to infer the shader lane
|
|
@@ -587,7 +719,22 @@ export function recordGeometryDraws(
|
|
|
587
719
|
// and walks 0, 1536, 3072, ... on the storage path.
|
|
588
720
|
const skinAllocator = pipelineState.skinPaletteAllocator;
|
|
589
721
|
const skinSlice = entry.source.skin;
|
|
590
|
-
|
|
722
|
+
// Authored Standard skin aliases deliberately publish the physical root
|
|
723
|
+
// with only their STORAGE_BUFFER capability axis. Their composed WGSL is
|
|
724
|
+
// the direct-lighting/palette (`skin`) ABI, even when the frame's
|
|
725
|
+
// canonical Standard lane uses clustered lighting. Only the canonical
|
|
726
|
+
// engine skin artifact can consume the HDRP unified skin group(2) layout;
|
|
727
|
+
// selecting it from the frame topology alone would bind
|
|
728
|
+
// `hdrp-skin-unified-bg-group2` to a three-entry URP skin PSO.
|
|
729
|
+
const clusteredSkin =
|
|
730
|
+
clusteredLighting &&
|
|
731
|
+
entry.source.materials.every((material) => {
|
|
732
|
+
const shaderId = material.materialShaderId;
|
|
733
|
+
return (
|
|
734
|
+
!isStandardPbrSkinMaterialShader(shaderId) ||
|
|
735
|
+
isCanonicalStandardPbrMaterialShader(shaderId)
|
|
736
|
+
);
|
|
737
|
+
});
|
|
591
738
|
const skinMeshBindGroupLayout = clusteredSkin
|
|
592
739
|
? pipelineState.hdrpSkinMeshBindGroupLayout
|
|
593
740
|
: pipelineState.pbrSkinMeshBindGroupLayout;
|
|
@@ -734,6 +881,19 @@ export function recordGeometryDraws(
|
|
|
734
881
|
// the async PSO compile resolves the cache hits and the next frame
|
|
735
882
|
// routes the skin BG + skin pipeline together. Mirrors the uniform
|
|
736
883
|
// null skip-draw shape (M6-T1, charter P3 explicit failure).
|
|
884
|
+
if (diagnosticsEnabled) {
|
|
885
|
+
console.error(
|
|
886
|
+
`[render-material] skin draw skipped: ${JSON.stringify({
|
|
887
|
+
entityKey: entry.source.entityKey,
|
|
888
|
+
materialHandle: entry.source.material.materialHandle,
|
|
889
|
+
reason: 'skin-pipeline-unavailable',
|
|
890
|
+
skinResourcesReady: skinResources !== null,
|
|
891
|
+
skinPsoReady: skinPsoProbe !== null,
|
|
892
|
+
paletteBufferReady: skinSlice?.buffer !== undefined,
|
|
893
|
+
paletteByteOffset: skinSlice?.byteOffset,
|
|
894
|
+
})}`,
|
|
895
|
+
);
|
|
896
|
+
}
|
|
737
897
|
continue;
|
|
738
898
|
}
|
|
739
899
|
// feat-20260520-2d-sprite-layer-mvp M-3 / w25 (@fallback sprite
|
|
@@ -828,6 +988,26 @@ export function recordGeometryDraws(
|
|
|
828
988
|
// injection, and Skylight merge; deduped cross-entity via the
|
|
829
989
|
// shaderId-outer `materialBgShared` cache.
|
|
830
990
|
const materialSlot = materialSlotIndices[i]?.[matSlotIdx] ?? materialSlotIndices[i]?.[0] ?? 0;
|
|
991
|
+
const processValue = (
|
|
992
|
+
globalThis as {
|
|
993
|
+
process?: { env?: Record<string, string | undefined> };
|
|
994
|
+
}
|
|
995
|
+
).process;
|
|
996
|
+
if (
|
|
997
|
+
processValue?.env?.FORGEAX_MATERIAL_PIPELINE_DIAGNOSTICS === '1' &&
|
|
998
|
+
(submeshMaterial.materialShaderId === 'forgeax::default-standard-pbr' ||
|
|
999
|
+
submeshMaterial.materialShaderId === 'forgeax::pbr-skin')
|
|
1000
|
+
) {
|
|
1001
|
+
console.error(
|
|
1002
|
+
`[render-material] draw receipt: ${JSON.stringify({
|
|
1003
|
+
entityIndex: entry.renderableIndex,
|
|
1004
|
+
materialSlot,
|
|
1005
|
+
materialHandle: submeshMaterial.materialHandle,
|
|
1006
|
+
clearcoat: submeshMaterial.paramSnapshot?.clearcoat,
|
|
1007
|
+
shader: submeshMaterial.materialShaderId,
|
|
1008
|
+
})}`,
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
831
1011
|
perSubmeshBg =
|
|
832
1012
|
profilePhase === undefined
|
|
833
1013
|
? resolveMaterialBindGroup(
|
|
@@ -849,7 +1029,9 @@ export function recordGeometryDraws(
|
|
|
849
1029
|
const smTopology = sm.topology;
|
|
850
1030
|
const smMaterialShaderId =
|
|
851
1031
|
entry.source.skin !== undefined
|
|
852
|
-
?
|
|
1032
|
+
? isStandardPbrSkinMaterialShader(submeshMaterial.materialShaderId)
|
|
1033
|
+
? submeshMaterial.materialShaderId
|
|
1034
|
+
: SKIN_MATERIAL_SHADER_ID
|
|
853
1035
|
: submeshMaterial.materialShaderId;
|
|
854
1036
|
const probeBlendAvailable =
|
|
855
1037
|
probeBlendRecordAvailable && isStandardPbrMaterialShader(smMaterialShaderId);
|
|
@@ -930,6 +1112,11 @@ export function recordGeometryDraws(
|
|
|
930
1112
|
hasVertexColor,
|
|
931
1113
|
probeBlendAvailable,
|
|
932
1114
|
);
|
|
1115
|
+
const transmissionAvailable = requestsStandardTransmissionVariant(submeshMaterial);
|
|
1116
|
+
const materialCapabilityVariantSet =
|
|
1117
|
+
transmissionAvailable && !capabilityVariantSet.includes('TRANSMISSION_AVAILABLE=')
|
|
1118
|
+
? `${capabilityVariantSet === '' ? '' : `${capabilityVariantSet}+`}TRANSMISSION_AVAILABLE=true`
|
|
1119
|
+
: capabilityVariantSet;
|
|
933
1120
|
// Sprite's base request must retain the boot-selected artifact. Only
|
|
934
1121
|
// SpriteInstances uses the explicit empty key for the
|
|
935
1122
|
// PER_INSTANCE_REGION=true variant; synthesizing the generic PBR
|
|
@@ -940,7 +1127,7 @@ export function recordGeometryDraws(
|
|
|
940
1127
|
? ''
|
|
941
1128
|
: undefined
|
|
942
1129
|
: entry.variantSet === undefined
|
|
943
|
-
?
|
|
1130
|
+
? materialCapabilityVariantSet
|
|
944
1131
|
: capabilityVariantSet === ''
|
|
945
1132
|
? entry.variantSet
|
|
946
1133
|
: `${capabilityVariantSet}+${entry.variantSet}`;
|
|
@@ -973,6 +1160,16 @@ export function recordGeometryDraws(
|
|
|
973
1160
|
}
|
|
974
1161
|
|
|
975
1162
|
if (smPipelineHandle === null) {
|
|
1163
|
+
if (diagnosticsEnabled) {
|
|
1164
|
+
console.error(
|
|
1165
|
+
`[render-material] draw skipped: ${JSON.stringify({
|
|
1166
|
+
entityKey: entry.source.entityKey,
|
|
1167
|
+
materialHandle: submeshMaterial.materialHandle,
|
|
1168
|
+
shader: smMaterialShaderId,
|
|
1169
|
+
reason: 'pipeline-unavailable',
|
|
1170
|
+
})}`,
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
976
1173
|
continue;
|
|
977
1174
|
}
|
|
978
1175
|
// The probe record is an ABI extension of the built-in Standard PBR
|
|
@@ -1003,6 +1200,31 @@ export function recordGeometryDraws(
|
|
|
1003
1200
|
if (selectedGroup === null) continue;
|
|
1004
1201
|
group2BindGroup = selectedGroup;
|
|
1005
1202
|
}
|
|
1203
|
+
if (diagnosticsEnabled && submeshMaterial.textureHandles !== undefined) {
|
|
1204
|
+
console.error(
|
|
1205
|
+
`[render-material] draw submitted: ${JSON.stringify({
|
|
1206
|
+
entityKey: entry.source.entityKey,
|
|
1207
|
+
materialHandle: submeshMaterial.materialHandle,
|
|
1208
|
+
shader: smMaterialShaderId,
|
|
1209
|
+
textureHandles: [...submeshMaterial.textureHandles.entries()].map(
|
|
1210
|
+
([field, handle]) => ({
|
|
1211
|
+
field,
|
|
1212
|
+
handle,
|
|
1213
|
+
}),
|
|
1214
|
+
),
|
|
1215
|
+
skin: isSkinEntry
|
|
1216
|
+
? {
|
|
1217
|
+
resourcesReady: skinResources !== null,
|
|
1218
|
+
psoReady: skinPsoProbe !== null,
|
|
1219
|
+
paletteBufferReady: skinSlice?.buffer !== undefined,
|
|
1220
|
+
paletteByteOffset: skinSlice?.byteOffset,
|
|
1221
|
+
dynamicOffsets: [...group2DynamicOffsets],
|
|
1222
|
+
}
|
|
1223
|
+
: undefined,
|
|
1224
|
+
pipelineReady: true,
|
|
1225
|
+
})}`,
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1006
1228
|
pass.setBindGroup(2, group2BindGroup, group2DynamicOffsets);
|
|
1007
1229
|
|
|
1008
1230
|
if (profilePhase === undefined) {
|
|
@@ -1034,6 +1256,9 @@ export function recordGeometryDraws(
|
|
|
1034
1256
|
),
|
|
1035
1257
|
);
|
|
1036
1258
|
}
|
|
1259
|
+
if (diagnosticsEnabled && perSubmeshBg !== null) {
|
|
1260
|
+
recordIblPipelineBinding(c, submeshMaterial, smPipelineHandle, perSubmeshBg);
|
|
1261
|
+
}
|
|
1037
1262
|
}
|
|
1038
1263
|
}
|
|
1039
1264
|
}
|