From 3de4f3dc616b566e9d6b1569db54ed305fa50de2 Mon Sep 17 00:00:00 2001 From: David Catuhe Date: Thu, 22 Sep 2022 12:39:34 -0700 Subject: [PATCH] More feature for the aggressive performance mode (#13014) --- packages/dev/core/src/Materials/material.ts | 8 +++- packages/dev/core/src/Meshes/subMesh.ts | 2 + .../dev/core/src/Particles/IParticleSystem.ts | 3 ++ .../core/src/Particles/baseParticleSystem.ts | 3 ++ .../core/src/Rendering/renderingManager.ts | 48 +++++++++++++------ .../dev/core/src/Sprites/spriteManager.ts | 6 +++ packages/dev/core/src/scene.ts | 22 ++++++++- 7 files changed, 73 insertions(+), 19 deletions(-) diff --git a/packages/dev/core/src/Materials/material.ts b/packages/dev/core/src/Materials/material.ts index 54c58aa49c2..51533efd3bd 100644 --- a/packages/dev/core/src/Materials/material.ts +++ b/packages/dev/core/src/Materials/material.ts @@ -1013,11 +1013,15 @@ export class Material implements IAnimatable { * @returns a boolean specifying if alpha blending is needed for the mesh */ public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean { - if (this._disableAlphaBlending && mesh.visibility >= 1.0) { + if (mesh.visibility < 1.0) { + return true; + } + + if (this._disableAlphaBlending) { return false; } - return this.needAlphaBlending() || mesh.visibility < 1.0 || mesh.hasVertexAlpha; + return mesh.hasVertexAlpha || this.needAlphaBlending(); } /** diff --git a/packages/dev/core/src/Meshes/subMesh.ts b/packages/dev/core/src/Meshes/subMesh.ts index 781eac1d2b9..2afd71c1aad 100644 --- a/packages/dev/core/src/Meshes/subMesh.ts +++ b/packages/dev/core/src/Meshes/subMesh.ts @@ -141,6 +141,8 @@ export class SubMesh implements ICullable { public _trianglePlanes: Plane[]; /** @internal */ public _lastColliderTransformMatrix: Nullable = null; + /** @internal */ + public _wasDispatched = false; /** @internal */ public _renderId = 0; diff --git a/packages/dev/core/src/Particles/IParticleSystem.ts b/packages/dev/core/src/Particles/IParticleSystem.ts index b4eb4d353a6..90f45aa0c05 100644 --- a/packages/dev/core/src/Particles/IParticleSystem.ts +++ b/packages/dev/core/src/Particles/IParticleSystem.ts @@ -278,6 +278,9 @@ export interface IParticleSystem { /** Gets or sets a matrix to use to compute projection */ defaultProjectionMatrix: Matrix; + /** @internal */ + _wasDispatched: boolean; + /** * Gets the maximum number of particles active at the same time. * @returns The max number of active particles. diff --git a/packages/dev/core/src/Particles/baseParticleSystem.ts b/packages/dev/core/src/Particles/baseParticleSystem.ts index 7239a5fd06f..cadba158f40 100644 --- a/packages/dev/core/src/Particles/baseParticleSystem.ts +++ b/packages/dev/core/src/Particles/baseParticleSystem.ts @@ -202,6 +202,9 @@ export class BaseParticleSystem { */ public preventAutoStart: boolean = false; + /** @internal */ + _wasDispatched = false; + protected _rootUrl = ""; private _noiseTexture: Nullable; diff --git a/packages/dev/core/src/Rendering/renderingManager.ts b/packages/dev/core/src/Rendering/renderingManager.ts index 1baab239706..669f87750e3 100644 --- a/packages/dev/core/src/Rendering/renderingManager.ts +++ b/packages/dev/core/src/Rendering/renderingManager.ts @@ -85,6 +85,12 @@ export class RenderingManager { private _customTransparentSortCompareFn: { [id: number]: Nullable<(a: SubMesh, b: SubMesh) => number> } = {}; private _renderingGroupInfo: Nullable = new RenderingGroupInfo(); + /** + * Gets or sets a boolean indicating that the manager will not reset between frames. + * This means that if a mesh becomes invisible or transparent it will not be visible until this boolean is set to false again.s + */ + public maintainStateBetweenFrames = false; + /** * Instantiates a new rendering group for a particular scene * @param scene Defines the scene the groups belongs to @@ -97,6 +103,14 @@ export class RenderingManager { } } + public getRenderingGroup(id: number) { + const renderingGroupId = id || 0; + + this._prepareRenderingGroup(renderingGroupId); + + return this._renderingGroups[renderingGroupId]; + } + private _clearDepthStencilBuffer(depth = true, stencil = true): void { if (this._depthStencilBufferAlreadyCleaned) { return; @@ -178,6 +192,10 @@ export class RenderingManager { * @internal */ public reset(): void { + if (this.maintainStateBetweenFrames) { + return; + } + for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) { const renderingGroup = this._renderingGroups[index]; if (renderingGroup) { @@ -225,11 +243,11 @@ export class RenderingManager { * @param spriteManager Define the sprite manager to render */ public dispatchSprites(spriteManager: ISpriteManager) { - const renderingGroupId = spriteManager.renderingGroupId || 0; - - this._prepareRenderingGroup(renderingGroupId); - - this._renderingGroups[renderingGroupId].dispatchSprites(spriteManager); + if (this.maintainStateBetweenFrames && spriteManager._wasDispatched) { + return; + } + spriteManager._wasDispatched = true; + this.getRenderingGroup(spriteManager.renderingGroupId).dispatchSprites(spriteManager); } /** @@ -237,11 +255,11 @@ export class RenderingManager { * @param particleSystem Define the particle system to render */ public dispatchParticles(particleSystem: IParticleSystem) { - const renderingGroupId = particleSystem.renderingGroupId || 0; - - this._prepareRenderingGroup(renderingGroupId); - - this._renderingGroups[renderingGroupId].dispatchParticles(particleSystem); + if (this.maintainStateBetweenFrames && particleSystem._wasDispatched) { + return; + } + particleSystem._wasDispatched = true; + this.getRenderingGroup(particleSystem.renderingGroupId).dispatchParticles(particleSystem); } /** @@ -254,11 +272,11 @@ export class RenderingManager { if (mesh === undefined) { mesh = subMesh.getMesh(); } - const renderingGroupId = mesh.renderingGroupId || 0; - - this._prepareRenderingGroup(renderingGroupId); - - this._renderingGroups[renderingGroupId].dispatch(subMesh, mesh, material); + if (this.maintainStateBetweenFrames && subMesh._wasDispatched) { + return; + } + subMesh._wasDispatched = true; + this.getRenderingGroup(mesh.renderingGroupId).dispatch(subMesh, mesh, material); } /** diff --git a/packages/dev/core/src/Sprites/spriteManager.ts b/packages/dev/core/src/Sprites/spriteManager.ts index ad047145f80..a04f35fd092 100644 --- a/packages/dev/core/src/Sprites/spriteManager.ts +++ b/packages/dev/core/src/Sprites/spriteManager.ts @@ -69,6 +69,9 @@ export interface ISpriteManager extends IDisposable { /** Defines the default height of a cell in the spritesheet */ cellHeight: number; + /** @internal */ + _wasDispatched: boolean; + /** * Tests the intersection of a sprite with a specific ray. * @param ray The ray we are sending to test the collision @@ -119,6 +122,9 @@ export class SpriteManager implements ISpriteManager { /** Gets or sets a boolean indicating if the sprites are pickable */ public isPickable = false; + /** @internal */ + public _wasDispatched = false; + /** * An event triggered when the manager is disposed. */ diff --git a/packages/dev/core/src/scene.ts b/packages/dev/core/src/scene.ts index 9e7ee3457e3..bdf6d7d00f4 100644 --- a/packages/dev/core/src/scene.ts +++ b/packages/dev/core/src/scene.ts @@ -283,10 +283,21 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold this._performancePriority = value; switch (value) { + case ScenePerformancePriority.BackwardCompatible: + this.skipFrustumClipping = false; + this._renderingManager.maintainStateBetweenFrames = false; + this.skipPointerMovePicking = false; + this.autoClear = true; + break; + case ScenePerformancePriority.Intermediate: + this.skipFrustumClipping = false; + this._renderingManager.maintainStateBetweenFrames = false; + this.skipPointerMovePicking = true; + this.autoClear = false; + break; case ScenePerformancePriority.Aggressive: this.skipFrustumClipping = true; - // eslint-disable-next-line no-fallthrough - case ScenePerformancePriority.Intermediate: + this._renderingManager.maintainStateBetweenFrames = true; this.skipPointerMovePicking = true; this.autoClear = false; break; @@ -1323,6 +1334,13 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold private _renderingManager: RenderingManager; + /** + * Gets the scene's rendering manager + */ + public get renderingManager() { + return this._renderingManager; + } + /** @internal */ public _activeAnimatables = new Array();