Unity 之Camera 属性Clear Flags 浅谈

时间:2024-04-10 08:02:40

Camera 作为Unity中最为重要的组件,充当着整个游戏世界大门的作用,只有有了它,用户才能看到游戏,可以说是游戏玩家的虚拟世界之眼睛。

作为开发者,首先就要彻底理解Camera的所有属性与作用,只有这样才能已最恰当的方式,将游戏呈献给玩家,让玩家毫不出戏、身临其境的游戏。

学习Uinty半年时间,一直在使用Camera,但是对有些属性还是一知半解。今天就将所有的理解写出来,方便别人也方便自己。对于其中有问题的,不理解的,后续也方便补充。

其中 每一个属性,我都将先列出Ceeger圣典上的说法,然后那个上面难免有很多不好理解的说法,我再用红字谈谈自己的想法
Unity 之Camera 属性Clear Flags 浅谈
Clear Flags

Each Camera stores color and depth information when it renders its view. The portions of the screen that are not drawn in are empty, and will display the skybox by default. When you are using multiple Cameras, each one stores its own color and depth information in buffers, accumulating more data as each Camera renders. As any particular Camera in your scene renders its view, you can set the Clear Flags to clear different collections of the buffer information. This is done by choosing one of the four options:

每个相机在渲染时会存储颜色和深度信息。屏幕的未绘制部分是空的,默认情况下会显示天空盒。当你使用相机时,每一个都将自己的颜色和深度信息存储在缓冲区中,还将积累大量的每个相机的渲染数据。当场景中的任何特定相机进行渲染时,你可以设定清除标记以清除缓冲区信息的不同集合。可以通过下面四个四个选项之一来完成

Skybox 天空盒
This is the default setting. Any empty portions of the screen will display the current Camera’s skybox. If the current Camera has no skybox set, it will default to the skybox chosen in the Render Settings (found in Edit->Render Settings). It will then fall back to the Background Color. Alternatively a Skybox component can be added to the camera

这是默认设置。屏幕上的任何空的部分将显示当前相机的天空盒。如果当前的相机没有设置天空盒,它会默认在渲染设置(Render Settings )选择天空盒(在 Edit->Render Settings可以找到)。它将会变回背景色。另外天空盒组件可以添加到相机上。

我们观察属性会发现,属性Clear Flags下面紧跟着属性Background,这个就是当Camera也没有Skybox组件,也没有设置系统天空盒时,用来显示的纯色。关于系统天空盒,在Unity 5.0中已经变更位置了。在Window->Light中可以找到。

Solid Color 纯色
Any empty portions of the screen will display the current Camera’s Background Color.

任何空部分,屏幕显示为当前相机的背景色。

Depth Only 仅深度
If you wanted to draw a player’s gun without letting it get clipped inside the environment, you would set one Camera at Depth 0 to draw the environment, and another Camera at Depth 1 to draw the weapon alone. The weapon Camera’s Clear Flags should be set to to depth only. This will keep the graphical display of the environment on the screen, but discard all information about where each object exists in 3-D space. When the gun is drawn, the opaque parts will completely cover anything drawn, regardless of how close the gun is to the wall.

如果你想绘制一个玩家的枪,又不让它内部环境被裁剪,你会设置深度为0的相机绘制环境,和另一个深度为1的相机单独绘制武器。武器相机的清除标志(Clear Flags )应设置 为depth only。这将保持环境的图形显示在屏幕上,但会丢弃所有关于每个对象在三维空间中的位置的信息。当枪被绘制出来,不透明的部分将完全覆盖任何已绘制的事物,而不管枪到墙之间如何接近(我的注释:横线部分我在后面将单独解析)

这里边有几个知识点:内部环境裁剪(Clipped inside the environment),深度(depth)

clipped inside ths environment:这个说的是Camera的另一个属性Clipping Planes,这个属性包含两个值Near/Far。举个简单的例子,比如人眼睛,距离人眼睛太近的物体看不清、距离人眼睛太远的物体看不到,这就是Near、Far了。看下图
Unity 之Camera 属性Clear Flags 浅谈
你看,这个观赏树的近端可以看完整,远景也OK。这个时候Clipping Planes Near == 0.3 Far == 1000
Unity 之Camera 属性Clear Flags 浅谈
再看,近端丢了一块,远景也丢了。这个时候Near == 3 Far == 6

