diff --git a/src/doc/languagespec.tex b/src/doc/languagespec.tex
index 7c90ed198..68d5b38e9 100644
--- a/src/doc/languagespec.tex
+++ b/src/doc/languagespec.tex
@@ -3488,42 +3488,43 @@ \section{Pattern generation}
performed component-by-component (separately for $x$, $y$, and $z$).
\apiend
-\apiitem{float {\ce linearstep} (float edge0, float edge1, float x) \\
-\emph{type} {\ce linearstep} (\emph{type} edge0, \emph{type} edge1, \emph{type} x)}
+\apiitem{float {\ce linearstep} (float low, float high, float x) \\
+\emph{type} {\ce linearstep} (\emph{type} low, \emph{type} high, \emph{type} x)}
\indexapi{linearstep()}
-Returns 0 if $x \le {\mathit edge0}$, and 1 if $x \ge {\mathit edge1}$,
+Returns 0 if $x \le {\mathit low}$, and 1 if $x \ge {\mathit high}$,
and performs a linear
-interpolation between 0 and 1 when ${\mathit edge0} < x < {\mathit edge1}$.
-This is equivalent to {\cf step(edge0, x)} when {\cf edge0 == edge1}.
+interpolation between 0 and 1 when ${\mathit low} < x < {\mathit high}$.
+This is equivalent to {\cf step(low, x)} when {\cf low == high}.
For \color and \point-like types, the computations are
performed component-by-component (separately for $x$, $y$, and $z$).
\apiend
-\apiitem{float {\ce smoothstep} (float edge0, float edge1, float x) \\
-\emph{type} {\ce smoothstep} (\emph{type} edge0, \emph{type} edge1, \emph{type} x)}
+\apiitem{float {\ce smoothstep} (float low, float high, float x) \\
+\emph{type} {\ce smoothstep} (\emph{type} low, \emph{type} high, \emph{type} x)}
\indexapi{smoothstep()}
-Returns 0 if $x \le {\mathit edge0}$, and 1 if $x \ge {\mathit edge1}$,
+Returns 0 if $x \le {\mathit low}$, and 1 if $x \ge {\mathit high}$,
and performs a smooth Hermite
-interpolation between 0 and 1 when ${\mathit edge0} < x < {\mathit edge1}$.
+interpolation between 0 and 1 when ${\mathit low} < x < {\mathit high}$.
This is useful in cases where you would want a thresholding function
-with a smooth transition.
+with a smooth transition. In the degenerate case where ${\mathit high} \le
+{\mathit low}$, the return value will be 0 if $x < {\mathit high}$ and 1 if $x
+\ge {\mathit high}$, making the behavior identical to `step(high, x)`.
The \emph{type} may be any of of \float, \color, \point, \vector, or
\normal. For \color and \point-like types, the computations are
performed component-by-component.
\apiend
-\apiitem{float {\ce smooth_linearstep} (float edge0, float edge1, float x, float eps) \\
-\emph{type} {\ce smooth_linearstep} (\emph{type} edge0, \emph{type} edge1, \emph{type} x, \emph{type} eps)}
+\apiitem{float {\ce smooth_linearstep} (float low, float high, float x, float eps) \\
+\emph{type} {\ce smooth_linearstep} (\emph{type} low, \emph{type} high, \emph{type} x, \emph{type} eps)}
\indexapi{smooth_linearstep()}
-This function is strictly linear between ${\mathit edge0}+{\mathit eps}$ and ${\mathit edge1}-{\mathit eps}$
-but smoothly ramps to 0 between ${\mathit edge0}-{\mathit eps}$ and ${\mathit edge0}+{\mathit eps}$
-and smoothly ramps to 1 between ${\mathit edge1}-{\mathit eps}$ and ${\mathit edge1}+{\mathit eps}$.
-It is 0 when $x \le {\mathit edge0}-{\mathit eps}$, and 1 if $x \ge {\mathit edge1}+{\mathit eps}$,
-and performs a linear
-interpolation between 0 and 1 when ${\mathit edge0} < x < {\mathit edge1}$.
-For \color and \point-like types, the computations are
-performed component-by-component.
+This function returns 0 if $x < {\mathit low}-{\mathit eps}$, and 1 if
+$x \ge {\mathit high}+{\mathit eps}$, is strictly linear between
+${\mathit low}+{\mathit eps}$ and ${\mathit high}-{\mathit eps}$ but smoothly
+ramps to 0 between ${\mathit low}-{\mathit eps}$ and ${\mathit low}+{\mathit eps}$
+and smoothly ramps to 1 between ${\mathit high}-{\mathit eps}$ and
+${\mathit high}+{\mathit eps}$. For \color and \point-like types, the
+computations are performed component-by-component.
\apiend
diff --git a/src/doc/stdlib.md b/src/doc/stdlib.md
index 2fce1e09d..d3e53c870 100644
--- a/src/doc/stdlib.md
+++ b/src/doc/stdlib.md
@@ -458,36 +458,36 @@ the computations are performed component-by-component (separately for `x`,
performed component-by-component (separately for $x$, $y$, and $z$).
-`float` **`linearstep`** `(float edge0, float edge1, float x)`
*`type`* **`linearstep`** (*`type`* `edge0`, *`type`* `edge1`, *`type`* `x`)
+`float` **`linearstep`** `(float low, float high, float x)`
*`type`* **`linearstep`** (*`type`* `low`, *`type`* `high`, *`type`* `x`)
- : Returns 0 if `x` $\le$ `edge0`, and 1 if `x` $\ge$ `edge1`, and performs a
- linear interpolation between 0 and 1 when `edge0` $<$ `x` $<$ `edge1`.
- This is equivalent to `step(edge0, x)` when `edge0 == edge1`. For `color`
+ : Returns 0 if `x` $<$ `low`, and 1 if `x` $\ge$ `high`, and performs a
+ linear interpolation between 0 and 1 when `low` $<$ `x` $<$ `high`.
+ This is equivalent to `step(low, x)` when `low == high`. For `color`
and `point`-like types, the computations are performed
component-by-component (separately for $x$, $y$, and $z$).
-`float` **`smoothstep`** `(float edge0, float edge1, float x)`
*`type`* **`smoothstep`** (*`type`* `edge0`, *`type`* `edge1`, *`type`* `x`)
+`float` **`smoothstep`** `(float low, float high, float x)`
*`type`* **`smoothstep`** (*`type`* `low`, *`type`* `high`, *`type`* `x`)
- : Returns 0 if `x` $\le$ `edge0`, and 1 if `x` $\ge$ `edge1`, and performs a
- smooth Hermite interpolation between 0 and 1 when `edge0` $<$ `x` $<$
- `edge1`. This is useful in cases where you would want a thresholding
- function with a smooth transition.
+ : Returns 0 if `x` $\le$ `low`, and 1 if `x` $\ge$ `high`, and performs a
+ smooth Hermite interpolation between 0 and 1 when `low` $<$ `x` $<$
+ `high`. This is useful in cases where you would want a thresholding
+ function with a smooth transition. In the degenerate case where
+ `high` $\le$ `low`, the return value will be 0 if `x` $<$ `high` and 1 if
+ `x` $\ge$ `high`, making the behavior identical to `step(high, x)`.
The *`type`* may be any of of `float`, `color`, `point`, `vector`, or
`normal`. For `color` and `point`-like types, the computations are
performed component-by-component.
-`float` **`smooth_linearstep`** `(float edge0, float edge1, float x, float eps)`
*`type`* **`smooth_linearstep`** (*`type`* `edge0`, *`type`* `edge1`, *`type`* `x`, *`type`* eps)
+`float` **`smooth_linearstep`** `(float low, float high, float x, float eps)`
*`type`* **`smooth_linearstep`** (*`type`* `low`, *`type`* `high`, *`type`* `x`, *`type`* eps)
- : This function is strictly linear between `edge0 + eps` and `edge1 - eps`
- but smoothly ramps to 0 between `edge0 - eps` and `edge0 + eps`
- and smoothly ramps to 1 between `edge1 - eps` and `edge1 + eps`.
- It is 0 when `x` $\le$ `edge0-eps,` and 1 if `x` $\ge$ `edge1 + eps`,
- and performs a linear interpolation between 0 and 1 when
- `edge0` < x < `edge1`. For `color` and `point`-like types, the
- computations are performed component-by-component.
+ : This function returns 0 if `x` $<$ `low-eps`, and 1 if `x` $\ge$ `high + eps`,
+ is strictly linear between `low + eps` and `high - eps`, but smoothly
+ ramps to 0 between `low - eps` and `low + eps` and smoothly ramps to 1
+ between `high - eps` and `high + eps`. For `color` and `point`-like types,
+ the computations are performed component-by-component.
%## Noise functions
diff --git a/src/include/OSL/dual.h b/src/include/OSL/dual.h
index a7b5e4063..b3eb8685d 100644
--- a/src/include/OSL/dual.h
+++ b/src/include/OSL/dual.h
@@ -1311,27 +1311,29 @@ safe_fmod (const Dual& a, const Dual& b)
-OSL_HOSTDEVICE OSL_FORCEINLINE float smoothstep(float e0, float e1, float x) {
- if (x < e0) return 0.0f;
- else if (x >= e1) return 1.0f;
- else {
- float t = (x - e0)/(e1 - e0);
+OSL_HOSTDEVICE OSL_FORCEINLINE float smoothstep(float low, float high, float x) {
+ if (x >= high) {
+ return 1.0f;
+ } else if (x <= low) {
+ return 0.0f;
+ } else {
+ float t = (x - low) / (high - low);
return (3.0f-2.0f*t)*(t*t);
}
}
-// f(t) = (3-2t)t^2, t = (x-e0)/(e1-e0)
+// f(t) = (3-2t)t^2, t = (x-low)/(high-low)
template
-OSL_HOSTDEVICE OSL_FORCEINLINE Dual smoothstep (const Dual &e0, const Dual &e1, const Dual &x)
+OSL_HOSTDEVICE OSL_FORCEINLINE Dual smoothstep (const Dual &low, const Dual &high, const Dual &x)
{
- if (x.val() < e0.val()) {
- return Dual (T(0));
- }
- else if (x.val() >= e1.val()) {
- return Dual (T(1));
- }
- Dual t = (x - e0)/(e1-e0);
- return (T(3) - T(2)*t)*t*t;
+ if (x.val() >= high.val()) {
+ return Dual(T(1));
+ } else if (x.val() <= low.val()) {
+ return Dual(T(0));
+ } else {
+ Dual t = (x - low) / (high - low);
+ return (T(3) - T(2)*t)*t*t;
+ }
}
diff --git a/src/shaders/stdosl.h b/src/shaders/stdosl.h
index 98ecbf8da..d32771749 100644
--- a/src/shaders/stdosl.h
+++ b/src/shaders/stdosl.h
@@ -319,73 +319,73 @@ point step (point edge, point x) BUILTIN;
vector step (vector edge, vector x) BUILTIN;
normal step (normal edge, normal x) BUILTIN;
float step (float edge, float x) BUILTIN;
-float smoothstep (float edge0, float edge1, float x) BUILTIN;
+float smoothstep (float low, float high, float x) BUILTIN;
-color smoothstep (color edge0, color edge1, color x)
+color smoothstep (color low, color high, color x)
{
- return color (smoothstep(edge0[0], edge1[0], x[0]),
- smoothstep(edge0[1], edge1[1], x[1]),
- smoothstep(edge0[2], edge1[2], x[2]));
+ return color (smoothstep(low[0], high[0], x[0]),
+ smoothstep(low[1], high[1], x[1]),
+ smoothstep(low[2], high[2], x[2]));
}
-vector smoothstep (vector edge0, vector edge1, vector x)
+vector smoothstep (vector low, vector high, vector x)
{
- return vector (smoothstep(edge0[0], edge1[0], x[0]),
- smoothstep(edge0[1], edge1[1], x[1]),
- smoothstep(edge0[2], edge1[2], x[2]));
+ return vector (smoothstep(low[0], high[0], x[0]),
+ smoothstep(low[1], high[1], x[1]),
+ smoothstep(low[2], high[2], x[2]));
}
-float linearstep (float edge0, float edge1, float x) {
+float linearstep (float low, float high, float x) {
float result;
- if (edge0 != edge1) {
- float xclamped = clamp (x, edge0, edge1);
- result = (xclamped - edge0) / (edge1 - edge0);
+ if (low != high) {
+ float xclamped = clamp (x, low, high);
+ result = (xclamped - low) / (high - low);
} else { // special case: edges coincide
- result = step (edge0, x);
+ result = step (low, x);
}
return result;
}
-color linearstep (color edge0, color edge1, color x)
+color linearstep (color low, color high, color x)
{
- return color (linearstep(edge0[0], edge1[0], x[0]),
- linearstep(edge0[1], edge1[1], x[1]),
- linearstep(edge0[2], edge1[2], x[2]));
+ return color (linearstep(low[0], high[0], x[0]),
+ linearstep(low[1], high[1], x[1]),
+ linearstep(low[2], high[2], x[2]));
}
-vector linearstep (vector edge0, vector edge1, vector x)
+vector linearstep (vector low, vector high, vector x)
{
- return vector (linearstep(edge0[0], edge1[0], x[0]),
- linearstep(edge0[1], edge1[1], x[1]),
- linearstep(edge0[2], edge1[2], x[2]));
+ return vector (linearstep(low[0], high[0], x[0]),
+ linearstep(low[1], high[1], x[1]),
+ linearstep(low[2], high[2], x[2]));
}
-float smooth_linearstep (float edge0, float edge1, float x_, float eps_) {
+float smooth_linearstep (float low, float high, float x_, float eps_) {
float result;
- if (edge0 != edge1) {
+ if (low != high) {
float rampup (float x, float r) { return 0.5/r * x*x; }
- float width_inv = 1.0 / (edge1 - edge0);
+ float width_inv = 1.0 / (high - low);
float eps = eps_ * width_inv;
- float x = (x_ - edge0) * width_inv;
+ float x = (x_ - low) * width_inv;
if (x <= -eps) result = 0;
else if (x >= eps && x <= 1.0-eps) result = x;
else if (x >= 1.0+eps) result = 1;
else if (x < eps) result = rampup (x+eps, 2.0*eps);
else /* if (x < 1.0+eps) */ result = 1.0 - rampup (1.0+eps - x, 2.0*eps);
} else {
- result = step (edge0, x_);
+ result = step (low, x_);
}
return result;
}
-color smooth_linearstep (color edge0, color edge1, color x, color eps)
+color smooth_linearstep (color low, color high, color x, color eps)
{
- return color (smooth_linearstep(edge0[0], edge1[0], x[0], eps[0]),
- smooth_linearstep(edge0[1], edge1[1], x[1], eps[1]),
- smooth_linearstep(edge0[2], edge1[2], x[2], eps[2]));
+ return color (smooth_linearstep(low[0], high[0], x[0], eps[0]),
+ smooth_linearstep(low[1], high[1], x[1], eps[1]),
+ smooth_linearstep(low[2], high[2], x[2], eps[2]));
}
-vector smooth_linearstep (vector edge0, vector edge1, vector x, vector eps)
+vector smooth_linearstep (vector low, vector high, vector x, vector eps)
{
- return vector (smooth_linearstep(edge0[0], edge1[0], x[0], eps[0]),
- smooth_linearstep(edge0[1], edge1[1], x[1], eps[1]),
- smooth_linearstep(edge0[2], edge1[2], x[2], eps[2]));
+ return vector (smooth_linearstep(low[0], high[0], x[0], eps[0]),
+ smooth_linearstep(low[1], high[1], x[1], eps[1]),
+ smooth_linearstep(low[2], high[2], x[2], eps[2]));
}
float aastep (float edge, float s, float dedge, float ds) {