pmndrs/react-three-fiber

React Native: load a GLB with embedded textures

axeldelafosse opened this issue Β· 63 comments

Hi everyone!

I'm checking out the beta with React Native and I wanted to check if someone was able to load via a remote URL with GLTFLoader. Looks like React Native's FileLoader implementation isn't working correctly. I started to patch it but wanted to check here.

Let me know if you have any feedback! Thanks :)

I did this with r133 but with r134 three swapped over to the fetch API under the hood which react-native's polyfill doesn't implement correctly (no streaming, blob/array buffer support).

Maybe we can create a FileLoader in three-stdlib that could progressively fallback to the old API or just prefer to use loaders' parse methods. I don't want the API to change from web if we can help it though.

I did this with r133 but with r134 three swapped over to the fetch API under the hood which react-native's polyfill doesn't implement correctly (no streaming, blob/array buffer support).

Good to know, thanks! Just saw that you use r133 in your example app.

Maybe we can create a FileLoader in three-stdlib that could progressively fallback to the old API or just prefer to use loaders' parse methods.

Yeah that's a good idea. Happy to help!

I don't want the API to change from web if we can help it though.

Me neither.


Thank you very much for your reactivity and for your work on React Native support. Really appreciate it.

@axeldelafosse could you please share your sample...I can't get a working sample with beta version...I have issues when try to install dependency. thanks! :-)

@wiulma, I'd see the react-native example in the docs. You'd roll back three to r133 for full compatibility as described here though.

hi @CodyJasonBennett . thanks for the quick reply. I'm trying to get it working since some hours... I have a conflict in npm install with fiber v8, react native 064 or 0.65 and react@rc. So I'm trying different configurations or versions, but without any luck. I'm pretty sure I'm doing something wrong, but I can't address it. Maybe it's because I started from a bare react native project. and I manually installed expo modules, but in any case the dependency conflict is between react and fiber.
npm WARN ERESOLVE overriding peer dependency npm WARN While resolving: @react-three/fiber@8.0.0-beta-04 npm WARN Found: react@undefined npm WARN node_modules/react npm WARN react@"^18.0.0-rc.0" from the root project npm WARN npm WARN Could not resolve dependency: npm WARN peer react@">=18.0" from @react-three/fiber@8.0.0-beta-04 npm WARN node_modules/@react-three/fiber npm WARN @react-three/fiber@"^8.0.0-beta-04" from the root project npm WARN ERESOLVE overriding peer dependency npm ERR! code ETARGET npm ERR! notarget No matching version found for react@>=18.0. npm ERR! notarget In most cases you or one of your dependencies are requesting npm ERR! notarget a package version that doesn't exist.
this is the last npm error log I got

@wiulma, react 18 isn't released yet so it won't resolve but you can pass --legacy-peer-deps to skip through.

I had to specify it because react@rc can't be resolved when I launch npm i, and install fails. in any case I tried to skip the error with --force, but it fails again. I'll try with --legacy-peer-deps. thanks.

@wiulma use yarn instead of npm
yarn add react@rc

I went and polyfilled loader behavior in #1994 so loaders should behave correctly with and without useLoader. Only loader not covered is THREE.ImageBitmapLoader which doesn't seem useful for native (all other loaders in core or examples extend or use THREE.ImageLoader or THREE.FileLoader.

Will release a beta (or release-candidate at this point, just waiting on React 18), but in the meantime you can try it by pointing R3F to the PR in your package.json:

"@react-three/fiber": "https://pkg.csb.dev/pmndrs/react-three-fiber/commit/61888404/@react-three/fiber"

Leaving this issue open until we roll this out.

Thank you Cody! It's working well on iOS πŸ’―

We are experiencing some issues on Android tho, it looks like expo-gl crashes. I also tried with your example app but still no luck. Did you manage to make it work on Android?

Yes, what's happening on Android?

