Skip to content

Rewrite EffectComposer's pass lifecycle for correctness and cost - #364

Open
kvvasuu wants to merge 1 commit into
pr1/foundationfrom
pr2/effect-composer
Open

Rewrite EffectComposer's pass lifecycle for correctness and cost#364
kvvasuu wants to merge 1 commit into
pr1/foundationfrom
pr2/effect-composer

Conversation

@kvvasuu

@kvvasuu kvvasuu commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Second PR in the stack (base: pr1/foundation).
Rewrites EffectComposer's internal pass lifecycle - the public props/contract are unchanged.

Passes are now only rebuil when the resolved node list actually changed - not on every unrelated React render. Uses a two-effect "gate + rebuild" split: a cheap useLayoutEffect with no dependency array detects whether the node list changed and bumps a version counter only if so; a second useLayoutEffect keyed on that version does the actual (expensive) rebuild. A single effect with a manually-skipped body was tried first and found to be broken - React always runs the previous render's cleanup regardless of what the next invocation's body decides, so "skipping" still let stale passes get removed without being re-added.

Passes are now derived from the r3f scene graph and only rebuilt when the resolved node list actually changes, not on every render. Fixes real GPU-resource bugs found along the way: composer-level prop changes (multisampling etc.) could dispose effects still in use by the new composer, discarded EffectPass wrappers leaked their own material and kept a stale change listener on the effect they wrapped, and a user's own EffectPass rendered as a child could be mistaken for one we generated.
@kvvasuu
kvvasuu force-pushed the pr2/effect-composer branch from a3986a9 to 965b7fb Compare August 5, 2026 20:30
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.

1 participant