vasturiano / globe.gl

UI component for Globe Data Visualization using ThreeJS/WebGL
https://vasturiano.github.io/globe.gl/example/world-population/
MIT License
2.03k stars 301 forks source link

All materials render black on some mobile devices #44

Open Supernuija opened 3 years ago

Supernuija commented 3 years ago

Testing on various mobile devices (phones and pads) indicates that depending on the drivers, GPU:s and browser versions three.js may render all or some objects pitch-black. In this case with globe.gl most of the coloured objects rendered correctly but the textured dark night globe didn't.

Mobile device having the same GPU/processor may behave differently depending on the phone model and year; older may work while newer doesn't. The same device may operate correctly with Chrome but not with Firefox etc.    

The solution to this would be using material precision: 'mediump' on all mobile devices as a default value. Solving this has first been suggested in 2018 by @Mugen87 https://github.com/mrdoob/three.js/issues/14570. These examples are from another thread, and I can confirm that this is an issue. Testing various devices using these two tests below confirmed it.    This will show a white cube on all devices:   var material = newTHREE.MeshPhongMaterial( { precision: 'mediump' } );  https://jsfiddle.net/f2Lommf5/6721/embedded/result   This will not show a white cube on some devices, rendering it pitch-black   var material = new THREE.MeshPhongMaterial( { precision: 'highp' } );  https://jsfiddle.net/f2Lommf5/6722/embedded/result   IHMO is very important that 3D graphics operate flawlessly by default on all devices capable of running them, despite the bad drivers, operating systems, or browser versions.   Is anyone interested to investigate a solution to this? I am willing to test and confirm how possible solution works with various devices. 

vasturiano commented 3 years ago

@Supernuija thanks a lot for creating this issue, and for investigating this! Much appreciated.

As of now, I'm not totally certain that forcing mediump by default on the renderer in this repo is the best long-lasting approach. Specially if the default may be switched internally at some point in threejs as part of https://github.com/mrdoob/three.js/issues/14570. I'm inclined to wait until that resolves, as it feels like something to be solved at the framework level.

But, one can optionally set that in the user application via the rendererConfig settings, at instantiation time. Like so:

const myGlobe = Globe({ rendererConfig: { precision: 'mediump' }})

So, at least for the intent of testing this option can be used. Would you mind checking if this addresses all the rendering issues in your examples?

Supernuija commented 3 years ago

Thanks for your suggestion, I had now a bit more time to investigate this issue further. The solution I am looking for would be some simple way to set that value when browsing any external site that uses three.js and has this issue. If I understood correcty, the method you described above can be set only on server side.

So do you have any ideas, if someone would like to see your site https://vasturiano.github.io/globe.gl/example/world-population/ with a device that has this render black issue correctly? How could one insert that value you suggested above in e.g. url to make sure that the globe map displays with continents viewing your site, and not totally black? I ran out of ideas...

I know that these kind of irritating bugs in various devices caused by manufacturers are not on top of anyone's fix list. That's why any simple solution that wouldn't require three.js to fix this would be great to pass on to anyone who wants to ensure correct display of any website in mobile. That would be a lifesaver!

vasturiano commented 3 years ago

@Supernuija I understand your struggle. This is an internal application setting though, so I cannot think of a way that a user could override this via the url or any other means. Maybe if you hack the WebGL browser config, but that's quite far-fetched, I don't think any browser really exposes this level of config, nor would it be an easy thing to do.

Basically, it's a decision of the app developer to set the renderer precision to mediump. Or they could expose this specific setting to the user in some way, but that's totally the developper's specific call, and not a generic approach.

Supernuija commented 3 years ago

Just out of curiosity, would you be willing to make a quick test version on your server of e.g. https://vasturiano.github.io/globe.gl/example/world-population/ - scene with that 'mediump' setting that I could test and report to you how it looks on various devices.

As said above, I am pretty confident that three.js is just wishing that this problem would vanish by itself during the years. For me, the usability comes always first, and despite the bad HW/SW producers, things should always work, no matter what. When one must choose between the finest quality rendering vs. the fact that some users will not see the materials at all (like in your globe, no visible continents) and setting default slightly lower quality instead, I am more for the latter one.

I did test one other site already where the site owner created quickly a set that was defaulting to mediump, and at least I couldn't tell any quality difference my test set no difference between highpand mediump, the only difference was that the materials were not matte black. ; )

vasturiano commented 3 years ago

I've made a codepen with the basic example set to mediump precision: https://codepen.io/vasturiano/pen/JjWrEPX?editors=0010

You should also be able to easily switch the precision to highp or lowp by editting the code.

Are you able to test with that example?

Supernuija commented 3 years ago

Thanks for super fast work! I will test it as soon as possible. That codepen example is great for checking out the quality options on different devices. Have some other projects going on now but I will test that this coming week! =)

Supernuija commented 3 years ago

Now I have completed my tests and here are the results: https://drive.google.com/drive/folders/15xdeVIgehmLVLsGqWG9ZNR_ysT_Wjy0F?usp=sharing

As I suspected it behaves exactly like I expected, rendering highp pitch black on some device/browser combinations. Using highp setting breaks it, and at least I couldn't see any difference in quality between using lowp, mediump, highp on Chrome browser that renders all three values correctly in one device.

I have been investigating this same issue regarding also another project, and there was recently a little breakthrough in figuring out when bug always occurs by the author of that project. With a simple pre-rendering test one can see if the bug occurs, and then set the mediump value when needed. See https://github.com/kovacsv/Online3DViewer/issues/69.

vasturiano commented 3 years ago

@Supernuija thanks for testing this. Do you have a list of devices/browsers that are known to have issues with highp? And a list of those that we know don't have any issues?

Supernuija commented 3 years ago

Used browsers were the latest versions of Chrome and Firefox. Samsung J5 (2014) operates correctly with both browsers but newer Samsung J5 (2016) fails with both browsers. Both these phones have the same Adreno gpu. Sony Xperia Z2 pad works with Chrome but fails with Firefox and has another Adreno gpu than Samsung's have. This indicates clearly that this issue is really arbitrary, unpredictable and can affect any device/browser combination, especially on Android side.