6

I am looking into smoothstep(edge0, edge1, x) function. docs say results are undefined if edge0 >= edge1.

In a shader there is a line:

smoothstep(radius + SIZE, radius + SIZE / 1.2, dist);

this means edge0 >= edge1 it still works fine, how is that possible?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
eguneys
  • 6,028
  • 7
  • 31
  • 63
  • 1
    This has nothing to do with `javascript` and `html`, please remove those tags. Also if you read a little further in the docs you will find that `smoothstep` is equivalent to `t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t);` so it _can_ work if `edge0 => edge1` but the result is not defined – Wendelin Aug 23 '19 at 20:21

2 Answers2

3

Looks to me like the docs are wrong.

Here's from playing around with smoothstep:

y = smoothstep(1.0,-1.0,x); enter image description here

y = smoothstep(-1.0,1.0,x); enter image description here

It looks like when edge0 > edge1, it flips the side at 1 to be at negative infinity, and the side at 0 to be at positive infinity.

Another example:

#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265359

uniform vec2 u_resolution;

float plot(vec2 st, float pct){
  return  smoothstep( pct+0.02, pct, st.y) -
          smoothstep( pct, pct-0.02, st.y);
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution;

    // Smooth interpolation between 0.1 and 0.9
    float y = smoothstep(0.1,0.9,st.x);

    vec3 color = vec3(y);

    float pct = plot(st,y);
    color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0);

    gl_FragColor = vec4(color,1.0);
}

enter image description here

Changing y to a step from 0.9 to 0.1 changes the output to this:

enter image description here

WilliamNHarvey
  • 2,335
  • 2
  • 17
  • 26
  • I don't think the docs are wrong, they and the spec just don't specify what should happen if `edge0 => edge1`, so the result could be anything. But otherwise great answer. – Wendelin Aug 23 '19 at 20:33
  • Undefined in a sense synonymous with unspecified is accurate, so a better word would be that the docs are _unclear_. Thanks! – WilliamNHarvey Aug 23 '19 at 20:45
  • 1
    The docs are not wrong nor unclear. Undefined means *anything* could happen. Including a full GPU device lost (i.e. TDR), even if unlikely. Don't go against the spec just because it works on your machine. It could stop working or cause severe glitching in the future. If you need the mathematical behavior, write your own smoothstep routine in glsl to workaround that limitation – Matias N Goldberg Dec 08 '21 at 22:24
1

Adding to @Asthamatic's answer above, from Nvidia developer docs:

https://developer.download.nvidia.com/cg/smoothstep.html

Interpolates smoothly from 0 to 1 based on x compared to a and b.

1) Returns 0 if x < a < b or x > a > b 
1) Returns 1 if x < b < a or x > b > a 
3) Returns a value in the range [0,1] for the domain [a,b]. 

The slope of smoothstep(a,b,a) and smoothstep(a,b,b) is zero.

For vectors, the returned vector contains the smooth interpolation of each element of the vector x

This explains any kind of behavior represented by smoothstep functions.

UnixNoob
  • 11
  • 3
  • 1
    Your link is about Cg, not GLSL. They are completely different languages, and thus may have different specifications, even when function's name and signature are the same. – Maxim Kamalov Apr 10 '22 at 12:43