Skip to content

Comments

feat: effects component support mask settings#1300

Merged
yiiqii merged 1 commit intofeat/2.8from
feat/effects-component-mask
Dec 3, 2025
Merged

feat: effects component support mask settings#1300
yiiqii merged 1 commit intofeat/2.8from
feat/effects-component-mask

Conversation

@wumaolinmaoan
Copy link
Contributor

@wumaolinmaoan wumaolinmaoan commented Dec 3, 2025

Summary by CodeRabbit

  • New Features

    • Mesh components now support stencil mask rendering for advanced visual masking effects.
  • Improvements

    • Enhanced type safety for effect component initialization with stricter data validation.
  • API Changes

    • Mesh component constructor now requires an Engine parameter for proper initialization.

✏️ Tip: You can customize this high-level summary in your review settings.

@wumaolinmaoan wumaolinmaoan requested a review from yiiqii December 3, 2025 06:59
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

Walkthrough

Type narrowing applied to EffectComponent's fromData parameter. MeshComponent extended with mask functionality by implementing the Maskable interface, adding a MaskProcessor instance, and introducing mask-related initialization and rendering methods with updated constructor signature.

Changes

Cohort / File(s) Change Summary
Type Narrowing
packages/effects-core/src/components/effect-component.ts
Method parameter in fromData narrowed from unknown to spec.EffectComponentData for improved type safety.
Mask Functionality
packages/effects-core/src/components/mesh-component.ts
MeshComponent now implements Maskable interface; added maskManager field, updated constructor to accept Engine parameter, added drawStencilMask public method for stencil rendering, and added fromData override for mask initialization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify that the type narrowing in EffectComponent.fromData is consistent with all call sites and doesn't break existing implementations
  • Confirm MeshComponent's Maskable interface implementation is complete and properly integrates with the new maskManager
  • Validate constructor signature change to Engine parameter doesn't introduce breaking changes in existing instantiation patterns
  • Review mask initialization logic in fromData and ensure proper state management across material references

Poem

🐰 Masks now in place, components refined,
Types grow tighter, logic aligned,
Stencils drawn with purpose so true,
Engineering polish through and through!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: effects component support mask settings' directly aligns with the main changes, which add mask-related functionality to MeshComponent and EffectComponent, including Maskable interface implementation and mask initialization support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/effects-component-mask

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/effects-core/src/components/mesh-component.ts (3)

40-53: Consider try-finally to guarantee colorMask restoration.

If drawGeometry throws, colorMask won't be restored. While unlikely, a try-finally pattern ensures consistent state.

  drawStencilMask (renderer: Renderer): void {
    if (!this.isActiveAndEnabled) {
      return;
    }

    for (let i = 0;i < this.materials.length;i++) {
      const material = this.materials[i];
      const previousColorMask = material.colorMask;

-      material.colorMask = false;
-      renderer.drawGeometry(this.geometry, this.transform.getWorldMatrix(), material, i);
-      material.colorMask = previousColorMask;
+      try {
+        material.colorMask = false;
+        renderer.drawGeometry(this.geometry, this.transform.getWorldMatrix(), material, i);
+      } finally {
+        material.colorMask = previousColorMask;
+      }
    }
  }

79-80: Track the TODO: Update data spec.

The any type is a temporary workaround. Consider opening an issue to properly type this parameter once the spec is updated.

Would you like me to open an issue to track adding proper type definitions for mask-related data in the spec?


90-95: Consider conditionally applying stencil settings.

The stencilRef and maskMode are set on all materials even when no maskOptions exist. This works correctly (defaults to NONE which disables stencil test), but explicitly gating on mask presence would make intent clearer and avoid unnecessary property assignments.

-    for (const material of this.materials) {
-      const stencilRef = this.maskManager.getRefValue();
-
-      material.stencilRef = [stencilRef, stencilRef];
-      setMaskMode(material, this.maskManager.maskMode);
-    }
+    if (maskOptions) {
+      for (const material of this.materials) {
+        const stencilRef = this.maskManager.getRefValue();
+
+        material.stencilRef = [stencilRef, stencilRef];
+        setMaskMode(material, this.maskManager.maskMode);
+      }
+    }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c428eb2 and c056b02.

📒 Files selected for processing (2)
  • packages/effects-core/src/components/effect-component.ts (1 hunks)
  • packages/effects-core/src/components/mesh-component.ts (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-05T07:51:18.728Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:162-164
Timestamp: 2025-08-05T07:51:18.728Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the //ts-expect-error usage for accessing siblingComponent.splits (around lines 162-164) is temporary debugging code that will be properly implemented later, as confirmed by ChengYi996.

Applied to files:

  • packages/effects-core/src/components/effect-component.ts
📚 Learning: 2025-08-05T07:50:26.317Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:135-219
Timestamp: 2025-08-05T07:50:26.317Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the mesh subdivision logic (lines 147-219) within the collectSpriteComponents method is temporary debug code that will be properly implemented later, as confirmed by ChengYi996.

Applied to files:

  • packages/effects-core/src/components/mesh-component.ts
🧬 Code graph analysis (1)
packages/effects-core/src/components/mesh-component.ts (4)
packages/effects-core/src/components/renderer-component.ts (1)
  • RendererComponent (10-45)
packages/effects-core/src/material/types.ts (1)
  • Maskable (90-92)
packages/effects-core/src/material/mask-ref-manager.ts (1)
  • MaskProcessor (9-43)
packages/effects-core/src/material/utils.ts (1)
  • setMaskMode (92-121)
🔇 Additional comments (3)
packages/effects-core/src/components/effect-component.ts (1)

32-35: LGTM! Type narrowing improves type safety.

Narrowing from unknown to spec.EffectComponentData provides better compile-time checking and documents the expected data shape. This aligns well with the spec-driven component architecture.

packages/effects-core/src/components/mesh-component.ts (2)

15-15: LGTM! Interface implementation enables mask functionality.

Implementing Maskable allows this component to be referenced and used as a stencil mask source by other components via MaskProcessor.


25-30: LGTM! Proper initialization of MaskProcessor.

The maskManager is correctly encapsulated as private readonly and initialized with the engine reference needed for findObject lookups.

@yiiqii yiiqii merged commit 5ca5c1c into feat/2.8 Dec 3, 2025
2 checks passed
@yiiqii yiiqii deleted the feat/effects-component-mask branch December 3, 2025 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants