@onerjs/core 8.51.3 → 8.51.4
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/Animations/animationGroup.d.ts +2 -1
- package/Animations/animationGroup.js +3 -2
- package/Animations/animationGroup.js.map +1 -1
- package/Engines/WebGPU/webgpuSnapshotRendering.js +7 -3
- package/Engines/WebGPU/webgpuSnapshotRendering.js.map +1 -1
- package/Events/deviceInputEvents.d.ts +5 -0
- package/Events/deviceInputEvents.js.map +1 -1
- package/FlowGraph/Blocks/Data/flowGraphIsKeyPressedBlock.d.ts +65 -0
- package/FlowGraph/Blocks/Data/flowGraphIsKeyPressedBlock.js +74 -0
- package/FlowGraph/Blocks/Data/flowGraphIsKeyPressedBlock.js.map +1 -0
- package/FlowGraph/Blocks/Data/index.d.ts +1 -0
- package/FlowGraph/Blocks/Data/index.js +1 -0
- package/FlowGraph/Blocks/Data/index.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphKeyDownEventBlock.d.ts +39 -0
- package/FlowGraph/Blocks/Event/flowGraphKeyDownEventBlock.js +42 -0
- package/FlowGraph/Blocks/Event/flowGraphKeyDownEventBlock.js.map +1 -0
- package/FlowGraph/Blocks/Event/flowGraphKeyUpEventBlock.d.ts +19 -0
- package/FlowGraph/Blocks/Event/flowGraphKeyUpEventBlock.js +25 -0
- package/FlowGraph/Blocks/Event/flowGraphKeyUpEventBlock.js.map +1 -0
- package/FlowGraph/Blocks/Event/flowGraphKeyboardEventBlock.d.ts +64 -0
- package/FlowGraph/Blocks/Event/flowGraphKeyboardEventBlock.js +50 -0
- package/FlowGraph/Blocks/Event/flowGraphKeyboardEventBlock.js.map +1 -0
- package/FlowGraph/Blocks/Event/index.d.ts +3 -0
- package/FlowGraph/Blocks/Event/index.js +3 -0
- package/FlowGraph/Blocks/Event/index.js.map +1 -1
- package/FlowGraph/Blocks/flowGraphBlockFactory.js +7 -0
- package/FlowGraph/Blocks/flowGraphBlockFactory.js.map +1 -1
- package/FlowGraph/Blocks/flowGraphBlockNames.d.ts +3 -0
- package/FlowGraph/Blocks/flowGraphBlockNames.js +3 -0
- package/FlowGraph/Blocks/flowGraphBlockNames.js.map +1 -1
- package/FlowGraph/flowGraph.d.ts +6 -0
- package/FlowGraph/flowGraph.js +10 -1
- package/FlowGraph/flowGraph.js.map +1 -1
- package/FlowGraph/flowGraphContext.d.ts +8 -0
- package/FlowGraph/flowGraphContext.js.map +1 -1
- package/FlowGraph/flowGraphEventType.d.ts +2 -0
- package/FlowGraph/flowGraphEventType.js +2 -0
- package/FlowGraph/flowGraphEventType.js.map +1 -1
- package/FlowGraph/flowGraphSceneEventCoordinator.d.ts +14 -0
- package/FlowGraph/flowGraphSceneEventCoordinator.js +56 -0
- package/FlowGraph/flowGraphSceneEventCoordinator.js.map +1 -1
- package/FlowGraph/utils.d.ts +7 -0
- package/FlowGraph/utils.js +8 -0
- package/FlowGraph/utils.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +6 -0
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.js +30 -8
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.js.map +1 -1
- package/Misc/snapshotRenderingHelper.d.ts +4 -2
- package/Misc/snapshotRenderingHelper.js +33 -22
- package/Misc/snapshotRenderingHelper.js.map +1 -1
- package/Particles/thinParticleSystem.d.ts +6 -1
- package/Particles/thinParticleSystem.js +23 -6
- package/Particles/thinParticleSystem.js.map +1 -1
- package/package.json +1 -1
|
@@ -97,8 +97,9 @@ export declare class SnapshotRenderingHelper {
|
|
|
97
97
|
* to degenerate triangles via zero-fill. This keeps the recorded GPU bundle's draw call valid every frame, while
|
|
98
98
|
* the live particle data is uploaded to the bundle-referenced vertex buffer through the normal `animate()` path.
|
|
99
99
|
*
|
|
100
|
-
* The helper additionally updates view/projection (and `eyePosition`/`invView`
|
|
101
|
-
* particle system's draw wrappers each frame,
|
|
100
|
+
* The helper additionally advances the particle simulation and updates view/projection (and `eyePosition`/`invView`
|
|
101
|
+
* for billboard modes) into the particle system's draw wrappers each frame, because FAST snapshot replay skips the
|
|
102
|
+
* normal scene particle evaluation path after the bundle is recorded.
|
|
102
103
|
*
|
|
103
104
|
* Notes:
|
|
104
105
|
* - Call this BEFORE `enableSnapshotRendering()` so the recording sees the correct draw count.
|
|
@@ -109,6 +110,7 @@ export declare class SnapshotRenderingHelper {
|
|
|
109
110
|
* @param particleSystem The particle system to fix
|
|
110
111
|
*/
|
|
111
112
|
fixParticleSystem(particleSystem: IParticleSystem): void;
|
|
113
|
+
private _updateFixedCapacityParticleSystem;
|
|
112
114
|
private _particleSystemUpdateEffects;
|
|
113
115
|
private _particleSystemBillboardFlags;
|
|
114
116
|
private _particleSystemDirectMatrixUpdate;
|
|
@@ -56,7 +56,7 @@ export class SnapshotRenderingHelper {
|
|
|
56
56
|
}
|
|
57
57
|
this._log("onResize", "end");
|
|
58
58
|
});
|
|
59
|
-
this._scene.onBeforeRenderObservable.add(() => {
|
|
59
|
+
this._onBeforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => {
|
|
60
60
|
if (!this._fastSnapshotRenderingEnabled) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
@@ -107,8 +107,9 @@ export class SnapshotRenderingHelper {
|
|
|
107
107
|
// Handles fixed-capacity particle systems
|
|
108
108
|
if (scene.particleSystems && camera) {
|
|
109
109
|
for (const ps of scene.particleSystems) {
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
const particleSystem = ps;
|
|
111
|
+
if (particleSystem._useFixedCapacityForSnapshot) {
|
|
112
|
+
this._updateFixedCapacityParticleSystem(particleSystem, camera);
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
}
|
|
@@ -343,8 +344,9 @@ export class SnapshotRenderingHelper {
|
|
|
343
344
|
* to degenerate triangles via zero-fill. This keeps the recorded GPU bundle's draw call valid every frame, while
|
|
344
345
|
* the live particle data is uploaded to the bundle-referenced vertex buffer through the normal `animate()` path.
|
|
345
346
|
*
|
|
346
|
-
* The helper additionally updates view/projection (and `eyePosition`/`invView`
|
|
347
|
-
* particle system's draw wrappers each frame,
|
|
347
|
+
* The helper additionally advances the particle simulation and updates view/projection (and `eyePosition`/`invView`
|
|
348
|
+
* for billboard modes) into the particle system's draw wrappers each frame, because FAST snapshot replay skips the
|
|
349
|
+
* normal scene particle evaluation path after the bundle is recorded.
|
|
348
350
|
*
|
|
349
351
|
* Notes:
|
|
350
352
|
* - Call this BEFORE `enableSnapshotRendering()` so the recording sees the correct draw count.
|
|
@@ -363,20 +365,31 @@ export class SnapshotRenderingHelper {
|
|
|
363
365
|
return;
|
|
364
366
|
}
|
|
365
367
|
const ps = particleSystem;
|
|
366
|
-
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
ps.useFixedCapacityForSnapshot = true;
|
|
368
|
+
const fixedCapacityInitialized = ps._initFixedCapacitySnapshotData();
|
|
370
369
|
// The recorded bundle bakes in the draw-call vertex/instance count. If snapshot rendering is already active
|
|
371
370
|
// (or in the process of being enabled) when we flip the flag, the bundle was recorded with the live particle
|
|
372
371
|
// count and is now stale. Cycle disable/enable so the next recording picks up the fixed-capacity draw count.
|
|
373
|
-
if (this._fastSnapshotRenderingEnabled || this._isEnabling) {
|
|
372
|
+
if (fixedCapacityInitialized && (this._fastSnapshotRenderingEnabled || this._isEnabling)) {
|
|
374
373
|
Logger.Warn(`SnapshotRenderingHelper.fixParticleSystem("${particleSystem.name}") was called after snapshot rendering was enabled. ` +
|
|
375
374
|
`Forcing a re-record so the bundle uses the fixed-capacity draw count. Call fixParticleSystem before enableSnapshotRendering to avoid this.`);
|
|
376
375
|
this.disableSnapshotRendering("fixParticleSystem auto-recover");
|
|
377
376
|
this.enableSnapshotRendering("fixParticleSystem auto-recover");
|
|
378
377
|
}
|
|
379
378
|
}
|
|
379
|
+
_updateFixedCapacityParticleSystem(ps, camera) {
|
|
380
|
+
if (!this._scene.particlesEnabled || !ps.isStarted() || !ps.emitter) {
|
|
381
|
+
ps._clearFixedCapacitySnapshotData();
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const emitter = ps.emitter;
|
|
385
|
+
if (!emitter.position || emitter.isEnabled?.()) {
|
|
386
|
+
ps.animate();
|
|
387
|
+
this._particleSystemUpdateEffects(ps, camera);
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
ps._clearFixedCapacitySnapshotData();
|
|
391
|
+
}
|
|
392
|
+
}
|
|
380
393
|
_particleSystemUpdateEffects(ps, camera) {
|
|
381
394
|
const drawWrappers = ps._drawWrappers;
|
|
382
395
|
if (!drawWrappers) {
|
|
@@ -386,31 +399,24 @@ export class SnapshotRenderingHelper {
|
|
|
386
399
|
const projectionMatrix = ps.defaultProjectionMatrix ?? camera.getProjectionMatrix();
|
|
387
400
|
// Compute invView lazily once per system per frame, only if any draw wrapper actually needs it.
|
|
388
401
|
let invViewMatrix = null;
|
|
389
|
-
const getInvView = () => {
|
|
390
|
-
if (!invViewMatrix) {
|
|
391
|
-
invViewMatrix = TmpVectors.Matrix[0];
|
|
392
|
-
viewMatrix.invertToRef(invViewMatrix);
|
|
393
|
-
}
|
|
394
|
-
return invViewMatrix;
|
|
395
|
-
};
|
|
396
402
|
for (const perPass of drawWrappers) {
|
|
397
403
|
if (!perPass) {
|
|
398
404
|
continue;
|
|
399
405
|
}
|
|
400
406
|
for (const dw of perPass) {
|
|
401
|
-
this._particleSystemDirectMatrixUpdate(dw, viewMatrix, projectionMatrix, camera,
|
|
407
|
+
invViewMatrix = this._particleSystemDirectMatrixUpdate(dw, viewMatrix, projectionMatrix, camera, invViewMatrix);
|
|
402
408
|
}
|
|
403
409
|
}
|
|
404
410
|
}
|
|
405
|
-
_particleSystemDirectMatrixUpdate(dw, viewMatrix, projectionMatrix, camera,
|
|
411
|
+
_particleSystemDirectMatrixUpdate(dw, viewMatrix, projectionMatrix, camera, invViewMatrix) {
|
|
406
412
|
const effect = dw?.effect;
|
|
407
413
|
if (!effect) {
|
|
408
|
-
return;
|
|
414
|
+
return invViewMatrix;
|
|
409
415
|
}
|
|
410
416
|
const dataBuffer = dw.drawContext.buffers["LeftOver"];
|
|
411
417
|
const ubLeftOver = effect._pipelineContext?.uniformBuffer;
|
|
412
418
|
if (!dataBuffer || !ubLeftOver || !ubLeftOver.setDataBuffer(dataBuffer)) {
|
|
413
|
-
return;
|
|
419
|
+
return invViewMatrix;
|
|
414
420
|
}
|
|
415
421
|
effect.setMatrix("view", viewMatrix);
|
|
416
422
|
effect.setMatrix("projection", projectionMatrix);
|
|
@@ -424,9 +430,14 @@ export class SnapshotRenderingHelper {
|
|
|
424
430
|
effect.setVector3("eyePosition", camera.globalPosition);
|
|
425
431
|
}
|
|
426
432
|
if (flags.billboardAll) {
|
|
427
|
-
|
|
433
|
+
if (!invViewMatrix) {
|
|
434
|
+
invViewMatrix = TmpVectors.Matrix[0];
|
|
435
|
+
viewMatrix.invertToRef(invViewMatrix);
|
|
436
|
+
}
|
|
437
|
+
effect.setMatrix("invView", invViewMatrix);
|
|
428
438
|
}
|
|
429
439
|
ubLeftOver.update();
|
|
440
|
+
return invViewMatrix;
|
|
430
441
|
}
|
|
431
442
|
_executeAtFrame(frameId, func, mode = "whenEnabled") {
|
|
432
443
|
const callback = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshotRenderingHelper.js","sourceRoot":"","sources":["../../../../dev/core/src/Misc/snapshotRenderingHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n type AbstractEngine,\r\n type AbstractMesh,\r\n type EffectLayer,\r\n type Mesh,\r\n type Nullable,\r\n type Observer,\r\n type Scene,\r\n type WebGPUDrawContext,\r\n type WebGPUShaderProcessor,\r\n type WebGPUPipelineContext,\r\n type GaussianSplattingMesh,\r\n type DrawWrapper,\r\n type Camera,\r\n type SpriteManager,\r\n type IParticleSystem,\r\n type ParticleSystem,\r\n type Matrix,\r\n} from \"core/index\";\r\n\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { BindMorphTargetParameters } from \"core/Materials/materialHelper.functions\";\r\nimport { ScenePerformancePriority } from \"core/scene\";\r\nimport { TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { FrameGraphBaseLayerTask } from \"../FrameGraph/Tasks/Layers/baseLayerTask\";\r\nimport { FrameGraphUtils } from \"../FrameGraph/frameGraphUtils\";\r\n\r\n/**\r\n * Options for the snapshot rendering helper\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface SnapshotRenderingHelpersOptions {\r\n /**\r\n * Maximum number of influences for morph target managers\r\n * In FAST snapshot mode, the number of influences must be fixed and cannot change from one frame to the next.\r\n * morphTargetsNumMaxInfluences is the maximum number of non-zero influences allowed in a morph target manager.\r\n * The final value defined for a morph target manager is: Math.min(morphTargetManager.numTargets, morphTargetsNumMaxInfluences)\r\n * Default: 20\r\n */\r\n morphTargetsNumMaxInfluences?: number;\r\n}\r\n\r\n/**\r\n * A helper class to simplify work with FAST snapshot mode (WebGPU only - can be used in WebGL too, but won't do anything).\r\n */\r\nexport class SnapshotRenderingHelper {\r\n private readonly _engine: AbstractEngine;\r\n private readonly _scene: Scene;\r\n private readonly _options: SnapshotRenderingHelpersOptions;\r\n private readonly _onBeforeRenderObserver: Nullable<Observer<Scene>>;\r\n private _onBeforeRenderObserverUpdateLayer: Nullable<Observer<Scene>>;\r\n private readonly _onResizeObserver: Nullable<Observer<AbstractEngine>>;\r\n private _disableRenderingRefCount = 0;\r\n private _currentPerformancePriorityMode = ScenePerformancePriority.BackwardCompatible;\r\n private _pendingCurrentPerformancePriorityMode?: ScenePerformancePriority;\r\n private _isEnabling = false;\r\n private _enableCancelFunctions: Map<() => void, () => void> = new Map(); // first function is the callback, second function is the cancel function\r\n private _disableCancelFunctions: Map<() => void, () => void> = new Map(); // same as above\r\n\r\n /**\r\n * Indicates if debug logs should be displayed\r\n */\r\n public showDebugLogs = false;\r\n\r\n /**\r\n * Creates a new snapshot rendering helper\r\n * Note that creating an instance of the helper will set the snapshot rendering mode to SNAPSHOTRENDERING_FAST but will not enable snapshot rendering (engine.snapshotRendering is not updated).\r\n * Note also that fixMeshes() is called as part of the construction\r\n * @param scene The scene to use the helper in\r\n * @param options The options for the helper\r\n */\r\n constructor(scene: Scene, options?: SnapshotRenderingHelpersOptions) {\r\n this._scene = scene;\r\n this._engine = scene.getEngine();\r\n\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n this._options = {\r\n morphTargetsNumMaxInfluences: 20,\r\n ...options,\r\n };\r\n\r\n this._engine.snapshotRenderingMode = Constants.SNAPSHOTRENDERING_FAST;\r\n\r\n this.fixMeshes();\r\n\r\n this._onResizeObserver = this._engine.onResizeObservable.add(() => {\r\n this._log(\"onResize\", \"start\");\r\n\r\n // enableSnapshotRendering() will delay the actual enabling of snapshot rendering by at least a frame, so these two lines are not redundant!\r\n if (this._fastSnapshotRenderingEnabled) {\r\n this.disableSnapshotRendering();\r\n this.enableSnapshotRendering();\r\n } else if (this._isEnabling) {\r\n // We are in the process of enabling snapshot rendering, but the engine got resized before we could actually enable it:\r\n // * cancel all \"enable\" pending callbacks\r\n // * increase the ref count to balance the decrease that enableSnapshotRendering() will do\r\n // * call enableSnapshotRendering() again to restart the enabling process\r\n this._enableCancelFunctions.forEach((cancel) => cancel());\r\n this._enableCancelFunctions.clear();\r\n this._disableRenderingRefCount++;\r\n this.enableSnapshotRendering();\r\n }\r\n\r\n this._log(\"onResize\", \"end\");\r\n });\r\n\r\n this._scene.onBeforeRenderObservable.add(() => {\r\n if (!this._fastSnapshotRenderingEnabled) {\r\n return;\r\n }\r\n\r\n // Animates skeletons\r\n for (const skeleton of scene.skeletons) {\r\n skeleton.prepare(true);\r\n }\r\n\r\n // Handles meshes\r\n for (const mesh of scene.meshes) {\r\n if (mesh.infiniteDistance) {\r\n mesh.transferToEffect(mesh.computeWorldMatrix(true));\r\n }\r\n\r\n if (mesh.skeleton) {\r\n mesh.transferToEffect(mesh.computeWorldMatrix(true));\r\n }\r\n\r\n if (mesh.getClassName() === \"GaussianSplattingMesh\") {\r\n (mesh as GaussianSplattingMesh)._postToWorker();\r\n }\r\n\r\n if (mesh.morphTargetManager && mesh.subMeshes) {\r\n // Make sure morph target animations work\r\n for (const subMesh of mesh.subMeshes) {\r\n const dw = subMesh._drawWrapper;\r\n const effect = dw.effect;\r\n if (effect) {\r\n const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n mesh.morphTargetManager._bind(effect);\r\n BindMorphTargetParameters(mesh, effect);\r\n ubLeftOver.update();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Handles sprite renderers\r\n let camera = scene.activeCamera;\r\n if (scene.frameGraph) {\r\n camera = FrameGraphUtils.FindMainCamera(scene.frameGraph) || camera;\r\n }\r\n if (scene.spriteManagers && camera) {\r\n for (const imanager of scene.spriteManagers) {\r\n const manager = imanager as SpriteManager;\r\n const renderer = manager.spriteRenderer;\r\n\r\n this._spriteRendererUpdateEffects(renderer._drawWrapperBase, renderer._drawWrapperDepth, camera);\r\n }\r\n }\r\n\r\n // Handles fixed-capacity particle systems\r\n if (scene.particleSystems && camera) {\r\n for (const ps of scene.particleSystems) {\r\n if ((ps as ParticleSystem).useFixedCapacityForSnapshot) {\r\n this._particleSystemUpdateEffects(ps as ParticleSystem, camera);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Gets a value indicating if the helper is in a steady state (not in the process of enabling snapshot rendering).\r\n */\r\n public get isReady() {\r\n return !this._isEnabling;\r\n }\r\n\r\n /**\r\n * Enable snapshot rendering\r\n * Use this method instead of engine.snapshotRendering=true, to make sure everything is ready before enabling snapshot rendering.\r\n * Note that this method is ref-counted and works in pair with disableSnapshotRendering(): you should call enableSnapshotRendering() as many times as you call disableSnapshotRendering().\r\n * @param debugMessage An optional message to display in debug logs to help identify the context of the call to enableSnapshotRendering\r\n */\r\n public enableSnapshotRendering(debugMessage?: string) {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n this._log(\"enableSnapshotRendering\", `called (refCount: ${this._disableRenderingRefCount - 1})${debugMessage ? ` - ${debugMessage}` : \"\"}`);\r\n\r\n if (--this._disableRenderingRefCount > 0) {\r\n return;\r\n }\r\n\r\n this._log(\"enableSnapshotRendering\", `execute`);\r\n\r\n if (this._disableCancelFunctions.size > 0) {\r\n this._log(\"enableSnapshotRendering\", `cancelling ${this._disableCancelFunctions.size} \"disable\" callbacks`);\r\n }\r\n\r\n this._disableCancelFunctions.forEach((cancel) => cancel());\r\n this._disableCancelFunctions.clear();\r\n\r\n this._isEnabling = true;\r\n this._disableRenderingRefCount = 0;\r\n\r\n this._currentPerformancePriorityMode = this._pendingCurrentPerformancePriorityMode ?? this._scene.performancePriority;\r\n this._pendingCurrentPerformancePriorityMode = undefined;\r\n this._scene.performancePriority = ScenePerformancePriority.BackwardCompatible;\r\n\r\n const callbackWhenSceneReady = () => {\r\n this._enableCancelFunctions.delete(callbackWhenSceneReady);\r\n\r\n // Make sure a full frame is rendered before enabling snapshot rendering, so use \"+2\" instead of \"+1\"\r\n const targetFrameId = this._engine.frameId + 2;\r\n\r\n this._log(\"enableSnapshotRendering\", `scene ready, add callbacks for frames ${targetFrameId} and ${targetFrameId + 1}`);\r\n\r\n this._executeAtFrame(targetFrameId, () => {\r\n this._log(\"enableSnapshotRendering\", `callback #1, enable snapshot rendering at the engine level`);\r\n this._engine.snapshotRendering = true;\r\n });\r\n\r\n // Render one frame with snapshot rendering enabled to make sure everything is ready\r\n this._executeAtFrame(targetFrameId + 1, () => {\r\n this._log(\"enableSnapshotRendering\", `callback #2, signals that snapshot rendering helper is ready`);\r\n this._isEnabling = false;\r\n });\r\n };\r\n\r\n this._enableCancelFunctions.set(callbackWhenSceneReady, () => this._scene.onReadyObservable.removeCallback(callbackWhenSceneReady));\r\n\r\n this._scene.executeWhenReady(callbackWhenSceneReady);\r\n }\r\n\r\n /**\r\n * Disable snapshot rendering\r\n * Note that this method is ref-counted and works in pair with enableSnapshotRendering(): you should call enableSnapshotRendering() as many times as you call disableSnapshotRendering().\r\n * @param debugMessage An optional message to display in debug logs to help identify the context of the call to disableSnapshotRendering\r\n */\r\n public disableSnapshotRendering(debugMessage?: string) {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n this._log(\r\n \"disableSnapshotRendering\",\r\n `called (refCount: ${this._disableRenderingRefCount === 0 ? 0 : this._disableRenderingRefCount + 1})${debugMessage ? ` - ${debugMessage}` : \"\"}`\r\n );\r\n\r\n if (this._disableRenderingRefCount === 0) {\r\n this._log(\"disableSnapshotRendering\", `execute (refCount set to 1 after execution)`);\r\n\r\n if (this._enableCancelFunctions.size > 0) {\r\n this._log(\"disableSnapshotRendering\", `cancelling ${this._enableCancelFunctions.size} \"enable\" callbacks`);\r\n }\r\n\r\n this._enableCancelFunctions.forEach((cancel) => cancel());\r\n this._enableCancelFunctions.clear();\r\n\r\n this._isEnabling = false;\r\n\r\n // Snapshot rendering switches from enabled to disabled\r\n // We reset the performance priority mode to that which it was before enabling snapshot rendering, but first set it to “BackwardCompatible” to allow the system to regenerate resources that may have been optimized for snapshot rendering.\r\n // We'll then restore the original mode at the next frame.\r\n this._scene.performancePriority = ScenePerformancePriority.BackwardCompatible;\r\n if (this._currentPerformancePriorityMode !== ScenePerformancePriority.BackwardCompatible) {\r\n this._log(\r\n \"disableSnapshotRendering\",\r\n `makes sure that the scene is rendered once in BackwardCompatible mode (code: ${ScenePerformancePriority.BackwardCompatible}) before switching to mode ${this._currentPerformancePriorityMode}`\r\n );\r\n\r\n this._pendingCurrentPerformancePriorityMode = this._currentPerformancePriorityMode;\r\n\r\n const callbackWhenSceneReady = () => {\r\n this._log(\"disableSnapshotRendering\", `scene ready, add callback for frame ${this._engine.frameId + 2}`);\r\n\r\n this._executeAtFrame(\r\n this._engine.frameId + 2,\r\n () => {\r\n this._log(\"disableSnapshotRendering\", `switching to performance priority mode ${this._pendingCurrentPerformancePriorityMode}`);\r\n this._scene.performancePriority = this._pendingCurrentPerformancePriorityMode!;\r\n this._pendingCurrentPerformancePriorityMode = undefined;\r\n },\r\n \"whenDisabled\"\r\n );\r\n };\r\n\r\n this._disableCancelFunctions.set(callbackWhenSceneReady, () => this._scene.onReadyObservable.removeCallback(callbackWhenSceneReady));\r\n\r\n this._scene.executeWhenReady(callbackWhenSceneReady);\r\n }\r\n }\r\n\r\n this._engine.snapshotRendering = false;\r\n this._disableRenderingRefCount++;\r\n }\r\n\r\n /**\r\n * Fix meshes for snapshot rendering.\r\n * This method will make sure that some features are disabled or fixed to make sure snapshot rendering works correctly.\r\n * @param meshes List of meshes to fix. If not provided, all meshes in the scene will be fixed.\r\n */\r\n public fixMeshes(meshes?: AbstractMesh[]) {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n meshes = meshes || this._scene.meshes;\r\n\r\n for (const mesh of meshes) {\r\n (mesh as Mesh).ignoreCameraMaxZ = false;\r\n if (mesh.morphTargetManager) {\r\n mesh.morphTargetManager.numMaxInfluencers = Math.min(mesh.morphTargetManager.numTargets, this._options.morphTargetsNumMaxInfluences!);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Call this method to update a mesh on the GPU after some properties have changed (position, rotation, scaling).\r\n * Note: in FAST snapshot mode the GPU bundle is recorded once and replayed every frame, so draw calls\r\n * (including instance counts) are baked in. This method updates per-mesh GPU data such as transforms and\r\n * `mesh.visibility`, but it cannot change whether a recorded draw call is emitted. To apply changes such as\r\n * `mesh.isVisible`, `setEnabled(false)`, or per-instance visibility/state changes that affect instance counts,\r\n * wrap the change in a disableSnapshotRendering() / enableSnapshotRendering() pair so the snapshot is\r\n * re-recorded.\r\n * @param mesh The mesh to update. Can be a single mesh or an array of meshes to update.\r\n * @param updateInstancedMeshes If true, the method will also update instanced meshes. Default is true. If you know instanced meshes won't move (or you don't have instanced meshes), you can set this to false to save some CPU time.\r\n */\r\n public updateMesh(mesh: AbstractMesh | AbstractMesh[], updateInstancedMeshes = true) {\r\n if (!this._fastSnapshotRenderingEnabled) {\r\n return;\r\n }\r\n\r\n if (Array.isArray(mesh)) {\r\n for (const m of mesh) {\r\n if (!updateInstancedMeshes || !this._updateInstancedMesh(m)) {\r\n m.transferToEffect(m.computeWorldMatrix());\r\n }\r\n }\r\n return;\r\n }\r\n\r\n if (!updateInstancedMeshes || !this._updateInstancedMesh(mesh)) {\r\n mesh.transferToEffect(mesh.computeWorldMatrix());\r\n }\r\n }\r\n\r\n private _updateInstancedMesh(mesh: AbstractMesh) {\r\n if (mesh.hasInstances) {\r\n if (mesh.subMeshes) {\r\n const sourceMesh = mesh as Mesh;\r\n for (const subMesh of sourceMesh.subMeshes) {\r\n const batch = sourceMesh._getInstancesRenderList(subMesh._id);\r\n sourceMesh._updateInstancedBuffers(subMesh, batch, batch.parent.instancesBufferSize, this._engine);\r\n }\r\n }\r\n return true;\r\n } else if (mesh.isAnInstance) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Update the meshes used in an effect layer to ensure that snapshot rendering works correctly for these meshes in this layer.\r\n * @param layer The effect layer or frame graph layer\r\n * @param autoUpdate If true, the helper will automatically update the meshes of the layer with each frame. If false, you'll need to call this method manually when the camera or layer meshes move or rotate.\r\n */\r\n public updateMeshesForEffectLayer(layer: EffectLayer | FrameGraphBaseLayerTask, autoUpdate = true) {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n const renderPassId = layer instanceof FrameGraphBaseLayerTask ? layer.objectRendererForLayer.objectRenderer.renderPassId : layer.mainTexture.renderPassId;\r\n\r\n if (autoUpdate) {\r\n this._onBeforeRenderObserverUpdateLayer = this._scene.onBeforeRenderObservable.add(() => {\r\n this._updateMeshMatricesForRenderPassId(renderPassId);\r\n });\r\n } else {\r\n this._updateMeshMatricesForRenderPassId(renderPassId);\r\n }\r\n }\r\n\r\n /**\r\n * Dispose the helper\r\n */\r\n public dispose() {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n this._scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n this._scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserverUpdateLayer);\r\n this._engine.onResizeObservable.remove(this._onResizeObserver);\r\n }\r\n\r\n private get _fastSnapshotRenderingEnabled() {\r\n return this._engine.snapshotRendering && this._engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST;\r\n }\r\n\r\n private _updateMeshMatricesForRenderPassId(renderPassId: number) {\r\n if (!this._fastSnapshotRenderingEnabled) {\r\n return;\r\n }\r\n\r\n const sceneTransformationMatrix =\r\n this._scene.objectRenderers.find((renderer) => renderer.renderPassId === renderPassId)?.activeCamera?.getTransformationMatrix() ?? this._scene.getTransformMatrix();\r\n\r\n for (let i = 0; i < this._scene.meshes.length; ++i) {\r\n const mesh = this._scene.meshes[i];\r\n if (!mesh.subMeshes) {\r\n continue;\r\n }\r\n\r\n for (let j = 0; j < mesh.subMeshes.length; ++j) {\r\n const dw = mesh.subMeshes[j]._getDrawWrapper(renderPassId);\r\n const effect = dw?.effect;\r\n if (effect) {\r\n const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n effect.setMatrix(\"viewProjection\", sceneTransformationMatrix);\r\n effect.setMatrix(\"world\", mesh.computeWorldMatrix());\r\n ubLeftOver.update();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _spriteRendererDirectMatrixUpdate(dw: DrawWrapper, camera: Camera) {\r\n const effect = dw?.effect;\r\n if (effect) {\r\n const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n effect.setMatrix(\"view\", camera.getViewMatrix());\r\n effect.setMatrix(\"projection\", camera.getProjectionMatrix());\r\n ubLeftOver.update();\r\n }\r\n }\r\n }\r\n\r\n private _spriteRendererUpdateEffects(drawWrapperBase: DrawWrapper, drawWrapperDepth: DrawWrapper, camera: Camera) {\r\n this._spriteRendererDirectMatrixUpdate(drawWrapperBase, camera);\r\n this._spriteRendererDirectMatrixUpdate(drawWrapperDepth, camera);\r\n }\r\n\r\n /**\r\n * Make a CPU particle system compatible with FAST snapshot rendering.\r\n * The particle system will always render at full capacity (`getCapacity()` quads), with inactive slots collapsed\r\n * to degenerate triangles via zero-fill. This keeps the recorded GPU bundle's draw call valid every frame, while\r\n * the live particle data is uploaded to the bundle-referenced vertex buffer through the normal `animate()` path.\r\n *\r\n * The helper additionally updates view/projection (and `eyePosition`/`invView` for billboard modes) into the\r\n * particle system's draw wrappers each frame, so a moving camera continues to work after the bundle is recorded.\r\n *\r\n * Notes:\r\n * - Call this BEFORE `enableSnapshotRendering()` so the recording sees the correct draw count.\r\n * - GPU particle systems (`GPUParticleSystem`) are not supported by this method.\r\n * - Vertex shader cost scales with `getCapacity()` rather than the live particle count, so size capacity realistically.\r\n * - Per-frame uniforms other than camera matrices (e.g. `textureMask`, `translationPivot`, clip planes, fog) are\r\n * baked at recording time and will not update during snapshot replay.\r\n * @param particleSystem The particle system to fix\r\n */\r\n public fixParticleSystem(particleSystem: IParticleSystem): void {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n if (particleSystem.getClassName() !== \"ParticleSystem\") {\r\n this._log(\"fixParticleSystem\", `skipping ${particleSystem.name}: only CPU ParticleSystem is supported (got ${particleSystem.getClassName()})`);\r\n return;\r\n }\r\n\r\n const ps = particleSystem as ParticleSystem;\r\n if (ps.useFixedCapacityForSnapshot) {\r\n return;\r\n }\r\n ps.useFixedCapacityForSnapshot = true;\r\n\r\n // The recorded bundle bakes in the draw-call vertex/instance count. If snapshot rendering is already active\r\n // (or in the process of being enabled) when we flip the flag, the bundle was recorded with the live particle\r\n // count and is now stale. Cycle disable/enable so the next recording picks up the fixed-capacity draw count.\r\n if (this._fastSnapshotRenderingEnabled || this._isEnabling) {\r\n Logger.Warn(\r\n `SnapshotRenderingHelper.fixParticleSystem(\"${particleSystem.name}\") was called after snapshot rendering was enabled. ` +\r\n `Forcing a re-record so the bundle uses the fixed-capacity draw count. Call fixParticleSystem before enableSnapshotRendering to avoid this.`\r\n );\r\n this.disableSnapshotRendering(\"fixParticleSystem auto-recover\");\r\n this.enableSnapshotRendering(\"fixParticleSystem auto-recover\");\r\n }\r\n }\r\n\r\n private _particleSystemUpdateEffects(ps: ParticleSystem, camera: Camera) {\r\n const drawWrappers = (ps as unknown as { _drawWrappers: DrawWrapper[][] })._drawWrappers;\r\n if (!drawWrappers) {\r\n return;\r\n }\r\n\r\n const viewMatrix = ps.defaultViewMatrix ?? camera.getViewMatrix();\r\n const projectionMatrix = ps.defaultProjectionMatrix ?? camera.getProjectionMatrix();\r\n // Compute invView lazily once per system per frame, only if any draw wrapper actually needs it.\r\n let invViewMatrix: Nullable<Matrix> = null;\r\n const getInvView = () => {\r\n if (!invViewMatrix) {\r\n invViewMatrix = TmpVectors.Matrix[0];\r\n viewMatrix.invertToRef(invViewMatrix);\r\n }\r\n return invViewMatrix;\r\n };\r\n\r\n for (const perPass of drawWrappers) {\r\n if (!perPass) {\r\n continue;\r\n }\r\n for (const dw of perPass) {\r\n this._particleSystemDirectMatrixUpdate(dw, viewMatrix, projectionMatrix, camera, getInvView);\r\n }\r\n }\r\n }\r\n\r\n private _particleSystemBillboardFlags = new WeakMap<object, { billboard: boolean; billboardAll: boolean }>();\r\n\r\n private _particleSystemDirectMatrixUpdate(dw: Nullable<DrawWrapper>, viewMatrix: Matrix, projectionMatrix: Matrix, camera: Camera, getInvView: () => Matrix) {\r\n const effect = dw?.effect;\r\n if (!effect) {\r\n return;\r\n }\r\n const dataBuffer = (dw!.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n if (!dataBuffer || !ubLeftOver || !ubLeftOver.setDataBuffer(dataBuffer)) {\r\n return;\r\n }\r\n effect.setMatrix(\"view\", viewMatrix);\r\n effect.setMatrix(\"projection\", projectionMatrix);\r\n let flags = this._particleSystemBillboardFlags.get(effect);\r\n if (!flags) {\r\n const defines = effect.defines ?? \"\";\r\n flags = { billboard: defines.indexOf(\"#define BILLBOARD\") >= 0, billboardAll: defines.indexOf(\"#define BILLBOARDMODE_ALL\") >= 0 };\r\n this._particleSystemBillboardFlags.set(effect, flags);\r\n }\r\n if (flags.billboard) {\r\n effect.setVector3(\"eyePosition\", camera.globalPosition);\r\n }\r\n if (flags.billboardAll) {\r\n effect.setMatrix(\"invView\", getInvView());\r\n }\r\n ubLeftOver.update();\r\n }\r\n\r\n private _executeAtFrame(frameId: number, func: () => void, mode: \"whenEnabled\" | \"whenDisabled\" = \"whenEnabled\") {\r\n const callback = () => {\r\n if (this._engine.frameId >= frameId) {\r\n this._engine.onEndFrameObservable.remove(obs);\r\n if (mode === \"whenEnabled\") {\r\n this._enableCancelFunctions.delete(callback);\r\n } else {\r\n this._disableCancelFunctions.delete(callback);\r\n }\r\n func();\r\n }\r\n };\r\n\r\n const obs = this._engine.onEndFrameObservable.add(callback);\r\n if (mode === \"whenEnabled\") {\r\n this._enableCancelFunctions.set(callback, () => this._engine.onEndFrameObservable.remove(obs));\r\n } else {\r\n this._disableCancelFunctions.set(callback, () => this._engine.onEndFrameObservable.remove(obs));\r\n }\r\n }\r\n\r\n private _log(funcName: string, message: string) {\r\n if (this.showDebugLogs) {\r\n Logger.Log(`[Frame: ${this._engine.frameId}] SnapshotRenderingHelper:${funcName} - ${message}`);\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"snapshotRenderingHelper.js","sourceRoot":"","sources":["../../../../dev/core/src/Misc/snapshotRenderingHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n type AbstractEngine,\r\n type AbstractMesh,\r\n type EffectLayer,\r\n type Mesh,\r\n type Nullable,\r\n type Observer,\r\n type Scene,\r\n type WebGPUDrawContext,\r\n type WebGPUShaderProcessor,\r\n type WebGPUPipelineContext,\r\n type GaussianSplattingMesh,\r\n type DrawWrapper,\r\n type Camera,\r\n type SpriteManager,\r\n type IParticleSystem,\r\n type ParticleSystem,\r\n type Matrix,\r\n} from \"core/index\";\r\n\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { BindMorphTargetParameters } from \"core/Materials/materialHelper.functions\";\r\nimport { ScenePerformancePriority } from \"core/scene\";\r\nimport { TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { FrameGraphBaseLayerTask } from \"../FrameGraph/Tasks/Layers/baseLayerTask\";\r\nimport { FrameGraphUtils } from \"../FrameGraph/frameGraphUtils\";\r\n\r\n/**\r\n * Options for the snapshot rendering helper\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface SnapshotRenderingHelpersOptions {\r\n /**\r\n * Maximum number of influences for morph target managers\r\n * In FAST snapshot mode, the number of influences must be fixed and cannot change from one frame to the next.\r\n * morphTargetsNumMaxInfluences is the maximum number of non-zero influences allowed in a morph target manager.\r\n * The final value defined for a morph target manager is: Math.min(morphTargetManager.numTargets, morphTargetsNumMaxInfluences)\r\n * Default: 20\r\n */\r\n morphTargetsNumMaxInfluences?: number;\r\n}\r\n\r\n/**\r\n * A helper class to simplify work with FAST snapshot mode (WebGPU only - can be used in WebGL too, but won't do anything).\r\n */\r\nexport class SnapshotRenderingHelper {\r\n private readonly _engine: AbstractEngine;\r\n private readonly _scene: Scene;\r\n private readonly _options: SnapshotRenderingHelpersOptions;\r\n private readonly _onBeforeRenderObserver: Nullable<Observer<Scene>>;\r\n private _onBeforeRenderObserverUpdateLayer: Nullable<Observer<Scene>>;\r\n private readonly _onResizeObserver: Nullable<Observer<AbstractEngine>>;\r\n private _disableRenderingRefCount = 0;\r\n private _currentPerformancePriorityMode = ScenePerformancePriority.BackwardCompatible;\r\n private _pendingCurrentPerformancePriorityMode?: ScenePerformancePriority;\r\n private _isEnabling = false;\r\n private _enableCancelFunctions: Map<() => void, () => void> = new Map(); // first function is the callback, second function is the cancel function\r\n private _disableCancelFunctions: Map<() => void, () => void> = new Map(); // same as above\r\n\r\n /**\r\n * Indicates if debug logs should be displayed\r\n */\r\n public showDebugLogs = false;\r\n\r\n /**\r\n * Creates a new snapshot rendering helper\r\n * Note that creating an instance of the helper will set the snapshot rendering mode to SNAPSHOTRENDERING_FAST but will not enable snapshot rendering (engine.snapshotRendering is not updated).\r\n * Note also that fixMeshes() is called as part of the construction\r\n * @param scene The scene to use the helper in\r\n * @param options The options for the helper\r\n */\r\n constructor(scene: Scene, options?: SnapshotRenderingHelpersOptions) {\r\n this._scene = scene;\r\n this._engine = scene.getEngine();\r\n\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n this._options = {\r\n morphTargetsNumMaxInfluences: 20,\r\n ...options,\r\n };\r\n\r\n this._engine.snapshotRenderingMode = Constants.SNAPSHOTRENDERING_FAST;\r\n\r\n this.fixMeshes();\r\n\r\n this._onResizeObserver = this._engine.onResizeObservable.add(() => {\r\n this._log(\"onResize\", \"start\");\r\n\r\n // enableSnapshotRendering() will delay the actual enabling of snapshot rendering by at least a frame, so these two lines are not redundant!\r\n if (this._fastSnapshotRenderingEnabled) {\r\n this.disableSnapshotRendering();\r\n this.enableSnapshotRendering();\r\n } else if (this._isEnabling) {\r\n // We are in the process of enabling snapshot rendering, but the engine got resized before we could actually enable it:\r\n // * cancel all \"enable\" pending callbacks\r\n // * increase the ref count to balance the decrease that enableSnapshotRendering() will do\r\n // * call enableSnapshotRendering() again to restart the enabling process\r\n this._enableCancelFunctions.forEach((cancel) => cancel());\r\n this._enableCancelFunctions.clear();\r\n this._disableRenderingRefCount++;\r\n this.enableSnapshotRendering();\r\n }\r\n\r\n this._log(\"onResize\", \"end\");\r\n });\r\n\r\n this._onBeforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => {\r\n if (!this._fastSnapshotRenderingEnabled) {\r\n return;\r\n }\r\n\r\n // Animates skeletons\r\n for (const skeleton of scene.skeletons) {\r\n skeleton.prepare(true);\r\n }\r\n\r\n // Handles meshes\r\n for (const mesh of scene.meshes) {\r\n if (mesh.infiniteDistance) {\r\n mesh.transferToEffect(mesh.computeWorldMatrix(true));\r\n }\r\n\r\n if (mesh.skeleton) {\r\n mesh.transferToEffect(mesh.computeWorldMatrix(true));\r\n }\r\n\r\n if (mesh.getClassName() === \"GaussianSplattingMesh\") {\r\n (mesh as GaussianSplattingMesh)._postToWorker();\r\n }\r\n\r\n if (mesh.morphTargetManager && mesh.subMeshes) {\r\n // Make sure morph target animations work\r\n for (const subMesh of mesh.subMeshes) {\r\n const dw = subMesh._drawWrapper;\r\n const effect = dw.effect;\r\n if (effect) {\r\n const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n mesh.morphTargetManager._bind(effect);\r\n BindMorphTargetParameters(mesh, effect);\r\n ubLeftOver.update();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Handles sprite renderers\r\n let camera = scene.activeCamera;\r\n if (scene.frameGraph) {\r\n camera = FrameGraphUtils.FindMainCamera(scene.frameGraph) || camera;\r\n }\r\n if (scene.spriteManagers && camera) {\r\n for (const imanager of scene.spriteManagers) {\r\n const manager = imanager as SpriteManager;\r\n const renderer = manager.spriteRenderer;\r\n\r\n this._spriteRendererUpdateEffects(renderer._drawWrapperBase, renderer._drawWrapperDepth, camera);\r\n }\r\n }\r\n\r\n // Handles fixed-capacity particle systems\r\n if (scene.particleSystems && camera) {\r\n for (const ps of scene.particleSystems) {\r\n const particleSystem = ps as ParticleSystem;\r\n if (particleSystem._useFixedCapacityForSnapshot) {\r\n this._updateFixedCapacityParticleSystem(particleSystem, camera);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Gets a value indicating if the helper is in a steady state (not in the process of enabling snapshot rendering).\r\n */\r\n public get isReady() {\r\n return !this._isEnabling;\r\n }\r\n\r\n /**\r\n * Enable snapshot rendering\r\n * Use this method instead of engine.snapshotRendering=true, to make sure everything is ready before enabling snapshot rendering.\r\n * Note that this method is ref-counted and works in pair with disableSnapshotRendering(): you should call enableSnapshotRendering() as many times as you call disableSnapshotRendering().\r\n * @param debugMessage An optional message to display in debug logs to help identify the context of the call to enableSnapshotRendering\r\n */\r\n public enableSnapshotRendering(debugMessage?: string) {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n this._log(\"enableSnapshotRendering\", `called (refCount: ${this._disableRenderingRefCount - 1})${debugMessage ? ` - ${debugMessage}` : \"\"}`);\r\n\r\n if (--this._disableRenderingRefCount > 0) {\r\n return;\r\n }\r\n\r\n this._log(\"enableSnapshotRendering\", `execute`);\r\n\r\n if (this._disableCancelFunctions.size > 0) {\r\n this._log(\"enableSnapshotRendering\", `cancelling ${this._disableCancelFunctions.size} \"disable\" callbacks`);\r\n }\r\n\r\n this._disableCancelFunctions.forEach((cancel) => cancel());\r\n this._disableCancelFunctions.clear();\r\n\r\n this._isEnabling = true;\r\n this._disableRenderingRefCount = 0;\r\n\r\n this._currentPerformancePriorityMode = this._pendingCurrentPerformancePriorityMode ?? this._scene.performancePriority;\r\n this._pendingCurrentPerformancePriorityMode = undefined;\r\n this._scene.performancePriority = ScenePerformancePriority.BackwardCompatible;\r\n\r\n const callbackWhenSceneReady = () => {\r\n this._enableCancelFunctions.delete(callbackWhenSceneReady);\r\n\r\n // Make sure a full frame is rendered before enabling snapshot rendering, so use \"+2\" instead of \"+1\"\r\n const targetFrameId = this._engine.frameId + 2;\r\n\r\n this._log(\"enableSnapshotRendering\", `scene ready, add callbacks for frames ${targetFrameId} and ${targetFrameId + 1}`);\r\n\r\n this._executeAtFrame(targetFrameId, () => {\r\n this._log(\"enableSnapshotRendering\", `callback #1, enable snapshot rendering at the engine level`);\r\n this._engine.snapshotRendering = true;\r\n });\r\n\r\n // Render one frame with snapshot rendering enabled to make sure everything is ready\r\n this._executeAtFrame(targetFrameId + 1, () => {\r\n this._log(\"enableSnapshotRendering\", `callback #2, signals that snapshot rendering helper is ready`);\r\n this._isEnabling = false;\r\n });\r\n };\r\n\r\n this._enableCancelFunctions.set(callbackWhenSceneReady, () => this._scene.onReadyObservable.removeCallback(callbackWhenSceneReady));\r\n\r\n this._scene.executeWhenReady(callbackWhenSceneReady);\r\n }\r\n\r\n /**\r\n * Disable snapshot rendering\r\n * Note that this method is ref-counted and works in pair with enableSnapshotRendering(): you should call enableSnapshotRendering() as many times as you call disableSnapshotRendering().\r\n * @param debugMessage An optional message to display in debug logs to help identify the context of the call to disableSnapshotRendering\r\n */\r\n public disableSnapshotRendering(debugMessage?: string) {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n this._log(\r\n \"disableSnapshotRendering\",\r\n `called (refCount: ${this._disableRenderingRefCount === 0 ? 0 : this._disableRenderingRefCount + 1})${debugMessage ? ` - ${debugMessage}` : \"\"}`\r\n );\r\n\r\n if (this._disableRenderingRefCount === 0) {\r\n this._log(\"disableSnapshotRendering\", `execute (refCount set to 1 after execution)`);\r\n\r\n if (this._enableCancelFunctions.size > 0) {\r\n this._log(\"disableSnapshotRendering\", `cancelling ${this._enableCancelFunctions.size} \"enable\" callbacks`);\r\n }\r\n\r\n this._enableCancelFunctions.forEach((cancel) => cancel());\r\n this._enableCancelFunctions.clear();\r\n\r\n this._isEnabling = false;\r\n\r\n // Snapshot rendering switches from enabled to disabled\r\n // We reset the performance priority mode to that which it was before enabling snapshot rendering, but first set it to “BackwardCompatible” to allow the system to regenerate resources that may have been optimized for snapshot rendering.\r\n // We'll then restore the original mode at the next frame.\r\n this._scene.performancePriority = ScenePerformancePriority.BackwardCompatible;\r\n if (this._currentPerformancePriorityMode !== ScenePerformancePriority.BackwardCompatible) {\r\n this._log(\r\n \"disableSnapshotRendering\",\r\n `makes sure that the scene is rendered once in BackwardCompatible mode (code: ${ScenePerformancePriority.BackwardCompatible}) before switching to mode ${this._currentPerformancePriorityMode}`\r\n );\r\n\r\n this._pendingCurrentPerformancePriorityMode = this._currentPerformancePriorityMode;\r\n\r\n const callbackWhenSceneReady = () => {\r\n this._log(\"disableSnapshotRendering\", `scene ready, add callback for frame ${this._engine.frameId + 2}`);\r\n\r\n this._executeAtFrame(\r\n this._engine.frameId + 2,\r\n () => {\r\n this._log(\"disableSnapshotRendering\", `switching to performance priority mode ${this._pendingCurrentPerformancePriorityMode}`);\r\n this._scene.performancePriority = this._pendingCurrentPerformancePriorityMode!;\r\n this._pendingCurrentPerformancePriorityMode = undefined;\r\n },\r\n \"whenDisabled\"\r\n );\r\n };\r\n\r\n this._disableCancelFunctions.set(callbackWhenSceneReady, () => this._scene.onReadyObservable.removeCallback(callbackWhenSceneReady));\r\n\r\n this._scene.executeWhenReady(callbackWhenSceneReady);\r\n }\r\n }\r\n\r\n this._engine.snapshotRendering = false;\r\n this._disableRenderingRefCount++;\r\n }\r\n\r\n /**\r\n * Fix meshes for snapshot rendering.\r\n * This method will make sure that some features are disabled or fixed to make sure snapshot rendering works correctly.\r\n * @param meshes List of meshes to fix. If not provided, all meshes in the scene will be fixed.\r\n */\r\n public fixMeshes(meshes?: AbstractMesh[]) {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n meshes = meshes || this._scene.meshes;\r\n\r\n for (const mesh of meshes) {\r\n (mesh as Mesh).ignoreCameraMaxZ = false;\r\n if (mesh.morphTargetManager) {\r\n mesh.morphTargetManager.numMaxInfluencers = Math.min(mesh.morphTargetManager.numTargets, this._options.morphTargetsNumMaxInfluences!);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Call this method to update a mesh on the GPU after some properties have changed (position, rotation, scaling).\r\n * Note: in FAST snapshot mode the GPU bundle is recorded once and replayed every frame, so draw calls\r\n * (including instance counts) are baked in. This method updates per-mesh GPU data such as transforms and\r\n * `mesh.visibility`, but it cannot change whether a recorded draw call is emitted. To apply changes such as\r\n * `mesh.isVisible`, `setEnabled(false)`, or per-instance visibility/state changes that affect instance counts,\r\n * wrap the change in a disableSnapshotRendering() / enableSnapshotRendering() pair so the snapshot is\r\n * re-recorded.\r\n * @param mesh The mesh to update. Can be a single mesh or an array of meshes to update.\r\n * @param updateInstancedMeshes If true, the method will also update instanced meshes. Default is true. If you know instanced meshes won't move (or you don't have instanced meshes), you can set this to false to save some CPU time.\r\n */\r\n public updateMesh(mesh: AbstractMesh | AbstractMesh[], updateInstancedMeshes = true) {\r\n if (!this._fastSnapshotRenderingEnabled) {\r\n return;\r\n }\r\n\r\n if (Array.isArray(mesh)) {\r\n for (const m of mesh) {\r\n if (!updateInstancedMeshes || !this._updateInstancedMesh(m)) {\r\n m.transferToEffect(m.computeWorldMatrix());\r\n }\r\n }\r\n return;\r\n }\r\n\r\n if (!updateInstancedMeshes || !this._updateInstancedMesh(mesh)) {\r\n mesh.transferToEffect(mesh.computeWorldMatrix());\r\n }\r\n }\r\n\r\n private _updateInstancedMesh(mesh: AbstractMesh) {\r\n if (mesh.hasInstances) {\r\n if (mesh.subMeshes) {\r\n const sourceMesh = mesh as Mesh;\r\n for (const subMesh of sourceMesh.subMeshes) {\r\n const batch = sourceMesh._getInstancesRenderList(subMesh._id);\r\n sourceMesh._updateInstancedBuffers(subMesh, batch, batch.parent.instancesBufferSize, this._engine);\r\n }\r\n }\r\n return true;\r\n } else if (mesh.isAnInstance) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Update the meshes used in an effect layer to ensure that snapshot rendering works correctly for these meshes in this layer.\r\n * @param layer The effect layer or frame graph layer\r\n * @param autoUpdate If true, the helper will automatically update the meshes of the layer with each frame. If false, you'll need to call this method manually when the camera or layer meshes move or rotate.\r\n */\r\n public updateMeshesForEffectLayer(layer: EffectLayer | FrameGraphBaseLayerTask, autoUpdate = true) {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n const renderPassId = layer instanceof FrameGraphBaseLayerTask ? layer.objectRendererForLayer.objectRenderer.renderPassId : layer.mainTexture.renderPassId;\r\n\r\n if (autoUpdate) {\r\n this._onBeforeRenderObserverUpdateLayer = this._scene.onBeforeRenderObservable.add(() => {\r\n this._updateMeshMatricesForRenderPassId(renderPassId);\r\n });\r\n } else {\r\n this._updateMeshMatricesForRenderPassId(renderPassId);\r\n }\r\n }\r\n\r\n /**\r\n * Dispose the helper\r\n */\r\n public dispose() {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n this._scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n this._scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserverUpdateLayer);\r\n this._engine.onResizeObservable.remove(this._onResizeObserver);\r\n }\r\n\r\n private get _fastSnapshotRenderingEnabled() {\r\n return this._engine.snapshotRendering && this._engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST;\r\n }\r\n\r\n private _updateMeshMatricesForRenderPassId(renderPassId: number) {\r\n if (!this._fastSnapshotRenderingEnabled) {\r\n return;\r\n }\r\n\r\n const sceneTransformationMatrix =\r\n this._scene.objectRenderers.find((renderer) => renderer.renderPassId === renderPassId)?.activeCamera?.getTransformationMatrix() ?? this._scene.getTransformMatrix();\r\n\r\n for (let i = 0; i < this._scene.meshes.length; ++i) {\r\n const mesh = this._scene.meshes[i];\r\n if (!mesh.subMeshes) {\r\n continue;\r\n }\r\n\r\n for (let j = 0; j < mesh.subMeshes.length; ++j) {\r\n const dw = mesh.subMeshes[j]._getDrawWrapper(renderPassId);\r\n const effect = dw?.effect;\r\n if (effect) {\r\n const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n effect.setMatrix(\"viewProjection\", sceneTransformationMatrix);\r\n effect.setMatrix(\"world\", mesh.computeWorldMatrix());\r\n ubLeftOver.update();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _spriteRendererDirectMatrixUpdate(dw: DrawWrapper, camera: Camera) {\r\n const effect = dw?.effect;\r\n if (effect) {\r\n const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n effect.setMatrix(\"view\", camera.getViewMatrix());\r\n effect.setMatrix(\"projection\", camera.getProjectionMatrix());\r\n ubLeftOver.update();\r\n }\r\n }\r\n }\r\n\r\n private _spriteRendererUpdateEffects(drawWrapperBase: DrawWrapper, drawWrapperDepth: DrawWrapper, camera: Camera) {\r\n this._spriteRendererDirectMatrixUpdate(drawWrapperBase, camera);\r\n this._spriteRendererDirectMatrixUpdate(drawWrapperDepth, camera);\r\n }\r\n\r\n /**\r\n * Make a CPU particle system compatible with FAST snapshot rendering.\r\n * The particle system will always render at full capacity (`getCapacity()` quads), with inactive slots collapsed\r\n * to degenerate triangles via zero-fill. This keeps the recorded GPU bundle's draw call valid every frame, while\r\n * the live particle data is uploaded to the bundle-referenced vertex buffer through the normal `animate()` path.\r\n *\r\n * The helper additionally advances the particle simulation and updates view/projection (and `eyePosition`/`invView`\r\n * for billboard modes) into the particle system's draw wrappers each frame, because FAST snapshot replay skips the\r\n * normal scene particle evaluation path after the bundle is recorded.\r\n *\r\n * Notes:\r\n * - Call this BEFORE `enableSnapshotRendering()` so the recording sees the correct draw count.\r\n * - GPU particle systems (`GPUParticleSystem`) are not supported by this method.\r\n * - Vertex shader cost scales with `getCapacity()` rather than the live particle count, so size capacity realistically.\r\n * - Per-frame uniforms other than camera matrices (e.g. `textureMask`, `translationPivot`, clip planes, fog) are\r\n * baked at recording time and will not update during snapshot replay.\r\n * @param particleSystem The particle system to fix\r\n */\r\n public fixParticleSystem(particleSystem: IParticleSystem): void {\r\n if (!this._engine.isWebGPU) {\r\n return;\r\n }\r\n\r\n if (particleSystem.getClassName() !== \"ParticleSystem\") {\r\n this._log(\"fixParticleSystem\", `skipping ${particleSystem.name}: only CPU ParticleSystem is supported (got ${particleSystem.getClassName()})`);\r\n return;\r\n }\r\n\r\n const ps = particleSystem as ParticleSystem;\r\n const fixedCapacityInitialized = ps._initFixedCapacitySnapshotData();\r\n\r\n // The recorded bundle bakes in the draw-call vertex/instance count. If snapshot rendering is already active\r\n // (or in the process of being enabled) when we flip the flag, the bundle was recorded with the live particle\r\n // count and is now stale. Cycle disable/enable so the next recording picks up the fixed-capacity draw count.\r\n if (fixedCapacityInitialized && (this._fastSnapshotRenderingEnabled || this._isEnabling)) {\r\n Logger.Warn(\r\n `SnapshotRenderingHelper.fixParticleSystem(\"${particleSystem.name}\") was called after snapshot rendering was enabled. ` +\r\n `Forcing a re-record so the bundle uses the fixed-capacity draw count. Call fixParticleSystem before enableSnapshotRendering to avoid this.`\r\n );\r\n this.disableSnapshotRendering(\"fixParticleSystem auto-recover\");\r\n this.enableSnapshotRendering(\"fixParticleSystem auto-recover\");\r\n }\r\n }\r\n\r\n private _updateFixedCapacityParticleSystem(ps: ParticleSystem, camera: Camera): void {\r\n if (!this._scene.particlesEnabled || !ps.isStarted() || !ps.emitter) {\r\n ps._clearFixedCapacitySnapshotData();\r\n return;\r\n }\r\n\r\n const emitter = ps.emitter as { position?: unknown; isEnabled?: () => boolean };\r\n if (!emitter.position || emitter.isEnabled?.()) {\r\n ps.animate();\r\n this._particleSystemUpdateEffects(ps, camera);\r\n } else {\r\n ps._clearFixedCapacitySnapshotData();\r\n }\r\n }\r\n\r\n private _particleSystemUpdateEffects(ps: ParticleSystem, camera: Camera) {\r\n const drawWrappers = (ps as unknown as { _drawWrappers: DrawWrapper[][] })._drawWrappers;\r\n if (!drawWrappers) {\r\n return;\r\n }\r\n\r\n const viewMatrix = ps.defaultViewMatrix ?? camera.getViewMatrix();\r\n const projectionMatrix = ps.defaultProjectionMatrix ?? camera.getProjectionMatrix();\r\n // Compute invView lazily once per system per frame, only if any draw wrapper actually needs it.\r\n let invViewMatrix: Nullable<Matrix> = null;\r\n\r\n for (const perPass of drawWrappers) {\r\n if (!perPass) {\r\n continue;\r\n }\r\n for (const dw of perPass) {\r\n invViewMatrix = this._particleSystemDirectMatrixUpdate(dw, viewMatrix, projectionMatrix, camera, invViewMatrix);\r\n }\r\n }\r\n }\r\n\r\n private _particleSystemBillboardFlags = new WeakMap<object, { billboard: boolean; billboardAll: boolean }>();\r\n\r\n private _particleSystemDirectMatrixUpdate(\r\n dw: Nullable<DrawWrapper>,\r\n viewMatrix: Matrix,\r\n projectionMatrix: Matrix,\r\n camera: Camera,\r\n invViewMatrix: Nullable<Matrix>\r\n ): Nullable<Matrix> {\r\n const effect = dw?.effect;\r\n if (!effect) {\r\n return invViewMatrix;\r\n }\r\n const dataBuffer = (dw!.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n if (!dataBuffer || !ubLeftOver || !ubLeftOver.setDataBuffer(dataBuffer)) {\r\n return invViewMatrix;\r\n }\r\n effect.setMatrix(\"view\", viewMatrix);\r\n effect.setMatrix(\"projection\", projectionMatrix);\r\n let flags = this._particleSystemBillboardFlags.get(effect);\r\n if (!flags) {\r\n const defines = effect.defines ?? \"\";\r\n flags = { billboard: defines.indexOf(\"#define BILLBOARD\") >= 0, billboardAll: defines.indexOf(\"#define BILLBOARDMODE_ALL\") >= 0 };\r\n this._particleSystemBillboardFlags.set(effect, flags);\r\n }\r\n if (flags.billboard) {\r\n effect.setVector3(\"eyePosition\", camera.globalPosition);\r\n }\r\n if (flags.billboardAll) {\r\n if (!invViewMatrix) {\r\n invViewMatrix = TmpVectors.Matrix[0];\r\n viewMatrix.invertToRef(invViewMatrix);\r\n }\r\n effect.setMatrix(\"invView\", invViewMatrix);\r\n }\r\n ubLeftOver.update();\r\n\r\n return invViewMatrix;\r\n }\r\n\r\n private _executeAtFrame(frameId: number, func: () => void, mode: \"whenEnabled\" | \"whenDisabled\" = \"whenEnabled\") {\r\n const callback = () => {\r\n if (this._engine.frameId >= frameId) {\r\n this._engine.onEndFrameObservable.remove(obs);\r\n if (mode === \"whenEnabled\") {\r\n this._enableCancelFunctions.delete(callback);\r\n } else {\r\n this._disableCancelFunctions.delete(callback);\r\n }\r\n func();\r\n }\r\n };\r\n\r\n const obs = this._engine.onEndFrameObservable.add(callback);\r\n if (mode === \"whenEnabled\") {\r\n this._enableCancelFunctions.set(callback, () => this._engine.onEndFrameObservable.remove(obs));\r\n } else {\r\n this._disableCancelFunctions.set(callback, () => this._engine.onEndFrameObservable.remove(obs));\r\n }\r\n }\r\n\r\n private _log(funcName: string, message: string) {\r\n if (this.showDebugLogs) {\r\n Logger.Log(`[Frame: ${this._engine.frameId}] SnapshotRenderingHelper:${funcName} - ${message}`);\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -115,7 +115,8 @@ export declare class ThinParticleSystem extends BaseParticleSystem implements ID
|
|
|
115
115
|
private _alive;
|
|
116
116
|
private _useInstancing;
|
|
117
117
|
private _vertexArrayObject;
|
|
118
|
-
|
|
118
|
+
/** @internal */
|
|
119
|
+
_useFixedCapacityForSnapshot: boolean;
|
|
119
120
|
private _fixedCapacityHighWaterMark;
|
|
120
121
|
/**
|
|
121
122
|
* Gets or sets a boolean indicating that the particle system should always render at full capacity.
|
|
@@ -582,6 +583,10 @@ export declare class ThinParticleSystem extends BaseParticleSystem implements ID
|
|
|
582
583
|
* @param preWarmOnly will prevent the system from updating the vertex buffer (default is false)
|
|
583
584
|
*/
|
|
584
585
|
animate(preWarmOnly?: boolean): void;
|
|
586
|
+
/** @internal */
|
|
587
|
+
_initFixedCapacitySnapshotData(): boolean;
|
|
588
|
+
/** @internal */
|
|
589
|
+
_clearFixedCapacitySnapshotData(): void;
|
|
585
590
|
/**
|
|
586
591
|
* Internal only. Calculates the current emit rate based on the gradients if any.
|
|
587
592
|
* @returns The emit rate
|
|
@@ -346,6 +346,7 @@ export class ThinParticleSystem extends BaseParticleSystem {
|
|
|
346
346
|
this._scaledGravity = Vector3.Zero();
|
|
347
347
|
this._currentRenderId = -1;
|
|
348
348
|
this._useInstancing = false;
|
|
349
|
+
/** @internal */
|
|
349
350
|
this._useFixedCapacityForSnapshot = false;
|
|
350
351
|
this._fixedCapacityHighWaterMark = 0;
|
|
351
352
|
this._started = false;
|
|
@@ -1631,17 +1632,12 @@ export class ThinParticleSystem extends BaseParticleSystem {
|
|
|
1631
1632
|
if (this._useFixedCapacityForSnapshot) {
|
|
1632
1633
|
// The vertex buffer is uploaded at full capacity so the FAST-snapshot bundle's draw call stays valid.
|
|
1633
1634
|
// Inactive slots must be zeroed so they collapse to degenerate (size=0) quads that emit no fragments.
|
|
1634
|
-
// Float32Array starts zeroed and `_appendParticleVertices` overwrites only the active range, so we
|
|
1635
|
-
// only need to clear slots that were active in a previous frame and aren't anymore — i.e. the range
|
|
1636
|
-
// [currentCount, highWaterMark). When the active count grows we just bump the high-water mark.
|
|
1637
1635
|
const stride = this._vertexBufferSize * (this._useInstancing ? 1 : 4);
|
|
1638
1636
|
const currentCount = this._particles.length;
|
|
1639
1637
|
if (currentCount < this._fixedCapacityHighWaterMark) {
|
|
1640
1638
|
this._vertexData.fill(0, currentCount * stride, this._fixedCapacityHighWaterMark * stride);
|
|
1641
1639
|
}
|
|
1642
|
-
|
|
1643
|
-
this._fixedCapacityHighWaterMark = currentCount;
|
|
1644
|
-
}
|
|
1640
|
+
this._fixedCapacityHighWaterMark = currentCount;
|
|
1645
1641
|
this._vertexBuffer.updateDirectly(this._vertexData, 0, this._capacity);
|
|
1646
1642
|
}
|
|
1647
1643
|
else {
|
|
@@ -1653,6 +1649,27 @@ export class ThinParticleSystem extends BaseParticleSystem {
|
|
|
1653
1649
|
this.stop();
|
|
1654
1650
|
}
|
|
1655
1651
|
}
|
|
1652
|
+
/** @internal */
|
|
1653
|
+
_initFixedCapacitySnapshotData() {
|
|
1654
|
+
if (this._useFixedCapacityForSnapshot) {
|
|
1655
|
+
return false;
|
|
1656
|
+
}
|
|
1657
|
+
this._useFixedCapacityForSnapshot = true;
|
|
1658
|
+
this._vertexData.fill(0);
|
|
1659
|
+
this._fixedCapacityHighWaterMark = 0;
|
|
1660
|
+
this._vertexBuffer?.updateDirectly(this._vertexData, 0, this._capacity);
|
|
1661
|
+
return true;
|
|
1662
|
+
}
|
|
1663
|
+
/** @internal */
|
|
1664
|
+
_clearFixedCapacitySnapshotData() {
|
|
1665
|
+
if (!this._useFixedCapacityForSnapshot || !this._vertexBuffer || this._fixedCapacityHighWaterMark === 0) {
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1668
|
+
const stride = this._vertexBufferSize * (this._useInstancing ? 1 : 4);
|
|
1669
|
+
this._vertexData.fill(0, 0, this._fixedCapacityHighWaterMark * stride);
|
|
1670
|
+
this._fixedCapacityHighWaterMark = 0;
|
|
1671
|
+
this._vertexBuffer.updateDirectly(this._vertexData, 0, this._capacity);
|
|
1672
|
+
}
|
|
1656
1673
|
/**
|
|
1657
1674
|
* Internal only. Calculates the current emit rate based on the gradients if any.
|
|
1658
1675
|
* @returns The emit rate
|