0

我从 Github 复制并粘贴了这个。它看起来更好,在这里更具可读性: https ://github.com/RylanYancey/temp-rusty-noise/issues/1

问题:

Unsure how to implement a seed for Simplex Noise algorithm.

Unsure how to increase octaves without flattening.

Unsure how to make a more robust FBM implementation.

参考:

https://github.com/RylanYancey/temp-rusty-noise/tree/main/src

这个存储库包含我将在这篇文章中引用的代码。重要的文件在 src.

main.rs -> File for testing the lib.
noise.rs -> File for interfacing with generate.rs and for applying Fractal Brownian Motion
generate.rs -> file which stores the Simplex Noise algorithm and related methods.

https://thebookofshaders.com/13/

这篇文章解释了分形布朗运动。我使用它的代码示例来构建我的 FBM。不确定如何为单纯形噪声算法实现种子。

据我了解,噪声算法使用排列来产生噪声。这是我的排列:它存在于 generate.rs 中。我怀疑你很难找到它。

This syntax is Rust. Know that [i32, 512] means an array of 32-bit integers that is 512 indices long.
static PERMUTATION: [i32; 512] = [
    151,160,137,91,90,15,
    131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
    190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
    88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
    77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
    102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
    135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
    5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
    223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
    129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
    251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
    49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
    138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
    151,160,137,91,90,15,
    131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
    190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
    88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
    77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
    102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
    135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
    5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
    223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
    129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
    251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
    49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
    138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
];

当我分析不同的噪声算法时,我注意到它使用种子来打乱这些值。它通过将给定的种子作为种子插入 Microsoft 的 System.random 库中,然后将排列的每个索引设置为 random.next() 中的“随机”值。

排列是随机的还是加扰的?我错了这是如何工作的吗?

此外,如何将种子实现为 Simplex Noise?不确定如何在不展平的情况下增加八度音阶。

我的库在生成噪声值后实现了分形布朗运动。看起来是这样的:这段代码使用了 Rust。如果您不熟悉 Rust 语法,请了解以下内容:

i32 / f32 are data types. (32-bit integer, 32-bit floating point)
-> i32 is a return type.
pub fn is short for public function.
mut is short for mutable. It means a variable can be changed after being initialized.
&config means a variable (in this case, called config) passed as a reference. in this case, it is a Noise Configuration.
pub fn generate(config: &NoiseConfig, x: i32, y: i32) -> i32{
    
    let mut x_frequency = config.x_frequency;
    let mut y_frequency = config.y_frequency;

    // Applies Fractal Brownian Motion to the value using the 
    // Defined variables in the NoiseConfig struct.
    let mut value: f32 = 0.0;
    for i in 0..config.octaves {
        value += generate_raw(x as f32 * x_frequency, y as f32 * y_frequency);
        x_frequency *= config.amplitude;
        y_frequency *= config.amplitude;
    }

    // Converts the value to the desired range. 
    let result: i32 = convert_range(0.855349 * config.octaves as f32, -0.855349 * config.octaves as f32, config.range.1 as f32, config.range.0 as f32, value);

    //return result;
    return result;
}

FBM 的实现由噪声配置控制,如下所示:

pub struct NoiseConfig {
    octaves: i32,
    x_frequency: f32,
    y_frequency: f32,
    amplitude: f32,
    range: (i32, i32),
    seed: i32,
}

噪声配置被传递到生成函数以控制 FBM。

注意:该值生成后会转换为 NoiseConfig 中指定的范围之间的整数

这种 FBM 实现的问题在于,随着八度音阶的增加,值趋于“扁平化”。如果您要转换为小范围(例如 0-7),这一点尤其明显。

有 1 个八度: 超级史诗般的形象

有 10 个八度音阶: 不是那么史诗般的形象

这是因为这些值被加在一起,并且由于这些值沿着钟形曲线(在一定程度上)下降,这些值往往会堆积在分布的中间,从而导致扁平化效果。

我希望我图书馆的用户能够将八度音阶增加到他们想要的最高值。这怎么可能?不确定如何进行更健壮的 FBM 实施。

If you havent read the previous question, please do. It explains the issue in depth.

在本期的上一个问题中,我分享了我的 FBM 代码。这就是启发我的代码的 FBM 代码的样子:这段代码是用 C# 编写的。

// Properties
const int octaves = 1;
float lacunarity = 2.0;
float gain = 0.5;
//
// Initial values
float amplitude = 0.5;
float frequency = 1.0;
//
// Loop of octaves
for (int i = 0; i < octaves; i++) {
    y += amplitude * noise(frequency*x);
    frequency *= lacunarity;
    amplitude *= gain;
}

上面的代码有几个问题。即,它不能轻易转换为给定范围。那是因为返回值乘以幅度。我不确定如何计算特定噪声配置的最大值/最小值。

其次,它仍然存在更高八度音阶使噪声图变平的问题。

我的问题,具体来说:

如何使我的 FBM 实现更加健壮?我应该添加哪些值,以及如何以可以将它们转换为指定范围的方式实现它们?

4

0 回答 0