Archived

This topic is now archived and is closed to further replies.

Perlin implementation is too slow

This topic is 5377 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I picked up the Procedural Texturing and Modelling book not too long ago and started to implement my own multifractal terrain engine. I''m moderately pleased with the results so far, with only a few artifacts that I could do without (sine wave undulation across terrain). My biggest hangup, however, is that the generation of the heightmap is unbearably slow. It takes anywhere from 30 seconds to a minute on a 640 x 640 map. I''ve seen other implementations of this (notably Stephen Schmitt''s World Machine) that run instantaneously. You press a key, and the algorithm finishes, or you can change parameters with a slider in real-time and watch them change. I really need this level of response in my code and was wondering if anyone out there would be kind enough to point out where I''m screwing this algorithm up. My code is as follows: This is my function to load the heightmap with the noise based values.
  
void heteroGrid(int grid[SIZEX][SIZEY],  int n, float p,int seed) //double h,double lac,double oct, double offset,int seed)

{
	float low=MAX_HEIGHT;
	float high=-MAX_HEIGHT;
	
	for (int x=0;x<SIZEX;x++)
		for(int y=0; y<SIZEY;y++)
		{
			//grid[x][y]=heteroTerrain(x,y,h,lac,oct,offset,seed) *(MAX_HEIGHT);

			grid[x][y]=HeteroPerlin_2D(x,y,n,p,seed)*(MAX_HEIGHT);//+MAX_HEIGHT;

			
		//	if(grid[x][y]<low) low=grid[x][y];

		//	if(grid[x][y]>high) high=grid[x][y];

		}
		//cout<<"low: "<<low<<" high: "<<high<<endl;

	
}
  
This function is the one called for each cell, the following are the functions it, in turn, calls to interpolate noise values, etc.
  
float HeteroPerlin_2D(float x, float y, int n, float p,int seed)
  {
      float total = 0;
	  float frequency,amplitude;
	  float itemp=1;
	  float increment;	
      float value;
	  
	  frequency=0.0125; 
	  value=(InterpolatedNoise(-1, x * frequency,y * frequency, seed)+0.5); 		if(value<0.0) value=0.0;
      for (int i=0;i<=n;i++)
	  {
		frequency = power(.25,n-i);
		
		  
		  
		increment=(InterpolatedNoise(i % NOISE_VERSIONS, x * frequency, y * frequency, seed));
		
		  
		amplitude = power(p,i);
		

		increment *= amplitude;
		if(increment<0) increment=0;
    	
		increment *=pow(value,SIZEX/128.0);
        value += increment;
		
      }

	  return (value>1.0)?1.0:value;
 }

float InterpolatedNoise(int v,float x, float y, int seed)
  {
      int integer_X    = int(x);
      float fractional_X = x - integer_X;

      int integer_Y    = int(y);
      float fractional_Y = y - integer_Y;

      float v1 = SmoothNoise(v,integer_X,     integer_Y,seed);
      float v2 = SmoothNoise(v,integer_X + 1, integer_Y,seed);
      float v3 = SmoothNoise(v,integer_X,     integer_Y + 1,seed);
      float v4 = SmoothNoise(v,integer_X + 1, integer_Y + 1,seed);
     
	  float i1 = Interpolate(v1 , v2 , fractional_X);
      float i2 = Interpolate(v3 , v4 , fractional_X);

      return Interpolate(i1 , i2 , fractional_Y);
  }

float SmoothNoise(int v, float x, float y,int seed)
{
    float corners = ( IntNoise(v,x-1, y-1,seed)+IntNoise(v,x+1, y-1,seed)+IntNoise(v,x-1, y+1,seed)+IntNoise(v,x+1, y+1,seed) ) / 16.0;
    float sides   = ( IntNoise(v,x-1, y,seed)  +IntNoise(v,x+1, y,seed)  +IntNoise(v,x, y-1,seed)  +IntNoise(v,x, y+1,seed) ) /  8.0;
    float center  =  IntNoise(v,x, y,seed) / 4.0;
    return corners + sides + center;
}

float IntNoise(int version, float x, float y, int seed)			 
{
	int n = seed + x + y  * 57 ;
    n = (n<<13) ^ n;
	
	switch (version)
	{
	case 0:return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);    
		break;
	case 1:return ( 1.0 - ( (n * (n * n * 966653 + 985079) + 500251883) & 0x7fffffff) / 1073741824.0);    
		break;
	case 2:return ( 1.0 - ( (n * (n * n * 968273 + 986411) + 500375033) & 0x7fffffff) / 1073741824.0);    
		break;
	case 3:return ( 1.0 - ( (n * (n * n * 500251883 + 15731) + 985079) & 0x7fffffff) / 1073741824.0);    
		break;
	case 4:return ( 1.0 - ( (n * (n * n * 500251883 + 966653) + 15731) & 0x7fffffff) / 1073741824.0);    
		break;
	case 5:return ( 1.0 - ( (n * (n * n * 500372623 + 500251883) + 985079) & 0x7fffffff) / 1073741824.0);    
		break;
	default:return ( 1.0 - ( (n * (n * n * 969179 + 985403) + 500372623) & 0x7fffffff) / 1073741824.0);    
		break;

	}
  
	

}

  
Rich Wilson Starving artist, graphics programmer, aspiring game developer http://mywebpages.comcast.net/Rich_wilson

Share this post


Link to post
Share on other sites
this is some wierd implementation try using one from ken perlin (http://mrl.nyu.edu/~perlin/noise/)

You should never let your fears become the boundaries of your dreams.

Share this post


Link to post
Share on other sites
strange, I had several octaves of perlin noise running in realtime on my comp in 3d. I was using the updated version from his web site adapted to c++ however. If thats still to slow for you, maybe you should check out the value noise implementations as showen in texturing and modeling?
Jesse

Share this post


Link to post
Share on other sites