-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React Native - glb/gltf model works in emulator/usb connected device but fails in android apk #2992
Comments
Have you seen import { useLoader } from '@react-three/fiber'
import { GLTFLoader } from 'three-stdlib'
function Model() {
const gltf = useLoader(GLTFLoader, require('./path/to/asset.glb'))
return <primitive object={gltf.scene} />
} |
I have similar issue on iOS in the release mode. Could you explain please why |
To clarify, I meant Android APK where uris are shortened for drawables. It remains unknown whether that includes GLB or other assets additionally configured in Metro. I detailed relevant sources in #2980 (comment), with fixes rolled up into #2982 of 8.14. |
I've confirmed that only image assets are considered drawables, and the polyfills for asset resolution correctly resolve in all cases between dev/APK. This is a new behavior coming from the networking stack and react-native/Expo, so it will be challenging to pinpoint. |
Workaround for loading glb import assert from 'assert';
import { decode } from 'base64-arraybuffer';
import { resolveAsync } from 'expo-asset-utils';
import * as FileSystem from 'expo-file-system';
import { suspend } from 'suspend-react';
import THREE from 'three';
import { GLTF, GLTFLoader } from 'three-stdlib';
async function loadFileAsync({
asset,
funcName,
}: {
asset: unknown;
funcName: string;
}) {
if (!asset) {
throw new Error(`ExpoTHREE.${funcName}: Cannot parse a null asset`);
}
return (await resolveAsync(asset)).localUri ?? null;
}
type ObjectGraph = {
nodes: Record<string, THREE.Mesh>;
materials: Record<string, THREE.Material>;
};
// Collects nodes and materials from a THREE.Object3D
export function buildGraph(object: THREE.Object3D) {
const data: ObjectGraph = { nodes: {}, materials: {} };
if (object) {
object.traverse((obj: any) => {
if (obj.name) {
data.nodes[obj.name] = obj;
}
if (obj.material && !data.materials[obj.material.name]) {
data.materials[obj.material.name] = obj.material;
}
});
}
return data;
}
async function loadGLTFAsync({
asset,
}: {
asset: unknown;
}): Promise<GLTF & ObjectGraph> {
const uri = await loadFileAsync({
asset,
funcName: 'loadGLTFAsync',
});
assert(uri, 'loadGLTFAsync uri should exist');
const base64 = await FileSystem.readAsStringAsync(uri, {
encoding: FileSystem.EncodingType.Base64,
});
const arrayBuffer = decode(base64);
const loader = new GLTFLoader();
const res = await loader.parseAsync(arrayBuffer, 'beb');
if (res.scene) {
Object.assign(res, buildGraph(res.scene));
}
return res as GLTF & ObjectGraph;
}
export const useGLTFCustom = (asset: unknown) =>
suspend(async () => loadGLTFAsync({ asset }), ['useGLTFCustom', asset]); |
In my case i have this error when trying to use useGLTF. I rebuilded native part but it's not the root
|
I'm not sure how |
He literally shares it)) |
Where? Sorry I can't seem to find it. because the one in his comments the code their was a quote reply, and not actually his code with the duck.glb |
Transform duck.glb with |
hey @kdmmanapul you can use the code given by @XantreGodlike, and as he said you have to load the textures separately by bake the textures into a .png file. You can clone my repo to try it react-native-3D-Example |
Thanks guys @XantreGodlike @Rakha112 |
Hmm @Rakha112 @XantreGodlike texture does not seem to work when exported into an APK and run on mobile. |
Yep, we are downgraded version to earlier one and patching three fiber( |
@kdmmanapul, is this latest R3F? @XantreGodlike, which version are you patching from? I can take a look. |
Hey @kdmmanapul. I tried it on 3 devices, Redmi Note 10, Samsung Galaxy Tab A8 and Samsung Galaxy Tab S8, all of them can load the Duck and its textures well using @XantreGodlike workaround. I haven't tried using the latest version Here is the APK file maybe you can try and this is the version of dependencies that I use
|
Note that the |
Sorry, I think, i should to recheck with latest version, because seems to be i've used old one |
Regarding this one @XantreGodlike @Rakha112 since we added a condition for Array not being supported, how can we add rougness texture on the model? Having normalMap and RoughnessMap and etc? Since useTexture by default can have an array of maps right? |
You can omit that callback. I added |
I'd update |
No, it's not possible to use meshopt or DRACO without JIT support on iOS to implement WebAssembly. Maybe wait until EU 2024 legislature WRT the browser ban which might incidentally help there. I've merged #3042 for 8.14.6 which reverts changes from #2982 or 8.14 that produces these cryptic promise rejections. I think we'll have to export a native-specific This undoes changes needed to load textures from a GLB, but should work in Android release mode and anywhere to begin with. Let me know if anything changes on your end and I'll look into a proper fix for textures. |
So my problem is when I try to run the app on my device using the apk without being connected via USB debugging. I am using android. It works fine on emulators but it doesn't work on apk.
This is the code:
I tried this too, but it never runs updateText("asset creato");.
Its like it gets stuck in:
const model = await loader.loadAsync(require('./assets/TempioHera/tempioHeraGLB.glb'));
This also happens with GLTFLoader by three/examples/jsm/loaders/GLTFLoader:
this is the uri i get:
The text was updated successfully, but these errors were encountered: