swift 如何更改ARKit更新函数频率(FPS)?

zazmityj  于 2023-04-19  发布在  Swift
关注(0)|答案(2)|浏览(155)

我目前正在努力限制我的ARKit iOS应用程序的CPU负载。为了做到这一点,我需要限制每秒会话的时间量(_ didUpdate:函数是每秒被调用的。我试着改变我的ARSCNView的preferredFramesPerSecond属性。这确实降低了传入视频的fps,但更新函数仍然被调用了疯狂的次数每秒。我的另一个解决方案是使用传入的ARFrame的timeStamp属性,并计算最后保存的渲染时间之间的差异。我尝试在Swift Playgrounds上运行程序,但由于某种原因,在渲染循环中设置TimeInterval类型的变量失败。这个解决方案在普通的iOS应用程序上确实有效。有没有合适的方法可以直接设置ARKit更新函数的频率?
当前代码:
我的AR属性:

private lazy var lastRenderTime = Date().timeIntervalSince1970

private lazy var sceneView: ARSCNView = {
    let sceneView = ARSCNView()
    sceneView.session.delegate = self
    sceneView.preferredFramesPerSecond = 30
    sceneView.debugOptions = [.showFeaturePoints]
    sceneView.translatesAutoresizingMaskIntoConstraints = false
    return sceneView
}()

委托实现:

extension MainViewController: ARSessionDelegate {
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        let timeSinceLastUpdate = lastRenderTime - frame.timestamp

        if timeSinceLastUpdate >= 0.1 || timeSinceLastUpdate < 0 {
            lastRenderTime = frame.timestamp
            // Do Updating Stuff
        }
    }
}
cpjpxq1n

cpjpxq1n1#

所以我也遇到了同样的问题,我找到了一个不错的解决方案来解决这个问题。你可以设置一个timer变量,然后根据timer调用didUpdate函数中所需的任何内容。我将在下面提供一些代码示例,其中我将每隔0.5秒调用一次session Didupdate帧函数。(你可以修改它以适应任何看起来最好的情况)
代码示例:

//setting up timer variables and functions 
    var time = 0.0
    var timer = Timer()

    func startTimer() {
        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
    }

    func resetTimer() {
        timer.invalidate()
        time = 0
        startTimer()
    }

    @objc func updateTime() {
        if time < 0.5 {
           time += 0.1
        } else {
            resetTimer()
        }
    }

在您的viewdidload或viewwillappear调用

startTimer()

最后,在didUpdate函数中创建一个条件语句

if time != 0.5 {
   return
} else {
   * your code * 
}
v1l68za4

v1l68za42#

我找不到直接影响会话每秒帧数的方法,但我想出了一个可能有效的解决方案。

/// Keeps track of the number of frames that render in a session.
var frameCount: UInt64 = 0

/// This runs the update() function every other frame.
func session(_ session: ARSession, didUpdate frame: ARFrame) {
    
    if frameCount % 2 == 0 {
        update()
    }

    frameCount += 1
}

// Place all of your scene logic in here.
func update() {
    ...
}

您可以调整模数值2,以获得所需的帧率。例如,如果场景以120 FPS运行,则模数4将每秒运行update()函数30次。

相关问题