I recently posted this issue in the react-three/fiber github discussions, but wanted to also see if there was perhaps anything that could be done pulling some native three.js strings to work around whatever the issue might be with the fiber implementation.
I’m working on a web app using react and react-three/fiber to implement a 3D environment. Everything is working normally on desktop browser and Android, and older versions of iOS, I’d been using on a dev ipad. I recently upgraded that ipad to the latest iOS 17.5.1 (at this time), and now there is an error when dealing with textures that is causing a fatal loss of context and crashes the 3D portion of the app.
Trying to log errors, from what i can tell there is some issue with the three.js implemented in the current react-three/fiber (8.16.8).
TypeError: null is not an object (evaluating 'gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision') [object Object]
LOGTHREE.WebGLRenderer: Context Lost.
which appears to be from this block of code found in my node_modules/three/build/three.cjs
Though this seems to be from the native three.js library, I’ve only found the error to occur when using a react-three/fiber implementation of the 3D environment.
My app is rather expansive to share, but this problem is readily seen exhibited with the online react-three/fiber tutorial examples. React Three Fiber Tutorials - Material Picker working example page of example with code
To see the issue, open the above linked examples on an ipad with iOS 17.5.1(21F90) it will produce a black screen.
Yes, the ipad that is exhibiting the issue described, and currently cannot see the example link from above, can see the rotating cube with numbers from the link you provided, saying “Your browser supports WebGL2”.
this would be quite impossible. r3f is vanilla threejs. any and every webgl crash is threejs. i would start by reducing texture size, 1k or 2k max. also reduce the amount of textures, instead of dozens of textures use a single atlas map. i’ve seen ios cancel the webgl context over memory limitations in the past.
Thanks for the recommendations on reducing demand, however that doesn’t seem to be a factor in this case. The issue is not specific to my application.
I understand that R3F is simply a wrapper around vanilla three.js, however the root cause certainly appears to be with how react-three/fiber is handling things. Perhaps it’s an asynchronous issue, or other factor that is causing an unexpected order of events, and in the iOS execution, the data required is still null at the time it is used.
not even a wrapper or a binding, it’s a renderer. it directly renders your jsx as threejs, there isn’t anything in between, it doesn’t even know what a mesh/group/material/texture/etc is. canvas merely sets up a webglrenderer. i can assure you you’re looking in the wrong direction.
there might be an issue with this sbcode thing in general, or how they set up textures, i don’t know. if you have a simplified sandbox that crashes in ios and the same box in vanilla doesn’t, i will look at it.
I can appreciate what you’re saying, but I have yet to actually find an R3F example that works, while all the plain three.js examples are working fine. Every R3F example that fails is reporting the same error I’ve described above.
I don’t have an exact side by side plain three.js and R3F example of the same exact code off hand, but here are some more examples in the mean time that aren’t working, just to show this is an issue that exhibits itself in every instance of R3F I can find from various sources, including the official site.
These are all in codesanbox for direct viewing of code and errors in iOS.
@mbaycura thanks for bringing attention back to this - I’ve seen it happen earlier, but it seemed to be happening due to WebGL2 support deprecation. Didn’t realize vanilla three.js was still working, and the issue could be related to r3f specifically.
Which iPad specifically (hardware, not software) are you testing on (which gen) ? I tested iPad 7th / 8th on Browserstack, and sandboxes you’ve shared are working there.
The ipad hardware I’m working with is a model A1701, 10.5" ipad-Pro (2017 i think).
It’s an older model, but worked just fine before the most recent iOS update.
Admittedly, I’m not an expert in this, but it feels like there is a timing issue with variables being used before being initialized somewhere, related possibly to react’s asynchronisity, and perhaps the speed, and/or order that the iOS is running instructions on an older gen ipad.
On one visit, to the non-working links, I’ve supplied, it did manage to render once on the ipad, but have not been able to repeat that. Not sure if the codesandbox was changed briefly, it did appear another user was in the codesandbox at that time, or the issue is actually intermittent, but happens so often that it appears constant.
Ok, here are some sandboxes for direct comparison.
I have two cube components one using vanilla three.js and one using R3F.
Here are 3 sanboxes, one with both components, one with only the fiber cube, and one with only the vanilla cube.
On my ipad i can see the vanilla cube rotating fine and i can see the both ways app if i comment out the fiber cube component. I get the described null error if I try to view the fiber only or the both ways with fiber cube enabled.
React-three-fiber uses defaults that make it heavier on memory than vanilla three.js - hence three examples keep working while R3F crashes with context loss. For Apple devices R3F enables both high DPR and antialiasing - which overloads the memory while having 0 visual difference. You can safely disable antialiasing on Canvas element - that makes iPads work again with no memory issues.