Skip to main content
GameDev.net gamedev.net
🔒 Locked

improved noise

Started by Khaos Dragon Jul 17, 2004 at 7:48 PM 1 replies 1k views
Original Post
Khaos Dragon
Khaos Dragon
I am using Ken Perlin's improved noise, which can be found here http://mrl.nyu.edu/~perlin/noise/ to try and develop my own 3d noise. Right now, I just use the sdl graphics library to view 2d slices of the noise, but to my dismay the noise function always returns a value of just 0 for any location in the noise (meaning that only solid blackness is displayed). I admit I do not quite understand fully what is going on, but I have attempted to basically port his java code to C and view the results in SDL. I do not really see a difference between mine and his code, but I have posted mine below, in case anybody may have a clue what is wrong here. I appreciate any help I can get.

#include <windows.h>
#include <sdl.h>
#include <math.h>

//basic graphic routines
void blit( SDL_Surface*, SDL_Surface*, int, int, int, int, int, int);
void putpixel(SDL_Surface*, int, int, Uint32);
//noise functions
double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); }
double lerp(double t, double a, double b) { return a + t * (b - a); }
double grad(int, double, double, double); 
double noise(double, double, double);
//noise tables
int p[512],
permutation[] = { 151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,
				  142,8,99,37,240,21,10,23,190, 6,148,247,120,234,75,0,26,197,62,94,252,219,
				  203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168, 68,175,
				  74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,
				  220,105,92,41,55,46,245,40,244,102,143,54, 65,25,63,161, 1,216,80,73,209,76,
				  132,187,208, 89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,
				  186, 3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,
				  206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152, 2,44,154,
				  163, 70,221,153,101,155,167,43,172,9,129,22,39,253, 19,98,108,110,79,113,
				  224,232,178,185, 112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,
				  179,162,241, 81,51,145,235,249,14,239,107,49,192,214, 31,181,199,106,157,
				  184, 84,204,176,115,121,50,45,127,4,150,254,138,236,205,93,222,114,67,29,
				  24,72,243,141,128,195,78,66,215,61,156,180 };

int main( int argc, char* argv[] )
{
	//initalizing noise table
	for(int i=0; i < 256 ; i++) 
		p[256+i] = p = permutation; 
	//create console to output noise for debugging
	AllocConsole();		
	freopen("CONOUT$", "w", stdout );
	//initialize and setup SDL to display graphics
	int w = 256, h = 256;
	SDL_Init ( SDL_INIT_VIDEO ) ; 
	SDL_Surface* screen = SDL_SetVideoMode ( w , h , 0, SDL_RESIZABLE );	
	Uint32 color;
	double value;
	/////////////////////////////////////////////////////////////////////////
	//use noise function to display a 2d slice of the 3d noise on screen   //
	/////////////////////////////////////////////////////////////////////////
	SDL_Surface* layer = SDL_CreateRGBSurface( SDL_HWSURFACE, w, h, 32, SDL_GetVideoSurface()->format->Rmask, SDL_GetVideoSurface()->format->Gmask, SDL_GetVideoSurface()->format->Bmask, SDL_GetVideoSurface()->format->Amask  );
	for( int i = 0; i < w; i++ )
		for( int j = 0; j < h; j++ )
		{
			value = noise(i,j,7);
			printf("%f\n",value);
			color = SDL_MapRGB( screen->format,value, value, value);
			putpixel( layer, i, j, color );
		}
	blit( layer, screen, 0,0, w, h, 0, 0 );
	//basic event loop to keep program checking for quit or exit messages, not too impotant
	SDL_Event event;
	while(1)
	{
		while(SDL_PollEvent(&event))
		{
			switch(event.type)
			{
			case SDL_QUIT:	
				return 0;
			}
		}
		SDL_Flip( screen );
	}			
	return 0;
}


double grad(int hash, double x, double y, double z) 
{
      int h = hash & 15;                     
      double u = h<8 ? x : y, v = h<4 ? y : h==12||h==14 ? x : z;
      return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
}

double noise(double x, double y, double z) 
{
      int X = (int)floor(x) & 255,                  // FIND UNIT CUBE THAT
          Y = (int)floor(y) & 255,                  // CONTAINS POINT.
          Z = (int)floor(z) & 255;
      x -= floor(x);                                // FIND RELATIVE X,Y,Z
      y -= floor(y);                                // OF POINT IN CUBE.
      z -= floor(z);
      double u = fade(x),                                // COMPUTE FADE CURVES
             v = fade(y),                                // FOR EACH OF X,Y,Z.
             w = fade(z);
      int A = p[X  ]+Y, AA = p[A]+Z, AB = p[A+1]+Z,      // HASH COORDINATES OF
          B = p[X+1]+Y, BA = p+Z, BB = p[B+1]+Z;      // THE 8 CUBE CORNERS,

      return lerp(w, lerp(v, lerp(u, grad(p[AA  ], x  , y  , z   ),  // AND ADD
                                     grad(p[BA  ], x-1, y  , z   )), // BLENDED
                             lerp(u, grad(p[AB  ], x  , y-1, z   ),  // RESULTS
                                     grad(p[BB  ], x-1, y-1, z   ))),// FROM  8
                     lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),  // CORNERS
                                     grad(p[BA+1], x-1, y  , z-1 )), // OF CUBE
                             lerp(u, grad(p[AB+1], x  , y-1, z-1 ),
                                     grad(p[BB+1], x-1, y-1, z-1 ))));
  }

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    int bpp = surface->format->BytesPerPixel;
    Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        *pix = pixel;
        break;

    case 2:
        *(Uint16 *)pix = pixel;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            pix[0] = (pixel >> 16) & 0xff;
            pix[1] = (pixel >> 8) & 0xff;
            pix[2] = pixel & 0xff;
        } else {
            pix[0] = pixel & 0xff;
            pix[1] = (pixel >> 8) & 0xff;
            pix[2] = (pixel >> 16) & 0xff;
        }
        break;

    case 4:
        *(Uint32 *)pix = pixel;
        break;
    }
}

void blit( SDL_Surface* source, SDL_Surface* target, int xs, int ys, int width, int height, int xt, int yt )
{
	SDL_Rect s, t;
	s.x = xs;
	s.y = ys;
	s.w = width;
	s.h = height;
	t.x = xt;
	t.y = yt;
	SDL_BlitSurface (source, &s, target, &t );
}

WilyCoder
WilyCoder
You know, for a second there, I thought you were talking about 3d sound, then I followed that link.

I just owned myself!

owned fool!

:)

PS Sorry I cant help
mattnewport
mattnewport
You seem to be sampling the noise only at integer lattice points (your loop does noise(i, j, 7). IIRC gradient noise is zero at integer boundaries. Try sampling at a higher frequency - the smooth part of gradient noise is between integer values. So instead of looping over each pixel and using the pixels integer coordinate to sample, have the left side be 0 and the right side be 20 or something and sample at non-integer values in between.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.