跳到主要内容

多相机

场景可以包含任意数量的相机,它们按一个简单模型合成最终图像:每台启用的相机按 priority 顺序,将自己的图层渲染到渲染目标的视口中;优先级越低越先渲染。未设置渲染目标时,目标就是屏幕。

这一模型适用于多种布局:多人分屏、迷你地图和后视镜等画中画叠加、在 3D 场景上渲染 UI,以及监控屏和传送门等实时渲染到纹理的表面。

多视图

视口​

默认情况下,相机占满渲染目标的宽度和高度。rect 属性将渲染限制在一个矩形内,以归一化的 0–1 坐标指定 [x, y, width, height],原点位于左下角。

实现双人左右分屏时,两台相机各占屏幕的一半:

左右分屏

// Player 1: left half of the screen
camera1.camera.rect = new pc.Vec4(0, 0, 0.5, 1);

// Player 2: right half of the screen, rendered after camera1
camera2.camera.rect = new pc.Vec4(0.5, 0, 0.5, 1);
camera2.camera.priority = 1;

实现上下分屏时,将视口上下排列:上方为 [0, 0.5, 1, 0.5],下方为 [0, 0, 1, 0.5]:

上下分屏

相关属性 scissorRect 使用相同的归一化格式将渲染裁剪到矩形区域,但不会改变图像投影到视口的方式。

图层​

每台相机仅渲染其 layers 属性中列出的图层,因此不同相机可以看到场景中完全不同的内容。典型用途包括只将 UI 图层叠加到游戏上的 UI 相机、跳过特效图层的迷你地图相机,以及第一人称武器渲染。完整示例参见相机模型遮罩教程。

相机堆叠​

当一台相机绘制在另一台之上时,无论是画中画叠加,还是绘制另一组图层的全屏相机,后渲染的相机(priority 较高)都不应擦除先前相机的图像。请按需禁用其清除标志:

// Render an overlay camera on top of the main view, in the bottom-right corner
overlay.camera.priority = 1;
overlay.camera.rect = new pc.Vec4(0.7, 0, 0.3, 0.3);
overlay.camera.clearColorBuffer = true; // overlay has its own background
overlay.camera.clearDepthBuffer = true; // don't depth-test against the main view

// For a full-screen overlay that composites over the main view instead:
// overlay.camera.clearColorBuffer = false;

渲染目标​

将 RenderTarget 赋给相机的 renderTarget 属性,即可将其渲染到离屏纹理,而非屏幕。生成的纹理可以用于材质,实现世界内屏幕、镜子和传送门,也可以继续处理。完整说明参见渲染目标,以及引擎的渲染到纹理示例:

渲染到纹理

性能注意事项​

  • 每台启用的相机都会重新渲染自己的图层,绘制调用随相机数量增加。应将每台相机的 layers 限制到实际需要的最小范围。
  • 缩小相机的 rect 会减少填充的像素数,但不会降低所渲染对象每次绘制调用的 CPU 开销。
  • 逐相机后处理对每台相机各运行一次,因此分屏视图中的效果会成倍增加 GPU 开销。
  • 偶尔才需要的渲染目标(例如静态镜面)无需每帧更新:可禁用相机,按需启用。