Texture is Causing loss of context in ipadOS (iOS) 17.5.1 When Using react-three/fiber

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

	function getMaxPrecision( precision ) {
		if ( precision === 'highp' ) {
			if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
				gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
				return 'highp';
			}
			precision = 'mediump';
		}
		if ( precision === 'mediump' ) {
			if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
				gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
				return 'mediump';
			}
		}
		return 'lowp';
	}

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.

Does WebGL2 support website work on the device you’re testing on?

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.

Every example with plain three.js using textures, even rapidly animated, works fine
(works) plain three.js - Animating Texture on rotating cube
(works) plain three.js - CodeSandbox Yellow Checkerboard, animated texture
(works) plain three.js - texture2darray example, looping video texture
Any example from the three.js site except for webGPU examples.

Every example applying texture using R3F fails
(not working) react-three/fiber - Material Picker from R3F tutorial site
(not working) react-three/fiber Fisheye example
(not working) react-three/fiber Photogrammetry Example
General Link for react-three/fiber examples

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.

1 Like

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.

Official React Fiber Examples Page
(not working) r3f - Image Gallery Example
(not working) r3f - Cards example

(not working) r3f - codesandbox of animated cube and texture

This online book has a page working with R3F and is walking through implementing R3F code, and beside each code segment is an embedded code mini sandbox and they all fail with the described error.
Shader Book
(embedded examples not working) The Shader Book - section on R3F

@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.

1 Like

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.

Basic-ThreeJS-Cubes-Bothways
Basic-ThreeJS-Cube-Fiber
Basic-ThreeJS-Cube-Vanilla

4 Likes

For any poor soul coming across this issue - and in need of keeping iPad Pro 10.5 support:

<Canvas gl={{ powerPreference: 'default', antialias: false }} />

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.

2 Likes