【问题标题】:2D perlin noise in CC中的2D柏林噪声
【发布时间】:2013-05-15 15:51:38
【问题描述】:

我关注了this tutorial

当我在代码中实现它(光线跟踪)并将其应用到球体上时,我得到一个单色球体,上面有一条较暗像素的条纹。当我更改随机浮点生成器时,我得到了基本的线性噪声,这不是我的目标。你能解释一下我错过了什么吗?

这是我的代码:

#include    <stdlib.h>
#include    <math.h>

float       noise(int x, int y)
{
  int       n;

  n = x + y * 57;
  n = pow((n << 13), n);
  return (1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}

float       interpolate(float a, float b, float x)
{
  float     pi_mod;
  float     f_unk;

  pi_mod = x * 3.1415927;
  f_unk = (1 - cos(pi_mod)) * 0.5;
  return (a * (1 - f_unk) + b * x);
}

float       smooth_noise(int x, int y)
{
  float     corners;
  float     center;
  float     sides;

  corners = (noise(x - 1, y - 1) + noise(x + 1, y - 1) +
         noise(x - 1, x + 1) + noise(x + 1, y + 1)) / 16;
  sides = (noise(x - 1, y) + noise(x + 1, y) + noise(x, y - 1) +
       noise(x, y + 1)) / 8;
  center = noise(x, y) / 4;
  return (corners + sides + center);
}

float       noise_handler(float x, float y)
{
  int       int_val[2];
  float     frac_val[2];
  float     value[4];
  float     res[2];

  int_val[0] = (int)x;
  int_val[1] = (int)y;
  frac_val[0] = x - int_val[0];
  frac_val[1] = y - int_val[1];
  value[0] = smooth_noise(int_val[0], int_val[1]);
  value[1] = smooth_noise(int_val[0] + 1, int_val[1]);
  value[2] = smooth_noise(int_val[0], int_val[1] + 1);
  value[3] = smooth_noise(int_val[0] + 1, int_val[1] + 1);
  res[0] = interpolate(value[0], value[1], frac_val[0]);
  res[1] = interpolate(value[2], value[3], frac_val[0]);
  return (interpolate(res[0], res[1], frac_val[1]));
}

float       perlin_two(float x, float y)
{
  float     total;
  float     per;
  float     amp;
  int       hz;
  int       i;
  int       octave;

  total = 0.0;
  per = 0.5;
  octave = 10;
  i = 0;
  while (i < octave)
    {
      hz = pow(2, i);
      amp = pow(per, (float)i);
      total += noise_handler(x * (float)hz, y * (float)hz) * amp;
      i += 1;
    }
  return (total);
}

编辑:我在噪声函数中发现了一个错误(我认为 XOR 操作数就像一个幂函数......现在我得到一个条形码,好像 y 参数在操作中被忽略了......

【问题讨论】:

    标签: c algorithm


    【解决方案1】:

    最近不得不在 C 中实现这一点,这篇文章帮助我开始了。如前所述,对噪声函数进行了一种修复。

    float noise(int x, int y) {
        int n;
    
        n = x + y * 57;
        n = (n << 13) ^ n;
        return (1.0 - ( (n * ((n * n * 15731) + 789221) +  1376312589) & 0x7fffffff) / 1073741824.0);
    }
    

    最重要的是,Fractal Brownian Motion 在实施 Perlin Noise 以用于高度图时非常重要。我没有遵循 Hugo Elias 的伪代码,而是使用了 Google Code Snippet

    float perlin_two(float x, float y, float gain, int octaves, int hgrid) {
        int i;
        float total = 0.0f;
        float frequency = 1.0f/(float)hgrid;
        float amplitude = gain;
        float lacunarity = 2.0;
    
        for (i = 0; i < octaves; ++i)
        {
            total += noise_handler((float)x * frequency, (float)y * frequency) * amplitude;         
            frequency *= lacunarity;
            amplitude *= gain;
        } 
    
        return (total);
    }
    

    在我这样做之前,我在统一的“剥离”或只是完成随机的高度图时遇到了同样的问题。

    【讨论】:

    • noise_hander 是什么?它只是任何可以给您带来噪音的功能吗? (在这种情况下,hander 是什么?为什么不直接叫它noise_generator?)
    【解决方案2】:

    您可能需要调试和返工所有变量类型;用笔和纸或在调试器中进行数学运算并检查值的范围。例如这里

    noise(int x, int y) {
          int n = x + y * 57;
          n = pow((n << 13), n);  ...
    }
    

    n 对于几乎所有非零值都会下溢或上溢。任何随机方法都无法产生好的随机值,这就是这些公式的样子。

    请查看此主题以获取一些reference code

    【讨论】:

    • 我换行:“n = pow((n
    • 条码表示选择公式n=x+y*57;当您使用 (x+1) 与 (y+1) 时,其中一项更改不会改变太多(或根本不会)输出。 (x+1) 与 (y+1)*57 ?
    • 如果我更改为 n = (x*57) + (y * 57),我会得到一些其他颜色,但总是条形码,就好像我尝试 n = (x + y) * 57。 Perlin 值被修改,但仍然画了一个循环...
    猜你喜欢
    • 2012-01-29
    • 2016-05-30
    • 2021-04-29
    • 1970-01-01
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 2013-09-16
    相关资源
    最近更新 更多