14islands / r3f-scroll-rig

A react-three-fiber scroll-rig for syncing 3D meshes and DOM elements.
MIT License
720 stars 36 forks source link

Jank while scrolling model/texture into view for first time #17

Closed kaspervdm closed 1 year ago

kaspervdm commented 1 year ago

I tried to create my own version of your example with the GLB model (https://6l2fc3.csb.app/)

My UseCanvas is lower on the page and when it comes in view for the first time, it seems like the model and textures are loaded for the first time, causing a noticeable jank. After the first time however, I don't notice any jank anymore.

I experience the same issue with your own example. If you resize the viewport so the first watch-model is outside the viewport, you will notice the jank when it comes into view for the first time.

I have this on both Chrome & Firefox, MacBook Pro 2019.

Is there maybe a way to preload the model and textures into the GPU?

ffdead commented 1 year ago

Hi @kaspervdm, yes this is a common challenge with threejs in general. You need to make sure all meshes are visible and rendered once for shaders to compile and textures to be uploaded.

ScrollScene will toggle visibility to false automatically for meshes outside the viewport to reduce the amount of draw calls.

If you use useTexture from Drei it will already request the image to be uploaded to the GPU at load time. For 3D models it's a bit trickier but the easiest way is to place a Preload component from Drei in the same suspense boundary as the useGLTF call.

There is also a 'preloadScene' method from useScrollRig that you can use if you need more imperative control.

Let me know how it goes! :)

kaspervdm commented 1 year ago

I realise now this issue has less to do with your scroll rig, so I appreciate taking the time of giving some general pointers on preloading! I'll look into those into more detail, thank you! React is new to me, so still learning here :).

In my project I am using the FlakesTexture from the three.js examples folder. Because this gets created in a CanvasTexture on every re-render. That was part of the problem.

I'm excited to get to know, and use, your scroll rig in more detail. It was exactly what was missing in the current react/threejs/smoothscroll ecosystem, so cool stuff, thanks for sharing!