Skip to main content

1. 反射探针的基础知识

反射探针捕捉其周围世界的图像,并将其存储到一个“立方图”中——一个六面的纹理,可以填充立方体的每一个面。

每个纹理的面都是正方形,且具有相同的分辨率。这意味着“512”分辨率的探针是六个512x512纹理,紧凑地组合在一起。这将占用2MB的空间和2MB的内存。

反射探针还会存储它们纹理的低分辨率版本。这些低分辨率副本被模糊处理,允许真实地表现粗糙或不平整的表面。

当场景中的物体被渲染时,它们会询问Unity“我在哪个反射探针中?”——Unity将为它们提供最接近其锚点位置的两个探针的纹理和位置,着色器将在它们之间进行混合。如果只有一个探针可用,Unity将只发送一个。

除了反射探针对象之外,每个场景都有一个“环境反射”,当附近没有反射探针时提供。这通常是从天空盒材质生成的,但可以手动覆盖。

一个反射探针纹理的示意

image-1643385044625.png

在这张图像中,您可以看到一个反射探针的内容。通常,反射探针以未压缩的形式存储,所有面就像这样展开,但Unity在导入它们或任何其他以同样方式排列的立方图纹理时,将自动组合它们。您可以看到这个示例中的探针包含了一座建筑物,上方的天空,以及一个外部区域。尽管探针每边只有512像素,它仍然非常清晰,并包含了实时中看起来准确和清晰的反射。

动态对象如何工作,比如玩家?

动态对象使用最接近其网格上锚点位置的探针。

probes1.png

在这张图像中,您可以看到一个对象的锚点。它位于对象的根部,而不是您可能期望的中间。

实际上,这个对象的锚点是红箭头指向的位置——尽管中心在别处。Unity将使用该位置为模型选择反射探针。这个位置默认是网格的“原点”——每个顶点都围绕的(0, 0, 0)点。

您可以通过在网格渲染器上设置一个GameObject在“锚点覆盖”字段中来覆盖这一点。

anchoroverride.png

静态对象如何工作,比如地图?

它们的工作方式与动态对象相同。然而,这可能会导致一些问题。

Unity有静态批处理,它将多个模型合并成一个网格,并在一个绘制调用中渲染它们。

然而,Unity不会合并受不同探针影响的对象。

您可以通过锚点覆盖部分解决这个问题。使用相同锚点覆盖的对象有时会被批处理在一起。尽管Unity经常无法将它们批处理在一起,因此在这些情况下,您将需要手动合并网格以恢复性能。

着色器如何处理反射探针?

在大多数情况下,着色器将遵循Unity标准着色器的做法。Unity提供了一些功能,让任何着色器使用标准的部分来提供与标准相同的反射,或者访问数据以自行完成。

如前所述,Unity将为它们提供最接近其锚点位置的两个探针的纹理和位置,着色器将使用Unity提供的一些方便功能在它们之间进行混合,大多数着色器都会使用这些功能。

在标准中,遮挡贴图用于定义光线通常无法到达的区域,这将使这些部分反射较少的光,并减弱反射的效果。