在unity中使用多个相机

2016年08月01日 18:00 0 点赞 0 评论 更新于 2025-11-21 19:16

很多Unity用户没有掌握在一个场景中使用多个Unity相机的概念。有人会问:“如果我只需要一个视角,为什么还要多个相机呢?”若回答说,在同一个视角使用多个相机能让场景看起来更完美,这或许会让人更加迷惑,毕竟这样做似乎会增加复杂度。但实际上,这么做的原因虽有些复杂,却非常值得学习,因为这能帮助我们更轻松地创建更好的视觉效果,而仅用一个相机达到同样的效果将会困难得多。

什么是Unity相机

在深入探讨之前,我们必须明确Unity的摄像机到底是什么。Unity渲染场景时需要确定诸多重要信息,为便于理解,我们简化这个列表,主要包括以下两方面:

  • 要渲染的物体列表
  • 相机参数(位置、朝向、缩放、可视范围、裁剪等)

这里我们先忽略矩阵等数学相关内容。

需要注意的是,要渲染的物体列表并非场景中所有物体的列表。每个相机只渲染它可见(可视区内,视锥体内),并且在它可见的层(裁剪遮罩)内的物体。裁剪遮罩可以设置为“Everything”,也可以只设置想看到的层,这是层的功能之一。

例如,有的相机能看到所有的层,而有的相机只能看到默认层(如地面)和红色的层(如红色的球体)。由此可知,不同的相机可以渲染不同的物体,这是在了解如何实际使用多个相机之前需要掌握的重要信息。这也意味着增加另一个相机并不会使场景被绘制两次,只有对第二个相机可见的物体才会被渲染。也就是说,用多个相机渲染不同的层,与只用一个相机渲染所有层的渲染效率相差不大。

综上所述,相机就是从指定的视角渲染特定物体列表的指令。

相机渲染什么

前面我们对相机渲染的物体有了一定了解,但其实相机渲染的内容还有可见和不可见两个部分。我们看到的最终图像称为颜色缓冲,还有一个不可见的部分叫深度缓冲(也叫Z缓冲)。

深度缓冲可以简单理解为和游戏屏幕同样大小的灰度图像,其每个像素值描述了该像素到摄像机的距离(严格来说,这种描述并非绝对准确,但在此我们先不考虑更复杂的情况)。GPU使用这个图像来决定将被渲染的像素应该被处理还是剔除,结果是被其他像素覆盖的像素将不可见,这与真实世界的情况一致。

简单的三维场景与Z缓冲表达 上图:简单的三维场景 下图:Z缓冲表达

相机顺序与清除

在将任何东西渲染到颜色缓冲和深度缓冲中之前,摄像机可以选择将两个缓冲都清除,或者只清除深度缓冲。例如,Unity 5的场景相机会将缓冲清空为天空盒。

相机的清除标志还有其他一些选项:

  • Skybox:把颜色缓冲设置为天空盒,并完全清空深度缓冲。
  • Solid:和天空盒一样,只是把颜色缓冲设置为纯色。
  • Depth only:这个选项会保留颜色缓冲,但会清空深度缓冲。
  • Don’t Clear:不清除任何缓冲。

如果把默认相机的清除标志设置为“Don’t Clear”,会出现有趣的效果。例如,进入播放模式之后,稍微移动一下相机,会看到好像球体被复制了很多次,看起来像是连接起来的圆管。除此之外,场景中还有另一个红色的球体(注意蓝色层对相机还是不可见的),游戏场景的图像看起来是有效的。这里没有使用任何图像加工技术,就用一个物体制造出多个复制物体的效果。

之所以会这样,是因为颜色缓冲没有每帧都清空(上一帧渲染出来的颜色会传递给下一帧),深度缓冲也是一样。深度缓冲记住了一些东西已经被渲染过了,并且在Unity渲染下一帧的时候依然保留这些信息。当球体想要渲染在已经被渲染的图像后面的像素时,这些不可见的像素将会被丢弃。当场景中有多个物体并依次渲染时也会发生同样的事情。

如果对上述效果还不理解,建议自己动手操作一下:创建一个新场景,添加一个物体,把相机的清除标志设置为不清除,然后移动物体或者相机。

这有什么好处

假设我们根本不想在游戏中使用这种效果,那这个选项有什么好处呢?我们可以创建两个摄像机:

蓝色相机(Blue Camera)

  • Clear Flags:Skybox
  • Culling Mask:Default, Blue
  • Depth:0

红色相机(Red Camera)

  • Clear Flags:Don’t Clear
  • Culling Mask:Red
  • Depth:1

这里出现了一个新的参数:深度。深度定义了相机渲染的顺序,深度值越小的相机会越先被渲染。

下面我们来看看Unity如何一步一步地渲染这个场景(为便于理解,此过程并非100%准确):

  1. 蓝色相机上下文
    • 颜色缓冲用天空盒填充。
    • 深度缓冲被清除。
    • 地板(默认层)和蓝色球(Blue层)被渲染。
  2. 红色相机上下文
    • 颜色缓冲和深度缓冲都不清空。
    • 红色球(Red层)被渲染。

最终结果是得到一个看上去和只用一个相机渲染出来的效果一样的场景。

那为什么要这么麻烦呢?我们尝试把红色相机的清除标志从不清除修改为只清除深度缓冲。此时可以看到,因为深度缓冲被清空了,红色球不知道它的部分像素是被遮挡的,所以它会绘制在场景其他物体的前面。也就是说,清空深度缓冲选项会使物体渲染在最前面,这在渲染3D UI元素的时候非常有用。例如在游戏“天际”中,以3D物体展示的道具,即使在背景物体距离摄像机很近的时候,它们也能被正确地渲染。

另外一个有意思的选项是让相机只渲染特定的层。如下面的截图所示(此处应插入对应的截图链接,若有),把蓝色相机选为只渲染blur层,然后把红色相机的清除标志设置为不清除,并且在蓝色相机上应用一个效果:Grayscale。

最后,在移动相机的时候,我们可能想同时移动所有相机(这也是为什么要把所有的相机都设置为同一个游戏物体的子物体)。但有时候也可能只想移动一个相机,那就需要根据具体需求进行操作了。

关注“泰斗社区”了解更多相关资讯。