Ryanas
Ryanas

Reputation: 1827

Perlin Noise and FBM generated image too grey

I've been working on generating noise using Perlin Noise and FBM as I understand it and I've seem to come into a bit of a problem.

The images I am generating seem to be too grey when they're meant to be greyscale but I see no variations of whites or blacks.

An example of this image is (This is generated using 8 octaves)

Perlin Noise example

An image of what I am expecting to produce;

enter image description here

I am generating the noise as follows;

float result = 0.0f;
  float amp = 1.0f;
  float frequency = 2.0f;

  float maxAmplitude = 0.0f;
  int i = _octaves;
  while (i--){
  result += noise(x * frequency, y * frequency, z * frequency) * amp;
  frequency *= 2.0f;
  maxAmplitude += amp;
  amp *= 0.5f;
  }
  return result / maxAmplitude;
  }

where the noise function is Ken Perlin's Improved Noise function found here; http://mrl.nyu.edu/~perlin/noise/ and I am using the default permutation table.

Then as I generate the images, I do the following to get a greyscale image;

ppm_image.pixel_colour[kk] = 255.0f  * noise;

I was just wondering how I can generate the same heightmap with a wider variation in the colours (more whites and blacks rather than just narrow greys).

Upvotes: 2

Views: 1206

Answers (2)

peepohug_smileww
peepohug_smileww

Reputation: 1

You can use tan(x) to redistribute values. I briefly read this article which explains the opposite of Histogram Equalization using random values. https://ericlippert.com/2012/02/21/generating-random-non-uniform-data/

f = tan(f);

I forgot to mention this initially but prior to tan(x), I put the values from 0-1, and after tan(x), you must clamp the value as it may go over 1.0.

// Usually, perlin or simplex noise ranges from -1 to 1
f = f*.5+.5;
f = tan(f);
f = clamp(f,0.0,1.0);

Upvotes: 0

Pikalek
Pikalek

Reputation: 946

I've generally find that I need to apply some manner of histogram equalization as a post process to noise data. This usually works for me:

float min = data[0];
float max = data[0];
for (float& f : data){
  if(min > f)
    min = f;
  if(max < f)
    max = f;
}
for (float& f : data){
  f = (f-min) / (max-min);      
}

Upvotes: 1

Related Questions