无偏差(unbiased)渲染的真相

多年来,大家都在争执到底是偏差式渲染(biased)或是无偏差式渲染(unbiased)哪个比较好。“无偏差式的渲染”这个词已被用了许多次了,几乎等于准确渲染的代言人。事实上几乎所有的渲染器其实多多少少都带有偏差,即使是那些宣称是无偏差的渲染器。 因为偏差式渲染真的比较快,更智慧,也不代表就不准确。为了要更了解这点,我们分成几个方面来了解:

什么是偏差的渲染?

基本上“无偏差渲染”表示计算时完全没有用到任何取巧,所有的射线(ray)都对等地看待。因此,没有哪个射线比较重要或是比较不重要,因此,就必须要计算大量的射线才能产生干净的结果。无偏差渲染最好的描述可看 Vlado 在 Chaos Group 官方论坛的说法:

    “理论上,计算某积分(本例为渲染方程式)的无偏差方法如果你以相同的输入数据(例如 3D 场景)跑了很多次,将会给你平均正确地结果(最终影像)。即便是每个各别的结果本身具有很大错误(例如噪声),这表示当你执行够多次算法时,平均的结果,你可以得到正确的影像。你可以想象一下在 VRay 里面就是渐进试采样(progressive sampler)。用这种方式让影像噪声变少,每个单独的影像带有很多噪声,但是够多的次数平均下来,得到干净的结果。”

因此,你应该会认为渐进式渲染是“无偏差的”。其实不正确,有很多偏差的技巧让渲染器能够加速渲染,可是还是保留渐进式路径追踪(progressive path tracer),这样的优化可是用户可控制的设定,或是根本藏起来让你看不到。如果你用的渲染软件的射线追踪器(raytracer)速度很快,那么很有可能是偏差的渲染器,而偏差的程度就根据射线追踪器的软件开发者,或是用户可用的设定有关。如果射线追踪器显露出很多偏差的设定给用户选择或是让您可以关闭,那么用户就要自觉这样的设定可能产生的效应。

对无偏差渲染的常见误解:

如果你有读过大家在吵什么,你会发现里面其实有很多关于无偏差渲染的误解,以下是我发现常见的:

    无偏差渲染是物理准确的 – 无偏差渲染并不表示物理准确,反之也不表示偏差渲染是物理不准确的。两者都是不准确的 。例如在 Blinn 使用 BRDF 或是 GGX 这样的概念本身就只是真实世界材质的逼近方法而已。关键在于怎样的方法可以达到物理上合理的方法,更快速地完成渲染。下面会详细说明。
    无偏差表示更少的设定– 仅仅因为渲染有比较少设定不代表渲染引擎就是无偏差的,很多渲染引擎的偏差设定是写在程序代码里面,没有暴露出参数供用户调整.
    Brute Force GI = 无偏差的渲染– 很多人认为如果你用某些方法计算全局照明(Global Illumination)然后使用快取数据,这样就是偏差渲染,事实上快取的 GI 数据是偏差的,而 Brute Force GI也有偏差的。
    路径追踪是无偏差的– 很多偏差的取巧同样可以用在路径追踪,所以这也不是正确的说法。

怎样会让渲染引擎变成偏差式的?

读到这里你可能会想,要怎样会让渲染由无偏差变成偏差的呢? 有哪些取巧会造成这样? 有很多常见的技巧,有些技巧参数会暴露给用户调整,例如V-Ray提供给使用者选择哪些取巧使用,以及使用到什么程度,怎样可以简化接口或是让用户以为这套渲染引擎是无偏差的

以下是使渲染引擎的偏差设置或取巧的几个示例:

    定义光线反弹的次数 – 无偏差的表示光线会具有无限次数地反弹直到场景完全地吸收光线为止。
    使用快取 – 这样的快取可以用内差的方式解决复杂的光线追踪问题,例如带有上百次反弹的全局照明(Global Illumination) 或者计算焦散。这些是偏差的方法能够加速解算,或者显着地允许更多的光线反弹次数。
    自适应采样 – 这个方法增加场景中重要区域射线的权重,例如场景中有光线的区域 GI快取的数据显示为重要的GI贡献区域,偏好这些地方的光线。
    压抑或是移除焦散射线 – 这是很多渲染器很常见的作法,因为焦散需要耗费大量的计算资源
    切头尾(Truncating,clamping)或是减少某些射线的强度 – 能够减少萤火虫效应(fireflies, 译注:过亮的白点) 这是一个常见技巧,例如反射模糊的射线,通常可以随机地捕捉到非常亮的光源,由此对二级射线(secondary rays)去头尾(clamping) 你就可以减少强度过高的点(也就是所谓的萤火虫)事实上,任何一种的去头尾或是容忍度值或是阀值来决定是否继续追踪某路径。再次,这样的技术能够减少计算,也能加速您的渲染。

