Open Trancoso opened 5 years ago
In prod with adb logcat i can see this error : "THREE.WebGLState exgl invalid pixel data argument for gl textImage2D()!". Could it be our problem ?
Hello, I work with @Trancoso and was able to find a workaround for our problem. Using adb logcat with a production build and logging the texture returned by ExpoTHREE.loadAsync I noticed that the asset localUri started with asset://. Then using https://github.com/expo/expo/issues/2693#issuecomment-488631357 to get a file:// uri for my asset, I overwrote the texture image localUri with the uri. So far it works fine. Here is the code:
const uri = await this.copyAssetToCacheAsync(require('../../../../assets/images/panorama.png'),'panorama.png');
const texture = await ExpoTHREE.loadAsync(uri);
texture.image.data.localUri = texture.image.data.uri;
const material = new THREE.MeshBasicMaterial({
map: texture
});
const geometry = new THREE.SphereBufferGeometry(GLOBE_RADIUS, 128, 128);
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
Where copyAssetToCacheAsync function is the one provided by adbl in the linked issue.
Thanks @bonbertr for the work around!
After some more digging, I think the root cause could be here, the native C++ implementation of expo-gl: https://github.com/expo/expo/blob/master/packages/expo-gl-cpp/cpp/UEXGL.cpp
The loadImage()
function has a special case to handle Assets passed in the form of JavaScript objects with a .localUri property. However, it only handles the file://
prefix and fails to handle the asset://
prefix (which only appears for assets loaded in standalone Android builds).
Hey everyone.. i was having a lot of trouble with expo-three when trying to load an .obj i will post here what me and my colleges have done to work around this. Every time that i tried to load an .obj using loadAsync or loadObjAsync the require method to load static assets always resolve to undefined.
The solution was create a metro.config.js in your root project folder adding assetExtensions like obj and mtl like this:
module.exports = {
resolver: {
assetExts: ["db", "mp3", "ttf", "obj", "png", "jpg", "mtl"]
}
};
and then in your app.json point to the new file
"packagerOpts": {
"config": "metro.config.js"
}
I'm posting this in case anyone pass trough the same hell
@bonbertr 's workaround is not working anymore after upgrading from Expo 43 to 45. End up with a black textured object. Non-textured objects render just fine. I was able to fix this by skipping the local cache thing and loading the texture from the module resource, but this doesn't obviously work on Android in production builds. Anyone else bumped into this? I've now spent two workdays trying to find the root cause to no avail. My current hypothesis is that TextureLoader cannot load from local URIs anymore.
Perhaps try one of my polyfills via expo-asset
:
This is what https://github.com/pmndrs/react-three-fiber uses ATM to unify loaders with web.
Off-topic: we ended up ditching expo-three altogether. Too frustrated with all the issues we had every time Expo was updated. Was never able to fix the texture loading issue, which was the last nail in the coffin.
I know the feeling XD. Out of curiosity, are you still using React Native at all, and if so with what graphics API? Or did you go 100% native?
I know the feeling XD. Out of curiosity, are you still using React Native at all, and if so with what graphics API? Or did you go 100% native?
We continue to use React Native. We just replaced the 3D content views with regular 2D views. The 3D views didn't sit well with the rest of the app's look and feel anyway.
you need to change the file resolution. For example "test1.png" to "test1.xpng" or "test2.jpg " on "test2.xjpg".
const texture = await ExpoTHREE.loadTextureAsync({asset: require('../../../../assets/images/panorama.xpng')}); const material = new THREE.MeshBasicMaterial({ map: texture });
const geometry = new THREE.SphereBufferGeometry(GLOBE_RADIUS, 128, 128); const sphere = new THREE.Mesh(geometry, material); scene.add(sphere);
work for me sdk44 react-native 0.64.0
Has anyone seen success on this workaround recently? I'm stuck on my android build, IOS works fine.
"expo": "^46.0.0",
"expo-asset": "^8.7.0",
"expo-file-system": "^15.1.1",
"expo-font": "~10.2.0",
"expo-gl": "~11.4.0",
"expo-three": "^7.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-native": "0.69.6",
"react-native-fs": "^2.20.0",
"react-native-web": "~0.18.7",
"three": "0.124.0",
Using the workaround @bonbertr mentioned I hit an issue during the ExpoTHREE.loadAsync
call
Error: Expected URL scheme 'http' or 'https' but was 'file'
I attempted downgrading three.js in hopes the loader lived there, but like @pehagg said it looks like the textureLoader is living in expo.
Any advice? I'm about three days in.
@DominicBartel you can try this:
const asset = Asset.fromURI(localPath);
asset.localUri = localPath;
const texture = await ExpoTHREE.loadAsync(asset);
I was having an issue where the model wouldnt load because "Expected URL scheme 'http' or 'https' but was 'file'". When I looked at the asset, I noticed that the localUri
url scheme was file, but uri
followed the http url scheme. Switching to that allowed me to load the model. There's probably a huge downside to this, but if you want the model to load on Android, there's this
asset.localUri = localPath;
Doing this gave me the error: TypeError: Cannot read property 'elements' of undefined, js engine: hermes
Struggling so much with this bug
in my case it's not a local path...
Hi I’m realizing a project where I have to realize a 3D earth with Expo-THREE but i would like to give a texture to my sphere . However, I only achieved this on development but with a standalone app (android) the texture doesn’t download. I have a black sphere. On IOS, everything goes well in development and with Testfligt app. I do like that to render my sphere :
I also tried to replace my local uri by a picture online but i had the same issue as before.
I also try to realize this issue :
but after tried this , the result was the same for the standalone app.
My config file :
App.json : { "expo": { "name": "name", "slug": "name-app", "privacy": "public", "sdkVersion": "32.0.0", "platforms": [ "ios", "android" ], "version": "2.0.0", "orientation": "portrait", "icon": ./launcher.png", "splash": { "image": "./splash.png", "resizeMode": "contain", "backgroundColor": "#ffdc00" }, "updates": { "fallbackToCacheTimeout": 0 }, "assetBundlePatterns": [ "/" ], "android": { "package": "org..***", "versionCode": 23, "googleServicesFile": "./google-services.json", "permissions": [ "ACCESS_COARSE_LOCATION", "ACCESS_FINE_LOCATION", "CAMERA", "READ_CONTACTS" ] } } }
Mon Package.json : { "main": "node_modules/expo/AppEntry.js", "scripts": { "start": "expo start", "android": "expo start --android", "ios": "expo start --ios", "eject": "expo eject" }, "dependencies": { "d3-geo": "^1.11.3", "expo": "^32.0.0", "expo-asset-utils": "^1.0.0", "expo-face-detector": "^4.0.0", "expo-graphics": "^1.0.3", "expo-three": "^3.0.0-alpha.8", "react": "16.5.0", "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz", "three": "^0.96.0" }, "devDependencies": { "babel-preset-expo": "^5.0.0" }, "private": true }
Can you tell me what can I do ? Thanks a lot !