Probleem met Perlin-ruis

Ik heb een Perlin-ruisfunctie gemaakt. Mijn probleem is wanneer ik een terreinkaart genereer uit de ruis die het blokkerig wordt, niets zoals de wolkenachtige afbeeldingen die ik heb gezien. Ik ben nieuwsgierig naar wat ik verkeerd doe (als er iets is). hier is mijn code:

main.cpp

#include "PerlinNoise.h"
#include 
#include 

void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B);
SDL_Surface *Render_Noise(int w, int h, int r, int g, int b);
PerlinNoise noiseGen(2,.5,25);

int main(int argc, char **argv)
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Surface *screen = SDL_SetVideoMode(500,500,32,SDL_SWSURFACE);
    SDL_Surface *noise = Render_Noise(500,500,255,255,255);

    SDL_SaveBMP(noise, "noise.bmp");

    bool quit = false;

    while(!quit)
    {
        SDL_Event e;

        SDL_WaitEvent(&e);

        switch(e.type)
        {
        case SDL_QUIT:
            quit = true;
        }

        SDL_BlitSurface(noise,NULL,screen,NULL);
        SDL_Flip(screen);
        SDL_Delay(2000);
    }

    SDL_FreeSurface(noise);
    SDL_Quit();

    return 0;
}

void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B)
{
    Uint32 color = SDL_MapRGB(screen->format, R, G, B);

    if(SDL_MUSTLOCK(screen))
    {
        if(SDL_LockSurface(screen) < 0)
        {
            return;
        }
    }

    switch(screen->format->BytesPerPixel)
    {
    case 1:
        {
        Uint8 *bufp;

        bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
        *bufp = color;
        }
        break;

    case 2:
        {
        Uint16 *bufp;
        bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
        *bufp = color;
        }
        break;

    case 3:
        {
        Uint8 *bufp;

        bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
        *(bufp+screen->format->Rshift/8) = R;
        *(bufp+screen->format->Bshift/8) = B;
        *(bufp+screen->format->Gshift/8) = G;
        }
        break;

    case 4:
        {
        Uint32 *bufp;

        bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
        *bufp = color;
        }
        break;
    }

    if(SDL_MUSTLOCK(screen))
    {
        SDL_UnlockSurface(screen);
    }
    SDL_UpdateRect(screen, x, y, 1, 1);
}

SDL_Surface *Render_Noise(int w, int h, int r, int g, int b)
{
    SDL_Surface *ret = SDL_CreateRGBSurface(SDL_SWSURFACE,w,h,32,0,0,0,0);          //create an empty image

    for(int y = 0; y < h; y++)
    {
        for(int x = 0; x < w; x++)
        {
            double getnoise = 0;
            for(int a = 0; a < noiseGen.n; a++)
            {
                getnoise += noiseGen.generateNoise(x,y);
                noiseGen.z = rand() % 100;
            }

            getnoise/noiseGen.n;

            int color = (int)((getnoise * 128.0) + 128.0);      //convert noise to 0-256 value

            if (color > 255)
                color = 255;
            if (color < 0)
                color = 0;

            DrawPixel( ret, x, y, (int)((r/255.0) * (double)color), (int)((g/255.0) * (double)color), (int)((b/255.0) * (double)color) );
        }
    }
    return ret;
}

perlinnoise.cpp

#include "PerlinNoise.h"

PerlinNoise::PerlinNoise(int octaves, double persistence, int zoom)
{
    p = persistence;
    n = octaves - 1;
    z = zoom;
}

PerlinNoise::~PerlinNoise()
{

}

///Gets a random number using x and y as seeds 
/// A double value 
/// A double value 
/// A random number between -1.0 and 1.0 
inline double PerlinNoise::noise(double x, double y)
{
    int n = x + y * 57; 
    n = (n << 13) ^ n;

    return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff)/1073741824.0);
}

/// Smooths out noise values 
/// a double value 
/// a double value 
/// a smoothed value between -1.0 and 1.0 
double PerlinNoise::smoothNoise(double x, double y)
{
    double corners = (noise(x+1, y+1) + noise(x+1,y-1) + noise(x-1,y+1) + noise(x-1,y-1))/16;
    double sides = (noise(x,y+1) + noise(x,y-1) + noise(x+1,y) + noise(x-1,y))/8;
    double center = noise(x,y)/4;

    return corners + sides + center;
}

/// Cosine Interpolation 
/// The low value to be interpolated 
/// The high value to be interpolated 
/// A value between -1.0 and 1.0 
/// Interpolated value between a and b 
double PerlinNoise::cosineInterpolation(double a, double b, double x)
{
    double ft = x * 3.1415927;
    double f = (1.0 - cos(ft)) * .5;

    return a * (1.0 - f) + b * f;
}

/// Gets smoothed noise values and interpolates them 
/// a double value 
/// a double value 
/// a value between -1 and 1 that's been smoothed and interpolated 
double PerlinNoise::interpolatedNoise(double x, double y)
{
    double integer_x = (int)x;
    double fractional_x = x - integer_x;

    double integer_y = (int)y;
    double fractional_y = y - integer_y;

    double v1 = smoothNoise(integer_x, integer_y);
    double v2 = smoothNoise(integer_x + 1, integer_y);
    double v3 = smoothNoise(integer_x, integer_y + 1);
    double v4 = smoothNoise(integer_x + 1, integer_y + 1);

    double inter1 = cosineInterpolation(v1, v2, fractional_x);
    double inter2 = cosineInterpolation(v3, v4, fractional_x);

    return cosineInterpolation(inter1, inter2, fractional_y);
}

double PerlinNoise::generateNoise(double x, double y)
{
    double total = 0;

    for(int i = 0; i < n; i++)
    {
        frequency = pow(2.0,i);
        amplitude = pow(p,i);

        total = total + interpolatedNoise(x * frequency/z, y * frequency/z) * amplitude;
    }

    return total;
}
0
Het plaatsen van een afbeelding van uw uitvoer zou zeer nuttig zijn.
toegevoegd de auteur Pubby, de bron
Aangezien uw code niet compileert (de lijst is onvolledig), is het een hele uitdaging om nuttige opmerkingen te maken. Dat gezegd hebbende, suggereren blokvormige outputs te weinig octaven van ruis, en zanderige outputs zouden suggereren dat een soort van filtering nodig is. Koppel een aantal uitgangen, alsjeblieft.
toegevoegd de auteur Rook, de bron
hier is wat ik heb gekregen. Voor compilatie hebt u SDL en this nodig. Ik heb de 2 belangrijkste bestanden gekozen om te uploaden, omdat stack overflow me alleen 2 zou toestaan
toegevoegd de auteur Zacharias3960, de bron

1 antwoord

Ik heb het probleem gevonden, mijn doorzettingsvermogen was veel lager dan het zou moeten zijn, ik hoopte dat ik het cloudachtige beeld kreeg dat ik verwachtte

0
toegevoegd