Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor mask #2369

Open
wants to merge 41 commits into
base: dev/1.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3ff8a7b
refactor(mask): refactor mask
singlecoder Sep 2, 2024
4afe44b
refactor(mask): opt stencil state
singlecoder Sep 3, 2024
603ba2a
refactor(mask): move sprite mask layer to root
singlecoder Sep 3, 2024
0ae6484
refactor(mask): opt code
singlecoder Sep 5, 2024
1a89b5d
refactor(mask): clear stencil when shadow
singlecoder Sep 9, 2024
a5f1ab9
refactor(mask): fix test error
singlecoder Sep 9, 2024
7ad02b4
refactor(mask): delete render queue check in RenderQueue
singlecoder Sep 10, 2024
e97c4aa
refactor(mask): rename api _isCulledByCamera to _isFilteredByLayer
singlecoder Sep 11, 2024
2f2615b
refactor(mask): when need mask, not change stencil state, upload to g…
singlecoder Sep 11, 2024
47c9c7e
refactor(mask): delete unless code
singlecoder Sep 11, 2024
e52b60a
refactor(mask): mask should be filtered by camera culling mask
singlecoder Sep 12, 2024
8a48797
refactor(mask): opt code
singlecoder Sep 13, 2024
a311f2d
refactor(mask): clear stencil by mask when current render queue has done
singlecoder Sep 14, 2024
9a06859
refactor(mask): opt code
singlecoder Sep 18, 2024
f6f373b
refactor(mask): opt code
singlecoder Sep 18, 2024
f6b35a9
refactor(mask): opt code
singlecoder Sep 18, 2024
47d670a
refactor(mask): opt code
singlecoder Sep 18, 2024
8c0fc37
refactor(mask): opt code
singlecoder Sep 19, 2024
e71b5d6
refactor(mask): delete useless stencil clear
singlecoder Sep 19, 2024
5df85bc
refactor(mask): opt custom stencil states cache
singlecoder Sep 19, 2024
0a09fee
refactor(mask): opt code
singlecoder Sep 19, 2024
82f7f82
refactor(mask): fix conflicts from dev/1.4
singlecoder Sep 19, 2024
12d40f3
refactor(mask): opt custom stencil states
singlecoder Sep 19, 2024
028e4b0
refactor(mask): opt code
singlecoder Sep 19, 2024
2b92fe1
refactor(mask): opt code for clear mask
singlecoder Sep 19, 2024
3d10522
Refactor: extract some methods of the 2D renderers from the Engine (#15)
eyworldwide Sep 29, 2024
5f50e58
refactor(mask): fix perttier
singlecoder Sep 29, 2024
f96f891
refactor(mask): opt code for custom stencil states
singlecoder Oct 9, 2024
ea9e05c
Merge branch 'dev/1.4' into refactor/sprite-mask
singlecoder Oct 12, 2024
6e6eab5
refactor(mask): support developers to customize stencil
singlecoder Oct 12, 2024
ce3efed
refactor(mask): opt code for resume stencil
singlecoder Oct 13, 2024
bd38b58
refactor(mask): migrate 2d default material to basic resources
singlecoder Oct 14, 2024
18ea656
refactor(mask): opt code
singlecoder Oct 14, 2024
894dff9
refactor(mask): opt code
singlecoder Oct 14, 2024
f0c6d4b
refactor(mask): opt mask and stencil clear time
singlecoder Oct 15, 2024
4f4218d
refactor(mask): opt color write mask set
singlecoder Oct 15, 2024
397ac0e
refactor(mask): perttier code
singlecoder Oct 15, 2024
d29b823
refactor(mask): opt code
singlecoder Oct 17, 2024
8a34428
refactor(mask): opt code
singlecoder Oct 17, 2024
61558b1
refactor(mask): opt code
singlecoder Oct 17, 2024
3fd4e4f
refactor(mask): opt code
singlecoder Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/core/src/2d/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export { SpriteMaskInteraction } from "./enums/SpriteMaskInteraction";
export { SpriteMaskLayer } from "./enums/SpriteMaskLayer";
export { TextHorizontalAlignment, TextVerticalAlignment } from "./enums/TextAlignment";
export { OverflowMode } from "./enums/TextOverflow";
export { FontStyle } from "./enums/FontStyle";
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/2d/sprite/SpriteMask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { SubPrimitiveChunk } from "../../RenderPipeline/SubPrimitiveChunk";
import { SubRenderElement } from "../../RenderPipeline/SubRenderElement";
import { Renderer, RendererUpdateFlags } from "../../Renderer";
import { assignmentClone, ignoreClone } from "../../clone/CloneManager";
import { SpriteMaskLayer } from "../../enums/SpriteMaskLayer";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Residual old import paths detected

The script found an occurrence of the old import path in packages/core/src/RenderPipeline/MaskManager.ts. Please update this reference to ensure consistency across the codebase.

🔗 Analysis chain

Verify import path consistency across the codebase

The import path for SpriteMaskLayer has been updated. Ensure that this change is consistent across the entire codebase to prevent any import-related issues.

Run the following script to check for any remaining occurrences of the old import path:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining occurrences of the old import path for SpriteMaskLayer

# Test: Search for the old import path
rg --type typescript 'from "../enums/SpriteMaskLayer"'

Length of output: 178


Script:

#!/bin/bash
# Description: Check for any remaining occurrences of the old import path for SpriteMaskLayer

# Test: Search for the old import path
rg --type ts "from \"../enums/SpriteMaskLayer\""

Length of output: 156

import { ShaderProperty } from "../../shader/ShaderProperty";
import { SimpleSpriteAssembler } from "../assembler/SimpleSpriteAssembler";
import { SpriteMaskLayer } from "../enums/SpriteMaskLayer";
import { SpriteModifyFlags } from "../enums/SpriteModifyFlags";
import { Sprite } from "./Sprite";

Expand Down Expand Up @@ -177,7 +177,7 @@ export class SpriteMask extends Renderer {
constructor(entity: Entity) {
super(entity);
SimpleSpriteAssembler.resetData(this);
this.setMaterial(this._engine._spriteMaskDefaultMaterial);
this.setMaterial(this._engine._basicResources.spriteMaskDefaultMaterial);
this.shaderData.setFloat(SpriteMask._alphaCutoffProperty, this._alphaCutoff);
this._renderElement = new RenderElement();
this._renderElement.addSubRenderElement(new SubRenderElement());
Expand Down Expand Up @@ -261,7 +261,7 @@ export class SpriteMask extends Renderer {
const { _engine: engine } = this;
// @todo: This question needs to be raised rather than hidden.
if (material.destroyed) {
material = engine._spriteMaskDefaultMaterial;
material = engine._basicResources.spriteMaskDefaultMaterial;
}

// Update position
Expand Down
28 changes: 2 additions & 26 deletions packages/core/src/2d/sprite/SpriteRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { SubRenderElement } from "../../RenderPipeline/SubRenderElement";
import { Renderer, RendererUpdateFlags } from "../../Renderer";
import { assignmentClone, deepClone, ignoreClone } from "../../clone/CloneManager";
import { ShaderProperty } from "../../shader/ShaderProperty";
import { CompareFunction } from "../../shader/enums/CompareFunction";
import { ISpriteAssembler } from "../assembler/ISpriteAssembler";
import { SimpleSpriteAssembler } from "../assembler/SimpleSpriteAssembler";
import { SlicedSpriteAssembler } from "../assembler/SlicedSpriteAssembler";
Expand Down Expand Up @@ -257,7 +256,6 @@ export class SpriteRenderer extends Renderer {

set maskInteraction(value: SpriteMaskInteraction) {
if (this._maskInteraction !== value) {
this._updateStencilState(this._maskInteraction, value);
this._maskInteraction = value;
}
}
Expand All @@ -269,7 +267,7 @@ export class SpriteRenderer extends Renderer {
super(entity);
this.drawMode = SpriteDrawMode.Simple;
this._dirtyUpdateFlag |= SpriteRendererUpdateFlags.Color;
this.setMaterial(this._engine._spriteDefaultMaterial);
this.setMaterial(this._engine._basicResources.spriteDefaultMaterial);
this._onSpriteChange = this._onSpriteChange.bind(this);
//@ts-ignore
this._color._onValueChanged = this._onColorChanged.bind(this);
Expand Down Expand Up @@ -334,7 +332,7 @@ export class SpriteRenderer extends Renderer {
}
// @todo: This question needs to be raised rather than hidden.
if (material.destroyed) {
material = this._engine._spriteDefaultMaterials[this._maskInteraction];
material = this._engine._basicResources.spriteDefaultMaterial;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add test coverage for material fallback logic

The line material = this._engine._basicResources.spriteDefaultMaterial; introduces new logic to handle cases where the material has been destroyed. However, static analysis indicates that this line is not covered by existing tests.

Consider adding a unit test to cover this scenario to ensure that the fallback to the default material behaves as expected when the original material is destroyed.

Would you like assistance in creating a test case for this?

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 335-335: packages/core/src/2d/sprite/SpriteRenderer.ts#L335
Added line #L335 was not covered by tests

}

// Update position
Expand Down Expand Up @@ -395,28 +393,6 @@ export class SpriteRenderer extends Renderer {
this._dirtyUpdateFlag &= ~SpriteRendererUpdateFlags.AutomaticSize;
}

private _updateStencilState(from: SpriteMaskInteraction, to: SpriteMaskInteraction): void {
const material = this.getMaterial();
const { _spriteDefaultMaterials: spriteDefaultMaterials } = this._engine;
if (material === spriteDefaultMaterials[from]) {
this.setMaterial(spriteDefaultMaterials[to]);
} else {
const { stencilState } = material.renderState;
if (to === SpriteMaskInteraction.None) {
stencilState.enabled = false;
stencilState.writeMask = 0xff;
stencilState.referenceValue = 0;
stencilState.compareFunctionFront = stencilState.compareFunctionBack = CompareFunction.Always;
} else {
stencilState.enabled = true;
stencilState.writeMask = 0x00;
stencilState.referenceValue = 1;
stencilState.compareFunctionFront = stencilState.compareFunctionBack =
to === SpriteMaskInteraction.VisibleInsideMask ? CompareFunction.LessEqual : CompareFunction.Greater;
}
}
}

@ignoreClone
private _onSpriteChange(type: SpriteModifyFlags): void {
switch (type) {
Expand Down
35 changes: 2 additions & 33 deletions packages/core/src/2d/text/TextRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { Renderer } from "../../Renderer";
import { TransformModifyFlags } from "../../Transform";
import { assignmentClone, deepClone, ignoreClone } from "../../clone/CloneManager";
import { ShaderData, ShaderProperty } from "../../shader";
import { CompareFunction } from "../../shader/enums/CompareFunction";
import { ShaderDataGroup } from "../../shader/enums/ShaderDataGroup";
import { Texture2D } from "../../texture";
import { FontStyle } from "../enums/FontStyle";
Expand Down Expand Up @@ -250,7 +249,6 @@ export class TextRenderer extends Renderer {
set maskInteraction(value: SpriteMaskInteraction) {
if (this._maskInteraction !== value) {
this._maskInteraction = value;
this._setDirtyFlagTrue(DirtyFlag.MaskInteraction);
}
}

Expand Down Expand Up @@ -294,7 +292,7 @@ export class TextRenderer extends Renderer {
const { engine } = this;
this._font = engine._textDefaultFont;
this._addResourceReferCount(this._font, 1);
this.setMaterial(engine._textDefaultMaterial);
this.setMaterial(engine._basicResources.textDefaultMaterial);
//@ts-ignore
this._color._onValueChanged = this._onColorChanged.bind(this);
}
Expand Down Expand Up @@ -394,11 +392,6 @@ export class TextRenderer extends Renderer {
return;
}

if (this._isContainDirtyFlag(DirtyFlag.MaskInteraction)) {
this._updateStencilState();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before implement is different!

this._setDirtyFlagFalse(DirtyFlag.MaskInteraction);
}

if (this._isContainDirtyFlag(DirtyFlag.SubFont)) {
this._resetSubFont();
this._setDirtyFlagFalse(DirtyFlag.SubFont);
Expand Down Expand Up @@ -437,29 +430,6 @@ export class TextRenderer extends Renderer {
camera._renderPipeline.pushRenderElement(context, renderElement);
}

private _updateStencilState(): void {
const material = this.getInstanceMaterial();
const stencilState = material.renderState.stencilState;
const maskInteraction = this._maskInteraction;

if (maskInteraction === SpriteMaskInteraction.None) {
stencilState.enabled = false;
stencilState.writeMask = 0xff;
stencilState.referenceValue = 0;
stencilState.compareFunctionFront = stencilState.compareFunctionBack = CompareFunction.Always;
} else {
stencilState.enabled = true;
stencilState.writeMask = 0x00;
stencilState.referenceValue = 1;
const compare =
maskInteraction === SpriteMaskInteraction.VisibleInsideMask
? CompareFunction.LessEqual
: CompareFunction.Greater;
stencilState.compareFunctionFront = compare;
stencilState.compareFunctionBack = compare;
}
}

private _resetSubFont(): void {
const font = this._font;
this._subFont = font._getSubFont(this.fontSize, this.fontStyle);
Expand Down Expand Up @@ -762,8 +732,7 @@ enum DirtyFlag {
LocalPositionBounds = 0x2,
WorldPosition = 0x4,
WorldBounds = 0x8,
MaskInteraction = 0x10,
Color = 0x20,
Color = 0x10,

Position = LocalPositionBounds | WorldPosition | WorldBounds,
Font = SubFont | Position
Comment on lines +735 to 738
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Incomplete Removal of DirtyFlag.MaskInteraction References

The search revealed multiple remaining references to DirtyFlag.MaskInteraction across various test and source files. This indicates that the removal of the MaskInteraction flag was not fully completed and may lead to potential issues.

  • Affected Files:
    • tests/src/core/SpriteRenderer.test.ts
    • packages/core/src/RenderPipeline/RenderQueue.ts
    • packages/core/src/Renderer.ts
    • packages/core/src/2d/text/TextRenderer.ts
    • And others as listed in the search results.

Please address these remaining references to ensure the DirtyFlag enum changes are fully integrated and do not cause inconsistencies or errors in the codebase.

🔗 Analysis chain

Verify the impact of DirtyFlag enum changes.

The DirtyFlag enum has been updated: the MaskInteraction flag has been removed, and the Color flag now occupies its previous position (0x10). This change suggests that mask interaction functionality has been removed or significantly altered.

Please ensure that:

  1. All references to DirtyFlag.MaskInteraction have been removed or updated throughout the codebase.
  2. The removal of mask interaction doesn't negatively impact existing functionality.
  3. Color-related operations now correctly use the DirtyFlag.Color flag.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to DirtyFlag.MaskInteraction
echo "Searching for DirtyFlag.MaskInteraction references:"
rg "DirtyFlag\.MaskInteraction" --type ts

# Search for uses of DirtyFlag.Color to ensure it's being used correctly
echo "Searching for DirtyFlag.Color usage:"
rg "DirtyFlag\.Color" --type ts

Length of output: 41441

Expand Down
123 changes: 123 additions & 0 deletions packages/core/src/BasicResources.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { SpriteMaskInteraction } from "./2d";
import { Engine } from "./Engine";
import { RenderQueueMaskType } from "./RenderPipeline/enums/RenderQueueMaskType";
import { ContentRestorer } from "./asset/ContentRestorer";
import { Buffer } from "./graphic/Buffer";
import { VertexElement } from "./graphic/VertexElement";
Expand All @@ -8,7 +10,17 @@ import { MeshTopology } from "./graphic/enums/MeshTopology";
import { VertexElementFormat } from "./graphic/enums/VertexElementFormat";
import { Material } from "./material";
import { ModelMesh } from "./mesh";
import {
BlendFactor,
BlendOperation,
ColorWriteMask,
CompareFunction,
CullMode,
RenderQueueType,
StencilOperation
} from "./shader";
import { Shader } from "./shader/Shader";
import { RenderStateElementKey } from "./shader/enums/RenderStateElementKey";
import { Texture, Texture2D, TextureCube, TextureCubeFace } from "./texture";
import { Texture2DArray } from "./texture/Texture2DArray";
import { TextureFormat } from "./texture/enums/TextureFormat";
Expand All @@ -17,6 +29,82 @@ import { TextureFormat } from "./texture/enums/TextureFormat";
* @internal
*/
export class BasicResources {
/** @internal */
static _maskReadInsideStencilStates: Record<number, number | boolean> = null;
/** @internal */
static _maskReadOutsideStencilStates: Record<number, number | boolean> = null;
/** @internal */
static _maskWriteIncrementStencilStates: Record<number, number | boolean> = null;
/** @internal */
static _maskWriteDecrementStencilStates: Record<number, number | boolean> = null;

/** @internal */
static _getMaskInteractionStencilStates(
maskInteraction: SpriteMaskInteraction
): Record<number, number | boolean> | null {
const visibleInsideMask = maskInteraction === SpriteMaskInteraction.VisibleInsideMask;
let stencilStates: Record<number, number | boolean>;
let compareFunction: CompareFunction;

if (visibleInsideMask) {
stencilStates = BasicResources._maskReadInsideStencilStates;
if (stencilStates) {
return stencilStates;
}
BasicResources._maskReadInsideStencilStates = stencilStates = {};
compareFunction = CompareFunction.LessEqual;
} else {
stencilStates = BasicResources._maskReadOutsideStencilStates;
if (stencilStates) {
return stencilStates;
}
BasicResources._maskReadOutsideStencilStates = stencilStates = {};
compareFunction = CompareFunction.Greater;
}

stencilStates[RenderStateElementKey.StencilStateEnabled] = true;
stencilStates[RenderStateElementKey.StencilStateWriteMask] = 0x00;
stencilStates[RenderStateElementKey.StencilStateReferenceValue] = 1;
stencilStates[RenderStateElementKey.StencilStateCompareFunctionFront] = compareFunction;
stencilStates[RenderStateElementKey.StencilStateCompareFunctionBack] = compareFunction;

return stencilStates;
}

/** @internal */
static _getMaskTypeStencilStates(maskType: RenderQueueMaskType): Record<number, number | boolean> | null {
const isIncrement = maskType === RenderQueueMaskType.Increment;
let stencilStates: Record<number, number | boolean>;
let passOperation: StencilOperation;

if (isIncrement) {
stencilStates = BasicResources._maskWriteIncrementStencilStates;
if (stencilStates) {
return stencilStates;
}
BasicResources._maskWriteIncrementStencilStates = stencilStates = {};
passOperation = StencilOperation.IncrementSaturate;
} else {
stencilStates = BasicResources._maskWriteDecrementStencilStates;
if (stencilStates) {
return stencilStates;
}
BasicResources._maskWriteDecrementStencilStates = stencilStates = {};
passOperation = StencilOperation.DecrementSaturate;
}

stencilStates[RenderStateElementKey.StencilStateEnabled] = true;
stencilStates[RenderStateElementKey.StencilStatePassOperationFront] = passOperation;
stencilStates[RenderStateElementKey.StencilStatePassOperationBack] = passOperation;
const failStencilOperation = StencilOperation.Keep;
stencilStates[RenderStateElementKey.StencilStateFailOperationFront] = failStencilOperation;
stencilStates[RenderStateElementKey.StencilStateFailOperationBack] = failStencilOperation;
stencilStates[RenderStateElementKey.StencilStateZFailOperationFront] = failStencilOperation;
stencilStates[RenderStateElementKey.StencilStateZFailOperationBack] = failStencilOperation;

return stencilStates;
}

/**
* Use triangle to blit texture, ref: https://michaldrobot.com/2014/04/01/gcn-execution-patterns-in-full-screen-passes/ .
*/
Expand All @@ -29,6 +117,10 @@ export class BasicResources {
readonly whiteTexture2DArray: Texture2DArray;
readonly uintWhiteTexture2D: Texture2D;

readonly spriteDefaultMaterial: Material;
readonly textDefaultMaterial: Material;
readonly spriteMaskDefaultMaterial: Material;

constructor(engine: Engine) {
// prettier-ignore
const vertices = new Float32Array([
Expand Down Expand Up @@ -74,6 +166,10 @@ export class BasicResources {
whitePixel32
);
}

this.spriteDefaultMaterial = this._create2DMaterial(engine, Shader.find("Sprite"));
this.textDefaultMaterial = this._create2DMaterial(engine, Shader.find("Text"));
this.spriteMaskDefaultMaterial = this._createSpriteMaskMaterial(engine);
}

private _createBlitMesh(engine: Engine, vertices: Float32Array): ModelMesh {
Expand Down Expand Up @@ -140,6 +236,33 @@ export class BasicResources {
);
return texture as T;
}

private _create2DMaterial(engine: Engine, shader: Shader): Material {
const material = new Material(engine, shader);
const renderState = material.renderState;
const target = renderState.blendState.targetBlendState;
target.enabled = true;
target.sourceColorBlendFactor = BlendFactor.SourceAlpha;
target.destinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha;
target.sourceAlphaBlendFactor = BlendFactor.One;
target.destinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha;
target.colorBlendOperation = target.alphaBlendOperation = BlendOperation.Add;
renderState.depthState.writeEnabled = false;
renderState.rasterState.cullMode = CullMode.Off;
renderState.renderQueueType = RenderQueueType.Transparent;
material.isGCIgnored = true;
return material;
}

private _createSpriteMaskMaterial(engine: Engine): Material {
const material = new Material(engine, Shader.find("SpriteMask"));
const renderState = material.renderState;
renderState.blendState.targetBlendState.colorWriteMask = ColorWriteMask.None;
renderState.rasterState.cullMode = CullMode.Off;
renderState.depthState.enabled = false;
material.isGCIgnored = true;
return material;
}
}

enum TextureType {
Expand Down
13 changes: 13 additions & 0 deletions packages/core/src/Camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Component } from "./Component";
import { DependentMode, dependentComponents } from "./ComponentsDependencies";
import { Entity } from "./Entity";
import { Layer } from "./Layer";
import { PipelineStage } from "./RenderPipeline";
import { BasicRenderPipeline } from "./RenderPipeline/BasicRenderPipeline";
import { PipelineUtils } from "./RenderPipeline/PipelineUtils";
import { Transform } from "./Transform";
Expand All @@ -16,6 +17,7 @@ import { DepthTextureMode } from "./enums/DepthTextureMode";
import { Downsampling } from "./enums/Downsampling";
import { MSAASamples } from "./enums/MSAASamples";
import { ReplacementFailureStrategy } from "./enums/ReplacementFailureStrategy";
import { SpriteMaskLayer } from "./enums/SpriteMaskLayer";
import { Shader } from "./shader/Shader";
import { ShaderData } from "./shader/ShaderData";
import { ShaderMacroCollection } from "./shader/ShaderMacroCollection";
Expand Down Expand Up @@ -603,6 +605,17 @@ export class Camera extends Component {
const context = engine._renderContext;
const virtualCamera = this._virtualCamera;

const lastCamera = context.camera;
if (lastCamera) {
const scene = lastCamera.scene;
if (this.clearFlags & CameraClearFlags.Stencil) {
scene._maskManager._preMaskLayer = SpriteMaskLayer.Nothing;
} else {
scene._maskManager.clearMask(context, PipelineStage.Forward);
}
scene._stencilManager.clearStencil();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid Direct Modification of Internal Properties

The code directly accesses and modifies internal properties like scene._maskManager._preMaskLayer and calls internal methods such as scene._stencilManager.clearStencil(). Direct manipulation of properties and methods prefixed with an underscore may break encapsulation and lead to maintenance issues.

Consider the following refinements:

  • Expose Public Methods or Properties: Update the MaskManager and StencilManager classes to provide public methods or properties that encapsulate these operations.
  • Enhance Encapsulation: Modify the code to interact with these managers through their public interfaces to maintain encapsulation and facilitate future maintenance.


const transform = this.entity.transform;
Matrix.multiply(this.projectionMatrix, this.viewMatrix, virtualCamera.viewProjectionMatrix);
virtualCamera.position.copyFrom(transform.worldPosition);
Expand Down
Loading
Loading