I am attempting to generate noise similar to perlin or value noise.
I am using stb_image_write library from here to write to image file (i write to disk as hdr and converted to png with GIMP to post on here).
This code requires C 20 because I am using std::lerp();
Because I am generating a linear gradient as testing I am expecting a linear gradient as output.
I know there are more steps to generating the desired noise but, this is where I'm having issues.
#include <cmath>
template <size_t size>
void noise(float seed[size][size], float output[size][size], size_t octave);
int main()
{
// generate test gradient
float seedNoise[64][64] = {};
for ( size_t x = 0; x < 64; x )
{
for ( size_t y = 0; y < 64; y )
{
seedNoise[x][y] = ((((float)x) / 64.0f ((float)y / 64.0f)) / 2.0f);
}
}
float _map[64][64] = { 0 };
noise<64>(seedNoise, _map, 4);
}
template <size_t size>
void noise(float seed[size][size], float output[size][size], size_t octave)
{
size_t step = size / octave; // went back to this
// size_t step = (size - 1) / octave; // took this back out
for ( size_t x = 0; x <= size - step; x = step )
{
for ( size_t y = 0; y <= size - step; y = step )
{ // each octave
// extract values at corners octave from seed
float a = seed[x][y];
float b = seed[x (step - 1)][y]; // changed this
float c = seed[x][y (step - 1)]; // this
float d = seed[x (step - 1)][y (step - 1)]; // and this
for ( size_t u = 0; u < step; u )
{
float uStep = ((float)u) / ((float)step); // calculate x step
for ( size_t v = 0; v < step; v )
{ // each element in each octave
float vStep = ((float)v) / ((float)step); // calculate y step
float x1 = std::lerp(a, b, uStep); // interpolate top edge
float x2 = std::lerp(c, d, uStep); // interpolate bottom edge
float y1 = std::lerp(a, c, vStep); // interpolate left edge
float y2 = std::lerp(b, d, vStep); // interpolate right edge
float x3 = std::lerp(x1, x2, vStep); // interpolate between top and bottom edges
float y3 = std::lerp(y1, y2, uStep); // interpolate between left and right edges
float odat = (x3 y3) / 2; // average top/bottom and left/right interpolations
output[x u][y v] = odat;
}
}
}
}
}
Source gradient I think this should be similar to what the output should be.
Output As you can see here the right and bottom of the output is all messed up.
CodePudding user response:
I think you're accessing the imago outside it's boundaries. X and y can go up to 60 in the loops:
for ( size_t x = 0; x <= size - step; x = step )
And the you are accessing position y step
and x step
, which gives 64.