【URP】Unity[相机]自定义相机

61 阅读3分钟

【从UnityURP开始探索游戏渲染】专栏-直达

Universal Additional Camera Data 组件概述

在 Unity Universal Render Pipeline (URP) 中,UniversalAdditionalCameraData 组件是扩展标准相机功能的核心组件,它提供了 URP 特有的相机配置选项。每个 URP 相机都会自动附加这个组件。

自定义相机的主要配置项

渲染类型 (Render Type)

  • Base‌: 主相机类型,可以独立渲染或作为其他叠加相机的基础
  • Overlay‌: 叠加相机,必须附加到 Base 相机上才能工作
  • ScreenSpaceOverlay‌: 屏幕空间叠加,用于UI等元素

堆栈相机系统 (Camera Stack)

  • 允许将多个 Overlay 相机叠加到 Base 相机上
  • 渲染顺序由相机的 Depth 值决定
  • 每个叠加相机可以有自己的清除标志和剔除遮罩

后期处理控制

  • 可以单独启用/禁用后期处理效果
  • 控制抗锯齿方式
  • 设置渲染比例(Render Scale)

高级渲染设置

  • 控制是否渲染阴影
  • 设置Opaque Texture和Depth Texture的生成
  • 配置运动矢量(Motion Vectors)

自定义相机原理

URP 的自定义相机系统基于以下核心原理:

  • 分层渲染架构‌:Base 相机负责基础场景渲染,Overlay 相机提供额外的渲染层
  • 渲染纹理复用‌:URP 会智能地复用中间渲染纹理,减少内存占用
  • 后期处理组合‌:每个相机可以有自己的后期处理效果,URP 会按顺序组合它们
  • 剔除优化‌:URP 会根据相机的视锥体和剔除遮罩优化渲染调用

具体使用示例

创建基础相机并添加叠加相机

// 获取或创建主相机

Camera mainCamera = Camera.main;

var mainCameraData = mainCamera.GetUniversalAdditionalCameraData();

// 设置相机属性

mainCameraData.renderType = CameraRenderType.Base;

mainCameraData.requiresColorTexture = true;

mainCameraData.requiresDepthTexture = true;

// 创建叠加相机

GameObject overlayCamObj = new GameObject("EffectCamera");

Camera overlayCam = overlayCamObj.AddComponent<Camera>();

var overlayCamData = overlayCam.GetUniversalAdditionalCameraData();

// 配置叠加相机

overlayCamData.renderType = CameraRenderType.Overlay;

overlayCam.clearFlags = CameraClearFlags.Depth;

overlayCam.cullingMask = LayerMask.GetMask("Effects");

// 添加到主相机堆栈

mainCameraData.cameraStack.Add(overlayCam);

高级自定义相机配置

// 创建特殊用途相机

Camera specialCamera = new GameObject("SpecialCamera").AddComponent<Camera>();

var specialCameraData = specialCamera.GetUniversalAdditionalCameraData();

// 详细配置

specialCameraData.renderType = CameraRenderType.Base;

specialCameraData.renderPostProcessing = true;

specialCameraData.antialiasing = AntialiasingMode.FastApproximateAntialiasing;

specialCameraData.antialiasingQuality = AntialiasingQuality.Low;

specialCameraData.requiresColorOption = CameraOverrideOption.On;

specialCameraData.requiresDepthOption = CameraOverrideOption.On;

specialCameraData.stopNaN = true;

specialCameraData.dithering = true;

// 设置目标纹理

specialCamera.targetTexture = RenderTexture.GetTemporary(1024, 1024, 24);

动态修改相机堆栈

// 获取主相机数据

var mainCamData = Camera.main.GetUniversalAdditionalCameraData();

// 动态添加叠加相机

Camera dynamicOverlay = new GameObject("DynamicOverlay").AddComponent<Camera>();

dynamicOverlay.GetUniversalAdditionalCameraData().renderType = CameraRenderType.Overlay;

mainCamData.cameraStack.Add(dynamicOverlay);

// 动态移除叠加相机

mainCamData.cameraStack.Remove(dynamicOverlay);

渲染纹理监控系统

  • 创建渲染纹理资源‌在Project窗口右键选择Assets > Create > Render Texture,命名为"SecurityFeed",分辨率设为1024x1024。

  • 配置渲染相机‌创建名为"SecurityCamera"的相机,将SecurityFeed拖入Output Texture属性,调整视角对准监控区域。

  • 显示监控画面‌创建Quad对象并附加材质,将SecurityFeed赋给材质的Base Map,通过主相机观察Quad。

    • 支持多路监控画面切换
    • 通过数组管理不同区域的渲染纹理
    • 可扩展为自动巡逻系统
  • SecurityCameraController.cs

    using UnityEngine;
    using UnityEngine.Rendering.Universal;
    
    public class SecurityCameraController : MonoBehaviour {
        public RenderTexture[] securityFeeds;
        private Camera securityCam;
        private int currentFeedIndex;
    
        void Start() {
            securityCam = GetComponent<Camera>();
            securityCam.targetTexture = securityFeeds[0];
        }
    
        public void SwitchFeed(int index) {
            securityCam.targetTexture = securityFeeds[index];
        }
    }
    
  • UICameraStack.cs

    void Start() {
        var uiCamera = GameObject.Find("UICamera").GetComponent<Camera>();
        var mainCameraData = Camera.main.GetUniversalAdditionalCameraData();
        mainCameraData.cameraStack.Add(uiCamera);
    }
    
  • ZoomBlurFeature.cs

    public override void AddRenderPasses(ScriptableRenderer renderer, 
        ref RenderingData renderingData) {
        if (zoomMaterial == null) return;
        blurPass.Setup(renderer.cameraColorTarget, zoomMaterial);
        renderer.EnqueuePass(blurPass);
    }
    

实际应用场景

  • 分屏游戏‌:为每个玩家创建独立的Base相机
  • 画中画效果‌:使用额外的Base相机渲染到纹理
  • UI特效‌:通过Overlay相机添加屏幕空间特效
  • 后处理组合‌:不同相机应用不同的后期处理效果
  • 优化渲染‌:通过禁用不需要的功能提高性能

注意事项

  • 叠加相机的Depth值必须大于其Base相机的Depth值
  • 过多的叠加相机会影响性能,应合理使用
  • 自定义相机的清除标志需要仔细配置以避免意外清除
  • 在VR中,每个相机都会为每只眼睛渲染一次,需特别注意性能
  • 相机堆栈中的顺序会影响最终渲染结果

【从UnityURP开始探索游戏渲染】专栏-直达 (欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)