Here is the crash report:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Build fingerprint: 'OnePlus/OnePlus9_EEA/OnePlus9:11/RKQ1.201105.002/2106092118:user/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2022-01-19 10:36:21+0100
pid: 25789, tid: 28986, name: mqt_js  >>> io.showtime.development <<<
uid: 10305
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x28
Cause: null pointer dereference
    x0  b400007738b549e0  x1  43e680000ef11452  x2  0000000000000001  x3  0000000000000001
    x4  00000076552fb400  x5  0000000000000045  x6  0000007738a33200  x7  0000007738b59400
    x8  0000000000000000  x9  0000000000000000  x10 0000000000000000  x11 4fd8921a018a0f63
    x12 0000000000000034  x13 00000000000001ff  x14 0000007647d1ddc0  x15 0000000000000001
    x16 000000768a071b10  x17 0000007689dddf40  x18 000000764d572000  x19 b4000077b8f63610
    x20 b400007788a29000  x21 0000021c0000021c  x22 00000076552fd000  x23 00000076552fb580
    x24 00000076552fd000  x25 00000076552fd000  x26 0000000000000029  x27 0000000000000004
    x28 0000000000000000  x29 00000076552fb5f0
    lr  000000763a0bb1a0  sp  00000076552fb570  pc  000000763a0bb1b8  pst 0000000060001000
backtrace:
      #00 pc 00000000000691b8  /data/app/~~oprxnNrJyd671FiyUN0abA==/io.showtime.development-OLSIpw8El6ol6i1XNbNMiQ==/lib/arm64/libexpo-gl.so (expo::gl_cpp::EXGLContext::prepareContext(facebook::jsi::Runtime&, std::__ndk1::function<void ()>)+476) (BuildId: deaed3376f22bd6e2c76f387c5493ff6426d38aa)
      #01 pc 000000000004d2a8  /data/app/~~oprxnNrJyd671FiyUN0abA==/io.showtime.development-OLSIpw8El6ol6i1XNbNMiQ==/lib/arm64/libexpo-gl.so (UEXGLContextPrepare+144) (BuildId: deaed3376f22bd6e2c76f387c5493ff6426d38aa)
      #02 pc 00000000000ba390  /data/app/~~oprxnNrJyd671FiyUN0abA==/io.showtime.development-OLSIpw8El6ol6i1XNbNMiQ==/lib/arm64/libexpo-gl.so (Java_expo_modules_gl_cpp_EXGL_EXGLContextPrepare+208) (BuildId: deaed3376f22bd6e2c76f387c5493ff6426d38aa)
      #03 pc 000000000007a66c  /data/app/~~oprxnNrJyd671FiyUN0abA==/io.showtime.development-OLSIpw8El6ol6i1XNbNMiQ==/oat/arm64/base.odex (art_jni_trampoline+188)
      #04 pc 00000000001337e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #05 pc 00000000001a8a94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #06 pc 00000000003185c8  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #07 pc 000000000030e8f4  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+996) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #08 pc 000000000067fbd8  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+548) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #09 pc 000000000012d994  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #10 pc 000000000166beee  /data/app/~~oprxnNrJyd671FiyUN0abA==/io.showtime.development-OLSIpw8El6ol6i1XNbNMiQ==/oat/arm64/base.vdex (expo.modules.gl.GLContext$1.run+70)
      #11 pc 0000000000305ef0  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7972480776628613073)+268) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #12 pc 000000000066b988  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+780) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #13 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #14 pc 0000000002032a14  /memfd:jit-cache (deleted) (offset 0x2000000)

And this is the crash report when running from Expo Go (same error):

