Appearance
虚拟摄像头 Unity Capture 集成
让 Unity 在 Windows 上模拟一个网络摄像头设备,渲染帧直接作为视频源流入 OBS / 直播姬,1080p@60FPS 无延迟,支持多摄像头与 Alpha 通道。
输出规格1080p@60
延迟无感知
上限4K
背景
B 站虚拟主播需要把 Unity 里渲染的 3D 虚拟人画面,作为直播源推到 B 站直播姬。传统方案是屏幕捕获或窗口捕获:延迟高、画质有损、还会把鼠标和窗口边框一起采进去。对直播场景来说这些问题都是硬伤——面捕驱动的虚拟人讲究音画同步和动作跟手,捕获链路每多一层延迟,观众看到的口型就对不上声音。
Unity Capture 是另一个思路——它是一个 Windows DirectShow 过滤器,把 Unity 渲染的相机直接变成一个系统级摄像头设备,任何能读摄像头的应用(OBS、直播姬)都能把它当视频源用。
问题
- 屏幕捕获链路损耗大:多一次系统级合成,延迟和画质都吃亏。
- 窗口捕获不专业:主播误操作(拖窗口、弹通知)会直接出现在直播画面里。
- 虚拟人需要透明背景:虚拟开播常要把虚拟人合成到游戏画面或实景上,需要 Alpha 通道,屏幕捕获给不了。
方案
把「渲染帧 → 直播源」这段链路从屏幕层下沉到设备层:
mermaid
flowchart LR
A["Unity 渲染相机"] -->|"渲染帧"| B["专用 RenderTexture"]
B --> C["Unity Capture<br>DirectShow 过滤器"]
C -->|"模拟摄像头设备"| D["OBS / B 站直播姬"]
D --> E["合成 + 推流<br>B 站直播"]Unity Capture 在 Windows 上注册为一个 DirectShow 视频设备。Unity 侧把指定相机的输出写到专用 RenderTexture,Unity Capture 按帧读取并以摄像头协议吐出去。对 OBS 来说,它和一个 USB 摄像头没有任何区别。
帧一级的时序如下:
mermaid
sequenceDiagram
participant U as Unity 渲染循环
participant R as RenderTexture
participant C as Unity Capture 设备
participant O as OBS / 直播姬
U->>R: 每帧写入渲染结果(锁 60FPS)
C->>R: 按输出帧率读取最新帧
C->>O: 以摄像头协议推帧
O->>O: 合成(含 Alpha)后推流读取侧帧率高于渲染侧会重复取到同一帧(画面卡顿感),渲染侧高于读取侧则中间帧被丢弃——所以锁帧要和输出规格对齐。
这也符合面动捕 CM 框架里 CaptureFrameWork 的设计:相机源可以是真实相机、虚拟相机、视频源、图片源——Unity Capture 就是「虚拟相机源」的一种实现,框架对上游透明。
关键实现
- DLL 注册:Unity Capture 的 DLL 需要注册到 Windows DirectShow,安装失败时设备列表里根本看不到这个「摄像头」。
- 相机配置:Unity 中创建专用 RenderTexture,配置 Unity Capture 读取该纹理,与游戏主相机解耦。
- 帧率同步:Unity 渲染帧率必须 ≥ 摄像头输出帧率,否则 OBS 侧丢帧。实践中让虚拟人渲染锁 60FPS。
- Alpha 通道:需要接收端也支持 Alpha(OBS 支持),配合色键或透明合成把虚拟人叠到其他画面上。
在采集框架里的位置
面捕 CM 框架的输入层抽象了四类相机源:真实相机源、虚拟相机源、视频源、图片源。Unity Capture 属于「虚拟相机源」——它让 Unity 的渲染输出可以被当作一路标准视频源接入框架,和面捕用的真实摄像头走同一套 CaptureFrameWork 接口。这样直播链路里「真人面捕输入」和「虚拟人画面输出」在框架内是对称的:都是视频设备,只是方向相反。
指标
| 指标 | 值 |
|---|---|
| 分辨率 | 1080p @ 60FPS(无延迟) |
| 高端 PC | 可处理 4K 分辨率 |
| 多摄像头 | 支持多个渲染相机同时输出 |
| Alpha 通道 | 支持透明通道(配合 OBS 合成) |
使用场景
- 虚拟 3D 开播:Unity 渲染 3D 虚拟人 → Unity Capture → OBS 合成 → B 站直播;
- 虚拟 2D 开播:Live2D 渲染 → 同上链路;
- 多机位:虚拟人正面 + 侧面两个相机同时输出,OBS 里切换机位。
接入验收清单
集成完成后按这条清单过一遍,能挡掉大部分上线前问题:
- Windows 设备管理器 / OBS 源列表里能看到 Unity Capture 虚拟摄像头;
- OBS 选中该设备后画面即出,分辨率与帧率和 Unity 侧 RenderTexture 配置一致;
- Unity 渲染帧率锁定 ≥ 60,OBS 统计面板无丢帧;
- 需要透明合成时,确认 OBS 源属性里 Alpha 通道生效(背景棋盘格透出);
- 多机位场景逐个相机验证,确认每路输出互不抢帧。
已知限制
| 限制 | 影响 | 应对 |
|---|---|---|
| 仅支持 Windows | DirectShow 是 Windows 专有,macOS/Linux 不可用 | 跨平台需求另选方案,不硬改 |
| 依赖 OBS 侧配置 | 摄像头源选错或参数不匹配会无画面 | 按验收清单逐项过 |
| 高分辨率 GPU 开销 | 4K 输出对 GPU 有额外压力 | 低端机降到 1080p 档 |
复盘
- 链路每少一层,问题就少一类。屏幕捕获的所有毛病(延迟、画质、误捕获)都来自「经过屏幕」这一步,设备层直出一劳永逸。
- 平台限制要认:Unity Capture 仅支持 Windows(DirectShow 专有),跨平台需求得另找方案,不要在它身上硬改。
- 帧率是端到端的事:Unity 渲染、Capture 读取、OBS 编码三段任何一段掉帧都会在直播画面体现出来,排查时按链路逐段定位,别只盯着 Unity。
- 已知代价:分辨率开得太高(4K)对 GPU 有额外开销,低端机上要降档。