如何在Unity的ARFoundation面部追踪中调整设备相机FOV?
Unity AR面部滤镜自定义相机FOV解决方案(不影响AR子系统)
问题背景
做Unity AR面部滤镜时碰到两个头疼的问题:
- 设备默认相机FOV太大,没法做流畅的自定义缩放,用户体验差
- 试了好几种方法都没搞定:
- 把XR Origin相机画面导到RenderTexture再用UI RawImage显示,结果AR面部滤镜直接不见了
- 给「Camera Offset」 GameObject加了个父物体,调父物体位置只会改滤镜在脸上的位置,缩放父物体又会让滤镜尺寸乱变
- 调用iOS原生相机FOV接口,缩放效果根本达不到预期,还干扰AR Foundation子系统的正常工作
解决方案:改AR Camera投影矩阵实现自定义FOV
核心思路是直接修改AR相机的投影矩阵,不去碰相机自带的FOV属性(避免搞乱AR子系统),同时把AR滤镜的渲染逻辑捋顺,确保能在RenderTexture里正常显示。
1. 先搞定AR滤镜在RenderTexture里显示的问题
- 给XR Origin下的AR Camera指定一个
RenderTexture作为目标纹理 - 检查面部滤镜的Shader:必须用支持渲染到RenderTexture的Shader(比如URP的Lit Shader),别用只认屏幕空间的Shader
- 确认面部滤镜的Layer在AR Camera的Culling Mask里,而且滤镜GameObject是AR Camera的子物体(或者通过AR Face Tracking组件正确绑定到人脸),别让渲染层级丢了
2. 写代码自定义FOV并替换投影矩阵
把下面的脚本挂到AR Camera上,通过计算自定义FOV对应的投影矩阵,替换掉相机的默认矩阵,同时保证AR跟踪数据不受影响:
using UnityEngine; using UnityEngine.XR.ARFoundation; [RequireComponent(typeof(ARCameraManager))] public class CustomARCameraFOV : MonoBehaviour { [Header("自定义FOV")] [Range(30f, 90f)] public float targetFOV = 60f; // 可通过UI滑块动态调,范围自己改 private ARCameraManager _cameraManager; private Camera _arCamera; void Awake() { _cameraManager = GetComponent<ARCameraManager>(); _arCamera = GetComponent<Camera>(); } void OnEnable() { _cameraManager.frameReceived += OnCameraFrameReceived; } void OnDisable() { _cameraManager.frameReceived -= OnCameraFrameReceived; } void OnCameraFrameReceived(ARCameraFrameEventArgs args) { if (_arCamera.projectionMatrix != Matrix4x4.zero) { // 按目标FOV算新的投影矩阵 float aspect = _arCamera.aspect; float near = _arCamera.nearClipPlane; float far = _arCamera.farClipPlane; float halfFOV = targetFOV * 0.5f * Mathf.Deg2Rad; float top = near * Mathf.Tan(halfFOV); float right = top * aspect; // 构建兼容AR的透视投影矩阵 Matrix4x4 customProj = Matrix4x4.Frustum(-right, right, -top, top, near, far); _arCamera.projectionMatrix = customProj; } } // 给UI滑块调用的方法,动态改FOV public void UpdateFOV(float newFOV) { targetFOV = Mathf.Clamp(newFOV, 30f, 90f); } }
3. 别再碰父物体缩放了
之前调「Camera Offset」父物体的方法直接弃用,完全靠上面的投影矩阵方案来改视野。面部滤镜的位置和尺寸就交给AR Foundation的Face Tracking组件,绑定到人脸特征点上,这样不管怎么调FOV,滤镜都能牢牢贴在脸上,不会变形。
4. 验证效果
- 运行后用UI滑块拉
targetFOV,看相机画面缩放是否流畅,同时面部滤镜有没有歪或者变形 - 检查RenderTexture里的画面是不是包含了相机画面和AR滤镜
- iOS设备上测一下,确保AR面部跟踪、平面检测这些子系统都正常工作
内容的提问来源于stack exchange,提问作者Mahmoud Anwar
相关产品推荐
相关产品推荐