backtrace:

    NOTE: Function names and BuildId information is missing for some frames due
    NOTE: to unreadable libraries. For unwinds of apps, only shared libraries
    NOTE: found under the lib/ directory are readable.
      #00 pc 00000000000691b8  /data/data/host.exp.exponent/lib-0/libexpo-gl.so
      #01 pc 000000000004d2a8  /data/data/host.exp.exponent/lib-0/libexpo-gl.so
      #02 pc 00000000000ba390  /data/data/host.exp.exponent/lib-0/libexpo-gl.so
      #03 pc 00000000001c77bc  /data/app/~~DHJIx5GU-UjsqRGYbpn_Xw==/host.exp.exponent-HOvYxjr0F1ZKEmxiBvRN4g==/oat/arm64/base.odex (art_jni_trampoline+188)
      #04 pc 00000000001337e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #05 pc 00000000001a8a94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #06 pc 00000000003185c8  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #07 pc 000000000030e8f4  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+996) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #08 pc 000000000067fbd8  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+548) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #09 pc 000000000012d994  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #10 pc 0000000000e53c26  /data/app/~~DHJIx5GU-UjsqRGYbpn_Xw==/host.exp.exponent-HOvYxjr0F1ZKEmxiBvRN4g==/oat/arm64/base.vdex (abi44_0_0.expo.modules.gl.GLContext$1.run+70)
      #11 pc 0000000000305ef0  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7972480776628613073)+268) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #12 pc 000000000066b988  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+780) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #13 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #14 pc 000000000064fdbc  /system/framework/arm64/boot-framework.oat (android.os.Handler.dispatchMessage+76) (BuildId: 5be5ff0c099e7aacfd0e46382ad5e3b1a98c5fac)
      #15 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #16 pc 00000000001a8a78  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #17 pc 00000000003185c8  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #18 pc 000000000030e8f4  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+996) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #19 pc 000000000067da34  /apex/com.android.art/lib64/libart.so (MterpInvokeSuper+1792) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #20 pc 000000000012d894  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_super+20) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #21 pc 0000000000dea5cc  /data/app/~~DHJIx5GU-UjsqRGYbpn_Xw==/host.exp.exponent-HOvYxjr0F1ZKEmxiBvRN4g==/oat/arm64/base.vdex (abi44_0_0.com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage)
      #22 pc 0000000000305ef0  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7972480776628613073)+268) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #23 pc 000000000066b988  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+780) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #24 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #25 pc 0000000000653384  /system/framework/arm64/boot-framework.oat (android.os.Looper.loop+1668) (BuildId: 5be5ff0c099e7aacfd0e46382ad5e3b1a98c5fac)
      #26 pc 00000000001337e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #27 pc 00000000001a8a94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #28 pc 00000000003185c8  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #29 pc 000000000030e8f4  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+996) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #30 pc 000000000067fbd8  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+548) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #31 pc 000000000012d994  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #32 pc 0000000000dea6e6  /data/app/~~DHJIx5GU-UjsqRGYbpn_Xw==/host.exp.exponent-HOvYxjr0F1ZKEmxiBvRN4g==/oat/arm64/base.vdex (abi44_0_0.com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run+74)
      #33 pc 0000000000305ef0  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7972480776628613073)+268) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #34 pc 000000000066b988  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+780) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #35 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #36 pc 000000000015ddf8  /apex/com.android.art/javalib/arm64/boot.oat (java.lang.Thread.run+72) (BuildId: f3abbf7f7b16d75544b33437039cf4d7fc3bf37d)
      #37 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #38 pc 00000000001a8a78  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #39 pc 0000000000555364  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+460) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #40 pc 00000000005a4714  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1308) (BuildId: 933c1474400fb2058ebeb692559ccfa8)
      #41 pc 00000000000b0048  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: 07fbaeed7b7a19203975f06be6f1d5ef)
      #42 pc 00000000000503c8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 07fbaeed7b7a19203975f06be6f1d5ef)
"expo-gl": "~11.0.3",
"expo-gl-cpp": "~11.0.1",

Why are you pinning expo-gl and why are you adding expo-gl-cpp manually?

Edit: using the same expo-gl version as r3f fixes this issue.

That doesn't look correct, looks like a mistake. Same for expo-asset which is automatically pulled in by expo.

We'll have to unpin expo-gl and drop or list the others as peer deps.

I tried tweaking this in #2004. Hopefully, that should work without issue:

