react-postprocessing
react-postprocessing copied to clipboard
Turning effects on and off during runtime?
Hi,
We are using this library and its working well for us. Great job! We need to dynamically turn some effects (specifically on and off) during the viewing of the page - sometimes we want high FPS, sometimes we want beautiful visuals.
We currently do this like this, using an isPostOn prop:
{isPostOn && <Post aoPreset={Post.aoPresetsTypes.low} />}
with Post being a component with our chain:
const Post = ({ aoPreset }) => (
<Suspense fallback={null}>
<EffectComposer smaa>
<SSAO {...aoConfig[aoPreset]} />
</EffectComposer>
</Suspense>
);
This works, however it is leaking GPU memory, when switching between on/off modes, as the Post component (and thus the SSAO object) being recreated every time. It seems like the resources do not get cleaned up correctly.
Is there a better way to do this?
You can disable effects by using blendFunction
:
import { SSAO } from 'react-postprocessing'
import { BlendFunction } from 'postprocessing'
return (
<SSAO
blendFunction={BlendFunction.SKIP}
/>
)
Thanks for the answer! And I could change these on the fly and resources would not be recreated? From this code: https://github.com/pmndrs/react-postprocessing/blob/master/src/effects/SSAO.tsx Looks like it memos on all of the props, so if the blendFunction changes, the object would be recreated, wouldn't it?
I found this demo of SSAO using react-postprocessing: https://codesandbox.io/s/r3f-gamma-correction-kmb9i?file=/src/index.js I forked it to be able to change the blendFunction: https://codesandbox.io/s/r3f-gamma-correction-forked-wszrc?file=/src/index.js
It seems like the framework is not responding to runtime changes. If you change the useState default from true to false, you will get the SSAO flag update (so the use of blendFunction is correct). However, if you click the canvas, it will not get turned on/off, despite the console logs showing that the object does get called with the update parameter. Is this a bug?
I want to note that i tried different modes of this (including not using useMemo at all, and only putting the SSAO component inside useMemo) but they all exhibited the same behavior
@noamgat yep seems like a bug...
if you know the fix pull requests are welcome :P
I don't know the library well enough to fix, but I created a branch and modified the "Selection" example to reproduce the bug in the react-postprocessing dev env: https://github.com/noamgat/react-postprocessing/tree/ssao-runtime-toggle Clicking on the bottom right sphere now toggles SSAO, but it has no visual effect.
I have also noticed that changes to postprocessing parameters do not take effect immediately. I have to toggle the entire postprocess pipeline off and back on (which it sounds like it may leak resources?) to get them to take.
Hi, I have the same problem and it causes more problems. I thought it was different and created an issue. Seems like duplicate.
After a re-render of the component, Bloom effect is broken (i.e. you cannot change its properties anymore). Please see repro
- You will see blinking bloom animation
- Click Toggle state button
- Blinking bloom animation is broken. Although bloomRef.current.intensity is changed, it has no effect on bloom https://codesandbox.io/s/react-postprocessing-dof-blob-forked-8cu0k?file=/src/App.js
i am doing it here: https://codesandbox.io/s/fun-with-rectarea-lights-pz0q6?file=/src/App.js and it seems to work. blendMode.setBlendFunction(...). although this is in a loop. i think this library experiences some problems with reactive updates atm, would be great if someone could look into it.
We also noticed severe memory issues using Bloom
in one of our prototypes. We decided to remove it for now.
I will try to extract our implementation into a codesandbox for better testing/reproduction.
We used BlendFunction .REFLECT
and saw that when changing bloomRef.current.intensity
, the GPU memory increased with every change.
Here's our reproduction:
https://codesandbox.io/s/mystifying-kare-k4lh3b?file=/src/App.js
useFrame(() => {
if (bloomRef.current && intensityRef.current) {
bloomRef.current.intensity = intensityRef.current;
}
});
Screencast: (Activity Monitor > View > Update Frequency > Very Often (1sec)
I can open a separate issue for this if needed.