跳跃洪水算法可分离吗?


10

JFA(此处描述的算法:http : //www.comp.nus.edu.sg/~tants/jfa/i3d06.pdf)可用于获得Voronoi图的近似值或距离变换。它是根据对数图像的大小而不是种子的数量在对数时间内完成的。

如果每个轴上的图像大小都不相同,该怎么办?

如果它们的大小相似,我相信您可以让较短的轴具有大小为1的额外JFA步长,而较大的轴则可以完成它的工作(例如具有512 x 256大小的图像)。但是,对于大小各异的轴尺寸,效率可能低得多-假设您的体积纹理为512 x 512 x 4。

是否可以在每个轴上分别运行JFA并仍然获得不错的结果?

还是那时候更适合使用其他算法?如果是这样,那可能是什么算法?

在我的情况下,理想情况下,我希望同时支持单点种子和任意形状的种子。甚至可能是加权种子,其中到种子的距离由乘数和/或加法器调整以或多或少地产生影响。

Answers:


7

快速解答您的单个问题

如果每个轴上的图像大小都不相同,该怎么办?

本文使用边长为2的幂的正方形图像,这是为了便于说明,但对于算法起作用不是必需的。请参阅第3.1节:

不失一般性,我们可以假设n为2的幂。

也就是说,为了使算法起作用,不需要此假设。

是否可以在每个轴上分别运行JFA并仍然获得不错的结果?

在每个轴上分别运行可能会产生更多不正确的像素结果,并且在大多数情况下需要更长的时间才能运行。在图像边长之一小于8(跳转方向数)的极端情况下,由于算法会顺序处理这8个方向,因此速度可能会更快,但是对于任何较宽的图像,将轴分开将失去处理它们的优势在平行下。

在我的情况下,理想情况下,我希望同时支持单点种子和任意形状的种子

本文在第6节“广义Voronoi图”下提到了任意形状的种子:

...我们的算法将此类广义种子视为点种子的集合,因此期望继承继承针对点种子获得的良好性能。

因此,只要适合您的目的,即可将任意形状建模为像素集合,则无需对算法进行任何调整。只需输入一个纹理即可,该纹理用相同的种子编号但位置不同来标记任意形状的种子中的所有像素。

可能是加权种子,其中到种子的距离由乘数和/或加法器调整以或多或少地产生影响

对于“加权种子,例如乘法和加法”,本文仅提及将第8节作为潜在的未来工作通过的可能性。但是,只要您所需的权重可以包含在从一个像素传递到另一个像素的种子数据中,这应该很容易实现。

当前算法通过<s, position(s)>以指定种子及其位置,并且在任何时间每个像素仅存储一个种子。扩展此存储以<s, position(s), weight(s)>提供权重距离函数并计算传递给像素的新种子是否比当前存储的种子更接近所需的所有信息。

您甚至可以包括两个权重,一个乘积和一个加法,只需在不需要时将乘数设置为1,将加法器设置为0。然后,您的算法将包括可能用于一次加权或多次加权的种子,加法加权的种子,甚至是两者的组合。这只需要

<s, position(s), multiplicative(s), additive(s)>

并且当前算法将等效于使用

<s, position(s), 1, 0>


原因的详细说明

与本文一样,所有用法均以2为底的对数。日志

该算法无需适应不同的边长

如果边长不相等且不是2的幂,则无需调整算法。它已经处理了图像边缘上的像素,某些跳转方向将这些像素引到图像外部。由于该算法已经省略了引导到图像外部的方向的种子信息,因此宽度或高度不是2的幂的问题将不成问题。对于宽W高H的图像,所需的最大跳转大小为

2日志最高w ^H-1个

对于宽度和高度N相等的情况,这减少为

2日志ñ-1个

在边长N为2的幂的情况下,这减小为

2日志ñ-1个=ñ/2

如本文所用。

用更直观的术语来说,将最大边长四舍五入到下一个2的幂,然后将其减半以获得最大的跳跃大小。

这总是足以覆盖图像中每个其他像素的图像,因为如果最长边长为N,则任何像素的偏移量将在0到N-1的范围内。2的幂的组合如果N是2的幂,则0到N / 2会覆盖最多N-1的每个整数,如果N不是2的幂,则由于取对数的上限,所以覆盖的范围只能大于要求的范围(四舍五入到2的下一个幂。

边数不是2的幂的图像将不会大大降低效率

跳数取决于最长边的长度,例如L。如果L为2的幂,则跳数为。如果L不是2的幂,则跳转数为。对于相当大的图像,这不会有太大的差异。日志大号日志大号

例如,一个1024 x 1024的图像将需要10次跳转迭代。512 x 512的图像将需要9次跳转迭代。两种大小之间的任何值都将需要10次迭代。即使在图像的最坏情况下,仅是2的幂,例如513 x 513图像,它也只需要进行1次额外的迭代,在此比例下,迭代大约要多11%(由10代替9)。

非正方形图像的单位面积效率较低

由于所需的迭代次数由最长边长决定,因此1024 x 1024图像所需的时间与1024 x 16图像所需的时间相同。正方形图像允许在相同数量的迭代中覆盖更大的区域。

分离轴可能会降低质量

本文的第5节介绍了可能的错误。每个像素都可以通过其他每个像素的路径到达,但是某些路径没有带来正确的最近种子,因为该种子与该路径中的前一个像素不是最近的种子。不允许种子传播通过它的像素被称为“杀死”了该种子。如果最接近像素的种子在到该像素的所有路径上被杀死,则该像素将记录其他种子,并且最终图像中的颜色将不正确。

为了最终结果正确,只需要存在一条不会杀死种子的路径即可。仅当阻止了从正确种子到给定像素的所有路径时,才会出现不正确的颜色。

如果路径涉及水平和垂直跳变,则分开的轴将使该路径不可能(所有水平跳变将在所有垂直跳变之前进行,从而使交替变得不可能)。对角跳根本不可能。因此,任何替代或包含对角线跳跃的路径都将被排除。每个像素仍将具有到其他像素的路径,但是由于现在路径较少,因此给定像素被阻止接收正确种子的机会更大,因此最终结果将更容易出错。

分离轴可能会使算法花费更长的时间

分开轴可能会降低效率,因为将不再并行执行泛洪,而是会对每个轴重复进行。对于2D,这可能需要大约两倍的时间,而对于3D,大约需要三倍的时间。

缺少对角线跳动可能会在某种程度上缓解这种情况,但是我仍然希望效率整体下降。


1
我已经开始尝试其中的一些。我发现以+号(5个读数)而不是完整的9个采样显示我的测试没有差异,但是我确定在更复杂的情况下也会有所差异。做一个完整的x jfa,然后做一个完整的y jfa确实会造成很多错误。如果有的话,我会想听听更多的详细信息,但接受您的回答:P
艾伦·沃尔夫

1
忘了,这是我的实验之一的链接:shadertoy.com/view/Mdy3D3
艾伦·沃尔夫

有趣的是,显然只有5个读取也可以正常工作-尤其是因为它们无法并行化。由于该论文列出了导致错误的情况,因此您可以有意地设置这些错误,并查看5个跳转方向是否仍然很好。
trichoplax

听起来您准备好发布自己的答案了……
trichoplax

我的信息为您提供了补充:P
艾伦·沃尔夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.