Takes too much RAM loading a texture #1806
-
Hi, i'm using react three fiber (the react native compactible version). What is the amount of memory needed to load/render a simple plane with texture? Everytime i spawn a plane with a 1MB image as the texture, it takes me over 200MB of memory storage. Which means if i have 10 plane like that, it would take over 2GB of RAM just to render a basic scene. Have anyone met this situation before? I'm using expo-three TextureLoader to load the texture from the internet since useLoader and THREE.TextureLoader do not work with mobile. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 5 replies
-
i don't think that a texture generates 200mb, at least on the web, but that's something you would need to clear with expo and/or threejs. r3f just casts jsx into threejs function calls. maybe @CodyJasonBennett can help you, and i think he's made default threejs loaders work already in the new RN version (r3f v8). |
Beta Was this translation helpful? Give feedback.
-
How are you loading your texture? As a module, URL, data URL, etc.? The latter can eat up memory and block the main thread. I'd let In the meantime, here's something that utilizes the filesystem using import { Asset } from 'expo-asset'
import * as THREE from 'three'
import { useLoader } from '@react-three/fiber'
const getAsset = (input) => {
if (input instanceof Asset) return input
switch (typeof input) {
case 'string':
return Asset.fromURI(input)
case 'number':
return Asset.fromModule(input)
default:
throw 'Invalid asset! Must be a URI or module.'
}
}
class ExpoTextureLoader extends THREE.Loader {
async load(url, onLoad) {
// Generate & cache asset
const asset = await getAsset(url).downloadAsync()
// There's no Image in native, so we create & pass a data texture instead
const texture = new THREE.Texture()
texture.isDataTexture = true
texture.image = { data: asset, width: asset.width, height: asset.height }
texture.needsUpdate = true
return onLoad(texture)
}
} // Suspense is enabled by useLoader here, and the response is cached
const textureSrc = url || require('./path/to/asset')
const texture = useLoader(ExpoTextureLoader, textureSrc) |
Beta Was this translation helpful? Give feedback.
-
Hi everyone, I've combined your code and expo textureloader, its something like this
}` |
Beta Was this translation helpful? Give feedback.
-
Choose .ktx2 format for best performance, its easy on gpu Check this out : https://github.com/HacksawStudios/basisu |
Beta Was this translation helpful? Give feedback.
Hi everyone, I've combined your code and expo textureloader, its something like this
`export default class ExpoTextureLoader extends THREE.TextureLoader {
load(asset, onLoad, onProgress, onError) {
if (!asset) {
throw new Error('ExpoTHREE.TextureLoader.load(): Cannot parse a null asset');
}
let texture = new THREE.Texture();
(async () => {
const fixAsset = await getAsset(asset).downloadAsync()
function parseAsset(image) {
texture.image = image;
texture.needsUpdate = true;
}