"@react-three/fiber": "https://pkg.csb.dev/pmndrs/react-three-fiber/commit/673ffe4e/@react-three/fiber"

Thanks for the quick turnaround! Unfortunately it gives the same error as before. The solution looks correct but I don't think this works as expected:

expo-gl@^11.0.3, expo-gl@^11.1.1:
  version "11.1.1"
  resolved "https://registry.yarnpkg.com/expo-gl/-/expo-gl-11.1.1.tgz#2d611f3cff7422e591274d8b91334b2973a7132b"
  integrity sha512-1bpPGmLnn6H4vs9X019zxMAlOdSqIyyWAT/yJC7f/qGzs9lTPM6STN3N+7fVMtPkXaCMyvyJL8vFJQ75+YmGpQ==
  dependencies:
    expo-gl-cpp "~11.1.0"
    invariant "^2.2.4"

Can you create an issue for this? We're not getting dependencies quite right and I'd like to get more eyes on this.

Yeah sure :) Here it is: #2013

Hey @CodyJasonBennett!

I'm working with Axel (@axeldelafosse) on getting Three to load remote models/textures correctly in React Native.

I have noticed that RN does not support constructing Blobs from ArrayBuffer instances (see code here), so I implemented this.

I created a library called react-native-blob-jsi-helper, which you just have to call in that code piece from RN Core. I have locally patched this in our repo, but Three still doesn't load remote models correctly, this is the error message I'm getting:

-Unable to download file: Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSErrorFailingURLStringKey=blob:D7FFA2DB-8747-4C22-863E-470C3C8AACA9?offset=0&size=12332, NSErrorFailingURLKey=blob:D7FFA2DB-8747-4C22-863E-470C3C8AACA9?offset=0&size=12332, _NSURLErrorRelatedURLSessionTaskErrorKey=(
-    "BackgroundDownloadTask <FA2791A0-A1D2-4E93-9A44-1EE92FDA8AF6>.<13>"
-), _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundDownloadTask <FA2791A0-A1D2-4E93-9A44-1EE92FDA8AF6>.<13>, NSLocalizedDescription=unsupported URL}

I am thinking, either URL.createObjectURL does not work with the Blob passed in, but that's basically a simple concat function.
I then thought maybe the native platform (iOS in this case) cannot handle URLs starting with blob: correctly, so I put a breakpoint in the canHandleRequest function of RCTBlobManager.mm (code here), but that never got hit.

I am now thinking maybe Three is loading the URL wrong, since it successfully loads a blob: URL in an Image component:

<Image source={{uri: sourceURI}} style={{width: 100, height: 100}} />

Do you have any ideas where I could help looking?

I think the main issue here is that RN does not support streaming. @CodyJasonBennett let me know if you can think of a workaround that would unblock us here, otherwise the only option would be to implement Streams into RN Core.

Yes, I pointed this out to three where they swapped over to fetch under the hood for loaders. They since patched loaders to skip onprogress checks for environments without streaming in r136 (Firefox also suffers from this).

I polyfilled loaders in #1994 that you can try from this gist. I'll be releasing a v8 beta in a moment that should have these fixes.

I'm not sure if this polyfill is working correctly, I tried pulling it in and still got the same error.

GLTFLoader: Created blob URL: blob:09187D72-14DE-47CC-8FCF-E7DF06EEC48D?offset=0&size=12332
PayloadTooLargeError: request entity too large
    at readStream (/usr/local/lib/node_modules/expo-cli/node_modules/raw-body/index.js:155:17)
    at getRawBody (/usr/local/lib/node_modules/expo-cli/node_modules/raw-body/index.js:108:12)
    at read (/usr/local/lib/node_modules/expo-cli/node_modules/body-parser/lib/read.js:77:3)
    at jsonParser (/usr/local/lib/node_modules/expo-cli/node_modules/body-parser/lib/types/json.js:135:5)
    at call (/usr/local/lib/node_modules/expo-cli/node_modules/connect/index.js:239:7)
    at next (/usr/local/lib/node_modules/expo-cli/node_modules/connect/index.js:183:5)
    at remoteDevtoolsCorsMiddleware (/usr/local/lib/node_modules/expo-cli/node_modules/@expo/dev-server/src/middleware/remoteDevtoolsCorsMiddleware.ts:31:3)
    at call (/usr/local/lib/node_modules/expo-cli/node_modules/connect/index.js:239:7)
    at next (/usr/local/lib/node_modules/expo-cli/node_modules/connect/index.js:183:5)
    at serveStatic (/usr/local/lib/node_modules/expo-cli/node_modules/serve-static/index.js:75:16)

