drei icon indicating copy to clipboard operation
drei copied to clipboard

Toggling between `useGLTF` asset and a `<Text/>` or `<Text3D/>` makes the glTF asset disappear

Open haywirez opened this issue 3 years ago • 4 comments

It seems like toggling between useGLTF asset and a <Text/> or <Text3D/> in a scene makes the glTF asset disappear, even though it's mounted in the tree.

drei-bug

For reproduction, see:

https://codesandbox.io/s/r3f-drei-gltf-text-bug-l21qen?file=/src/index.js

Perhaps something to do with how loaders work internally?

haywirez avatar Jun 04 '22 13:06 haywirez

I'm able to reproduce this between R3F v7-v8 (and Drei 8-9, React 17-18).

Interestingly, this affects any foreign object passed through primitives:

  • https://codesandbox.io/s/r3f-drei-gltf-text-bug-forked-s0o0r8

CodyJasonBennett avatar Jun 04 '22 13:06 CodyJasonBennett

Tracking this behavior down to 5692b703c795fa8aaffb89ad6ab6297f25d91b4c (9.11.3, 8.12.0) where Text is now an async component. Notice how the demo works as expected if you wrap <Text /> with <Suspense /> immediately.

return !menu ? (
  <primitive ref={ref} object={object}>
    <meshStandardMaterial attach="material" />
  </primitive>
) : (
  <Suspense>
    <Text text={'menu'} outlineColor="black" outlineWidth="1" anchorX="center" anchorY="middle" fontSize="1">
      <meshStandardMaterial />
    </Text>
  </Suspense>
)

This isn't the case if you put it up any higher, which is how you'd want to flatten nested async ops. @drcmda, is this expected behavior of suspense?

<Suspense>
  <Thing />
</Suspense>

CodyJasonBennett avatar Jun 04 '22 13:06 CodyJasonBennett

Correct, text finally has deterministic load, that made it a suspending component.

drcmda avatar Jun 04 '22 14:06 drcmda

Should we update the README to reflect those by default, e.g.:

<Suspense fallback={null}>
  <Text color="black" anchorX="center" anchorY="middle">
    hello world!
  </Text>
</Suspense>

Text will suspend while loading the font data, but in order to completely avoid FOUC you can pass the characters it needs to render.

<Suspense fallback={null}>
  <Text font={fontUrl} characters="abcdefghijklmnopqrstuvwxyz0123456789!">
    hello world!
  </Text>
</Suspense>

or do you think that's confusing? I had no idea it could cause problems, so maybe it'd be helpful. I'm happy to make a PR to update all, there's only a few components with suspense badges.

haywirez avatar Jun 04 '22 21:06 haywirez

Sorry for the delayed response, we since annotated suspenseful components -- https://github.com/pmndrs/drei#text.

CodyJasonBennett avatar Oct 05 '22 00:10 CodyJasonBennett