Pixel errors on low-end devices

Im using r117 (r118 and greater are making more problems i dont have time to fix) to show some jewellery in the browser.

My code is working fine on windows and linux desktops, ios ipads and most of all android devices but im stuck by one problem on old android-devices

First device OnePlusOne:

Android 10 Lineageos 17.1

  • Firefox and Firefox nightly all fine
  • Android System Webview pixel errors

Second device Galaxy S4 gt-1905:

Android 5.0.1

  • Firefox black objects
  • Chrome pixel error

This is my envirment setup:

function setupEnvirment() {
container = document.getElementById(“viewer”);
camera = new THREE.PerspectiveCamera(30, (viewer).width() / (viewer).height(), 0.1, 500);
camera.position.x = -60;
camera.position.y = 60;
camera.position.z = 60;
var loader = new THREE.CubeTextureLoader();
loader.setPath(‘env/’);
textureCube = loader.load([
‘px.png’, ‘nx.png’,
‘py.png’, ‘ny.png’,
‘pz.png’, ‘nz.png’
]);
textureCube.generateMipmaps = false;
textureCube.magFilter = THREE.LinearFilter;
textureCube.minFilter = THREE.LinearFilter;
scene = new THREE.Scene();
scene.environment = textureCube;
scene.background = new THREE.Color(0xffffff);
var groundMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff
});
var plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(500, 500, 1, 1), groundMaterial);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add(plane);
var light;
light = new THREE.DirectionalLight(0xffffff, 30);
light.position.set(48, 80, 48);
light.castShadow = true;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
var d = 60;
light.shadow.camera.left = -d;
light.shadow.camera.right = d;
light.shadow.camera.top = d;
light.shadow.camera.bottom = -d;
light.shadow.camera.far = 500;
scene.add(light);
webglRenderer = new THREE.WebGLRenderer({antialias: false});
webglRenderer.domElement.style.position = “relative”;
webglRenderer.domElement.className = “viewer”;
webglRenderer.shadowMap.enabled = true;
webglRenderer.shadowMap.type = THREE.PCFSoftShadowMap;
webglRenderer.physicallyCorrectLights = true;
controls = new OrbitControls(camera, webglRenderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.minDistance = 1;
controls.maxDistance = 500;
controls.maxPolarAngle = Math.PI / 2 + 1;
container.appendChild(webglRenderer.domElement);
}

Im loading .stl file and this is my code to add the material to them:

geometry = new THREE.Geometry().fromBufferGeometry(geometry);
geometry.mergeVertices();
geometry.computeVertexNormals();
geometry = new THREE.BufferGeometry().fromGeometry(geometry);
var metallMaterial = new THREE.MeshPhysicalMaterial({
color: new THREE.Color(parseInt(object.color, 16)),
flatShading: false,
metalness: 1.0,
roughness: 0
});
var mesh = new THREE.Mesh(geometry, metallMaterial);
mesh.castShadow = true;
mesh.receiveShadow = true;

Any idea where the problem could be?

Old devices usually use outdated graphics drivers and often have GPUs with insufficient floating point precision in shaders. According to my experience, these cases are hard to fix.

Since three.js built-in materials do not support mediump in shaders yet (related https://github.com/mrdoob/three.js/issues/14570), I’m afraid there is no ad-hoc solution for this issue.

Thanks i understand this for the low-end device Galaxy S4 gt-1905.

But this do not completely match to the OnePlusOne. The scene get rendered correctly in Firefox but not on the Android Default Browser using Android Webview. If the device would not support highp the errors should be the same in the firefox browser?

Are there some better ways to check if a device will working than this one:

#if GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif

Well, it could be a bug in the browser.

The mentioned checks might help although there are mobile devices which basically GPU support high precision but only with bugs. Considering these cases, medium precision would be the better default for mobile devices.