Skip to main content

附录:关于 Unity 中天空盒渲染行为的差异

在 Unity 2022.3.22f1 中,场景编辑界面与游戏摄像机的天空盒渲染默认行为略有不同:

  • 在场景编辑界面中,通过观察渲染过程可以发现,如果开启了天空盒显示,天空盒会在场景绘制之前最先被渲染。
  • 而在游戏摄像机中,当清除标志设置为“天空盒”时,通过帧调试器检查渲染顺序可以发现,天空盒会在几何渲染(渲染队列 2000)之后、透明渲染(渲染队列 3000)之前渲染,其渲染队列通常为 2500。

为了更直观地理解这种差异及其带来的影响,我们可以通过一个简单的示例场景进行说明。

在下面的示例场景中,存在以下对象:

  • 一个渲染队列为 0 的蓝色球体,位于视图中央;
  • 一个渲染队列为 1 的透明平面,位于视图右侧;
  • 一个渲染队列为 2000 的地面,位于视图下方。

其中,这个透明平面使用了一个特殊的着色器,它可以将所覆盖片段的深度缓冲区(z-buffer)清零。因此,在它覆盖的区域内,任何渲染队列大于 1 的网格都会无条件地被完整渲染出来,并覆盖之前的内容(蓝色球体所覆盖的片段)。

在场景编辑界面(图左)中,天空盒会在场景绘制之前最先被渲染。因此,在画面左侧,蓝色球体首先被完整地渲染在天空盒之上。随后地面被渲染,其中被蓝色球体遮挡的片段因距离摄像机更近而跳过,从而呈现出蓝色球体遮挡地面的一部分。而在画面右侧,由于透明平面清除了蓝色球体的深度信息,地面得以完整渲染,没有片段被跳过,因此呈现出地面覆盖蓝色球体的效果。

而在游戏摄像机(图右)中,由于场景中所有材质的渲染队列均小于 2500,天空盒会在最后被渲染。因此,在画面左侧,蓝色球体首先被渲染,接着是未被蓝色球体遮挡的地面部分。最后天空盒渲染时,着色器会根据深度信息跳过被蓝色球体和地面覆盖的片段,并填充剩余区域,表现为天空盒被蓝色球体和地面遮挡。 然而在画面右侧,由于透明平面清除了蓝色球体的深度信息,地面片段无条件覆盖了蓝色球体的片段。而当天空盒最后渲染时,只跳过了地面覆盖的片段,却没有跳过原本被蓝色球体覆盖的片段,因此蓝色球体未被地面覆盖的部分会被天空盒完全覆盖,呈现出蓝色球体“消失”在天空盒后的效果。