1

I am working on a three.js application - when the model becomes fully textured it crashes mobile devices.

Is there a way - like VRML - to apply a field of distance to the model - to use lower resolution textures when further away - or only apply textures to the model seen in POV?

gman
  • 100,619
  • 31
  • 269
  • 393
The Old County
  • 89
  • 13
  • 59
  • 129
  • Maybe you can do something with this: https://stackoverflow.com/questions/17624021/determine-if-a-mesh-is-visible-on-the-viewport-according-to-current-camera – Niels Aug 10 '17 at 11:22
  • 1
    What have you tried already? You don't specify what mobile browser you are using, Or what resolution your textures are or how many you are using. What makes you think the crashing is texture related? Have you tried the numerous other questions here on stack about crashing on mobile? – 2pha Aug 10 '17 at 11:25
  • @2pha to be honest - I've yet to be given the job officially - so I really only know of the problem from a general perspective. From what I've been told it starts to crash when textures are loaded - so I was wondering if three.js has the ability to tailor POV rendering of textures only -- or distance calculation to toggle low res/high res textures.. – The Old County Aug 10 '17 at 13:49
  • AFAIK three doesn't do anything to textures. that's your job. Pre-process your assets offline – gman Aug 10 '17 at 18:19

2 Answers2

1

Here is the output from devtools of both the one that works and the one that doesn't (the links you provided in the comments).
The vertex count does not seem to be a problem.
But take a close look at the sizes of the textures (specifically, the last one).
Phones are not going to have the memory to store all these textures. Resize your textures to a smaller size, eg. 1024

enter image description here

2pha
  • 9,798
  • 2
  • 29
  • 43
0

Without much to go on, here are the things I'd review:

Your textures, likely jpg or png are unpacked as bitmap in ram and take up gobs of resources. For example, If you have 20 textures, and they're 2 mb each, it may be 800mb in allocated ram. Allocations are done in blocks. In Safari mobile for example, loading a 1 pixel image will allocate the same ram as a decoded 1024x1024 image! On the desktop, we have the option of using DDS images or similar to help solve performance issues by keeping those images in VRAM. Unfortunately, mobile support for DDS images is sketchy at best. You can find out how to load DDS images in a simple test and see if it works for your target devices.

If it does not suit your needs, you need to look for optimizations elsewhere:

You can look at your frame rate, understand how often you're asking the browser to render, and limit three to call a render only when the user has input a touch interaction to change the camera or any scene objects.

As well, if you can support DDS images or not, it is recommended to use textures that are 512x512 and 1024x1024 which share multiple textures on a single texture file. Although for Unity, this blog post has useful information that applies to three.js as well. It's good to understand the concepts explained, especially when targeting limited devices.

Also be sure your face count is manageable. The more faces you have, the more indexes you will need for placing textures properly across all those faces. That can lead to very large arrays, and very long procedures in JavaScript which can overrun mobile ram allocations. You can optimize your face counts with a decimation plugin

As for culling, you're unlikely to see a performance gain as you're likely having a ram issue which will be allocated regardless. You could use a decimation plugin, and switch to a specific set of models when a mobile device is detected. You could also determine the camera distance to a mesh to determine if the geometry should be replaced with something more detailed, but you still need to consider all of the above performance issues when loading more detailed models.

Radio
  • 2,810
  • 1
  • 21
  • 43
  • Yeah the face count could be high - its rendering house models – The Old County Aug 10 '17 at 19:39
  • The "index18" example brings my brand new macbookpro to a crawl. It looks like you're really whipping the render() call with your animate function. I would re-approach by nixing the tween and rendering only with the onchange event of the controls object, usually something like controls.addEventListener('change', onChange); where onChange is a function with a render() call. This should help mobile devices greatly, but may not solve everything. – Radio Aug 10 '17 at 19:50
  • :) yeah I may look at these options later. I didn't write this - so still learning three.js geometry functions and trying to resolve possible problems. – The Old County Aug 10 '17 at 19:57
  • I figured, that's why I wanted the answer to cover a bunch of different aspects to think about as you learn in the answer. So... I avoid "requestAnimationFrame" unless I have a continuously updating environment, and would really carefully consider its use on mobile. – Radio Aug 10 '17 at 20:17