对柏林噪声湍流返回值的混淆



湍流函数

从我的理解来看,柏林噪声中的湍流是不同频率不同权重的柏林噪声的累积。基于这种理解,湍流的返回值应该具有相同的颜色(或像素)范围。

然而,在一些实现中(光线追踪:下一周),湍流的范围不匹配[0,1]的范围

double turb(const point3& p, int depth=7) const {
auto accum = 0.0;
auto temp_p = p;
auto weight = 1.0;
for (int i = 0; i < depth; i++) {
accum += weight*noise(temp_p);
weight *= 0.5;
temp_p *= 2;
}
return fabs(accum);
}

weight的初始值为1,noise的取值范围为[- 1,1]。因此,有可能在第一次迭代后,accum变为1,后续的迭代可以使其大于1。

我也通读了原论文的相关部分,但是,伪代码看起来非常相似:

function turbulence(p)
t = 0
scale = 1
while (scale > pixelsize)
t += abs(Noise(p / scale) * scale)
scale /= 2
return t

从下面这行可以看出,Perlin原论文中的颜色表示也在[0,1]的范围内:

例如,

变量列表[红绿蓝]的一个可能像素是[0.5 0.3]

0.7)。

所以我想知道turbulence函数是否以这种方式设计,因为返回超出范围的值的概率极低。还是我错过了什么?

噪声函数

另外,原论文中对Noise()函数的描述也很混乱。Perlin没有明确说明返回值的范围。但他是这样说的:

通过计算模拟对象可见表面点的Noise(),我们可以创建一个简单的"随机"表面纹理(图Spotted.Donut):color = white * Noise(point)

所以我假设它应该是[0,1],这使得表达式white * Noise(point)在[0,1]

的范围内但是,在turbulence函数中增加了一个abs()函数

噪声函数或湍流函数(也称为分形噪声)的范围在很大程度上取决于它的实现和使用。例如,一个值噪声存在于范围为[0,1]的均匀间隔随机值之间的插值,因此它的范围也是[0,1]。另一方面,梯度噪声存在于通过原点的线性函数之间的插值,所以它的范围是[-a, a](我猜是[-1,1],但我不确定)。如果该范围与应用程序不对应,则可以简单地重新映射它。我所熟悉的分形噪声的实现使用了范围为[0,1]的噪声,它是将频率为k*2^i乘以1/2^(i+1)的噪声加起来,i从0开始,所以它的范围为[0,a<1]。

同样,正如你所说的,如果超过某个值的概率非常小(这里的情况是,因为噪声往往具有小的标准偏差),那么在图形应用程序中就不是那么大的问题,因为结果无论如何都会被限制在0和1之间。

最新更新