<p>A general answer is that behavior can be different using consts (i.e. solved at compile time) or variables (i.e. solved at runtime), because these are treated by 2 absolutely different engines.
The GLSL spec is very lazy in terms of compulsory behaviors, but I observed that the worst is often when relying to early evaluation of functions (i.e. all const parameters), e.g. in term of IEEE754 compliance, behavior for swapped parameters, etc.
Note also that despite some out-of-spec situations often work correctly ( i.e. as expected ), it can be very OS, GPU or browser dependant.</p>

CC BY-SA 4.0
2023-01-28T16:17:37.803Z
2023-01-28T16:17:37.803Z
Fabrice NEYRET
<p>Undefined behavior is undefined. <a href="https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml" rel="noreferrer"><code>smoothstep</code> requires that the first argument is less than the second.</a> If that is not the case, undefined behavior results.</p>

CC BY-SA 4.0
2023-01-10T14:49:17.780Z
Thank you.  I wonder why the code works when smoothstep is called with `(0.2, 0.0, abs(st.y - st.x))` but not when it's called with all literals e.g. `(0.2, 0.0, 0.1)`.  It does work when it's called with all literals and `edge0 < edge 1`, e.g. `(0.0, 0.2, 0.1)` but I wonder why a literal different from a variable?
AJP
CC BY-SA 4.0
2023-01-10T14:51:35.207Z
@AJP: Undefined behavior is *undefined*; that means *anything* can happen, including *contradictory* things. Maybe the constant expression evaluator in the compiler detected the UB and gave one result, while the runtime version delivered a different one. What does it matter? It'll be different for different compilers because the code itself is dysfunctional.
Nicol Bolas
CC BY-SA 4.0
2023-01-10T01:18:46.630Z
2023-01-10T01:18:46.630Z
Nicol Bolas
<p>I was working through <a href="https://thebookofshaders.com/05/" rel="nofollow noreferrer">https://thebookofshaders.com/05/</a> when I came across some unintuitive behaviour of <code>smoothstep</code>.  I wanted to understand it better so I replaced the following line of code:</p>
<pre><code>return smoothstep(0.02, 0.0, abs(st.y - st.x));
</code></pre>
<p>With all arguments as float literals:</p>
<pre><code>return smoothstep(0.02, 0.0, 0.0);
</code></pre>
<p>I was expecting <code>smoothstep</code> to return 1.0 but instead it seems to always return 0.0 regardless of the value of the third argument.  If instead of that you use a float variable:</p>
<pre><code>float temp = 0.0;
return smoothstep(0.02, 0.0, temp);
</code></pre>
<p>It works as expected and returns 1.0.  Why is this?  I assume this is documented somewhere though it's not obvious what to search for.</p>
<p>Minimal, Reproducible Example:</p>
<pre><code>#ifdef GL_ES
precision mediump float;
#endif

void main() {
    float diff = 0.0;
    float green = smoothstep(0.2, 0.0, diff);
    // Won't result in green if uncommented
    // green = smoothstep(0.2, 0.0, 0.0);

    gl_FragColor = vec4(0.0, green, 0.0, 1.0);
}
<span class="math-container">```</span>
</code></pre>

<glsl>
Why does GLSL smoothstep return 0 when all parameters are literal floats?
AJP
# Why does GLSL smoothstep return 0 when all parameters are literal floats?

(Asked by: username_0 on 2023-01-09)

I was working through <https://thebookofshaders.com/05/> when I came across some unintuitive behaviour of `smoothstep`. I wanted to understand it better so I replaced the following line of code:

```
return smoothstep(0.02, 0.0, abs(st.y - st.x));

```

With all arguments as float literals:

```
return smoothstep(0.02, 0.0, 0.0);

```

I was expecting `smoothstep` to return 1.0 but instead it seems to always return 0.0 regardless of the value of the third argument. If instead of that you use a float variable:

```
float temp = 0.0;
return smoothstep(0.02, 0.0, temp);

```

It works as expected and returns 1.0. Why is this? I assume this is documented somewhere though it's not obvious what to search for.

Minimal, Reproducible Example:

```
#ifdef GL_ES
precision mediump float;
#endif

void main() {
    float diff = 0.0;
    float green = smoothstep(0.2, 0.0, diff);
    // Won't result in green if uncommented
    // green = smoothstep(0.2, 0.0, 0.0);

    gl_FragColor = vec4(0.0, green, 0.0, 1.0);
}
```

```

**Tags:** glsl


---

## 2 answers

### Answer by username_2 on 2023-01-10. Score: 5 | Accepted answer

Undefined behavior is undefined. [`smoothstep` requires that the first argument is less than the second.](https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml) If that is not the case, undefined behavior results.

> **Comments:**
> **username_0**: Thank you.  I wonder why the code works when smoothstep is called with `(0.2, 0.0, abs(st.y - st.x))` but not when it's called with all literals e.g. `(0.2, 0.0, 0.1)`.  It does work when it's called with all literals and `edge0 < edge 1`, e.g. `(0.0, 0.2, 0.1)` but I wonder why a literal different from a variable?  
> **username_2**: @username_0: Undefined behavior is *undefined*; that means *anything* can happen, including *contradictory* things. Maybe the constant expression evaluator in the compiler detected the UB and gave one result, while the runtime version delivered a different one. What does it matter? It'll be different for different compilers because the code itself is dysfunctional.  

---

### Answer by username_1 on 2023-01-28. Score: 0

A general answer is that behavior can be different using consts (i.e. solved at compile time) or variables (i.e. solved at runtime), because these are treated by 2 absolutely different engines.
The GLSL spec is very lazy in terms of compulsory behaviors, but I observed that the worst is often when relying to early evaluation of functions (i.e. all const parameters), e.g. in term of IEEE754 compliance, behavior for swapped parameters, etc.
Note also that despite some out-of-spec situations often work correctly ( i.e. as expected ), it can be very OS, GPU or browser dependant.


---

