@forgeax/engine-vfx-render 0.1.4 → 0.1.6
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 +6 -12
- package/dist/.tsbuildinfo +1 -1
- package/dist/feature/gpu-particle-feature.d.ts +20 -26
- package/dist/feature/gpu-particle-feature.d.ts.map +1 -1
- package/dist/feature/particle-resources.d.ts +0 -3
- package/dist/feature/particle-resources.d.ts.map +1 -1
- package/dist/feature/stage-plan.d.ts +1 -1
- package/dist/feature/stage-plan.d.ts.map +1 -1
- package/dist/host/vfx-runtime-host.d.ts +6 -3
- package/dist/host/vfx-runtime-host.d.ts.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +452 -720
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
- package/src/__tests__/billboard-advanced.integration.test.ts +0 -23
- package/src/__tests__/fog-producer.integration.test.ts +4 -3
- package/src/__tests__/gpu-host.integration.test.ts +54 -120
- package/src/__tests__/particle-resources.unit.test.ts +0 -9
- package/src/__tests__/stage-plan.integration.test.ts +132 -0
- package/src/feature/gpu-particle-feature.ts +482 -888
- package/src/feature/particle-resources.ts +0 -8
- package/src/feature/stage-plan.ts +4 -1
- package/src/host/vfx-runtime-host.ts +34 -17
- package/src/index.ts +0 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { RenderFeatureMaterialShaderBindingContract } from '@forgeax/engine-render';
|
|
2
1
|
import {
|
|
3
2
|
err,
|
|
4
3
|
type MaterialAsset,
|
|
@@ -157,13 +156,6 @@ export function particleMaterialPass(
|
|
|
157
156
|
};
|
|
158
157
|
}
|
|
159
158
|
|
|
160
|
-
/** Scene-depth is a shader binding contract, not a renderer-kind convention. */
|
|
161
|
-
export function particleMaterialUsesSceneDepth(
|
|
162
|
-
contract: RenderFeatureMaterialShaderBindingContract | 'view-with-resource',
|
|
163
|
-
): boolean {
|
|
164
|
-
return contract === 'group-0-resource' || contract === 'view-with-resource';
|
|
165
|
-
}
|
|
166
|
-
|
|
167
159
|
/** True when the authored particle shader consumes the standard material bind group. */
|
|
168
160
|
export function particleMaterialUsesBindings(material: MaterialAsset | undefined): boolean {
|
|
169
161
|
return (material?.parameters?.length ?? 0) > 0;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import type { RenderFeatureGpuBindingsRef, RenderFeatureGpuDispatch } from '@forgeax/engine-render';
|
|
2
1
|
import type { VfxGpuStageReflection } from '@forgeax/engine-vfx';
|
|
2
|
+
import type {
|
|
3
|
+
RenderFeatureGpuBindingsRef,
|
|
4
|
+
RenderFeatureGpuDispatch,
|
|
5
|
+
} from '../../../render/src/features/prepared-gpu-work.js';
|
|
3
6
|
|
|
4
7
|
const MANAGED_STAGES = new Set(['spawn', 'update', 'scan', 'compact']);
|
|
5
8
|
const RESOURCE_NAMES = new Set([
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
1
|
+
import type { AssetRegistry as LegacyAssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
2
|
+
import type { AssetRegistry as CoreAssetRegistry } from '@forgeax/engine-assets-runtime/internal';
|
|
2
3
|
import {
|
|
3
4
|
type AssetRegistryResolver,
|
|
4
5
|
getAssetRegistryResolver,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
VFX_GPU_RUNTIME_RESOURCE_KEY,
|
|
22
23
|
type VfxGpuRuntime,
|
|
23
24
|
vfxGpuEffectContribution,
|
|
25
|
+
vfxGpuEffectPackLoader,
|
|
24
26
|
vfxGpuRuntimePlugin,
|
|
25
27
|
} from '@forgeax/engine-vfx';
|
|
26
28
|
import type { ParticleRenderCameraSource } from '../feature/camera.js';
|
|
@@ -30,6 +32,8 @@ import {
|
|
|
30
32
|
type VfxDataInterfaceRegistry,
|
|
31
33
|
} from './data-interface-providers.js';
|
|
32
34
|
|
|
35
|
+
type AssetRegistry = LegacyAssetRegistry | CoreAssetRegistry;
|
|
36
|
+
|
|
33
37
|
export interface VfxRuntimeHostOptions {
|
|
34
38
|
readonly camera: ParticleRenderCameraSource;
|
|
35
39
|
readonly maxQueuedTicks?: number;
|
|
@@ -108,8 +112,8 @@ export interface VfxRuntimeHost {
|
|
|
108
112
|
}): Promise<Result<{ readonly state: 'detached' | 'not-attached' }, VfxRuntimeHostError>>;
|
|
109
113
|
}
|
|
110
114
|
|
|
111
|
-
/** Install the VFX owner decoder into the
|
|
112
|
-
export function installVfxRuntimeDecoder(registry:
|
|
115
|
+
/** Install the VFX owner decoder into the core registry. */
|
|
116
|
+
export function installVfxRuntimeDecoder(registry: CoreAssetRegistry): AssetDecoderLease {
|
|
113
117
|
return registry.installDecoder(vfxGpuEffectContribution.kind, vfxGpuEffectContribution.decoder);
|
|
114
118
|
}
|
|
115
119
|
|
|
@@ -142,7 +146,7 @@ function controlFailure(
|
|
|
142
146
|
}
|
|
143
147
|
|
|
144
148
|
export function createVfxRuntimeHost(options: VfxRuntimeHostOptions): VfxRuntimeHost {
|
|
145
|
-
const
|
|
149
|
+
const registries = new WeakSet<AssetRegistry>();
|
|
146
150
|
const worlds = new WeakMap<
|
|
147
151
|
World,
|
|
148
152
|
{
|
|
@@ -169,12 +173,19 @@ export function createVfxRuntimeHost(options: VfxRuntimeHostOptions): VfxRuntime
|
|
|
169
173
|
const key = `${kind}:${guid.toLowerCase()}`;
|
|
170
174
|
const cached = attached.renderAssets.get(key);
|
|
171
175
|
if (cached?.kind === kind) return cached as Kind extends 'material' ? MaterialAsset : MeshAsset;
|
|
176
|
+
if ('lookup' in attached.assets) {
|
|
177
|
+
const legacy = attached.assets.lookup(guid);
|
|
178
|
+
if (legacy?.kind === kind) {
|
|
179
|
+
attached.renderAssets.set(key, legacy);
|
|
180
|
+
return legacy as Kind extends 'material' ? MaterialAsset : MeshAsset;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
172
183
|
const resolved = attached.resolver?.lookup<MaterialAsset | MeshAsset>(guid);
|
|
173
184
|
if (resolved?.kind === kind) {
|
|
174
185
|
attached.renderAssets.set(key, resolved);
|
|
175
186
|
return resolved as Kind extends 'material' ? MaterialAsset : MeshAsset;
|
|
176
187
|
}
|
|
177
|
-
if (!attached.pendingRenderAssets.has(key)) {
|
|
188
|
+
if ('load' in attached.assets && !attached.pendingRenderAssets.has(key)) {
|
|
178
189
|
const epoch = attached.catalogEpoch;
|
|
179
190
|
const request = attached.assets
|
|
180
191
|
.load(guid, kind)
|
|
@@ -314,15 +325,20 @@ export function createVfxRuntimeHost(options: VfxRuntimeHostOptions): VfxRuntime
|
|
|
314
325
|
dataInterfaces.resolve(requirements, generation),
|
|
315
326
|
attachWorld: async ({ world, assets }) => {
|
|
316
327
|
if (worlds.has(world)) return ok({ state: 'already-attached' });
|
|
317
|
-
if (!
|
|
328
|
+
if (!registries.has(assets)) {
|
|
318
329
|
try {
|
|
319
|
-
|
|
330
|
+
if ('installDecoder' in assets) {
|
|
331
|
+
assets.installDecoder(vfxGpuEffectContribution.kind, vfxGpuEffectContribution.decoder);
|
|
332
|
+
} else {
|
|
333
|
+
assets.loaders.registerPackLoader(vfxGpuEffectPackLoader);
|
|
334
|
+
}
|
|
335
|
+
registries.add(assets);
|
|
320
336
|
} catch (cause) {
|
|
321
337
|
return err(
|
|
322
338
|
failure(
|
|
323
339
|
'vfx-host-loader-install-failed',
|
|
324
|
-
'the VFX
|
|
325
|
-
'remove a conflicting particle-effect
|
|
340
|
+
'the v2 VFX loader to be registered once',
|
|
341
|
+
'remove a conflicting particle-effect loader and retry attachWorld',
|
|
326
342
|
cause,
|
|
327
343
|
),
|
|
328
344
|
);
|
|
@@ -346,10 +362,12 @@ export function createVfxRuntimeHost(options: VfxRuntimeHostOptions): VfxRuntime
|
|
|
346
362
|
);
|
|
347
363
|
}
|
|
348
364
|
let resolver: AssetRegistryResolver | undefined;
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
365
|
+
if ('installDecoder' in assets) {
|
|
366
|
+
try {
|
|
367
|
+
resolver = getAssetRegistryResolver(assets);
|
|
368
|
+
} catch {
|
|
369
|
+
resolver = undefined;
|
|
370
|
+
}
|
|
353
371
|
}
|
|
354
372
|
const attached = {
|
|
355
373
|
assets,
|
|
@@ -359,14 +377,13 @@ export function createVfxRuntimeHost(options: VfxRuntimeHostOptions): VfxRuntime
|
|
|
359
377
|
renderAssets: new Map<string, MaterialAsset | MeshAsset>(),
|
|
360
378
|
pendingRenderAssets: new Map<string, Promise<void>>(),
|
|
361
379
|
catalogEpoch:
|
|
362
|
-
|
|
380
|
+
'snapshot' in assets && typeof assets.snapshot === 'function'
|
|
363
381
|
? assets.snapshot().epoch
|
|
364
382
|
: 0,
|
|
365
383
|
unsubscribeAssets: () => {},
|
|
366
384
|
};
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
attached.unsubscribeAssets = subscribe((snapshot) => {
|
|
385
|
+
if ('subscribe' in assets && typeof assets.subscribe === 'function') {
|
|
386
|
+
attached.unsubscribeAssets = assets.subscribe((snapshot) => {
|
|
370
387
|
if (snapshot.epoch === attached.catalogEpoch) return;
|
|
371
388
|
attached.catalogEpoch = snapshot.epoch;
|
|
372
389
|
attached.renderAssets.clear();
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,6 @@ export {
|
|
|
10
10
|
VFX_EVENT_COUNTER_BYTES,
|
|
11
11
|
VFX_EVENT_INPUT_BYTES,
|
|
12
12
|
} from './feature/event-resources.js';
|
|
13
|
-
export type { VfxGpuRenderObservation } from './feature/gpu-particle-feature.js';
|
|
14
13
|
export {
|
|
15
14
|
createVfxRenderInspectSnapshot,
|
|
16
15
|
gpuParticleRenderFeature,
|