- THREE.GLTFLoader: Couldn't load texture, blob:09187D72-14DE-47CC-8FCF-E7DF06EEC48D?offset=0&size=12332
at /Users/mrousavy/Projects/showtime-frontend/node_modules/three/examples/jsm/loaders/GLTFLoader.js:2923:3 in Promise.resolve.then.then._catch$argument_0

How are you loading your model? Is this packed into a single GLB/GLTF or split up into bin/textures? Not sure if the implementation is the same in GLTFLoader but GLBs will go through a different code path.

It's a single .glb file indeed.

Can you send me an email at axeldelafosse@gmail.com please? Tried to reach out via your email address on GitHub but "The email account that you tried to reach does not exist".

Just an update, the polyfills to threejs core loaders is published in beta-05 (see react-native installation instructions), but there's some work to be done on react-native's side for Blobs/URL APIs to make texture decoding in GLTFLoader work.

A fix is in progress for rn core, so hopefully we can update this issue soon.

Hi @CodyJasonBennett just wanted to know that Loading of glb models in react-native is still in work in progress ?

@Pratim-Kumar-Hazarika, yes some issues in react-native we're sorting out. If a polyfill becomes available we can use it but currently loading binary embedded images out of GLBs doesn't work right (working on fixing this upstream rn).

You can load these images/textures separately or from a gltf+bin just fine though.

@Pratim-Kumar-Hazarika, yes some issues in react-native we're sorting out. If a polyfill becomes available we can use it but currently loading binary embedded images out of GLBs doesn't work right (working on fixing this upstream rn).

You can load these images/textures separately or from a gltf+bin just fine though.

Thankyou @CodyJasonBennett

@CodyJasonBennett just wanted to ask if there is an issue / pr in react native core that I can check that tracks whats needed in core for supporting embedded textures in glb files?

Any updates here? I tried with the polyfilled loaders without luck

@filipengberg, @LautaroNavarro, there was previously facebook/react-native#21209 and facebook/react-native#30769, but they grew stale.

There is a fix via react-native-blob-jsi-helper, but it cannot be upstreamed ATM. See CodyJasonBennett/react-native@facd9bb, these modules are rarely touched so this should apply to any supported react-native version. It might be possible to rip these out and re-apply as a polyfill.

@CodyJasonBennett first of all thanks for answering!
We are missing the blob parameter in this function on your commit
It's working but now I got another error, there is a problem parsing the byte array. Inside of the GLTFLoader when we are trying to get the header of the glTF
We have this line, which is supposed to return the first 4 bytes of the data
const magic = LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) );
but it's returning the entire byte array instead, do you know which is the problem here?

It looks like readAsArrayBuffer needs to return an ArrayBuffer instead of an Uint8Array.
We can do that changing this line
this._result = buffer.buffer;

Here is where base64-js uses Uint8Array https://github.com/beatgammit/base64-js/blob/master/index.js#L9

That fixes the previuos issues, but we got a new one! (Surprise?)
THREE.GLTFLoader: Couldn't load texture {"_h": 1, "_i": 2, "_j": [Error: Cannot create URL for blob!], "_k": null}
I'm gonna need to continue debugging this

