<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;
}

```

[![enter image description here](https://i.sstatic.net/p5zn0.png)](https://i.sstatic.net/p5zn0.png)

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:

[![enter image description here](https://i.sstatic.net/qE0qp.png)](https://i.sstatic.net/qE0qp.png)

**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](https://glm.g-truc.net/0.9.4/api/a00129.html#gabdfe71a62ef69b5ec834601e87588667)).

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.  

---

