Three.js: RectAreaLightUniformsLib.js is broken on iOS 14

Created on 25 Sep 2020  路  7Comments  路  Source: mrdoob/three.js

Describe the bug

examples/js/lights/RectAreaLightUniformsLib.js does not work in iOS 14. It used to work on iOS 13 (with some linear banding artefacts in the reflection of the area light), but under iOS 14 an area light created using this library is simply black and gives no light.

To Reproduce

Steps to reproduce the behavior:

  1. Go to https://threejs.org/examples/?q=area#webgl_lights_rectarealight
  2. On desktop, the area light is completely white
  3. On iOS 13, the area light reflection has horizontal bands
  4. On iOS 14, the area light is black and does not illuminate the scene and an error message says "OES_texture_float_linear not supported"

Screenshots

Desktop (Chrome on Win 10):

image (9)

iOS 13 (iPad Air 2019 model):

File (1)

iOS 14 (iPhone 11):

File

Diagnosis:

The problem seems to be caused by a change in Webkit in Safari on iOS 14. Previously in iOS 13 Webkit would claim it supported the WebGL extension OES_texture_float_linear but it actually didn't. Now in iOS 14, Webkit correctly reports that it does not support that extension.

Suggested fix:

Change RectAreaLightUniformsLib to fallback from THREE.LinearFilter to THREE.NearestFilter when the OES_texture_float_linear WebGL extension is not available.

Device Issue

Most helpful comment

Thanks @Mugen87 we'll look into that. It's nice to know a PR would be welcome!

All 7 comments

Change RectAreaLightUniformsLib to fallback from THREE.LinearFilter to THREE.NearestFilter when the OES_texture_float_linear WebGL extension is not available.

Sounds good. Do you mind creating a PR with the fix?

Thanks @Mugen87 we'll look into that. It's nice to know a PR would be welcome!

I've added a draft pull request (see above), which works when I tested it on iOS 14, and also still works on iOS 13 and Chrome for Windows. However, to access the renderer I changed the API from RectAreaLightUniformsLib.init() to RectAreaLightUniformsLib.init(renderer).

I'd love suggestions on how to avoid changing the API if possible.

Reconsidering this issue: I'm not sure anymore if using NearestFilter is actually an appropriate fix.

Maybe it would be better to check if OES_texture_half_float and OES_texture_half_float_linear can be used. This is also mentioned in the original PR: #9234

explore using HalfFloat textures instead of Float to increase mobile support

I agree that would be a better approach, as it would avoid rendering area lights with visible artefacts, but it would take a little bit longer to implement.

From a quick test on iOS 13 and 14 using Khronos comformance tests, it looks like OES_texture_half_float and OES_texture_half_float_linear are supported.

Using half-float for area lighting involves converting the two 16k float32 arrays in examples/jsm/lights/RectAreaLightUniformsLib.js to uint16 arrays via a function like toHalf(): https://github.com/mrdoob/three.js/blob/ff48de58e216bc72abb4085a080c5acb66f2f584/examples/js/loaders/RGBELoader.js#L348

I've created PR #20477 which uses half-float instead of float and renders area lighting without artefacts on Windows, iOS 13 and iOS 14.

I've put some to-do items and questions in the PR.

Whatever you guys are providing solution above, Is it helpful with jsQR library? because i am using jsQR library to scan the QR code and its not working with latest release version 14 on iOS device and also i am not using three.js.
Can anyone suggest me to resolve it?

Was this page helpful?
0 / 5 - 0 ratings