简体   繁体   中英

Three.js - stop rendering scene when not visible / out of viewport

I'm making a website that uses a lot of js and animations and first section is fullscreen three.js scene which is moving with mouse movement. Scene itself is fine but everyting is being rendered all the time even when im not looking at the three.js webgl canvas and it's making performace problems, while other animations are happening lower on the website.

I need to stop rendering scene completely while scene is not in viewport and that will boost pewrformacne drastically.

Here is render function:

const render = () => {
    requestAnimationFrame(render);


    camera.position.x += (mouseX - camera.position.x) * 0.05;
    camera.position.y += (mouseY * -1 - camera.position.y) * 0.05;
    camera.lookAt(scene.position);

    const t = Date.now() * 0.001;
    const rx = Math.sin(t * 0.6) * 0.5;
    const ry = Math.sin(t * 0.3) * 0.5;
    const rz = Math.sin(t * 0.2) * 0.5;
    group.rotation.x = rx;
    group.rotation.y = ry;
    group.rotation.z = rz;
    textMesh.rotation.x = rx;
    textMesh.rotation.y = ry;
    textMesh.rotation.z = rx; // :) 

    renderer.render(scene, camera);
};
render();

Here's what i tried to add to stop rendering (found this on another thread here but cant make it work)

var stopRendering = (af) => {
    cancelAnimationFrame(af);
    isRendering = false;
};

window.addEventListener('scroll', () => {
    let scrollPosition = document.body.scrollTop;

    //element is almost about to be visible, time to start rendering
    if (scrollPosition >= ("#canvas-wrapper")-50) {
        if (everythingIsLoaded && !isRendering) {
            render();
            console.log('render has been started');
        } else {
            //wait until everythingIsLoaded is true
        }
    //element is not visible, stop rendering
    } else {
        //need to stop rendering here!
        if (render) {
            stopRendering(render);
            console.log('render has been halted');
        }
    }
});

Here is full codepen

Another thing is, but that shouldnt be a problem, i'm using locomotive scroll library for scroll and viewport visibility detection and this library is highjacking scroll so basic "scroll" is not working.

Main goal of pausing of rendering is to drastically boost performance.

WORKING SOLUTION HERE in case someone finds this question.

You can use an IntersectionObserver to get an event when an element is on/off screen.

 const statusElem = document.querySelector('.status'); const onScreen = new Set(); const intersectionObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { onScreen.add(entry.target); } else { onScreen.delete(entry.target); } }); statusElem.textContent = onScreen.size ? `on screen: ${[...onScreen].map(e => e.textContent).join(', ')}` : 'none'; }); document.querySelectorAll('.test').forEach(elem => { intersectionObserver.observe(elem); });
 body { font-size: xx-large; } .test { padding: 3em; background: orange; } .status { position: fixed; background: rgba(0,0,0,0.8); color: white; padding: 1em; font-size: medium; top: 0; left: 0; }
 <div class="test">a</div> <p>Lorem ipsum dolor sit amet, quaestio principes ea eos. Feugait ocurreret mea ea. Wisi altera intellegebat vix an, sed iuvaret tincidunt adipiscing ea, at debet iudico labores eum. Mucius adversarium vix no, nec amet contentiones ea. Sea noluisse mandamus referrentur cu. Facilisis similique quo eu, pri alii noluisse efficiantur in. </p> <div class="test">b</div> <p> Sea cu vidit neglegentur, te pro maluisset accusamus, ad est diceret iudicabit. Honestatis referrentur no vim, per no putant prompta antiopam. Est singulis vituperata no, adhuc nonumy consectetuer quo cu, quas primis at mel. No doming fabulas admodum est. Cu usu ornatus principes constituam, sint petentium at quo. </p> <div class="test">c</div> <div class="status"></div>

You can then use that to start/stop rendering those elements

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM