录屏时如何在不影响相机feed的前提下减慢ARSession实现3D慢动作
需求可实现性结论
这个需求完全可实现。你之前调用arView.session.pause()会冻结相机feed,是因为这个接口会停止整个AR管线的所有运行逻辑——既包括相机帧采集,也包括设备运动追踪、场景计算,本质是把整个AR功能停了,根本不适合用来做虚拟内容的慢放效果。
AR渲染本身是两套完全解耦的渲染流:底层是相机实时采集的feed纹理,上层是叠加对齐的3D虚拟增强内容,两层的更新逻辑可以完全独立控制,不需要为了调整虚拟内容的速率影响相机输出。
最优实现方案:虚拟内容时间缩放
这是效果最好、性能损耗最低的实现方式,全程不需要修改ARSession运行状态,也不需要调整全局渲染帧率:
- 保持ARSession全程正常运行,不要调用暂停、修改采集配置类的接口,相机feed会始终按设备原生帧率流畅输出,6DoF追踪也不会中断,不会出现虚拟内容对位漂移的问题。
- 不要直接用系统每帧回调给出的真实时间差(deltaTime)驱动3D对象的运动、动画、物理模拟,单独维护一个慢放时间系数:比如要实现《黑客帝国》0.2倍速的慢动作效果,就把每帧拿到的真实deltaTime乘以0.2,再把这个缩放后的时间差传给所有3D虚拟内容的更新逻辑。
- 如果你用RealityKit开发,不需要自己写时间拦截逻辑,直接修改
arView.scene.speed属性即可,属性值设为目标慢放倍率(比如0.2对应五倍慢放),这个属性只会控制场景内所有虚拟内容的动画播放、物理运动速率,完全不会影响相机feed和AR追踪,一行代码就能实现效果。 - 如果你用SceneKit或者自定义Metal/OpenGL渲染管线,就在每帧的渲染更新回调里自行拦截原始deltaTime,乘上慢放系数后再传给虚拟内容的动画、物理更新模块即可,物理引擎的固定时间步长也同步使用缩放后的值,避免物理模拟穿模、速率异常。
你提到的「自主管理渲染帧、降低3D渲染FPS」思路说明
这个思路确实可以跑通,但不是最优方案,存在明显缺陷:
- 降低3D渲染帧率会让虚拟内容出现明显的卡顿感,真正的慢动作效果是流畅的速率放缓,不是掉帧导致的跳变卡顿,观感差距很大。
- 手动分离3D内容和相机feed的渲染帧,很容易出现帧同步问题,导致虚拟内容和真实画面对位不准、画面撕裂,调试成本很高。
实现注意事项
不要为了慢放效果修改ARSession的相机采集配置、不要调整相机feed的输出帧率,相机层保持原生帧率运行是保证画面流畅、AR追踪稳定的核心,所有慢动作逻辑只需要作用在上层虚拟内容层即可。
- 如果只需要在屏幕录制阶段触发慢动作,加一个简单的状态开关就行:录制开启时把慢放系数设为目标值,录制结束后把系数改回1,全程不需要重启、暂停ARSession,状态切换完全无感知。
内容的提问来源于stack exchange,提问作者Csabi
相关产品推荐
相关产品推荐

