pmndrs / react-postprocessing

📬 postprocessing for react-three-fiber
https://docs.pmnd.rs/react-postprocessing
MIT License
1.07k stars 101 forks source link

Route changes cause app to crash until page is refreshed #53

Closed snsie closed 9 months ago

snsie commented 3 years ago

Description of the bug

Route changes (e.g. when using react-router or wouter) cause the app to crash. However, the pages load successfully after they are reloaded. When this occurs, the following error is logged:

Uncaught TypeError: renderer.getClearAlpha is not a function at ClearPass.render (postprocessing.esm.js:3225) at RenderPass.render (postprocessing.esm.js:3660) at EffectComposer.render (postprocessing.esm.js:6271) at Object.current (index.js:1) at Mb (web.js:157) at web.js:158 at Map.forEach (<anonymous>) at Ec (web.js:158)

I created a demo sandbox to illustrate the issue: demo The app initially loads successfully, but when I select the Spheres link, the route change triggers the crash. The code in the Effects.js file was taken from this example. I tested this demo on a computer with a faster graphics card and the app doesn't crash.

The @react-three/postprocessing library isn't used in the demo, but the same crash occurs when using that library. The same can be said for wouter. I originally posted this issue in Raoul's postprocessing repo and was advised to post the issue here.

Calling window.open within an onClick event is working as a temporary solution.

The issue seems to result from resources not completely dismounting before the canvas fully dismounts. What would be the best way to ensure all resources dismount before mounting a new canvas?

Library versions used

"react": "^17.0.0" "three": "^0.121.1" "react-three-fiber": "^5.1.3" "postprocessing": "6.17.4"

drcmda commented 3 years ago

i think this comes from react-postprocessing.

stephencorwin commented 3 years ago

If you leverage the <EffectComposer /> from @react-three/postprocessing, it does not have this issue. Part of the reason why is because you can see the difference in how in that library, it cleans up on unmount as opposed to the Effects.js file which doesn't. https://github.com/pmndrs/react-postprocessing/blob/master/src/EffectComposer.tsx#L65-L75

You can see where we made this change to fix some related issues previously: https://github.com/pmndrs/react-postprocessing/pull/38

Basically though, postprocessing is attempting to call a function during the render cycle after it has already unmounted. We need to gracefully unmount prior to the next frame being processed.

snsie commented 3 years ago

I added a component to the demo in the file Effects-r3pp.js that uses the @react-three/postprocessing library. I also updated the related libraries. Both that file and the vanilla postprocessing implementation (in the Effects.js file) still triggers the renderer.getClearAlpha error.

I appreciate your help with this issue. I modified my primary app so it only uses a single canvas. As a result, I'm no longer dealing with this issue. For the sake of other users, I'll continue to update the sandbox to reflect new library updates and test if the issue resolves.

CharlieHess commented 3 years ago

I'm hitting this as well with the latest EffectComposer, and have a debugger attached: it looks like a useFrame gets hit before the effect composer's passes have been removed but after the renderer has been wiped out:

image

In the case above the breakpoint inside the useEffect clean-up hadn't been hit.