也就是说距Camera小于Nea距离的物体被裁剪掉、距Camera大于Far距离的物体被裁剪掉。

那么,怎么能避免物体被裁剪掉,而且还能离摄像头Near>=3呢?那就是,把这个景观树单独用另一个摄像头来显示。具体,看下一个知识点:

Depth:这个深度,顾名思义,就是摄像机的深度了。当只有一个摄像机时,这个属性没有意义。当有大于两个摄像机时,就牵扯到多个摄像机的前后层叠问题了。Depth值越大,越靠上,也就是越靠外,也就是可以遮挡值较小的摄像机的画面。比如MainCamera就默认为-1,然后新建摄像机就是0,在上边。那么回到刚才景观树这个问题,如果想用一个摄像机专门展示景观树,而且还在主摄像机中可以看到,那么Depth必然要大一些,在主摄像机的上面喽。接下来,我们就来讨论Clear Flags 的Depth Only啦:

我们先试着把显示景观树的摄像机的Clear Flags设置为SkyBox或者Solid Color,我们会发现主摄像机镜头被天空盒或者纯色挡住了。然后将ClearFlags改为Depth only,我们会发现,景观树成功的嵌入了主摄像机的其他景色中,浑然天成。根据Depth only字面意思来讨论,也就是说,这个时候摄像机的未渲染部分的显示内容取决于深度,未渲染部分显示什么由深度小于本摄像机的内容来决定。

现在回到枪的话题。我做了一个小例子,如图就是场景,其中有三个Enemy,一个Player(蓝色),一个Gun(绿色):
Unity 之Camera 属性Clear Flags 浅谈
,然后先是只有一个Camera,我们看看效果:
Unity 之Camera 属性Clear Flags 浅谈
看,由于枪离人物太近,导致从人物的视角观察时,最近的一部分被裁剪掉了。那怎么办?我总不能把枪再朝外吧?再朝外就不自然了呢。

那么我把枪的Layer设置成GunLayer,然后在MainCamera中CullingMask中取消对GunLayer的显示。然后新建Camera,把深度设置为0(因为MainCamera的深度为-1),Clear Flags设置成Depth only,把CullingMask中只勾选GunLayer,那么这个新的Camera就只显示Gun了。调整Camera的位置到适合位置。看效果:
Unity 之Camera 属性Clear Flags 浅谈
人物举枪的姿势,很自然吧?

接下来,我将专门解析这段话的含义,觉得上面的翻译有些不好,我自己尝试翻译了下

This will keep the graphical display of the environment on the screen, but discard all information about where each object exists in 3-D space. When the gun is drawn, the opaque parts will completely cover anything drawn, regardless of how close the gun is to the wall.

(设置深度的这个操作)将会保持环境中的图形显示的完整,但是,会丢弃所有其他物体在3D空间中存放位置的信息。当枪被绘制时,它的透明部分会完整的覆盖其他任何绘制,不管这把枪到低离墙有多的的近。

那么我理解的意思就是设置成Depth only的Camera中的物体,将会凌驾在其他任何物体上,当然,只能凌驾在Depth比他小的物体上。不受3D位置的前后影响。能够完整的呈现在观察者面前。

我做实验如下:

我先将一个Enemy顶进了枪里:
Unity 之Camera 属性Clear Flags 浅谈
再来观察效果:
Unity 之Camera 属性Clear Flags 浅谈
枪还在外面,没有顶进去。很明显,其他物体的3D位置信息没有体现出来,不然就不是这个效果了。

至此,这个Depth Only,的含义已经很传神了。

至于Don’t Clear,借用一段翻译:

Don’t Clear 不清除
该模式不清除任何颜色或深度缓存。其结果是,每帧绘制在下一帧之上,造成涂片效果。这不是用于游戏的典型方式,最好是与自定义着色器一起使用。

我目前的理解和曾实验看到的效果确实是帧叠加了。确实不是用于游戏的典型方式。没有理解之前,暂不讨论了。
参考文献https://blog.csdn.net/narutojzm1/article/details/51291008