4

I have a nasty problem with a SceneKit app when running on iPhone X (iOS 11.1.2) with the Metal renderer. The app has the plist key SCNDisableLinearSpaceRendering set to YES in order to get the same color rendering on iOS 9 and later versions. It also has a SpriteKit 2D overlay added via overlaySKScene.

In release builds, the iPhone X shows weird colors in the overlay, but not in the 3D scene. Debug builds crash with the error log:

-[MTLDebugRenderCommandEncoder validateFramebufferWithRenderPipelineState:]:1196: failed assertion `For color attachment 0, the render pipeline's pixelFormat (MTLPixelFormatRGBA8Unorm_sRGB) does not match the framebuffer's pixelFormat (MTLPixelFormatBGR10_XR).'

The way I understand this is that the pixel format of the 2D and 3D scenes are different. I have no idea how I could change that. Any suggestions?

The error will only show on the iPhone X, not the simulator or any other device I have tested (4s, 5s, 6 Plus, 6s, 7, iPad Pro 1G). When I use the OpenGL ES renderer, everything is fine. When I switch off SCNDisableLinearSpaceRendering, everything works with the Metal renderer too, but the 3D color rendering is very different, of course.

If you have an iPhone X you can reproduce this by creating a new project from the Game template and adding this code in viewDidLoad():

let overlaySize = CGSize(width: 100, height: 100)
let overlay = SKScene(size: overlaySize)
let sprite = SKSpriteNode(color: UIColor.blue, size: overlaySize)
overlay.addChild(sprite)
scnView.overlaySKScene = overlay

I'd also be very interested to hear if this also occurs on iPhone 8/8 Plus?

Dorian Roy
  • 3,094
  • 2
  • 31
  • 51
  • did you see https://stackoverflow.com/questions/39522086/scenekit-how-to-reproduce-ios-9-lighting-color-effect-one-directional-one-amb – Knight0fDragon Nov 27 '17 at 19:41
  • @Knight0fDragon found one workaround, but are you aware of any drawbacks? https://stackoverflow.com/questions/49246043/ios-drawbacks-of-disabling-metal-api-validation-in-order-to-fix-pipeline-failed – Crashalot Mar 12 '18 at 23:39
  • Disabling the API validation just helps you with the crashing debug builds. But the color shifting will still occur. As far as I know release builds won't crash anyway (I came across this bug when my app was already live). – Dorian Roy Mar 13 '18 at 08:32
  • @DorianRoy Assert is ignored on release, so the problem should still exist, just the error goes away – Knight0fDragon Mar 13 '18 at 13:29

3 Answers3

3

One valid workaround is to disable Metal API Validation (in Edit Scheme > Options).

Not sure what the drawbacks are, but at least the app doesn't crash with this.

Crashalot
  • 33,605
  • 61
  • 269
  • 439
1

In the meantime I saw people reporting several other SceneKit issues with iOS 11. So I believe this is a bug in iOS 11. I filed a radar a month ago but the problem still exists in 11.2.5.

My current workaround ist to use the OpenGL ES renderer instead of Metal.

Dorian Roy
  • 3,094
  • 2
  • 31
  • 51
  • Is it possible to use OpenGL for just some brief animations in a SpriteKit overlay and Metal for everything else? Trying to work around this bug as well, but would like to preserve Metal where possible. How did you switch to OpenGL? – Crashalot Mar 12 '18 at 23:04
  • 1) No. You can only use one renderer at a time – Dorian Roy Mar 13 '18 at 08:35
  • 2) You choose the renderer in renderingAPI property of your SCNView – Dorian Roy Mar 13 '18 at 08:37
  • I have read that if you do not call `presentScene` and instead manually assign the scene variable to the view that this problem goes away. Can anybody verify this? – Knight0fDragon Mar 13 '18 at 13:30
  • @Knight0fDragon not sure how this happened, but we dropped all the code into a new scenekit project and the code magically started working ... the scene var, for what's it worth, is and was always manually assigned. – Crashalot Mar 13 '18 at 15:51
  • @Crashalot then perhaps they fixed the issue with the new project – Knight0fDragon Mar 13 '18 at 15:52
  • @Knight0fDragon how would it get fixed on a project level basis? thanks for the fast reply! – Crashalot Mar 13 '18 at 15:53
  • Because the settings are using the proper colorspace for spritekit and scenekit – Knight0fDragon Mar 13 '18 at 15:58
1

Try setting SCNDisableWideGamut to YES in the app's Info.plist file. It works for me. (credit to http://stackoverflow.com/questions/49988314/scnview-present-alternative)

slfan
  • 8,950
  • 115
  • 65
  • 78
babibo
  • 305
  • 1
  • 8