Combine render and composer in R3F

Hi,

I’m having some trouble in mixing a render overlay on top of effect composer in R3F, the following is an (updated) example ( by @prisoner849 ) as to what i’d like to achieve but in R3F using postprocessing…

it’s not the exact same effects chain as i’m using in R3F but should be in essence a similar process, are there any examples of making this happen in R3F or any leads on how this would be done in @react-three/fiber with @react-three/postprocessing?

no worries, I sorted it using the same thing in R3F syntax and ensuring to set objects to the correct layers in useLayoutEffect…

    useFrame(({ gl }) => {

        gl.autoClear = false;
        gl.clear();
        
        camera.layers.set(0);
        composerRef.current.render();
        
        gl.clearDepth();
        camera.layers.set(1);
        gl.render(overlayScene.current, camera);

    }, 1);
1 Like

In practice this works but feels like it has performance implications, when using dev tools to record a snapshot of the performance it looks like everything doubles up plus adds other processes to the main thread, would anyone know what sort of performance implications doing this in R3F has and if internal rendering would need to be bypassed if doing this? @drcmda does this seem like the correct way of achieving this?

    const renderOverlayScene = useCallback((gl) => {
        gl.clearDepth();
        camera.layers.set(SceneLayers.overlayScene);
        gl.render(overlayScene.current, camera);
    }, [camera, overlayScene]);

    useFrame(({ gl }) => {

        gl.autoClear = false;
        gl.clear();
        
        camera.layers.set(SceneLayers.effectScene);
        composerRef.current.render();
        
        renderOverlayScene(gl)

    }, 1);

is this about bloom? or something more general? if it’s bloom i would consider it not a good solution as it would be way easier.

no performance implications for useframe. }, 1 basically switches off the default render and that’s all, now the contents of your useFrame will run 120 times/sec and you have to render yourself. if something doubles that is something else, perhaps a side-effect, an object created twice etc.

1 Like

Not bloom in totality, I have a scene i have affected by composer which has a chain of effects, bloom, depth of field and noise, I’m rendering some objects into this scene, i’m then using another overlay scene with some custom text shaders that i don’t want to be affected by composer so it’s just clean, the above seems to be working but the performance is unusable on some laptops and even mobile devices, it’s around 8fps tops :face_exhaling: even removing bloom and noise passes just rendering depth of feild the performance is pretty much too low, as well as adding <AdaptiveDpr/> <AdaptiveEvents/> inside the canvas which don’t seem to have an effect

there is a component in drei called HUD, it would work in lockstep with <EffectComposer>, just use the renderPriority prop, the hud needs a higher one.

docs GitHub - pmndrs/drei: 🥉 useful helpers for react-three-fiber this makes use of react portalling, a whole scene can be rendered into it without disturbing the main scene. everything will keep working, you have events, you can add environments in it, cameras, …

1 Like

as for the performance problem, if you want upload it as a codesandbox and i can have a quick look. if something goes 8fps it is probably easy to find in chrome dev tools

1 Like

That’s really helpful info thanks!

as it stands I’ve done some profiling, optimizing and testing, on mobile the performance is pretty all over the place, one second it’ll be smooth next it will be choppy then maybe smooth again, if i close the browser and reopen it everything (sometimes) looks pretty smooth until about 20 seconds in and then back to chopy which would indicate a memory leak but i can’t tell how or where, i’ve followed all the pointers on react-three-fiber/advanced/scaling-performance and react-three-fiber/advanced/pitfalls using useMemo where necissary, reusing materials where possible and mutuating useRef.current values in useFrame. if i remove <DepthOfFeild/> it runs rapid but loses the nice aesthetic

dof is a pretty heavy effect all by itself. try tiltshift2 maybe, perhaps it’s faster