Perlin Noise 2D: turning static into clouds

…衆ロ難τιáo~ 提交于 2019-12-11 03:15:17

问题


I am trying to wrap my head around Perlin noise.

This article has helped and I have been trying to recreate the cloud type images that it provides.

My noise code is as follows:

#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;
}

To actually implement the algorithm, I am trying to make the clouds he depicted in the article.

I am using openGL and I am making my own texture and pasting it onto a quad that covers the screen. That is irrelevant though. In the code below, just know that the set pixel function works correctly and that its parameters are (x, y, red, green, blue).

This is essentially my draw loop:

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);
    }
}

What I get is the following:

How can I manipulate my algorithm to achieve the effect I am looking for? changing the persistence or number of octaves doesn't seem to do much at all.


回答1:


As your result looks almost like white noise, your samples are probably too far apart within the perlin noise. Try using something smaller than the pixel coordinates to evaluate the noise at.

Something similar to this:

perlin_noise_2D((float)x/texture_width,(float)y/texture_height);



来源:https://stackoverflow.com/questions/29452265/perlin-noise-2d-turning-static-into-clouds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!