You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:23:20