Perlin Noise with Smooth function vs Lerp I tried implementing Perlin Noise using the Wikipedia as my main resource. From what I can tell my implementation of the algorithm is spot on but for some reason I'm getting a lot of values equating to 1 or to 0.

This is my Perlin function:

GLfloat perlin(GLfloat x, GLfloat y)
{
    // Turn param into vector
    glm::vec2 xy = glm::vec2(x, y);

    // Grid Cell Coordinates
    glm::vec2 bottomLeft = glm::vec2(std::floor(x), std::floor(y));
    glm::vec2 topRight = glm::vec2(bottomLeft.x + 1, bottomLeft.y + 1);

    GLfloat sx = x - bottomLeft.x;
    GLfloat sy = y - bottomLeft.y;

    GLfloat bottomLeftDot = glm::dot(gradients[(GLint)bottomLeft.x][(GLint)bottomLeft.y], xy - bottomLeft);
    GLfloat bottomRightDot = glm::dot(gradients[(GLint)topRight.x][(GLint)bottomLeft.y], xy - glm::vec2(topRight.x, bottomLeft.y));

    GLfloat smooth1 = glm::smoothstep(bottomLeftDot, bottomRightDot, sx);

    GLfloat topLeftDot = glm::dot(gradients[(GLint)bottomLeft.x][(GLint)topRight.y], xy - glm::vec2(bottomLeft.x, topRight.y));
    GLfloat topRightDot = glm::dot(gradients[(GLint)topRight.x][(GLint)topRight.y], xy - topRight);

    GLfloat smooth2 = glm::smoothstep(topLeftDot, topRightDot, sx);

    GLfloat value = glm::smoothstep(smooth1, smooth2, sy);
    return value;
}




As you can see, I am using the generated values as a height map. In the image above you can see that there's a straight wall and I'm wondering if maybe I'm not interpolating correctly. Can someone point out my mistake?

I'm generating a 100 by 100 grid and my input values are from 0.00 to 0.99 on each axis.

Another question I have is Wikipedia says to use a smoothstep function but I'm not sure for what values?

Update:
I changed the smoothstep and function to the lerp function and now everything seems to be working well but can someone please explain why the outcome is so drastically different.

New outcome below:
It looks like the way you're using smoothstep isn't quite right.

With lerp, the first two parameters are the endpoints of the output range, and the third is a 0–1 value specifying how far to interpolate. It looks like you're trying to use smoothstep the same way, but it doesn't work like that: the first two parameters to smoothstep are endpoints of the input range, and the third is a value in the input range; the output of smoothstep is always in 0–1. It's almost the inverse of lerp in that regard. (See also the GLM docs for smoothstep).

To use smoothstep here, you'd want to do something like this:

glm::lerp(bottomLeftDot, bottomRightDot, glm::smoothstep(0, 1, sx));


This applies smoothstep to the sx value (which is between 0 and 1). The result, which is another 0–1 value, is then used to lerp between the two "dot" values.