Interesting, I've run into that issue before, but couldn't pinpoint why/when. The error is emitted from https://github.com/facebook/react-native/blob/dbe6fab06343281e4d96c073bf1a69f73024b810/Libraries/Blob/URL.js#L128. Will have to create a blank project and test.

Hey @CodyJasonBennett! Do you have updates on this? Were you able to get it to work?

I'm wondering if we can test the embedded texture glb files by patch-package react-native's FileReader...

readAsArrayBuffer(blob: ?Blob) {
    this._aborted = false;

    if (blob == null) {
      throw new TypeError(
        "Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'",
      );
    }

    NativeFileReaderModule.readAsDataURL(blob.data).then(
      (text: string) => {
        if (this._aborted) {
          return;
        }

        const base64 = text.split(',')[1];
        const typedArray = toByteArray(base64);

        this._result = typedArray.buffer;
        this._setReadyState(DONE);
      },
      error => {
        if (this._aborted) {
          return;
        }
        this._error = error;
        this._setReadyState(DONE);
      },
    );
  }

https://github.com/acostalima/react-native-polyfill-globals/blob/master/patches/react-native%2B0.63.3.patch

@CodyJasonBennett Can you provide a link to the full React Native loading GLB format demo?

@CodyJasonBennett Can you provide an example code that can load GLB format on React Native? I'm trying to load the GLB file, but I can't

I have a basic starter here: https://github.com/CodyJasonBennett/r3f-native-starter, but I need to update it to Expo 46 and apply patches from this issue (for embedded textures).

I have a basic starter here: https://github.com/CodyJasonBennett/r3f-native-starter, but I need to update it to Expo 46 and apply patches from this issue (for embedded textures).

@CodyJasonBennett Excuse me, have you figured out how to load the glb model in react native without setting useTexture?

