ARKit 光估计不工作

ARKit light estimation not working

我正在尝试用 ARKit 实现 Light Estimation,但没有成功。我所做的是 运行 一个 session

configuration.isLightEstimationEnabled = true

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

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

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

autoEnablesDefaultLighting是一个布尔值,决定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])

    }
}

希望对您有所帮助...