expo-three: LoadTextureAsync not working with standalone app

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 :

const terre = require("../../../../assets/images/panorama.png")    
    scene = new THREE.Scene();
    const light = new THREE.DirectionalLight(new THREE.Color(0xffffff), 1);
    light.position.set(6, 6, 8);
    scene.add(light)
    camera = new THREE.PerspectiveCamera(
      75,
      gl.drawingBufferWidth / gl.drawingBufferHeight,
      0.1,
      1000
    );
    renderer = new ExpoTHREE.Renderer({ gl });
    renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);

    const texture = await ExpoTHREE.loadTextureAsync({asset: terre})
    const geometry = new THREE.SphereBufferGeometry(GLOBE_RADIUS, 128, 128);
    const material = await new THREE.MeshLambertMaterial({
      map: texture
    });
    const sphere = new THREE.Mesh(geometry, material);
    scene.add(sphere);
    camera.position.set(6, 6, 8);

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 !

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 6
  • Comments: 15

Most upvoted comments

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.

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

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.