相同的颜色在 SpriteView 和 SceneView 中呈现不同的效果

2023-12-27

出于性能原因,我必须在 macOS 项目中从 SceneView 切换到 SpriteView(显示超过 63 个场景无法使用 SceneView,但可以使用 SpriteView)。

但现在我面临一个问题,SpriteView 渲染颜色与 SceneView 不同。下面是我面临的问题的简单再现。

我尝试了多种材质和照明选项,但我似乎错过了一些更基本的东西。非常感谢您的帮助。

    var body: some View {
        
            HStack {
                
                // SpriteView
                SpriteView(scene: { () -> SKScene in
                    
                    let scene = SKScene()
                    scene.backgroundColor = .white
                    scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
                    
                    let node = SK3DNode()
                    node.scnScene = self.sphereScene
                    scene.addChild(node)
                    
                    return scene
                }())

                // SceneView
                SceneView(scene: sphereScene,
                          options: [.autoenablesDefaultLighting])
            }
    }
    
    var sphereScene: SCNScene {
        
        let scnScene = SCNScene()
        
        let ballGeometry = SCNSphere(radius: 5)
        let ballNode = SCNNode(geometry: ballGeometry)
        
        let material = SCNMaterial()
        material.diffuse.contents = NSColor.purple
        material.lightingModel = .physicallyBased
        ballGeometry.materials = [material]
        
        scnScene.rootNode.addChildNode(ballNode)
        
        return scnScene
    }

你说得完全正确:SpriteKit 处理 SceneKit 场景的方式与 SceneKit 不同。视觉上可以明显看出,90度反射的照明强度、高光模糊和边缘脱色都是不同的。在这种情况下可以建议的主要工具是使用环境光根据 SceneKit 内容额外照亮 SpriteKit 场景。您应该关闭默认照明(为了消除彩色伪影)并使用常规灯光。这里我使用了定向光。

精灵视图:

import SwiftUI
import SceneKit
import SpriteKit

struct SpriteView: NSViewRepresentable {
    
    var scene = SKScene()

    func makeNSView(context: Context) -> SKView {
        let skView = SKView(frame: .zero)
        skView.presentScene(scene)
        scene.backgroundColor = .black
        return skView
    }
    func updateNSView(_ uiView: SKView, context: Context) { }
}

内容查看:

struct ContentView: View {
    var body: some View {
        ZStack {
            HStack {
                SpriteView(scene: { () -> SKScene in
                       
                    let scene = SKScene()
                    scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)

                    let ambient = SCNNode()
                    ambient.light = SCNLight()
                    ambient.light?.type = .ambient
                    ambient.light?.intensity = 1200
                   
                    let node = SK3DNode()
                    node.autoenablesDefaultLighting = false
                    node.scnScene = self.sphereScene
                    node.scnScene?.rootNode.addChildNode(ambient)
                    scene.addChild(node)
                    return scene
                }() )

                SceneView(scene: sphereScene, options: [])
            }
        }
    }
   
   var sphereScene: SCNScene {
       
       let scnScene = SCNScene()
       scnScene.background.contents = NSColor.black
       let ballNode = SCNNode(geometry: SCNSphere(radius: 5.0))
       
       let directional = SCNNode()
       directional.light = SCNLight()
       directional.light?.type = .directional
       directional.light?.intensity = 500
       scnScene.rootNode.addChildNode(directional)
       
       let material = SCNMaterial()
       material.lightingModel = .physicallyBased
       material.diffuse.contents = NSColor.purple
       ballNode.geometry?.materials = [material]
       scnScene.rootNode.addChildNode(ballNode)
       return scnScene
   }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

相同的颜色在 SpriteView 和 SceneView 中呈现不同的效果 的相关文章

随机推荐