Perlin Noise 2D: turning static into clouds

2

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:

enter image description here

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.

c++
opengl
perlin-noise
asked on Stack Overflow Apr 4, 2015 by Luke • edited Apr 18, 2019 by genpfault

1 Answer

3

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

answered on Stack Overflow Apr 4, 2015 by Gigo

User contributions licensed under CC BY-SA 3.0