<p>It looks like the way you're using smoothstep isn't quite right.</p>

<p>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 <em>input</em> 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 <a href="https://glm.g-truc.net/0.9.4/api/a00129.html#gabdfe71a62ef69b5ec834601e87588667" rel="nofollow noreferrer">the GLM docs for smoothstep</a>).</p>

<p>To use smoothstep here, you'd want to do something like this:</p>

<pre><code>glm::lerp(bottomLeftDot, bottomRightDot, glm::smoothstep(0, 1, sx));
</code></pre>

<p>This applies smoothstep to the <code>sx</code> 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.</p>

CC BY-SA 3.0
2017-09-01T19:25:41.983Z
But what exactly is the smoothstep doing? How will it change the outcome?
Archmede
CC BY-SA 3.0
2017-09-01T20:38:00.733Z
Smoothstep is just a hermite curve (a 3rd degree polynomial) that smoothly varies between 0 and 1. Rather than a straight line, it ramps up slowly at first, then faster, then eases up at the end. So it looks sort of like an integral symbol if you map it from 0 to 1. Like this: ∫. You can read [the wikipedia article](https://en.wikipedia.org/wiki/Smoothstep), which has a graph.
user1118321
CC BY-SA 3.0
2017-09-01T04:27:54.810Z
2017-09-01T04:27:54.810Z
Nathan Reed
<p>I tried implementing <code>Perlin Noise</code> using the <code>Wikipedia</code> 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.</p>

<p>This is my Perlin function:</p>

<pre><code>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;
}
</code></pre>

<p><a href="https://i.sstatic.net/p5zn0.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/p5zn0.png" alt="enter image description here"></a></p>

<p>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?</p>

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

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

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

<p>New outcome below:</p>

<p><a href="https://i.sstatic.net/qE0qp.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/qE0qp.png" alt="enter image description here"></a></p>

<interpolation><vectors>
Perlin Noise with Smooth function vs Lerp
Archmede
# Perlin Noise with Smooth function vs Lerp

(Asked by: username_0 on 2017-08-31)

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:

**Tags:** interpolation, vectors

---

## 1 answers

### Answer by username_1 on 2017-09-01. Score: 3 | Accepted answer

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.

> **Comments:**
> **username_0**: But what exactly is the smoothstep doing? How will it change the outcome?  
> **username_2**: Smoothstep is just a hermite curve (a 3rd degree polynomial) that smoothly varies between 0 and 1. Rather than a straight line, it ramps up slowly at first, then faster, then eases up at the end. So it looks sort of like an integral symbol if you map it from 0 to 1. Like this: ∫. You can read [the wikipedia article](https://en.wikipedia.org/wiki/Smoothstep), which has a graph.  

---

