【问题标题】:Is there a more effecient way to calculate and use Perlin noise?有没有更有效的方法来计算和使用 Perlin 噪声?
【发布时间】:2014-08-02 19:17:46
【问题描述】:

我几天前才开始使用 Perlin 噪声,结果看起来相当不错。但是计算和绘制一个 1024x1024 的上述噪声位图需要 3 秒多的时间。我使用一个 1024x1024 的数组来存储 int32 的范围从 -1 到 1。

创建 Perlin 噪声数组的代码:

 private void button1_Click(object sender, EventArgs e)
    {
        sw.Start();
        LibNoise.Perlin perlinMap = new LibNoise.Perlin();
        perlinMap.Lacunarity = lacunarity + 0.01d;
        perlinMap.NoiseQuality = LibNoise.NoiseQuality.High;
        perlinMap.OctaveCount = octaveCount;
        perlinMap.Persistence = persistence;
        perlinMap.Frequency = frequency;
        perlinMap.Seed = 1024;

        if (radioButton1.Checked)
            perlinMap.NoiseQuality = LibNoise.NoiseQuality.Low;
        else if (radioButton2.Checked)
            perlinMap.NoiseQuality = LibNoise.NoiseQuality.Standard;
        else if (radioButton3.Checked)
            perlinMap.NoiseQuality = LibNoise.NoiseQuality.High;

        double sample = trackBar6.Value * 10;

        double[,] perlinArray = new double[resolutieX, resolutieY];
        for (int x = 0; x < resolutieX; x++)
        {
            for (int y = 0; y < resolutieY; y++)
            {
                perlinArray[x, y] = perlinMap.GetValue(x / sample, y / sample, 1d);
            }
        }
        draw(perlinArray);
        textBox12.Text = sw.ElapsedMilliseconds.ToString() + "ms";
        sw.Reset();
    }

提取柏林噪声的代码:

 public void draw(double[,] array)
    {
        Bitmap afbeelding = new Bitmap(1024, 1024);
        Color color;
        int tileSize = 1024 / resolutieY;
        for (int y = 1; y < resolutieY; y++)
        {
            for (int x = 1; x < resolutieX; x++)
            {
                if (array[x, y] <= -0.2)
                    color = Color.DarkBlue;
                if (array[x, y] <= 0)
                    color = Color.DarkBlue;
                else if (array[x, y] <= 0.1)
                    color = Color.Blue;
                else if (array[x, y] <= 0.2)
                    color = Color.Beige;
                else if (array[x, y] <= 0.22)
                    color = Color.LightGreen;
                else if (array[x, y] <= 0.40)
                    color = Color.Green;
                else if (array[x, y] <= 0.75)
                    color = Color.DarkGreen;
                else if (array[x, y] <= 0.8)
                    color = Color.LightSlateGray;
                else if (array[x, y] <= 0.9)
                    color = Color.Gray;
                else if (array[x, y] <= 1)
                    color = Color.DarkSlateGray;
                else
                    color = Color.DarkSlateGray;

                //  color = Color.FromArgb(255);

                for (int i = 0; i < tileSize; i++)
                {
                    for (int j = 0; j < tileSize; j++)
                    {
                        afbeelding.SetPixel(((x - 1) * tileSize) + i, ((y - 1) * tileSize) + j, color);
                    }
                }

            }
        }

        pictureBox1.Image = afbeelding;
    }

我应该使用单纯形噪声吗?还是我在这里遗漏了什么?

【问题讨论】:

  • SetPixel 很可能是您的瓶颈。调查 C# 中不安全的位图编辑。
  • 这个问题似乎是题外话,因为它是关于提高工作代码的性能。请改用codereview.stackexchange.com 提问。
  • 您的代码与柏林噪声无关。
  • @Euphoric 添加了 Perlin 噪声代码
  • 一定是柏林噪音吗?因为您可以使用 Simplex 噪声来获得类似的结果,但更容易计算 en.wikipedia.org/wiki/Simplex_noise

标签: c# noise perlin-noise


【解决方案1】:

在读取或写入大块图像时,您应该使用 LockBits 而不是 SetPixel。

并确保您在没有附加调试器的情况下以发布模式运行代码。这两者都会显着影响性能。

单纯形噪声在这里没有帮助,因为它在更高维度上获得了性能。 2D 噪声可能没有任何性能提升。

【讨论】:

    【解决方案2】:

    计算和使用

    这是两种截然不同的野兽,每种都有许多不同的方法。 通过在数据结构中存储 perlin 噪声或任何昂贵的隐式评估的结果,您可以节省大量时间。 如果你想在你的应用程序中维持一个不错的帧速率,即使在现代硬件上实时评估噪声也不是一个好主意,因为它会消耗大量的处理资源。一旦存储在数据结构中,您就可以将处理简化为对该结构的简单访问,这大大降低了成本,并且通常可以为您返还大部分处理预算。

    【讨论】:

      猜你喜欢
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      • 1970-01-01
      相关资源
      最近更新 更多