怎样才正确 偏差或是不偏差的?
要注意的是这些技巧,并不表示偏差式的方法是不准确的。精确的,或是物理上准确的。以下是引用Vlado在Chaos Group论坛上说的话:
我最近很难过地发现有很多人以为无偏差的这个词表示,物理准确的,偏差的就从某种角度是物理不准确。 而事实上,这两个此之间的关系就跟精确性(precision)与准确性(accuracy)在科学上的用法很类似,无偏差的计算具有很高的精确性, 但是不代表任何准确性(准确性表示跟实际正确的结果接近的程度)反之亦为真。偏差的计算也可能相当正确(例如接近实际的结果)但通常是不精确。

因此偏差式的渲染事实上可以是物理准确的,在大部分情况,能够达到正确的结果。如果目标是在越短时间内,最终影像很接近物理正确的,那么你就需要偏差式的算法。如果你必须要确认所有可能的射线,即便是眼睛无法察觉差异的,那么你就需要无偏差的算法。

哪个比较好呢?偏差的或是无偏差的?

正如我们已经确认了,大部分的渲染器使用偏差式的方案,即便其对外宣称是无偏差的。引用 Vlado 在 Chaos Group 论坛上的话:

    “如果这些软件没有这样做,那么渲染会变得超级慢。偏差的引擎非常智能,会用最有效率的方式取得正确影像。事实上,你可以说大部分无偏差的渲染器非常没效率。在学术论文里面,无偏差这个词听起来比偏差式的高尚,因为无(-un) 表示无限制。但说来有趣,如果把无偏差换成「蠢」 偏差的换成「聪明」,还是有道理的。”

长话短说,如果你真的是在做科学物理计算,你有很强的计算机,很多时间,那么无偏差式的渲染可能就适合你。如果你对物理上合理的影像感兴趣,偏差式的渲染可以让你更快地达到目标。很有可能你已经这样做了不论你是用哪套渲染引擎。

事实上所有的都是偏差式的 但我想要更少设定参数

你可以暴露出设定来决定多偏差或是隐藏那些参数,这也就是为什么 V-Ray 会有这么多参数,因为不同用户会有不同需求。最近的几个版本,你会发现我们已经跨出一大步减少设定参数,这也是为什么只有当你切换到进阶“advanced”或是专家“expert”模式才会看到许多 V-Ray 的设定。我们也在努力减少 V-Ray 需要手动调整的部份,因此如果用户希望加载场景,按下一两个按钮就渲染,就可以。

在最近几版的 V-Ray 会刻意忽略用户的设定(例如灯光或材质的细分值),因为这事实上会让渲染变慢。很多用户以新版的 V-Ray 开启旧场景,发现渲染变得非常快,这是因为 V-Ray 的核心已经大规模地加速渲染,忽略旧版的设定对于渲染速度上有很大的效应。好的是大部分状况,现在的 V-Ray 你只需要控制三个参数,以下影片 Vlado 解释了他的通用设定,帮助用户加速场景,而且只动了几个参数而已:

事实上,影片里面 Vlado 指出的设定现在已经变成 V-Ray 的默认值了。所以大部分的用户只需要开启场景,使用默认值,不需要调整参数就能得到很棒的渲染结果了

V-Ray其实可以变成真正的无偏差渲染:

大多数人不知道的是,由于V-Ray暴露了所有的参数设置给使用者,因此技术上可以让 V-Ray变成无偏差渲染。这样做,你就可以真正地看到偏差与无偏差的差异,除此变得超级慢之外,你会发现用户不会得到两者有任何明显差异的结果。

结论: 偏差的算法可行 ,这也是为什么大家都在用

再次,我们引用John Carmack先生的睿智说法, 他说了我想要说的话,只要把以下的优化改成偏差

    “当今有很多工作正在进行,这也就是影像渲染尖端科技的所在,你要如何优化路径追踪,能不同的情况下更有效率地计算。但总是你想做的事做近似值计算, 这种解决事情的方法,是相当有用的”