@forgeax/engine-render 0.1.32 → 0.1.33
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 +379 -33
- package/dist/assembly/analytic-fog-registration.d.ts +3 -0
- package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
- package/dist/assembly/fxaa-registration.d.ts +4 -0
- package/dist/assembly/fxaa-registration.d.ts.map +1 -0
- package/dist/assembly/lod-observation.d.ts +4 -0
- package/dist/assembly/lod-observation.d.ts.map +1 -0
- package/dist/assembly/motion-blur-registration.d.ts +3 -0
- package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
- package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
- package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready.d.ts +1 -1
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/bloom-admission.d.ts +13 -0
- package/dist/bloom-admission.d.ts.map +1 -0
- package/dist/{chunk-DRR7D3KX.mjs → chunk-3RTCJTH4.mjs} +12 -9
- package/dist/chunk-3RTCJTH4.mjs.map +1 -0
- package/dist/{chunk-S665NJNF.mjs → chunk-LEAXOMYJ.mjs} +3 -3
- package/dist/{chunk-S665NJNF.mjs.map → chunk-LEAXOMYJ.mjs.map} +1 -1
- package/dist/{chunk-6TFBXLRJ.mjs → chunk-NB2S7ZRX.mjs} +155 -11
- package/dist/chunk-NB2S7ZRX.mjs.map +1 -0
- package/dist/{chunk-LULCA3OF.mjs → chunk-NNQL7CB3.mjs} +4 -4
- package/dist/{chunk-LULCA3OF.mjs.map → chunk-NNQL7CB3.mjs.map} +1 -1
- package/dist/{chunk-4NNZQCL3.mjs → chunk-OO3DRYK7.mjs} +66 -200
- package/dist/chunk-OO3DRYK7.mjs.map +1 -0
- package/dist/{chunk-GWCEMDVR.mjs → chunk-PLAXOOX5.mjs} +232 -7
- package/dist/chunk-PLAXOOX5.mjs.map +1 -0
- package/dist/{chunk-JRIPCMYC.mjs → chunk-VOZWDM3L.mjs} +283 -193
- package/dist/chunk-VOZWDM3L.mjs.map +1 -0
- package/dist/{chunk-JCIRYQ4V.mjs → chunk-ZDQWGQW7.mjs} +10 -4
- package/dist/chunk-ZDQWGQW7.mjs.map +1 -0
- package/dist/components/atmosphere.d.ts +2 -0
- package/dist/components/atmosphere.d.ts.map +1 -1
- package/dist/components/camera.d.ts +20 -4
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/mesh-filter.d.ts +6 -5
- package/dist/components/mesh-filter.d.ts.map +1 -1
- package/dist/components/motion-blur.d.ts +1 -0
- package/dist/components/motion-blur.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +2865 -526
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +6 -0
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/environment/analytic-fog.d.ts +6 -0
- package/dist/environment/analytic-fog.d.ts.map +1 -0
- package/dist/errors/render.d.ts +6 -2
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +7 -0
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/environment.d.ts +2 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/features/error-reporting.d.ts +13 -0
- package/dist/features/error-reporting.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/motion-blur/motion-blur-feature.d.ts +20 -2
- package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
- package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
- package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
- package/dist/features/plan.d.ts +7 -4
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +9 -5
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts +7 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +3 -1
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +9 -0
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +6 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/inspection-types.d.ts +43 -2
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances.d.ts +8 -1
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +6 -6
- package/dist/pipeline/standard-post.d.ts +28 -19
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +2 -2
- package/dist/record/frame-snapshot.d.ts +3 -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 +5 -2
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +6 -5
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +12 -28
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +5 -3
- package/dist/record/skybox-post-pass.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.map +1 -1
- package/dist/render-contract.d.ts +24 -4
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +3 -1
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +8 -1
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +7 -1
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +2 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +7 -0
- package/dist/temporal/frame.d.ts.map +1 -1
- package/dist/temporal/index.mjs +5 -5
- package/dist/temporal/view.d.ts +6 -1
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +10 -7
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +0 -1
- package/dist/volume/component.d.ts.map +1 -1
- package/dist/volume/passes.d.ts.map +1 -1
- package/dist/volume/temporal.d.ts +3 -1
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +21 -21
- package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
- package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
- package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
- package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
- package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
- package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
- package/src/__tests__/environment-selection.unit.test.ts +12 -0
- package/src/__tests__/factory-contract.integration.test.ts +331 -68
- package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
- package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +1 -1
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +11 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
- package/src/__tests__/gpu-scene.unit.test.ts +91 -0
- package/src/__tests__/instances-store.unit.test.ts +75 -0
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
- package/src/__tests__/motion-blur-compute.dawn.test.ts +583 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
- package/src/__tests__/public-surface.test-d.ts +8 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +2 -0
- package/src/__tests__/render-feature-error-reporting.unit.test.ts +24 -0
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +31 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +7 -1
- package/src/__tests__/shader-manifest-fixture.ts +4 -4
- package/src/__tests__/skinned-shadow-caster.test.ts +2 -0
- package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
- package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
- package/src/__tests__/standard-pipeline.integration.test.ts +18 -8
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
- package/src/__tests__/temporal-view.unit.test.ts +2 -1
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
- package/src/__tests__/volume-optics-oracle.unit.test.ts +3 -1
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +177 -13
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +447 -61
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +19 -3
- package/src/assembly/analytic-fog-registration.ts +14 -0
- package/src/assembly/fxaa-registration.ts +17 -0
- package/src/assembly/lod-observation.ts +12 -0
- package/src/assembly/motion-blur-registration.ts +17 -0
- package/src/assembly/renderer-facade.ts +2 -0
- package/src/assembly/temporal-post-process-prewarm.ts +40 -0
- package/src/assembly/webgpu-ready-contract.ts +8 -3
- package/src/assembly/webgpu-ready.ts +181 -245
- package/src/assembly/webgpu-renderer.ts +16 -31
- package/src/bloom-admission.ts +21 -0
- package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
- package/src/components/atmosphere.ts +4 -0
- package/src/components/camera.ts +66 -10
- package/src/components/mesh-filter.ts +11 -9
- package/src/components/motion-blur.ts +1 -0
- package/src/device/gpu-residency.ts +56 -12
- package/src/environment/analytic-fog.ts +44 -0
- package/src/environment/background.ts +2 -2
- package/src/errors/render.ts +14 -1
- package/src/extract/camera.ts +20 -7
- package/src/extract/contracts.ts +7 -0
- package/src/extract/environment.ts +4 -0
- package/src/features/error-reporting.ts +78 -0
- package/src/features/host.ts +25 -12
- package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
- package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
- package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
- package/src/features/motion-blur/motion-blur-params.ts +70 -2
- package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
- package/src/features/plan.ts +25 -8
- package/src/features/prepared-gpu-work.ts +86 -35
- package/src/features/render-graph-compute.ts +13 -5
- package/src/features/render-graph-contribution.ts +2 -0
- package/src/gpu-driven/material-artifacts.ts +2 -7
- package/src/gpu-driven/prepared-draw.ts +15 -10
- package/src/gpu-driven/production-raster.ts +83 -7
- package/src/gpu-driven/view-gpu.ts +17 -0
- package/src/gpu-scene.ts +188 -21
- package/src/index.ts +32 -0
- package/src/inspection-types.ts +60 -2
- package/src/instances.ts +80 -1
- package/src/pipeline/standard-post.ts +307 -78
- package/src/pipeline-spec.ts +5 -5
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
- package/src/record/__tests__/temporal-payload.unit.test.ts +2 -1
- package/src/record/frame-snapshot.ts +5 -1
- package/src/record/frame-targets.ts +10 -6
- package/src/record/frame.ts +163 -22
- package/src/record/main-pass-geometry.ts +30 -1
- package/src/record/main-pass-sprite-draws.ts +6 -1
- package/src/record/mesh-ssbo.ts +43 -6
- package/src/record/render-context.ts +12 -28
- package/src/record/shadow-pass.ts +6 -1
- package/src/record/skybox-post-pass.ts +122 -196
- package/src/record/typed-frame-graph.ts +153 -9
- package/src/recovery/render-system-candidate.ts +22 -10
- package/src/render-contract.ts +23 -4
- package/src/render-pipeline.ts +6 -1
- package/src/render-system-extract-tail.ts +16 -0
- package/src/render-system-extract.ts +45 -13
- package/src/render-system.ts +255 -120
- package/src/scene/render-scene.ts +85 -4
- package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
- package/src/temporal/frame-coordinator.ts +8 -1
- package/src/temporal/frame.ts +20 -0
- package/src/temporal/view.ts +13 -2
- package/src/typed-render-graph-primitives.ts +121 -48
- package/src/volume/component.ts +0 -1
- package/src/volume/passes.ts +8 -4
- package/src/volume/resources.ts +1 -1
- package/src/volume/temporal.ts +11 -0
- package/dist/chunk-4NNZQCL3.mjs.map +0 -1
- package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
- package/dist/chunk-DRR7D3KX.mjs.map +0 -1
- package/dist/chunk-GWCEMDVR.mjs.map +0 -1
- package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
- package/dist/chunk-JRIPCMYC.mjs.map +0 -1
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
FALLBACK_BYTES_PER_ROW,
|
|
58
58
|
type SkylightFallback,
|
|
59
59
|
} from '../ibl/skylight-bind-group';
|
|
60
|
-
import type
|
|
60
|
+
import { type BloomInspection, emptyBloomInspection } from '../inspection-types';
|
|
61
61
|
import type { DeviceScope, RhiErrorListenerRegistry } from '../lifecycle';
|
|
62
62
|
import { assertStorageBufferCap } from '../light-buffer-layout';
|
|
63
63
|
import {
|
|
@@ -119,11 +119,12 @@ import {
|
|
|
119
119
|
selectProbePrewarmVariants,
|
|
120
120
|
selectStandardPbrTransmissionPrewarmVariants,
|
|
121
121
|
} from './shader-prewarm-policy';
|
|
122
|
+
import { createTemporalShaderPrewarmer } from './temporal-post-process-prewarm';
|
|
122
123
|
import { buildGpuDrivenPbrReadyLayouts, buildGpuDrivenPbrReadyModules } from './webgpu-pbr-ready';
|
|
123
124
|
import {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
BLOOM_COMPOSITE_PARAMS_BYTES,
|
|
126
|
+
BLOOM_DOWNSAMPLE_PARAMS_BYTES,
|
|
127
|
+
BLOOM_UPSAMPLE_PARAMS_BYTES,
|
|
127
128
|
HDR_COLOR_ATTACHMENT_FORMAT,
|
|
128
129
|
VIEW_UBO_BYTES,
|
|
129
130
|
} from './webgpu-ready-contract';
|
|
@@ -219,6 +220,7 @@ export async function buildReadyWebGPU(
|
|
|
219
220
|
registerBuiltinTonemap: (source: string) => void,
|
|
220
221
|
/** Register the special FXAA pass' final-output policy params UBO. */
|
|
221
222
|
registerBuiltinFxaa: (source: string) => void,
|
|
223
|
+
registerBuiltinAnalyticFog: (source: string) => void,
|
|
222
224
|
registerBuiltinTemporalPostProcesses: (entries: {
|
|
223
225
|
readonly motionBlur?: string;
|
|
224
226
|
readonly taaResolve?: string;
|
|
@@ -320,8 +322,8 @@ export async function buildReadyWebGPU(
|
|
|
320
322
|
let spriteLitModule: ShaderModule | null = null;
|
|
321
323
|
let fxaaModule: ShaderModule | null = null;
|
|
322
324
|
let skyboxModule: ShaderModule | null = null;
|
|
323
|
-
let
|
|
324
|
-
let
|
|
325
|
+
let bloomDownsampleModule: ShaderModule | null = null;
|
|
326
|
+
let bloomUpsampleModule: ShaderModule | null = null;
|
|
325
327
|
let bloomCompositeModule: ShaderModule | null = null;
|
|
326
328
|
let ssaoModule: ShaderModule | null = null;
|
|
327
329
|
const findEngineManifestEntry = (identifier: string): ManifestEntry | undefined => {
|
|
@@ -385,8 +387,8 @@ export async function buildReadyWebGPU(
|
|
|
385
387
|
let probeBackgroundEntry: ManifestEntry | undefined;
|
|
386
388
|
let fxaaEntry: ManifestEntry | undefined;
|
|
387
389
|
let skyboxEntry: ManifestEntry | undefined;
|
|
388
|
-
let
|
|
389
|
-
let
|
|
390
|
+
let bloomDownsampleEntry: ManifestEntry | undefined;
|
|
391
|
+
let bloomUpsampleEntry: ManifestEntry | undefined;
|
|
390
392
|
let bloomCompositeEntry: ManifestEntry | undefined;
|
|
391
393
|
let ssaoEntry: ManifestEntry | undefined;
|
|
392
394
|
// feat-20260609 R3-fixup: shadow_caster module pre-bake. T-009 deleted
|
|
@@ -462,23 +464,16 @@ export async function buildReadyWebGPU(
|
|
|
462
464
|
skyboxEntry ??= entry;
|
|
463
465
|
continue;
|
|
464
466
|
}
|
|
465
|
-
//
|
|
466
|
-
//
|
|
467
|
-
//
|
|
468
|
-
//
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
// `// bloomBrightExtract` content-marker COMMENTS, which naga's WGSL
|
|
472
|
-
// writeback drops (comments are not part of the IR), leaving the markers
|
|
473
|
-
// absent from the composed `entry.wgsl` so the triage never matched and
|
|
474
|
-
// bloom silently never initialised (bug-20260625). Same survives-naga
|
|
475
|
-
// rationale as the SSAO `fs_ssao_calc` entry-point marker below.
|
|
476
|
-
if (entry.wgsl.includes('BloomBrightParams')) {
|
|
477
|
-
bloomBrightEntry ??= entry;
|
|
467
|
+
// Multiscale Bloom marker triage. The composed WGSL retains these
|
|
468
|
+
// uniform-struct names through naga_oil, so shader ownership is resolved
|
|
469
|
+
// from the cooked manifest rather than from a runtime compiler or a
|
|
470
|
+
// second heuristic path.
|
|
471
|
+
if (entry.wgsl.includes('BloomDownsampleParams')) {
|
|
472
|
+
bloomDownsampleEntry ??= entry;
|
|
478
473
|
continue;
|
|
479
474
|
}
|
|
480
|
-
if (entry.wgsl.includes('
|
|
481
|
-
|
|
475
|
+
if (entry.wgsl.includes('BloomUpsampleParams')) {
|
|
476
|
+
bloomUpsampleEntry ??= entry;
|
|
482
477
|
continue;
|
|
483
478
|
}
|
|
484
479
|
if (entry.wgsl.includes('BloomCompositeParams')) {
|
|
@@ -1149,26 +1144,14 @@ export async function buildReadyWebGPU(
|
|
|
1149
1144
|
|
|
1150
1145
|
// Prewarm temporal fullscreen modules before readiness so first-frame
|
|
1151
1146
|
// recording cannot encounter an asynchronous compile miss.
|
|
1152
|
-
const prewarmTemporal =
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
})
|
|
1161
|
-
: invokeDeviceCreateShaderModule(rhiDevice, {
|
|
1162
|
-
code: entry.wgsl,
|
|
1163
|
-
label: postProcessShaderModuleLabel(id, entry.wgsl),
|
|
1164
|
-
}),
|
|
1165
|
-
'shader-compile-failed',
|
|
1166
|
-
`${id} shader module compiled (unified post-process prewarm)`,
|
|
1167
|
-
`inspect manifest ${id} entry composed wgsl; check device.features`,
|
|
1168
|
-
);
|
|
1169
|
-
if (!prewarm.ok) throw prewarm.error;
|
|
1170
|
-
seedShaderModule(postProcessShaderModuleLabel(id, entry.wgsl), prewarm.value);
|
|
1171
|
-
};
|
|
1147
|
+
const prewarmTemporal = createTemporalShaderPrewarmer({
|
|
1148
|
+
device: rhiDevice,
|
|
1149
|
+
asyncCreateShaderModule,
|
|
1150
|
+
seedShaderModule,
|
|
1151
|
+
});
|
|
1152
|
+
const analyticFogEntry = findEngineManifestEntry('forgeax::analytic-fog');
|
|
1153
|
+
await prewarmTemporal(analyticFogEntry, 'forgeax.analytic-fog');
|
|
1154
|
+
if (analyticFogEntry !== undefined) registerBuiltinAnalyticFog(analyticFogEntry.wgsl);
|
|
1172
1155
|
await prewarmTemporal(motionBlurEntry, 'forgeax.motion-blur');
|
|
1173
1156
|
await prewarmTemporal(taaResolveEntry, 'forgeax.taa-resolve');
|
|
1174
1157
|
await prewarmDepthOfField(manifestEntries, prewarmTemporal, registerBuiltinDepthOfField);
|
|
@@ -1354,40 +1337,43 @@ export async function buildReadyWebGPU(
|
|
|
1354
1337
|
// Their construction is still part of renderer readiness because the
|
|
1355
1338
|
// backend may expose only an asynchronous module factory; the expensive
|
|
1356
1339
|
// pipeline, binding, and parameter resources stay deferred until admission.
|
|
1357
|
-
if (
|
|
1340
|
+
if (bloomDownsampleEntry !== undefined) {
|
|
1358
1341
|
const result = await runShimStep(
|
|
1359
1342
|
() =>
|
|
1360
1343
|
asyncCreateShaderModule
|
|
1361
1344
|
? asyncCreateShaderModule(rhiDevice, {
|
|
1362
|
-
code:
|
|
1363
|
-
label: 'bloom-
|
|
1345
|
+
code: bloomDownsampleEntry.wgsl,
|
|
1346
|
+
label: 'bloom-downsample',
|
|
1364
1347
|
})
|
|
1365
1348
|
: invokeDeviceCreateShaderModule(rhiDevice, {
|
|
1366
|
-
code:
|
|
1367
|
-
label: 'bloom-
|
|
1349
|
+
code: bloomDownsampleEntry.wgsl,
|
|
1350
|
+
label: 'bloom-downsample',
|
|
1368
1351
|
}),
|
|
1369
1352
|
'shader-compile-failed',
|
|
1370
|
-
'bloom-
|
|
1371
|
-
'inspect manifest bloom-
|
|
1353
|
+
'bloom-downsample shader module compiled',
|
|
1354
|
+
'inspect manifest bloom-downsample entry composed wgsl; check device.features',
|
|
1372
1355
|
);
|
|
1373
1356
|
if (!result.ok) throw result.error;
|
|
1374
|
-
|
|
1357
|
+
bloomDownsampleModule = result.value;
|
|
1375
1358
|
}
|
|
1376
|
-
if (
|
|
1359
|
+
if (bloomUpsampleEntry !== undefined) {
|
|
1377
1360
|
const result = await runShimStep(
|
|
1378
1361
|
() =>
|
|
1379
1362
|
asyncCreateShaderModule
|
|
1380
|
-
? asyncCreateShaderModule(rhiDevice, {
|
|
1363
|
+
? asyncCreateShaderModule(rhiDevice, {
|
|
1364
|
+
code: bloomUpsampleEntry.wgsl,
|
|
1365
|
+
label: 'bloom-upsample',
|
|
1366
|
+
})
|
|
1381
1367
|
: invokeDeviceCreateShaderModule(rhiDevice, {
|
|
1382
|
-
code:
|
|
1383
|
-
label: 'bloom-
|
|
1368
|
+
code: bloomUpsampleEntry.wgsl,
|
|
1369
|
+
label: 'bloom-upsample',
|
|
1384
1370
|
}),
|
|
1385
1371
|
'shader-compile-failed',
|
|
1386
|
-
'bloom-
|
|
1387
|
-
'inspect manifest bloom-
|
|
1372
|
+
'bloom-upsample shader module compiled',
|
|
1373
|
+
'inspect manifest bloom-upsample entry composed wgsl; check device.features',
|
|
1388
1374
|
);
|
|
1389
1375
|
if (!result.ok) throw result.error;
|
|
1390
|
-
|
|
1376
|
+
bloomUpsampleModule = result.value;
|
|
1391
1377
|
}
|
|
1392
1378
|
if (bloomCompositeEntry !== undefined) {
|
|
1393
1379
|
const result = await runShimStep(
|
|
@@ -2514,10 +2500,10 @@ export async function buildReadyWebGPU(
|
|
|
2514
2500
|
} else if (fragModule === skyboxModule) {
|
|
2515
2501
|
const msaa = d.multisample as Record<string, unknown> | undefined;
|
|
2516
2502
|
label = msaa !== undefined ? 'skybox-pipeline-msaa' : 'skybox-pipeline';
|
|
2517
|
-
} else if (fragModule ===
|
|
2518
|
-
label = 'bloom-
|
|
2519
|
-
} else if (fragModule ===
|
|
2520
|
-
label =
|
|
2503
|
+
} else if (fragModule === bloomDownsampleModule) {
|
|
2504
|
+
label = 'bloom-downsample-pipeline';
|
|
2505
|
+
} else if (fragModule === bloomUpsampleModule) {
|
|
2506
|
+
label = 'bloom-upsample-pipeline';
|
|
2521
2507
|
} else if (fragModule === bloomCompositeModule) {
|
|
2522
2508
|
label = 'bloom-composite-pipeline';
|
|
2523
2509
|
} else if (fragModule === ssaoModule) {
|
|
@@ -2745,23 +2731,18 @@ export async function buildReadyWebGPU(
|
|
|
2745
2731
|
let skyboxSamplerHandle: Sampler | null = null;
|
|
2746
2732
|
let skyboxRotationBufferHandle: Buffer | null = null;
|
|
2747
2733
|
let skyboxPipelineMsaaHandle: RenderPipeline | null = null;
|
|
2748
|
-
//
|
|
2749
|
-
//
|
|
2750
|
-
//
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
let bloomBrightPipelineHandle: RenderPipeline | null = null;
|
|
2754
|
-
let bloomBlurHPipelineHandle: RenderPipeline | null = null;
|
|
2755
|
-
let bloomBlurVPipelineHandle: RenderPipeline | null = null;
|
|
2734
|
+
// Multiscale Bloom pipeline handles. One level-parameterized downsample
|
|
2735
|
+
// pipeline and one tent upsample pipeline serve the whole five-level graph;
|
|
2736
|
+
// the composite is the only other Bloom pipeline. All use rgba16float.
|
|
2737
|
+
let bloomDownsamplePipelineHandle: RenderPipeline | null = null;
|
|
2738
|
+
let bloomUpsamplePipelineHandle: RenderPipeline | null = null;
|
|
2756
2739
|
let bloomCompositePipelineHandle: RenderPipeline | null = null;
|
|
2757
|
-
let
|
|
2758
|
-
let
|
|
2740
|
+
let bloomDownsampleBglHandle: BindGroupLayout | null = null;
|
|
2741
|
+
let bloomUpsampleBglHandle: BindGroupLayout | null = null;
|
|
2759
2742
|
let bloomCompositeBglHandle: BindGroupLayout | null = null;
|
|
2760
2743
|
let bloomSamplerHandle: Sampler | null = null;
|
|
2761
|
-
let
|
|
2762
|
-
|
|
2763
|
-
let bloomBlurHParamsBufferHandle: Buffer | null = null;
|
|
2764
|
-
let bloomBlurVParamsBufferHandle: Buffer | null = null;
|
|
2744
|
+
let bloomDownsampleParamsBufferHandle: Buffer | null = null;
|
|
2745
|
+
let bloomUpsampleParamsBufferHandle: Buffer | null = null;
|
|
2765
2746
|
let bloomCompositeParamsBufferHandle: Buffer | null = null;
|
|
2766
2747
|
let bloomResourcesReady = false;
|
|
2767
2748
|
let ensureBloomResources: (() => void) | undefined;
|
|
@@ -2799,22 +2780,7 @@ export async function buildReadyWebGPU(
|
|
|
2799
2780
|
const inspectBloomResourcesStable = (
|
|
2800
2781
|
graph?: import('@forgeax/engine-render-graph').CompiledRenderGraphInfo,
|
|
2801
2782
|
): BloomInspection => {
|
|
2802
|
-
return (
|
|
2803
|
-
inspectBloomResources?.(graph) ?? {
|
|
2804
|
-
graphStatus: 'empty',
|
|
2805
|
-
enabled: false,
|
|
2806
|
-
targetCount: 0,
|
|
2807
|
-
targetBytes: 0,
|
|
2808
|
-
resourceCount: 0,
|
|
2809
|
-
passCount: 0,
|
|
2810
|
-
encodeCount: 0,
|
|
2811
|
-
bindGroupCount: 0,
|
|
2812
|
-
uploadCount: 0,
|
|
2813
|
-
residentChildBytes: 0,
|
|
2814
|
-
generation: 0,
|
|
2815
|
-
state: 'off',
|
|
2816
|
-
}
|
|
2817
|
-
);
|
|
2783
|
+
return inspectBloomResources?.(graph) ?? emptyBloomInspection();
|
|
2818
2784
|
};
|
|
2819
2785
|
// feat-20260612-hdrp-ssao M6 / w26 + w43: SSAO pipeline handles (D-A).
|
|
2820
2786
|
// calc + blur RenderPipeline pair sharing a dedicated 6-entry BGL.
|
|
@@ -3108,18 +3074,10 @@ export async function buildReadyWebGPU(
|
|
|
3108
3074
|
skyboxRotationBufferHandle = skyboxRotationBufferResult.value;
|
|
3109
3075
|
}
|
|
3110
3076
|
|
|
3111
|
-
//
|
|
3112
|
-
//
|
|
3113
|
-
//
|
|
3114
|
-
//
|
|
3115
|
-
// absent (legacy manifest), handles stay null and execute closures
|
|
3116
|
-
// skip the bloom passes entirely (zero-overhead opt-out).
|
|
3117
|
-
//
|
|
3118
|
-
// Pipeline roster:
|
|
3119
|
-
// bloom-bright : 1-tex + sampler + UBO@2 BGL, rgba16float target
|
|
3120
|
-
// bloom-blur-h : same BGL, same module as blur-v, H-axis texelSize
|
|
3121
|
-
// bloom-blur-v : same BGL, same module as blur-h, V-axis texelSize
|
|
3122
|
-
// bloom-composite: 2-tex + sampler + UBO@3 BGL, rgba16float target
|
|
3077
|
+
// Multiscale Bloom pipeline assembly. The runtime owns exactly one
|
|
3078
|
+
// parameterized downsample PSO, one tent upsample PSO, and one composite
|
|
3079
|
+
// PSO. The graph owns the five downsample and up to four upsample target
|
|
3080
|
+
// instances; no axis/radius compatibility route is retained.
|
|
3123
3081
|
|
|
3124
3082
|
ensureBloomResources = (): void => {
|
|
3125
3083
|
if (bloomResourcesReady) return;
|
|
@@ -3133,11 +3091,11 @@ export async function buildReadyWebGPU(
|
|
|
3133
3091
|
return value;
|
|
3134
3092
|
};
|
|
3135
3093
|
try {
|
|
3136
|
-
// Shared
|
|
3094
|
+
// Shared Bloom sampler: linear filter + clamp-to-edge (all passes
|
|
3137
3095
|
// sample from textures using fullscreen triangle UVs).
|
|
3138
3096
|
if (
|
|
3139
|
-
|
|
3140
|
-
|
|
3097
|
+
bloomDownsampleModule !== null ||
|
|
3098
|
+
bloomUpsampleModule !== null ||
|
|
3141
3099
|
bloomCompositeModule !== null
|
|
3142
3100
|
) {
|
|
3143
3101
|
const bloomSamplerResult = runShimSyncStep(
|
|
@@ -3158,12 +3116,12 @@ export async function buildReadyWebGPU(
|
|
|
3158
3116
|
bloomSamplerHandle = adopt('binding', bloomSamplerResult.value, () => undefined);
|
|
3159
3117
|
}
|
|
3160
3118
|
|
|
3161
|
-
// Bloom
|
|
3162
|
-
if (
|
|
3163
|
-
const
|
|
3119
|
+
// Bloom downsample: source texture + sampler + one level slice.
|
|
3120
|
+
if (bloomDownsampleModule !== null && bloomSamplerHandle !== null) {
|
|
3121
|
+
const downsampleBglResult = runShimSyncStep(
|
|
3164
3122
|
() =>
|
|
3165
3123
|
rhiDevice.createBindGroupLayout({
|
|
3166
|
-
label: 'bloom-
|
|
3124
|
+
label: 'bloom-downsample-bgl',
|
|
3167
3125
|
entries: [
|
|
3168
3126
|
{
|
|
3169
3127
|
binding: 0,
|
|
@@ -3183,30 +3141,30 @@ export async function buildReadyWebGPU(
|
|
|
3183
3141
|
],
|
|
3184
3142
|
}),
|
|
3185
3143
|
'webgpu-runtime-error',
|
|
3186
|
-
'createBindGroupLayout(bloom-
|
|
3144
|
+
'createBindGroupLayout(bloom-downsample) succeeded',
|
|
3187
3145
|
'check device.limits.maxBindGroupsPerPipelineLayout',
|
|
3188
3146
|
);
|
|
3189
|
-
if (!
|
|
3190
|
-
|
|
3147
|
+
if (!downsampleBglResult.ok) throw downsampleBglResult.error;
|
|
3148
|
+
bloomDownsampleBglHandle = adopt('binding', downsampleBglResult.value, () => undefined);
|
|
3191
3149
|
|
|
3192
|
-
const
|
|
3150
|
+
const downsamplePlResult = runShimSyncStep(
|
|
3193
3151
|
() =>
|
|
3194
3152
|
rhiDevice.createPipelineLayout({
|
|
3195
|
-
label: 'bloom-
|
|
3196
|
-
bindGroupLayouts: [
|
|
3153
|
+
label: 'bloom-downsample-pl',
|
|
3154
|
+
bindGroupLayouts: [downsampleBglResult.value],
|
|
3197
3155
|
}),
|
|
3198
3156
|
'webgpu-runtime-error',
|
|
3199
|
-
'createPipelineLayout(bloom-
|
|
3200
|
-
'verify bloom-
|
|
3157
|
+
'createPipelineLayout(bloom-downsample) succeeded',
|
|
3158
|
+
'verify bloom-downsample BindGroupLayout matches shader @group(0) bindings',
|
|
3201
3159
|
);
|
|
3202
|
-
if (!
|
|
3203
|
-
adopt('binding',
|
|
3160
|
+
if (!downsamplePlResult.ok) throw downsamplePlResult.error;
|
|
3161
|
+
adopt('binding', downsamplePlResult.value, () => undefined);
|
|
3204
3162
|
|
|
3205
|
-
//
|
|
3163
|
+
// One pipeline serves D0 extraction and D1..D4 fixed reduction.
|
|
3206
3164
|
{
|
|
3207
|
-
const
|
|
3165
|
+
const downsampleSpec: PipelineSpec = {
|
|
3208
3166
|
shader: {
|
|
3209
|
-
id: 'forgeax::post::bloom-
|
|
3167
|
+
id: 'forgeax::post::bloom-downsample',
|
|
3210
3168
|
passKind: 'post-process',
|
|
3211
3169
|
variantSet: undefined,
|
|
3212
3170
|
},
|
|
@@ -3223,20 +3181,21 @@ export async function buildReadyWebGPU(
|
|
|
3223
3181
|
renderState: { cullMode: 'none' },
|
|
3224
3182
|
};
|
|
3225
3183
|
const modules = {
|
|
3226
|
-
vertex:
|
|
3227
|
-
fragment:
|
|
3228
|
-
layout:
|
|
3184
|
+
vertex: bloomDownsampleModule,
|
|
3185
|
+
fragment: bloomDownsampleModule,
|
|
3186
|
+
layout: downsamplePlResult.value,
|
|
3187
|
+
label: 'bloom-downsample-pipeline',
|
|
3229
3188
|
};
|
|
3230
3189
|
try {
|
|
3231
|
-
|
|
3232
|
-
|
|
3190
|
+
bloomDownsamplePipelineHandle = getOrBuildPipeline(
|
|
3191
|
+
downsampleSpec,
|
|
3233
3192
|
pipelineDeviceProvider,
|
|
3234
3193
|
pipelineCache,
|
|
3235
3194
|
modules,
|
|
3236
3195
|
) as RenderPipeline;
|
|
3237
|
-
|
|
3196
|
+
bloomDownsamplePipelineHandle = adopt(
|
|
3238
3197
|
'pipeline',
|
|
3239
|
-
|
|
3198
|
+
bloomDownsamplePipelineHandle,
|
|
3240
3199
|
() => undefined,
|
|
3241
3200
|
);
|
|
3242
3201
|
} catch (err) {
|
|
@@ -3244,37 +3203,41 @@ export async function buildReadyWebGPU(
|
|
|
3244
3203
|
throw new PipelineSpecError({
|
|
3245
3204
|
code: 'pipeline-build-failed',
|
|
3246
3205
|
detail: { cause: err },
|
|
3247
|
-
hint: 'createRenderPipeline (bloom-
|
|
3206
|
+
hint: 'createRenderPipeline (bloom-downsample fullscreen) failed; inspect gpuMessage',
|
|
3248
3207
|
});
|
|
3249
3208
|
}
|
|
3250
3209
|
}
|
|
3251
3210
|
|
|
3252
|
-
//
|
|
3253
|
-
|
|
3211
|
+
// Five 32-byte std140 slices: threshold, knee, destination extent,
|
|
3212
|
+
// level and padding. The level is selected by the graph pass.
|
|
3213
|
+
const downsampleParamsResult = runShimSyncStep(
|
|
3254
3214
|
() =>
|
|
3255
3215
|
rhiDevice.createBuffer({
|
|
3256
|
-
label: 'bloom-
|
|
3257
|
-
size:
|
|
3216
|
+
label: 'bloom-downsample-params-ubo',
|
|
3217
|
+
size: BLOOM_DOWNSAMPLE_PARAMS_BYTES,
|
|
3258
3218
|
usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,
|
|
3259
3219
|
mappedAtCreation: false,
|
|
3260
3220
|
}),
|
|
3261
3221
|
'webgpu-runtime-error',
|
|
3262
|
-
'createBuffer (bloom-
|
|
3222
|
+
'createBuffer (bloom-downsample params UBO) succeeded',
|
|
3263
3223
|
'check device.limits.maxUniformBufferBindingSize',
|
|
3264
3224
|
);
|
|
3265
|
-
if (!
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3225
|
+
if (!downsampleParamsResult.ok) throw downsampleParamsResult.error;
|
|
3226
|
+
bloomDownsampleParamsBufferHandle = adopt(
|
|
3227
|
+
'buffer',
|
|
3228
|
+
downsampleParamsResult.value,
|
|
3229
|
+
(value) => {
|
|
3230
|
+
rhiDevice.destroyBuffer(value);
|
|
3231
|
+
},
|
|
3232
|
+
);
|
|
3269
3233
|
}
|
|
3270
3234
|
|
|
3271
|
-
// Bloom
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
const blurBglResult = runShimSyncStep(
|
|
3235
|
+
// Bloom upsample: current/coarse textures + sampler + scatter slice.
|
|
3236
|
+
if (bloomUpsampleModule !== null && bloomSamplerHandle !== null) {
|
|
3237
|
+
const upsampleBglResult = runShimSyncStep(
|
|
3275
3238
|
() =>
|
|
3276
3239
|
rhiDevice.createBindGroupLayout({
|
|
3277
|
-
label: 'bloom-
|
|
3240
|
+
label: 'bloom-upsample-bgl',
|
|
3278
3241
|
entries: [
|
|
3279
3242
|
{
|
|
3280
3243
|
binding: 0,
|
|
@@ -3284,43 +3247,45 @@ export async function buildReadyWebGPU(
|
|
|
3284
3247
|
{
|
|
3285
3248
|
binding: 1,
|
|
3286
3249
|
visibility: GPU_SHADER_STAGE_FRAGMENT,
|
|
3287
|
-
|
|
3250
|
+
texture: { sampleType: 'float', viewDimension: '2d' },
|
|
3288
3251
|
},
|
|
3289
3252
|
{
|
|
3290
3253
|
binding: 2,
|
|
3291
3254
|
visibility: GPU_SHADER_STAGE_FRAGMENT,
|
|
3255
|
+
sampler: { type: 'filtering' },
|
|
3256
|
+
},
|
|
3257
|
+
{
|
|
3258
|
+
binding: 3,
|
|
3259
|
+
visibility: GPU_SHADER_STAGE_FRAGMENT,
|
|
3292
3260
|
buffer: { type: 'uniform' },
|
|
3293
3261
|
},
|
|
3294
3262
|
],
|
|
3295
3263
|
}),
|
|
3296
3264
|
'webgpu-runtime-error',
|
|
3297
|
-
'createBindGroupLayout(bloom-
|
|
3265
|
+
'createBindGroupLayout(bloom-upsample) succeeded',
|
|
3298
3266
|
'check device.limits.maxBindGroupsPerPipelineLayout',
|
|
3299
3267
|
);
|
|
3300
|
-
if (!
|
|
3301
|
-
|
|
3268
|
+
if (!upsampleBglResult.ok) throw upsampleBglResult.error;
|
|
3269
|
+
bloomUpsampleBglHandle = adopt('binding', upsampleBglResult.value, () => undefined);
|
|
3302
3270
|
|
|
3303
|
-
const
|
|
3271
|
+
const upsamplePlResult = runShimSyncStep(
|
|
3304
3272
|
() =>
|
|
3305
3273
|
rhiDevice.createPipelineLayout({
|
|
3306
|
-
label: 'bloom-
|
|
3307
|
-
bindGroupLayouts: [
|
|
3274
|
+
label: 'bloom-upsample-pl',
|
|
3275
|
+
bindGroupLayouts: [upsampleBglResult.value],
|
|
3308
3276
|
}),
|
|
3309
3277
|
'webgpu-runtime-error',
|
|
3310
|
-
'createPipelineLayout(bloom-
|
|
3311
|
-
'verify bloom-
|
|
3278
|
+
'createPipelineLayout(bloom-upsample) succeeded',
|
|
3279
|
+
'verify bloom-upsample BindGroupLayout matches shader @group(0) bindings',
|
|
3312
3280
|
);
|
|
3313
|
-
if (!
|
|
3314
|
-
adopt('binding',
|
|
3281
|
+
if (!upsamplePlResult.ok) throw upsamplePlResult.error;
|
|
3282
|
+
adopt('binding', upsamplePlResult.value, () => undefined);
|
|
3315
3283
|
|
|
3316
|
-
//
|
|
3317
|
-
// H and V share the same PSO descriptor — only per-axis texelSize UBO
|
|
3318
|
-
// distinguishes them at record time. getOrBuildPipeline cache-hit on the
|
|
3319
|
-
// second call returns the same handle (identical spec, identical PSO).
|
|
3284
|
+
// One pipeline serves every coarse-to-fine edge.
|
|
3320
3285
|
{
|
|
3321
|
-
const
|
|
3286
|
+
const upsampleSpec: PipelineSpec = {
|
|
3322
3287
|
shader: {
|
|
3323
|
-
id: 'forgeax::post::bloom-
|
|
3288
|
+
id: 'forgeax::post::bloom-upsample',
|
|
3324
3289
|
passKind: 'post-process',
|
|
3325
3290
|
variantSet: undefined,
|
|
3326
3291
|
},
|
|
@@ -3337,21 +3302,21 @@ export async function buildReadyWebGPU(
|
|
|
3337
3302
|
renderState: { cullMode: 'none' },
|
|
3338
3303
|
};
|
|
3339
3304
|
const modules = {
|
|
3340
|
-
vertex:
|
|
3341
|
-
fragment:
|
|
3342
|
-
layout:
|
|
3343
|
-
label: 'bloom-
|
|
3305
|
+
vertex: bloomUpsampleModule,
|
|
3306
|
+
fragment: bloomUpsampleModule,
|
|
3307
|
+
layout: upsamplePlResult.value,
|
|
3308
|
+
label: 'bloom-upsample-pipeline',
|
|
3344
3309
|
};
|
|
3345
3310
|
try {
|
|
3346
|
-
|
|
3347
|
-
|
|
3311
|
+
bloomUpsamplePipelineHandle = getOrBuildPipeline(
|
|
3312
|
+
upsampleSpec,
|
|
3348
3313
|
pipelineDeviceProvider,
|
|
3349
3314
|
pipelineCache,
|
|
3350
3315
|
modules,
|
|
3351
3316
|
) as RenderPipeline;
|
|
3352
|
-
|
|
3317
|
+
bloomUpsamplePipelineHandle = adopt(
|
|
3353
3318
|
'pipeline',
|
|
3354
|
-
|
|
3319
|
+
bloomUpsamplePipelineHandle,
|
|
3355
3320
|
() => undefined,
|
|
3356
3321
|
);
|
|
3357
3322
|
} catch (err) {
|
|
@@ -3359,47 +3324,26 @@ export async function buildReadyWebGPU(
|
|
|
3359
3324
|
throw new PipelineSpecError({
|
|
3360
3325
|
code: 'pipeline-build-failed',
|
|
3361
3326
|
detail: { cause: err },
|
|
3362
|
-
hint: 'createRenderPipeline (bloom-
|
|
3327
|
+
hint: 'createRenderPipeline (bloom-upsample fullscreen) failed; inspect gpuMessage',
|
|
3363
3328
|
});
|
|
3364
3329
|
}
|
|
3365
|
-
// V is cache-hit on the same spec (identical PSO; per-axis UBO differentiates at record time).
|
|
3366
|
-
bloomBlurVPipelineHandle = bloomBlurHPipelineHandle;
|
|
3367
3330
|
}
|
|
3368
3331
|
|
|
3369
|
-
//
|
|
3370
|
-
|
|
3371
|
-
// shared-buffer writeBuffer race made both passes blur vertically).
|
|
3372
|
-
const blurHParamsResult = runShimSyncStep(
|
|
3373
|
-
() =>
|
|
3374
|
-
rhiDevice.createBuffer({
|
|
3375
|
-
label: 'bloom-blur-h-params-ubo',
|
|
3376
|
-
size: BLUR_PARAMS_BYTES,
|
|
3377
|
-
usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,
|
|
3378
|
-
mappedAtCreation: false,
|
|
3379
|
-
}),
|
|
3380
|
-
'webgpu-runtime-error',
|
|
3381
|
-
'createBuffer (bloom-blur-h params UBO) succeeded',
|
|
3382
|
-
'check device.limits.maxUniformBufferBindingSize',
|
|
3383
|
-
);
|
|
3384
|
-
if (!blurHParamsResult.ok) throw blurHParamsResult.error;
|
|
3385
|
-
bloomBlurHParamsBufferHandle = adopt('buffer', blurHParamsResult.value, (value) => {
|
|
3386
|
-
rhiDevice.destroyBuffer(value);
|
|
3387
|
-
});
|
|
3388
|
-
|
|
3389
|
-
const blurVParamsResult = runShimSyncStep(
|
|
3332
|
+
// Four 16-byte std140 slices carry scatter for U0..U3.
|
|
3333
|
+
const upsampleParamsResult = runShimSyncStep(
|
|
3390
3334
|
() =>
|
|
3391
3335
|
rhiDevice.createBuffer({
|
|
3392
|
-
label: 'bloom-
|
|
3393
|
-
size:
|
|
3336
|
+
label: 'bloom-upsample-params-ubo',
|
|
3337
|
+
size: BLOOM_UPSAMPLE_PARAMS_BYTES,
|
|
3394
3338
|
usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,
|
|
3395
3339
|
mappedAtCreation: false,
|
|
3396
3340
|
}),
|
|
3397
3341
|
'webgpu-runtime-error',
|
|
3398
|
-
'createBuffer (bloom-
|
|
3342
|
+
'createBuffer (bloom-upsample params UBO) succeeded',
|
|
3399
3343
|
'check device.limits.maxUniformBufferBindingSize',
|
|
3400
3344
|
);
|
|
3401
|
-
if (!
|
|
3402
|
-
|
|
3345
|
+
if (!upsampleParamsResult.ok) throw upsampleParamsResult.error;
|
|
3346
|
+
bloomUpsampleParamsBufferHandle = adopt('buffer', upsampleParamsResult.value, (value) => {
|
|
3403
3347
|
rhiDevice.destroyBuffer(value);
|
|
3404
3348
|
});
|
|
3405
3349
|
}
|
|
@@ -3505,7 +3449,7 @@ export async function buildReadyWebGPU(
|
|
|
3505
3449
|
() =>
|
|
3506
3450
|
rhiDevice.createBuffer({
|
|
3507
3451
|
label: 'bloom-composite-params-ubo',
|
|
3508
|
-
size:
|
|
3452
|
+
size: BLOOM_COMPOSITE_PARAMS_BYTES,
|
|
3509
3453
|
usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,
|
|
3510
3454
|
mappedAtCreation: false,
|
|
3511
3455
|
}),
|
|
@@ -3526,17 +3470,15 @@ export async function buildReadyWebGPU(
|
|
|
3526
3470
|
bloomCandidateBundle = {
|
|
3527
3471
|
scope: candidateScope,
|
|
3528
3472
|
generation: bloomGeneration + 1,
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
bloomBlurVPipeline: bloomBlurVPipelineHandle,
|
|
3473
|
+
bloomDownsamplePipeline: bloomDownsamplePipelineHandle,
|
|
3474
|
+
bloomUpsamplePipeline: bloomUpsamplePipelineHandle,
|
|
3532
3475
|
bloomCompositePipeline: bloomCompositePipelineHandle,
|
|
3533
|
-
|
|
3534
|
-
|
|
3476
|
+
bloomDownsampleBindGroupLayout: bloomDownsampleBglHandle,
|
|
3477
|
+
bloomUpsampleBindGroupLayout: bloomUpsampleBglHandle,
|
|
3535
3478
|
bloomCompositeBindGroupLayout: bloomCompositeBglHandle,
|
|
3536
3479
|
bloomSampler: bloomSamplerHandle,
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
bloomBlurVParamsBuffer: bloomBlurVParamsBufferHandle,
|
|
3480
|
+
bloomDownsampleParamsBuffer: bloomDownsampleParamsBufferHandle,
|
|
3481
|
+
bloomUpsampleParamsBuffer: bloomUpsampleParamsBufferHandle,
|
|
3540
3482
|
bloomCompositeParamsBuffer: bloomCompositeParamsBufferHandle,
|
|
3541
3483
|
};
|
|
3542
3484
|
inspectBloomResources = (graph): BloomInspection => {
|
|
@@ -3550,6 +3492,10 @@ export async function buildReadyWebGPU(
|
|
|
3550
3492
|
return {
|
|
3551
3493
|
graphStatus: 'empty',
|
|
3552
3494
|
enabled: false,
|
|
3495
|
+
levelCount: 0,
|
|
3496
|
+
levelDimensions: [],
|
|
3497
|
+
downsamplePassCount: 0,
|
|
3498
|
+
upsamplePassCount: 0,
|
|
3553
3499
|
targetCount: 0,
|
|
3554
3500
|
targetBytes: 0,
|
|
3555
3501
|
resourceCount: 0,
|
|
@@ -3573,6 +3519,10 @@ export async function buildReadyWebGPU(
|
|
|
3573
3519
|
return {
|
|
3574
3520
|
graphStatus: active === undefined ? 'empty' : graphInspection.status,
|
|
3575
3521
|
enabled: active !== undefined,
|
|
3522
|
+
levelCount: active === undefined ? 0 : graphInspection.levelCount,
|
|
3523
|
+
levelDimensions: active === undefined ? [] : graphInspection.levelDimensions,
|
|
3524
|
+
downsamplePassCount: active === undefined ? 0 : graphInspection.downsamplePassCount,
|
|
3525
|
+
upsamplePassCount: active === undefined ? 0 : graphInspection.upsamplePassCount,
|
|
3576
3526
|
targetCount: active === undefined ? 0 : graphInspection.targetCount,
|
|
3577
3527
|
targetBytes: active === undefined ? 0 : graphInspection.targetBytes,
|
|
3578
3528
|
resourceCount: ownedBundles.reduce(
|
|
@@ -3583,7 +3533,14 @@ export async function buildReadyWebGPU(
|
|
|
3583
3533
|
encodeCount: active === undefined ? 0 : receipts.encodeCount,
|
|
3584
3534
|
bindGroupCount: active === undefined ? 0 : receipts.bindGroupCount,
|
|
3585
3535
|
uploadCount: active === undefined ? 0 : receipts.uploadCount,
|
|
3586
|
-
|
|
3536
|
+
// The graph owns the target allocations. Use its validated
|
|
3537
|
+
// descriptor byte sum for the active child; zero is reserved for
|
|
3538
|
+
// an absent/invalid current graph, never a placeholder for a
|
|
3539
|
+
// live Bloom allocation.
|
|
3540
|
+
residentChildBytes:
|
|
3541
|
+
active === undefined || graphInspection.status !== 'valid'
|
|
3542
|
+
? 0
|
|
3543
|
+
: graphInspection.targetBytes,
|
|
3587
3544
|
generation: selected?.generation ?? 0,
|
|
3588
3545
|
state,
|
|
3589
3546
|
};
|
|
@@ -3660,17 +3617,15 @@ export async function buildReadyWebGPU(
|
|
|
3660
3617
|
commitBloomResources = undefined;
|
|
3661
3618
|
discardBloomResources = undefined;
|
|
3662
3619
|
drainBloomResources = undefined;
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
bloomBlurVPipelineHandle = null;
|
|
3620
|
+
bloomDownsamplePipelineHandle = null;
|
|
3621
|
+
bloomUpsamplePipelineHandle = null;
|
|
3666
3622
|
bloomCompositePipelineHandle = null;
|
|
3667
|
-
|
|
3668
|
-
|
|
3623
|
+
bloomDownsampleBglHandle = null;
|
|
3624
|
+
bloomUpsampleBglHandle = null;
|
|
3669
3625
|
bloomCompositeBglHandle = null;
|
|
3670
3626
|
bloomSamplerHandle = null;
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
bloomBlurVParamsBufferHandle = null;
|
|
3627
|
+
bloomDownsampleParamsBufferHandle = null;
|
|
3628
|
+
bloomUpsampleParamsBufferHandle = null;
|
|
3674
3629
|
bloomCompositeParamsBufferHandle = null;
|
|
3675
3630
|
throw cause;
|
|
3676
3631
|
}
|
|
@@ -4039,24 +3994,17 @@ export async function buildReadyWebGPU(
|
|
|
4039
3994
|
shadowLightSpaceMatrix: null,
|
|
4040
3995
|
shadowCsmLightViewProj: null,
|
|
4041
3996
|
shadowCsmSelection: null,
|
|
4042
|
-
//
|
|
4043
|
-
//
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
// (ensureLazyTexture, slot width/height tracking for size-drift rebuild).
|
|
4047
|
-
// BindGroup caches survive until the intermediate view is invalidated
|
|
4048
|
-
// by a resize (width/height drift forces null).
|
|
4049
|
-
bloomBrightPipeline: null,
|
|
4050
|
-
bloomBlurHPipeline: null,
|
|
4051
|
-
bloomBlurVPipeline: null,
|
|
3997
|
+
// Multiscale Bloom pipeline handles are generation-owned by the ready
|
|
3998
|
+
// builder; graph targets are frame-owned and are not stored here.
|
|
3999
|
+
bloomDownsamplePipeline: null,
|
|
4000
|
+
bloomUpsamplePipeline: null,
|
|
4052
4001
|
bloomCompositePipeline: null,
|
|
4053
|
-
|
|
4054
|
-
|
|
4002
|
+
bloomDownsampleBindGroupLayout: null,
|
|
4003
|
+
bloomUpsampleBindGroupLayout: null,
|
|
4055
4004
|
bloomCompositeBindGroupLayout: null,
|
|
4056
4005
|
bloomSampler: null,
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
bloomBlurVParamsBuffer: null,
|
|
4006
|
+
bloomDownsampleParamsBuffer: null,
|
|
4007
|
+
bloomUpsampleParamsBuffer: null,
|
|
4060
4008
|
bloomCompositeParamsBuffer: null,
|
|
4061
4009
|
ensureBloomResources: ensureBloomResourcesStable,
|
|
4062
4010
|
getBloomResources: getBloomResourcesStable,
|
|
@@ -4068,18 +4016,6 @@ export async function buildReadyWebGPU(
|
|
|
4068
4016
|
retireBloomResources: retireBloomResourcesStable,
|
|
4069
4017
|
drainBloomResources: drainBloomResourcesStable,
|
|
4070
4018
|
inspectBloomResources: inspectBloomResourcesStable,
|
|
4071
|
-
bloomBrightTexture: null,
|
|
4072
|
-
bloomBrightView: null,
|
|
4073
|
-
bloomBrightWidth: 0,
|
|
4074
|
-
bloomBrightHeight: 0,
|
|
4075
|
-
bloomBlurHTexture: null,
|
|
4076
|
-
bloomBlurHView: null,
|
|
4077
|
-
bloomBlurHWidth: 0,
|
|
4078
|
-
bloomBlurHHeight: 0,
|
|
4079
|
-
bloomBlurVTexture: null,
|
|
4080
|
-
bloomBlurVView: null,
|
|
4081
|
-
bloomBlurVWidth: 0,
|
|
4082
|
-
bloomBlurVHeight: 0,
|
|
4083
4019
|
// feat-20260612-hdrp-ssao M6 / w26 + M8 / w38: SSAO pipeline slots.
|
|
4084
4020
|
ssaoCalcPipeline: ssaoCalcPipelineHandle,
|
|
4085
4021
|
ssaoBlurPipeline: ssaoBlurPipelineHandle,
|