Why android device is not good for webgl

There’s a million reasons why it may not work well.

(1) You are starting the render loop, and at the same time execute 1200+ lines of loading assets and conditional material updates. Asset requests do affect the rendering for as long as they are active (so if you’re loading a big model, it can slow down the execution for a longer time.)

(1b) Especially considering your use case, it’s best if you pack all the models and textures into a single glTF / glb, allow it to load, adjust materials, and then start rendering. This will also allow you to optimize materials on the go (ex. using mesh names, you can decrease visual quality of items that won’t be much visible anyway, or just hide them altogether.)

(1c) It’s not possible to see how detailed your models and textures are, but be sure the model does not exceed 10k verts and (at least on mobile) textures are optimised - if that’s necessary, use 512-2K textures for albedo and normals, but any other texture can usually have a lower resolution. Use textures appropriate for the object size - metal bolts don’t need 4K albedo maps.

(2) If I remember right how texture sampling worked, setting anisotropy to 100.0 - first, is not power of 2, second, increases texture sampling 100 times. It may decrease performance. A lot.

(3) If your models are very complex, allowing every single submesh to cast and receive shadows may decrease performance.

(4) If your models are complex, setting MeshPhysicalMaterial / MeshStandardMaterial for virtually every submesh (moreover a transparent MeshPhysicalMaterial with transmission enabled) can decrease the performance significantly.

(4b) Instead, for smaller, shiny surfaces you can use MeshPhongMaterial, and MeshLambertMaterial for rough ones.

(4c) Reuse materials. It’s hard to believe none of these submeshes have a similar-looking surface.

(4d) If you absolutely must use this amount of complex materials - precompile them after loading all assets and before rendering the scene.

(5) You don’t have to call renderer.render on every requestAnimationFrame - especially on lower-end devices. Use frame throttling, or intervals to limit framerate to something lower (ex. 30fps) but stable - frame stutter is far more noticable than just a lower framerate.

(5b) There’s nothing stopping you from dynamically adjusting the framerate as well. If you detect that the device is struggling with 60FPS, lock it as 30.

(Bonus) Back in my days you go straight to jail for that:

window.color_change = function color_change(code) { ... };

See also:

2 Likes