@XiongMeng1992, I'm not aware of a way to do that without either patching react-native or three's GLTFLoader to create data textures instead of ArrayBuffer => Blob => Texture, hence this issue (see #1972 (comment), #1972 (comment)).

My current focus is investigating a polyfill we can ship optionally in R3F's <Canvas />.

@XiongMeng1992, I'm not aware of a way to do that without either patching react-native or three's GLTFLoader to create data textures instead of ArrayBuffer => Blob => Texture, hence this issue (see #1972 (comment), #1972 (comment)).

My current focus is investigating a polyfill we can ship optionally in R3F's <Canvas />.

@CodyJasonBennett R3F's <Canvas /> is a good option, is this currently available? Can you share an example, like you learn

@CodyJasonBennett
Thanks for answering my issue above.
And just so you know, the basic starter you created works fine but if I switch to files downloaded from web sites like Sketchfab gives me the error like.
THREE.GLTFLoader: Couldn't load texture {"_U": 1, "_V": 2, "_W": [Error: Creating blobs from 'ArrayBuffer' and 'ArrayBufferView' are not supported], "_X": null}

Is there a current working work around for this? patch, polyfill, rc or otherwise?
Thanks!

See #1972 (comment), a workaround would be to load a glTF without embedded textures from an absolute URL.

@CodyJasonBennett
Thanks for the tip, been trying that, however with this combination of deps:

{
    "@react-three/drei": "^9.29.1",
    "@react-three/fiber": "^8.3.1",
    "expo": "^46.0.0",
    "expo-asset": "~8.6.1",
    "expo-file-system": "~14.1.0",
    "expo-gl": "~11.4.0",
    "expo-linking": "^3.2.2",
    "expo-modules-core": "~0.11.3",
    "expo-random": "^12.3.0",
    "expo-three": "^6.1.0",
    "expo-updates": "^0.14.5",
    "react": "18.0.0",
    "react-dom": "18.0.0",
    "react-native": "0.69.5",
    "react-native-file-viewer": "^2.1.5",
    "three": "^0.144.0"
},

And this structure in gltf:

"images": [
    {
      "name": "baked_mesh_tex0",
      "uri": "https://path.com/to/image.png"
    },
    {
      "name": "baked_mesh_norm0",
      "uri": "https://path.com/to/image.png"
    },
    {
      "name": "baked_mesh_ao0",
      "uri": "https://path.com/to/image.png"
    }
  ],

I get a very verbose output of raw data, finishing on:

dsEI+kJA4PwL6Qj7e4js/nz1rPiUYTT9DxW4+/AtPPyt5fz6IP0o/3CV/PhLnOT/Dcms+tF83P8FeVT6uVzg/c7M3PuYfRD9wmTY+5ic+PyMLMD76h0E/i4VpPnjFQj+lIGA+vLJFP0QqfD6Bh0Q/Re2NPnSXRz9EKnw+gYdEP28TiT6ZRko/6fiQPnjzPj+Ggok+MME+P7sBmD5Vd0M/hoKJPjDBPj9h5Jc+Z8ZIP7sBmD5Vd0M/, NSErrorFailingURLKey=data:application/octet-stream;base64,gLfHPgzfAD6V4rk+AIcKPo5yxD4A6w8+t0/uPjykKT47SPI+RHgiPsb37j58iBY+IifPPmDlUz2mMsA+wON ... mD5Vd0M/, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "BackgroundDownloadTask <DC7A5ED3-473F-4A3B-BE6C-FE23B37C1F79>.<3>"
), _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundDownloadTask <DC7A5ED3-473F-4A3B-BE6C-FE23B37C1F79>.<3>, NSLocalizedDescription=unsupported URL}
promiseMethodWrapper@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:23530:45
@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:113864:46
@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:117984:61
generatorResume@[native code]
asyncGeneratorStep@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:25080:26
_next@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:25102:29
@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:25109:14
tryCallTwo@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:30621:9
doResolve@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:30785:25
Promise@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:30644:14
@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:25098:25
downloadAsync@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:117973:32
@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:117380:67
generatorResume@[native code]
asyncGeneratorStep@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:25080:26
_next@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:25102:29
tryCallOne@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:30612:16
@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:30713:27
@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:31792:26
_callTimer@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:31692:17
_callReactNativeMicrotasksPass@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:31727:17
callReactNativeMicrotasks@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:31934:44
__callReactNativeMicrotasks@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:24010:46
@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:23789:45
__guard@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:23993:15
flushedQueue@LOCAL_IP/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:23788:21
flushedQueue@[native code]
invokeCallbackAndReturnFlushedQueue@[native code]
PayloadTooLargeError: request entity too large
    at readStream (REPO_DIR\node_modules\raw-body\index.js:155:17)
    at getRawBody (REPO_DIR\node_modules\raw-body\index.js:108:12)
    at read (REPO_DIR\node_modules\body-parser\lib\read.js:77:3)
    at jsonParser (REPO_DIR\node_modules\body-parser\lib\types\json.js:135:5)
    at call (REPO_DIR\node_modules\connect\index.js:239:7)
    at next (REPO_DIR\node_modules\connect\index.js:183:5)
    at remoteDevtoolsCorsMiddleware (REPO_DIR\node_modules\@expo\dev-server\build\middlew    at call (REPO_DIR\node_modules\connect\index.js:239:7)
    at next (REPO_DIR\node_modules\connect\index.js:183:5)
    at remoteDevtoolsCorsMiddleware (REPO_DIR\node_modules\@expo\dev-server\build\middleware\remoteDevtoolsCorsMiddleware.js:44:3)
    at call (REPO_DIR\node_modules\connect\index.js:239:7)
    at next (REPO_DIR\node_modules\connect\index.js:183:5)
    at serveStatic (REPO_DIR\node_modules\serve-static\index.js:75:16)

Tried with different images, different urls, running in production mode. No luck. Am I missing something obvious? (Relatively new to react native and expo)

Cheers!

Any update on this issue? Or there any workaround to load glb files.

See #1972 (comment). This is a downstream issue in react-native. I'm looking into sending in a PR with a fix based on the linked workarounds but they've been notoriously slow to triage related issues/PRs. If a workaround becomes available that we can ship/inject within R3F I can release it in a minor.

Any updates on this?

No, and please don't ask that of open-source projects. I have now a chain of responses that outline user-land fixes and work-arounds, but we can't make this official without a fix in react-native downstream.

It looks like your arrayBuffer changes might have finally been merged

@filipengberg, @LautaroNavarro, there was previously facebook/react-native#21209 and facebook/react-native#30769, but they grew stale.

There is a fix via react-native-blob-jsi-helper, but it cannot be upstreamed ATM. See CodyJasonBennett/react-native@facd9bb, these modules are rarely touched so this should apply to any supported react-native version. It might be possible to rip these out and re-apply as a polyfill.

Does this mean that support for .glb's with texture might be possible now?

Hi, thanks @CodyJasonBennett, for all the support you provide!

Is there a way to export an object in glb/gltf properly from Blender so that it loads on RN like the iPhone in this project: https://github.com/CodyJasonBennett/r3f-native-starter

Currently, our models are not working, and I feel like we are not exporting them properly to make them work like your iPhone

Secondly @CodyJasonBennett, where can we help to solve this issue regarding the new comment of @bawolf

I'll take a look to give you a better answer as for pending work. This issue is notably exclusive to inlined textures within GLBs or GLTF (avoid, this is slow), since you need both Blob and ArrayBuffer APIs to decode images in any graphics API (I also use bitmaps with WebGPU which I'm worried could pop up as a blocker). As a work-around, you can export without textures and load/apply them declaratively via pmndrs/gltfjsx.

