Home > Net >  C noise interpolation issue
C noise interpolation issue

Time:10-12

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.

new output

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.

  •  Tags:  
  • c
  • Related