Неправильное рисование с помощью SceneKit с наложением на macOS Sierra

#sprite-kit #scenekit #macos-sierra

#sprite-kit #scenekit #macos-sierra

Вопрос:

Я использую два SCNView для рисования своего интерфейса, и у меня есть наложение SpriteKit (на самом верхнем SCNView для функций, подобных HUD. На macOS 10.11 (El Capitan) все работает нормально, но на 10.12 (Sierra) наложение, похоже, смешивается с альфа-фоном.

Сравните 10.11 (ожидаемый результат):

macOS 10.11

С выводом на 10.12:

macOS 10.12 полностью прозрачный фон

Стек просмотра:

  • SCNView (непрозрачный черный фон)
  • SCNView (очистить фон)
    • Наложение SpriteKit (частично прозрачное, частично непрозрачное)

Желтый квадрат (альфа = 0,50) и красный квадрат (непрозрачный) взяты из наложения . Белый куб нарисован в самом верхнем (прозрачном) SCNView .

Когда я делаю фон полупрозрачным, больше квадратов становится видимым, оставаясь прозрачным:

macOS 10.12 полупрозрачный фон

Код для этой настройки:

     sceneView.scene=SCNScene()
    sceneView.scene?.rootNode.addChildNode(SCNNode(geometry: SCNBox(width: 10, height: 10, length: 10, chamferRadius: 1)))

    //An overlay
    let overlayScene=SKScene(size: CGSize(width: 500, height: 10))
    overlayScene.scaleMode = .resizeFill

    let bar=SKSpriteNode(color: NSColor.yellow.withAlphaComponent(0.5), size: CGSize(width: 250, height: 40))
    bar.anchorPoint=CGPoint.zero

    let smallBar=SKSpriteNode(color: NSColor.red, size: CGSize(width: 250, height: 20))
    smallBar.position=CGPoint(x: 125, y: 20)

    bar.addChild(smallBar)
    overlayScene.addChild(bar)

    sceneView.overlaySKScene=overlayScene

    //Optionally:
    sceneView.backgroundColor=NSColor.black.withAlphaComponent(0.5)
  

Я не смог найти ничего, чтобы заставить Sierra правильно отображать наложение, например, установить режим наложения сцены SpriteKit.

Любые предложения о том, как я могу исправить эту проблему с рисованием?

Комментарии:

1. Похоже, проблема с линейным цветовым пространством. Можете ли вы попытаться установить для ключа ‘SCNDisableLinearSpaceRendering’ значение YES в вашем info.plist?

2. Это обеспечивает правильное поведение прозрачности. Цвета все еще немного отличаются. Я не смог найти никакой реальной информации о том, как все это работает и почему наложение исчезает на заднем плане при линейном пространственном рендеринге. У вас есть какая-нибудь документация?

Ответ №1:

Есть ли что-то, чего вы нам не показываете? Это работает для меня, используя проекты, созданные с помощью Xcode 7 или Xcode 8, на MacBook Pro под управлением 10.12. Может быть, это проблема с графической картой?

введите описание изображения здесь

Я не вижу, где вы меняете режим наложения SKOverlay . Поэтому по умолчанию .alpha используется значение per docs.

Чтобы воспроизвести мой проект, начните с игрового шаблона Xcode SceneKit. Удалите mouseDown определение из GameView класса. Импортируйте SpriteKit в GameViewController.swift и awakeFromNib замените этим:

 override func awakeFromNib(){
    super.awakeFromNib()

    // create a new scene
    gameView.scene=SCNScene()
    gameView.scene?.rootNode.addChildNode(SCNNode(geometry: SCNBox(width: 10, height: 10, length: 10, chamferRadius: 1)))

    //An overlay
    let overlayScene=SKScene(size: CGSize(width: 500, height: 10))
    overlayScene.scaleMode = .resizeFill

    let bar=SKSpriteNode(color: NSColor.yellow.withAlphaComponent(0.5), size: CGSize(width: 250, height: 90))
    bar.anchorPoint=CGPoint.zero

    let smallBar=SKSpriteNode(color: NSColor.red, size: CGSize(width: 250, height: 30))
    smallBar.position=CGPoint(x: 125, y: 50)

    bar.addChild(smallBar)
    overlayScene.addChild(bar)

    gameView.overlaySKScene=overlayScene

    //Optionally:
    gameView.backgroundColor=NSColor.black.withAlphaComponent(0.5)

    // create and add a camera to the scene
    //        let cameraNode = SCNNode()
    //        cameraNode.camera = SCNCamera()
    //        gameView.scene!.rootNode.addChildNode(cameraNode)

    // place the camera
    //        cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)

    // create and add a light to the scene
    let lightNode = SCNNode()
    lightNode.light = SCNLight()
    lightNode.light!.type = SCNLight.LightType.omni
    lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
    //        gameView.scene!.rootNode.addChildNode(lightNode)

    // create and add an ambient light to the scene
    let ambientLightNode = SCNNode()
    ambientLightNode.light = SCNLight()
    ambientLightNode.light!.type = SCNLight.LightType.ambient
    ambientLightNode.light!.color = NSColor.darkGray
    //        gameView.scene!.rootNode.addChildNode(ambientLightNode)

    // allows the user to manipulate the camera
    self.gameView!.allowsCameraControl = true

    // show statistics such as fps and timing information
    //        self.gameView!.showsStatistics = true

}
  

Комментарии:

1. Спасибо за ваш ответ. Пожалуйста, удалите последнюю строку из вашего awakeFromNib() . Я думаю, вы пропустили ту часть, которая у меня (самая верхняя) SCNView прозрачная. Затем ваш проект показывает то же поведение, что и мой.

2. Мало того, я пропустил часть о двух разных SCNViews друг над другом! Вот пересмотренный вид. Я думаю, я оставлю этот ответ здесь, но это не решение.

3. Что меня немного удивляет, так это то, что на вашем новом скриншоте квадраты не становятся прозрачными. Когда я удалил вашу последнюю строку в своей копии, (серый) фон стал виден за обоими квадратами, как на моем 3-м скриншоте.

4. В моем примере используется только один SCNView с overlaySKScene вместо двух SCNViews, как у вас. Похоже, это может быть актуально, но я не тестировал.

Ответ №2:

Если вы создаете подкласс своего SCNView, переопределите метод viewDidMoveToWindow() и не вызывайте super.viewDidMoveToWindow() в этом методе, он может сработать. У меня была очень похожая проблема с добавлением overlaySKScene в SCNView, и это устранило проблему с цветом. Однако по какой-то причине вид может изначально мигать красным.