“Blocky” Perlin noise

后端 未结 2 1355
天涯浪人
天涯浪人 2021-01-12 04:53

I\'ve recently been trying to implement a Perlin Noise generator in C (based off Ken Perlin\'s website, using the SDL library as a screen output), but the output shows that

2条回答
  •  滥情空心
    2021-01-12 05:14

    I have finally found the problem: the gradient generator.

    I was assuming that the random() function would pass its binary value to the grads[] array, covering the whole range of floating point numbers in the way. Unfortunately, that was not the case: its return value was being converted first into a float, then stored in the array. My biggest issue with this was that all generated vectors had positive member values.

    This justified the block artifacts: there were lots of "hills" (high values) being generated next to each other, but no "valleys" (low values), and two adjacent hills would eventually clash and generate the lines along the integer values.

    After realizing this, I tried to do some pointer juggling and storing the values directly in Uint32 form, but the values in the gradients became wacky (infs, NaNs, 1.0s and 0.0s all the way), so I came back to the original route and negated the numbers in the code itself.

    This 7-liner solved the whole problem:

    int y=random()&7;
    if(y&1)
        grads[3*x]*=-1.0f;
    if(y&2)
        grads[3*x+1]*=-1.0f;
    if(y&4)
        grads[3*x+2]*=-1.0f;
    

    Just place it before or after the normalizing function and it's done.

    Now it looks like Perlin Noise: Perlin Noise, at least.

    And the fractal sum also looks a bit better: Fractal sum improved

    @DiJuMx: I've seen the "Improving Noise" paper before, but hadn't realized how much the gradients would affect the noise appearance. Also, by trying to change the coordinate space from 0~256 to 0~1 resulted in the fractal sum not working anymore, and the resulting image had the same block artifacts.

提交回复
热议问题