[OPT] effects.js: rain update loops all particles every frame — consider frustum culling #34

Closed
opened 2026-03-18 20:23:45 -04:00 by perplexity · 2 comments
Owner

Severity: LOW (future optimization)
File: js/effects.js lines 77-89

Problem

updateEffects() iterates every rain particle every frame to update positions. At 2000 particles (high tier) this is 2000 iterations × 60fps = 120K iterations/second. The loop itself is lightweight (just position math), but on low-end devices it adds up.

The starfield particles are static but still rendered every frame even though they never move.

Suggested Optimization

  1. For low tier, consider updating rain positions every 2nd frame instead of every frame (halves iteration count, nearly imperceptible at 30fps)
  2. Mark starfield geometry as frustumCulled = true (default) and set a proper bounding sphere so Three.js can skip it when out of view
  3. Long-term: move rain update to a vertex shader for GPU-side animation (eliminates JS iteration entirely)
**Severity:** LOW (future optimization) **File:** `js/effects.js` lines 77-89 ## Problem `updateEffects()` iterates every rain particle every frame to update positions. At 2000 particles (high tier) this is 2000 iterations × 60fps = 120K iterations/second. The loop itself is lightweight (just position math), but on low-end devices it adds up. The starfield particles are static but still rendered every frame even though they never move. ## Suggested Optimization 1. For low tier, consider updating rain positions every 2nd frame instead of every frame (halves iteration count, nearly imperceptible at 30fps) 2. Mark starfield geometry as `frustumCulled = true` (default) and set a proper bounding sphere so Three.js can skip it when out of view 3. Long-term: move rain update to a vertex shader for GPU-side animation (eliminates JS iteration entirely)
Author
Owner

Fixed in PR #37 (QA Sprint v2).

Fixed in PR #37 (QA Sprint v2).
Author
Owner

Implemented in PR #59.

Pre-computed bounding spheres, disabled frustumCulled, adaptive draw range (drops particles below 20 FPS, recovers above 30), feedFps() render loop integration. Fixed starfield disposal leak.

Implemented in PR #59. Pre-computed bounding spheres, disabled frustumCulled, adaptive draw range (drops particles below 20 FPS, recovers above 30), feedFps() render loop integration. Fixed starfield disposal leak.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: perplexity/the-matrix#34