Skip to content

Particles: particles are on their emitter's visibility layer - #1833

Merged
obiot merged 1 commit into
masterfrom
particles-visibility-layer
Nov 2, 2026
Merged

obiot merged 1 commit into
masterfrom
particles-visibility-layer

Conversation

@obiot

@obiot obiot commented Nov 2, 2026

Copy link
Copy Markdown
Member

Description

A camera draws a renderable only if it and every container above it share a layer with the camera's cullMask. Particles stayed on layer 1 whatever their emitter was on. So the way to give an effect a camera of its own, putting the emitter on a layer and giving that camera a cullMask of just that layer, drew the emitter and none of its particles. (Leaving an emitter out of a camera already worked, because the container check covers its children.)

emitter.visibilityLayer = SPACE;   // 2
spaceCamera.cullMask = SPACE;      // before: no particles drawn

The fix follows the emitter's existing blendMode pattern:

  • a particle is born on its emitter's visibilityLayer (in Particle#onResetEvent, so a pooled particle no longer keeps the layer of its last life);
  • the emitter fans a change out to the particles already alive on its next update. This costs one number compare per emitter per frame.

A getter on Particle reading the parent's layer would have been simpler, but TypeScript rejects an accessor overriding Renderable's plain property (TS2611).

Also:

  • Changelog: a Fixed entry.
  • TSDoc: a "Visibility layers" section on ParticleEmitter.
  • Skills: the camera skill's visibilityLayer / cullMask section and a symptom row in the particles skill.

Found while building the Starsweep example, whose 3D star-dust background is drawn by a second, Camera3d, camera on its own layer.

Type of change

  • Bug fix
  • New feature
  • Documentation update
  • Performance improvement
  • Refactoring (no functional changes)

Checklist

  • I have read the Contributing Guide
  • My code follows the existing code style (pnpm lint passes): Biome clean, tsc clean, no new ESLint warnings
  • I have tested my changes locally (pnpm test passes): camera-cull-mask and every particle-* spec pass (207 tests)
  • I have added tests that cover my changes (if applicable): three in tests/camera-cull-mask.spec.js; the two behaviour tests fail without the fix
  • The build succeeds (pnpm build): left to CI

Related issues

None.


Generated by Claude Code

A camera draws a renderable only if it and every container above it share a
layer with the camera's cullMask. Particles stayed on layer 1 whatever
their emitter was on, so a camera that drew only the emitter's layer (the
way to give an effect a camera of its own) drew the emitter and none of its
particles.

Particles are now born on their emitter's visibilityLayer, and the emitter
fans a change out to the live ones on its next update, as it already does
for blendMode. A pooled particle no longer keeps the layer of its last life.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnzwA2BZwXkRJLpNxCXBNt
Copilot AI balanced review requested due to automatic review settings November 2, 2026 08:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@obiot
obiot merged commit e99059c into master Nov 2, 2026
6 checks passed
@obiot
obiot deleted the particles-visibility-layer branch November 2, 2026 08:51
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.

3 participants