I'll take a look to give you a better answer as for pending work. This issue is notably exclusive to inlined textures within GLBs or GLTF (avoid, this is slow), since you need both Blob and ArrayBuffer APIs to decode images in any graphics API (I also use bitmaps with WebGPU, which I'm worried could pop up as a blocker). As a workaround, you can export without textures and load/apply them declaratively via pmndrs/gltfjsx.

Thanks for the quick response @CodyJasonBennett πŸ™. Another question, other types of imports are supposed to work well on react-native? For example, β€˜.obj .mtlβ€˜ with packed textures as .png? Because we have some errors as well using this method of imports, with models that work ok on the web with reactjs
It could be another workaround just to use a different type of import that works ok.

hjopel commented

btw. if anyone here needs an example of how to do this, I've created a starter for this:
https://github.com/hjopel/r3f-native-starter

It looks like your arrayBuffer changes might have finally been merged

@filipengberg, @LautaroNavarro, there was previously facebook/react-native#21209 and facebook/react-native#30769, but they grew stale.
There is a fix via react-native-blob-jsi-helper, but it cannot be upstreamed ATM. See CodyJasonBennett/react-native@facd9bb, these modules are rarely touched so this should apply to any supported react-native version. It might be possible to rip these out and re-apply as a polyfill.

Does this mean that support for .glb's with texture might be possible now?

acc to this, does this mean we should be able load GLBs with embedded textures in React Native 0.72.0 onwards? currently still in the midst of upgrading, getting some errors with metro, symlinks, etc. but hopefully should be able to resolve them soon.

I've implemented patches for missing APIs in #2982 which is possible to upstream in react-native itself, pending coverage. Codesandbox CI creates preview builds if you want to try ahead of release.

// package.json
{
  "dependencies": {
    "@react-three/fiber": "https://pkg.csb.dev/pmndrs/react-three-fiber/commit/0772cfaa/@react-three/fiber"
  }
}

Below asset is from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Duck/glTF-Binary/Duck.glb, rendered on iOS emulator.

Had to do a partial revert in #3042, but I've since upstreamed related fixes in facebook/react-native#39276.

I'll see what else we need to do here, but it hinges around Blob/ArrayBuffer support and thus XMLHttpRequest and FileReader (not implemented in fetch yet).

Following up to #1972 (comment), I've put out v8.14.7 which hardens the surrounding networking stack and re-implements patches for Blob/URL/ArrayBuffer for this use-case.