swift - ARKit 光估计不工作

标签 swift arkit lightning

我正在尝试使用 ARKit 实现 Light Estimation,但没有成功。我所做的是用

运行一个 session
configuration.isLightEstimationEnabled = true

arSceneView.scene                        = SCNScene()
arSceneView.autoenablesDefaultLighting   = true
arSceneView.automaticallyUpdatesLighting = true

我还需要做些什么才能让它发挥作用吗?场景中没有其他灯光,只有 autoenablesDefaultLighting。我正在使用 iPhone 6s,它是否太旧无法运行此功能?

最佳答案

根据您实际需要实现的目标,以下可能会有所帮助。

autoEnablesDefaultLighting 是一个 bool 值,用于确定 SceneKit 是否自动向场景添加灯光。

默认设置为 false 意味着:

the only light sources SceneKit uses for rendering a scene are those contained in the scene graph.

另一方面,如果将其设置为 true:

SceneKit automatically adds and places an omnidirectional light source when rendering scenes that contain no lights or only contain ambient lights.

这是从相机的位置定位并指向相机的方向。

一个问题Mark Daws在他的优秀文章中指出:

The light has a changing direction, so as you walk around an object it will always look like the light is coming from your point of view (like you are holding a torch infront of you) which isn’t the case normally, most scenes have static lighting so your model will look unnatural as you move around.

isLightEstimationEnabled 另一方面:

provides light estimates in the lightEstimate property of each ARFrame it delivers. If you render your own overlay graphics for the AR scene, you can use this information in shading algorithms to help make those graphics match the real-world lighting conditions of the scene captured by the camera. The ARSCNView class automatically uses this information to configure SceneKit lighting.

这意味着,例如,如果您将房间的灯光调暗,并希望将这些照明条件应用于您的虚拟对象以使其更逼真,这就是您想要使用的;因为有了这些信息,我们可以从每一帧中获取 lightEstimate 并修改我们场景中的灯光强度,以模仿现实世界本身的环境光强度。

您可以通过设置获取lightingEstimate的详细信息:

configuration.isLightEstimationEnabled = true

然后使用以下回调:

//--------------------------
// MARK: - ARSCNViewDelegate
//--------------------------

extension ViewController: ARSCNViewDelegate{

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

        guard let lightEstimate = self.augmentedRealityView.session.currentFrame?.lightEstimate else { return }

        let ambientLightEstimate = lightEstimate.ambientIntensity

        let ambientColourTemperature = lightEstimate.ambientColorTemperature


        print(
            """
            Current Light Estimate = \(ambientLightEstimate)
            Current Ambient Light Colour Temperature Estimate = \(ambientColourTemperature)
            """)


        if ambientLightEstimate < 100 { print("Lighting Is Too Dark") }

    }
}

然后您需要对返回的值做一些事情并将它们应用到您的 sceneLights。

因此将其付诸实践,一个非常基本的示例可能如下所示:

//--------------------------
// MARK: - ARSCNViewDelegate
//--------------------------

extension ViewController: ARSCNViewDelegate{

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

        //1. Get The Current Light Estimate
        guard let lightEstimate = self.augmentedRealityView.session.currentFrame?.lightEstimate else { return }

        //2. Get The Ambient Intensity & Colour Temperatures
        let ambientLightEstimate = lightEstimate.ambientIntensity

        let ambientColourTemperature = lightEstimate.ambientColorTemperature

        print(
            """
            Current Light Estimate = \(ambientLightEstimate)
            Current Ambient Light Colour Temperature Estimate = \(ambientColourTemperature)
            """)

        if ambientLightEstimate < 100 { print("Lighting Is Too Dark") }

        //3. Adjust The Scene Lighting
        sceneLight.intensity = ambientLightEstimate
        sceneLight.temperature = ambientColourTemperature
    }
}

class ViewController: UIViewController {

    //1. Create A Reference To Our ARSCNView In Our Storyboard Which Displays The Camera Feed
    @IBOutlet weak var augmentedRealityView: ARSCNView!
    @IBOutlet weak var takeSnapshotButton: UIButton!

    //2. Create Our ARWorld Tracking Configuration
    let configuration = ARWorldTrackingConfiguration()

    //3. Create Our Session
    let augmentedRealitySession = ARSession()

    //4. Create Our Light
    var sceneLight: SCNLight!

    //-----------------------
    // MARK: - View LifeCycle
    //-----------------------

    override func viewDidLoad() {

        //2. Setup The ARSession
        setupARSession()

        //2. Generate Our Scene
        generateScene()

        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }

    //-------------------------
    // MARK: - Scene Generation
    //-------------------------

    /// Creates An SCNNode & Light For Our Scene
    func generateScene(){

        //1. Create An SCNNode With An SCNSphere Geometry
        let sphereNode = SCNNode()
        let sphereGeometry = SCNSphere(radius: 0.2)
        sphereGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
        sphereNode.geometry = sphereGeometry
        sphereNode.position = SCNVector3(0, 0, -1.5)

        //2. Create Our Light & Position It
        sceneLight = SCNLight()
        sceneLight.type = .omni

        let lightNode = SCNNode()
        lightNode.light = sceneLight
        lightNode.position = SCNVector3(0,0,2)

        //3. Add The Node & Light To Out Scene
        self.augmentedRealityView.scene.rootNode.addChildNode(sphereNode)
        self.augmentedRealityView.scene.rootNode.addChildNode(lightNode)

    }

    //-----------------
    //MARK: - ARSession
    //-----------------

    /// Sets Up The ARSession
    func setupARSession(){

        //1. Set The AR Session
        augmentedRealityView.session = augmentedRealitySession
        augmentedRealityView.delegate = self
        configuration.isLightEstimationEnabled = true
        augmentedRealityView.automaticallyUpdatesLighting = false
        augmentedRealityView.autoenablesDefaultLighting = false
        augmentedRealityView.session.run(configuration, options:[.resetTracking, .removeExistingAnchors])

    }
}

希望对你有帮助

关于swift - ARKit 光估计不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51351353/

相关文章:

ios - 从 Xcode10 部署到 iOS11 设备时,ARWorldTrackingConfiguration 不起作用

opengl-es - 使用 OpenGl 渲染真实的闪电

ios - 基于自定义 .xib 的 CollectionView 超出预期范围

ios - 更新 UIWebView Cookie 的到期日期

ios - 子类化 UITableViewCell & [tableView dequeueReusableCellWithIdentifier :CellIdentifier]

ios - 为什么 SCNNode "jiggling"掉落到 SCNPlane 上?

ios - 类型 'String' 的值没有成员 'removeVowels'

swift - iPad Pro Measure App 如何计算人的高度?

ios5 - iCalendar 创建 : RFC 5546 explanation