Perlin Noise 2D:将静态变成云
Perlin Noise 2D: turning static into clouds
我正在努力解决 Perlin 噪声问题。
This article 有帮助,我一直在尝试重新创建它提供的云类型图像。
我的噪音代码如下:
#include "terrain_generator.hpp"
using namespace std;
#define PI 3.1415927;
float noise(int x, int y)
{
int n = x + y * 57;
n = (n<<13) ^ n;
return (1.0 - ( (n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
float cosine_interpolate(float a, float b, float x)
{
float ft = x * PI;
float f = (1 - cos(ft)) * 0.5;
float result = a*(1-f) + b*f;
return result;
}
float smooth_noise_2D(float x, float y)
{
float corners = ( noise(x-1, y-1)+noise(x+1, y-1)+noise(x-1, y+1)+noise(x+1, y+1) ) / 16;
float sides = ( noise(x-1, y) +noise(x+1, y) +noise(x, y-1) +noise(x, y+1) ) / 8;
float center = noise(x, y) / 4;
return corners + sides + center;
}
float interpolated_noise(float x, float y)
{
int x_whole = (int) x;
float x_frac = x - x_whole;
int y_whole = (int) y;
float y_frac = y - y_whole;
float v1 = smooth_noise_2D(x_whole, y_whole);
float v2 = smooth_noise_2D(x_whole, y_whole+1);
float v3 = smooth_noise_2D(x_whole+1, y_whole);
float v4 = smooth_noise_2D(x_whole+1, y_whole+1);
float i1 = cosine_interpolate(v1,v3,x_frac);
float i2 = cosine_interpolate(v2,v4,x_frac);
return cosine_interpolate(i1, i2, y_frac);
}
float perlin_noise_2D(float x, float y)
{
int octaves=5;
float persistence=0.5;
float total = 0;
for(int i=0; i<octaves-1; i++)
{
float frequency = pow(2,i);
float amplitude = pow(persistence,i);
total = total + interpolated_noise(x * frequency, y * frequency) * amplitude;
}
return total;
}
为了实际实现该算法,我正在尝试制作他在文章中描绘的云。
我正在使用 openGL,我正在制作自己的纹理并将其粘贴到覆盖屏幕的四边形上。但这无关紧要。在下面的代码中,只要知道set pixel函数是正确的,它的参数是(x, y, red, green, blue)
就可以了。
这基本上是我的绘制循环:
for(int y=0; y<texture_height; y++)
{
for(int x=0; x<texture_width; x++)
{
seed2+=1;
float Val=perlin_noise_2D(x,y);
Val = Val/2.0;
Val = (Val + 1.0) / 2.0;
setPixel(x,y,Val,Val,Val);
}
}
我得到的是以下内容:
我怎样才能操纵我的算法来实现我正在寻找的效果?改变持久性或八度音阶的数量似乎根本没有多大作用。
由于您的结果看起来几乎像白噪声,您的样本可能在柏林噪声中相距太远。尝试使用小于像素坐标的值来评估噪声。
与此类似的内容:
perlin_noise_2D((float)x/texture_width,(float)y/texture_height);
我正在努力解决 Perlin 噪声问题。
This article 有帮助,我一直在尝试重新创建它提供的云类型图像。
我的噪音代码如下:
#include "terrain_generator.hpp"
using namespace std;
#define PI 3.1415927;
float noise(int x, int y)
{
int n = x + y * 57;
n = (n<<13) ^ n;
return (1.0 - ( (n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
float cosine_interpolate(float a, float b, float x)
{
float ft = x * PI;
float f = (1 - cos(ft)) * 0.5;
float result = a*(1-f) + b*f;
return result;
}
float smooth_noise_2D(float x, float y)
{
float corners = ( noise(x-1, y-1)+noise(x+1, y-1)+noise(x-1, y+1)+noise(x+1, y+1) ) / 16;
float sides = ( noise(x-1, y) +noise(x+1, y) +noise(x, y-1) +noise(x, y+1) ) / 8;
float center = noise(x, y) / 4;
return corners + sides + center;
}
float interpolated_noise(float x, float y)
{
int x_whole = (int) x;
float x_frac = x - x_whole;
int y_whole = (int) y;
float y_frac = y - y_whole;
float v1 = smooth_noise_2D(x_whole, y_whole);
float v2 = smooth_noise_2D(x_whole, y_whole+1);
float v3 = smooth_noise_2D(x_whole+1, y_whole);
float v4 = smooth_noise_2D(x_whole+1, y_whole+1);
float i1 = cosine_interpolate(v1,v3,x_frac);
float i2 = cosine_interpolate(v2,v4,x_frac);
return cosine_interpolate(i1, i2, y_frac);
}
float perlin_noise_2D(float x, float y)
{
int octaves=5;
float persistence=0.5;
float total = 0;
for(int i=0; i<octaves-1; i++)
{
float frequency = pow(2,i);
float amplitude = pow(persistence,i);
total = total + interpolated_noise(x * frequency, y * frequency) * amplitude;
}
return total;
}
为了实际实现该算法,我正在尝试制作他在文章中描绘的云。
我正在使用 openGL,我正在制作自己的纹理并将其粘贴到覆盖屏幕的四边形上。但这无关紧要。在下面的代码中,只要知道set pixel函数是正确的,它的参数是(x, y, red, green, blue)
就可以了。
这基本上是我的绘制循环:
for(int y=0; y<texture_height; y++)
{
for(int x=0; x<texture_width; x++)
{
seed2+=1;
float Val=perlin_noise_2D(x,y);
Val = Val/2.0;
Val = (Val + 1.0) / 2.0;
setPixel(x,y,Val,Val,Val);
}
}
我得到的是以下内容:
我怎样才能操纵我的算法来实现我正在寻找的效果?改变持久性或八度音阶的数量似乎根本没有多大作用。
由于您的结果看起来几乎像白噪声,您的样本可能在柏林噪声中相距太远。尝试使用小于像素坐标的值来评估噪声。
与此类似的内容:
perlin_noise_2D((float)x/texture_width,(float)y/texture_height);