在Unity中使用多个相机及其重要性

发表于2018-05-08
评论0 8.4k浏览
有很多Unity用户没有掌握在一个场景中使用多个Unity相机的概念。“如果我只需要一个视角,为什么还要多个相机呢?”如果回答说,在同一个视角使用多个相机能让场景看起来更完美,这会更加让人迷惑。为什么需要这么麻烦呢?这个原因有些复杂,但是非常值得学习。这能帮助你更简单的创建更好的视觉效果,而只用一个相机达到同样的效果将会非常困难。

什么是Unity相机?

在继续本文之前,你必须明白Unity的摄像机到底是什么。Unity渲染场景的时候需要确定很多重要的信息,但是让我们简化这个列表以便更容易理解。如下:
  • 要渲染的物体列表
  • 相机参数(位置,朝向,缩放,可视范围,裁剪等)

如果你曾经接触过这些东西,你可能会注意到我没有提到矩阵。这里会先忽略掉数学相关的东西。

要渲染的物体列表是在场景中的所有物体的列表,对吗?错!每个相机只渲染它可见(可视区内,视锥体内),并且在它可见的层(裁剪遮罩)内的物体。

裁剪遮罩可以设置为Everything,或者你可以只设置想看到的层。这是层的功能之一。
                                                         这个相机能看到所有的层。

                            这个相机只能看到默认层(地面)和红色的层(红色的球体)。

结论是,不同的相机可以渲染不同的物体。这是在了解如何实际使用它之前需要知道的重要信息。这也意味着增加另一个相机并不会使场景被绘制两次,而只有对第二个相机可见的物体才会被渲染。也就是说,用多个相机渲染不同的层,与只用一个相机渲染所有层的渲染效率相差无几。

现在让我们回答最开始的问题:相机就是从指定的视角渲染特定物体列表的指令。

相机渲染什么?

等一下,我们不是已经回答了这个问题了吗!其实,还不完全。其实有可见的和不可见的两个部分。你看到的是最终的图像(我们叫它颜色缓冲)。当然还有个东西是你看不到的,它叫深度缓冲(也叫Z缓冲)。

深度缓冲可以简单地描述为和游戏屏幕同样大小的灰度图像,它的每个像素值都描述了这个像素到摄像机的距离(坦诚地说这并非绝对正确,但是目前我们先不考虑更加复杂的情况)。GPU使用这个图像来决定将被渲染的像素应该被处理还是剔除。结果,被其他像素覆盖的像素将不可见(这与真实世界是一样的)。
                                           上图:简单的三维场景  下图: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%正确,只是为了帮助理解这个过程)
  • (蓝色相机上下文)
  • 颜色缓冲用天空盒填充
  • 深度缓冲被清除
  • 地板(默认层)和蓝色球(Blue层)被渲染
  • (红色相机上下文)
  • 颜色缓冲和深度缓冲都不清空
  • 红色球(Red层)被渲染

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

那为什么要这么麻烦呢?现在我们尝试把红色相机的清除标志从不清除修改为只清除深度缓冲。

看到了吗?因为深度缓冲被清空了,红色球不知道它的部分像素是被遮挡的,所以它会绘制在场景其他物体的前面。也就是说,清空深度缓冲选项会使物体渲染在最前面。这在渲染3D UI元素的时候是非常有用的。

在游戏“天际”中,以3D物体展示的道具。即使在背景物体距离摄像机很近的时候,他们也能被正确的渲染。

另外一个有意思的选项是让相机只渲染特定的层。如下面的截图所示,把蓝色相机选为只渲染blur层:

然后把红色相机的清除标志设置为不清除,并且在蓝色相机上应用一个效果:Grayscale。

最后,在移动相机的时候,你可能想同时移动所有相机(这也是为什么要把所有的相机都设置为同一个游戏物体的子物体)。但是有时候也可能就是想只移动一个相机,那就另当别论了。
来自:https://blog.csdn.net/qq_17758883/article/details/76572947

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引