Ein Diagramm der Funktionen smoothstep(x) und smootherstep(x), wobei 0 als linke Kante und 1 als rechte Kante verwendet wird
Smoothstep ist eine Familie von sigmoidartigen Interpolations- und Klemmfunktionen , die häufig in Computergrafiken , Videospiel-Engines und maschinellem Lernen verwendet werden .
Die Funktion hängt von drei Parametern ab, der Eingabe x , der "linken Kante" und der "rechten Kante", wobei die linke Kante kleiner als die rechte Kante angenommen wird. Die Funktion erhält eine reelle Zahl x als Argument und gibt 0 zurück, wenn x kleiner oder gleich der linken Kante ist, 1 wenn x größer oder gleich der rechten Kante ist, und interpoliert sanft mit einem Hermite-Polynom zwischen 0 und 1 sonst. Die Steigung der Smoothstep- Funktion ist an beiden Kanten null. Dies ist praktisch, um eine Folge von Übergängen unter Verwendung von Smoothstep zu erzeugen, um jedes Segment als Alternative zur Verwendung komplexerer oder teurerer Interpolationstechniken zu interpolieren.
In HLSL und GLSL , smoothstep Implementiert die , die kubische Hermite - Interpolation nach der Klemm :
Angenommen, die linke Kante ist 0, die rechte Kante ist 1, wobei der Übergang zwischen den Kanten mit 0 ≤ x ≤ 1 stattfindet.
Die von AMD bereitgestellte AC/C++-Beispielimplementierung folgt.
float smoothstep(float edge0, float edge1, float x) {
// Scale, bias and saturate x to 0..1 range
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
// Evaluate polynomial
return x * x * (3 - 2 * x);
}
float clamp(float x, float lowerlimit, float upperlimit) {
if (x < lowerlimit)
x = lowerlimit;
if (x > upperlimit)
x = upperlimit;
return x;
}
Die allgemeine Form für smoothstep , wiederum unter der Annahme, dass die linke Kante 0 und die rechte Kante 1 ist, ist
ist identisch mit der Klemmfunktion :
Die charakteristische "S"-förmige Sigmoidkurve erhält man mit nur für ganze Zahlen n ≥ 1. Die Ordnung des Polynoms im allgemeinen Smoothstep ist 2 n + 1. Bei n = 1 sind die Steigungen oder ersten Ableitungen des Smoothsteps gleich Null am linken und rechten Rand ( x = 0 und x = 1), wo die Kurve an die konstanten oder gesättigten Pegel angehängt wird . Bei einer höheren ganzen Zahl n sind die zweite und höhere Ableitung an den Kanten Null, wodurch die Polynomfunktionen möglichst flach und der Spleiß auf die Grenzwerte von 0 oder 1 nahtloser werden.
Variationen
Ken Perlin schlug eine verbesserte Version der häufig verwendeten Smoothstep-Funktion erster Ordnung vor, die der zweiten Ordnung ihrer allgemeinen Form entspricht. Es hat null Ableitungen 1. und 2. Ordnung bei x = 0 und x = 1:
C/C++-Referenzimplementierung:
float smootherstep(float edge0, float edge1, float x) {
// Scale, and clamp x to 0..1 range
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
// Evaluate polynomial
return x * x * x * (x * (x * 6 - 15) + 10);
}
float clamp(float x, float lowerlimit, float upperlimit) {
if (x < lowerlimit)
x = lowerlimit;
if (x > upperlimit)
x = upperlimit;
return x;
}
Herkunft
Gleichung 3. Ordnung
Beginnend mit einer generischen Polynomfunktion dritter Ordnung und ihrer ersten Ableitung :
Anwenden der gewünschten Werte für die Funktion an beiden Endpunkten:
Anwenden der gewünschten Werte für die erste Ableitung der Funktion an beiden Endpunkten:
Das Lösen des Systems der 4 Unbekannten, das durch die letzten 4 Gleichungen gebildet wird, ergibt die Werte der Polynomkoeffizienten:
Daraus ergibt sich die "Smoothstep" -Funktion dritter Ordnung :
Gleichung 5. Ordnung
Ausgehend von einer generischen Polynomfunktion fünfter Ordnung , ihrer ersten Ableitung und ihrer zweiten Ableitung:
Anwenden der gewünschten Werte für die Funktion an beiden Endpunkten:
Anwenden der gewünschten Werte für die erste Ableitung der Funktion an beiden Endpunkten:
Anwenden der gewünschten Werte für die zweite Ableitung der Funktion an beiden Endpunkten:
Das Lösen des Systems der 6 Unbekannten, das durch die letzten 6 Gleichungen gebildet wird, ergibt die Werte der Polynomkoeffizienten:
Daraus ergibt sich die Funktion "smootherstep" fünfter Ordnung :
Gleichung 7. Ordnung
Bei Anwendung ähnlicher Techniken ergibt sich die Gleichung 7. Ordnung wie folgt:
Verallgemeinerung auf Gleichungen höherer Ordnung
Smoothstep-Polynome sind verallgemeinert, mit 0 ≤ x ≤ 1 as
wobei N die Ordnung der resultierenden Polynomfunktion bestimmt, die 2 N + 1 ist. Die ersten sieben Smoothstep-Polynome mit 0 ≤ x ≤ 1 sind
Es kann gezeigt werden, dass die Smoothstep-Polynome , die von 0 auf 1 übergehen, wenn x von 0 auf 1 übergeht , einfach auf Polynome mit ungerader Symmetrie abgebildet werden können
wo
und
Das Argument von R N ( x ) ist −1 ≤ x ≤ 1 und wird links an die Konstante −1 und rechts an +1 angehängt.
Eine Implementierung von in Javascript:
// Generalized smoothstep
function generalSmoothStep(N, x) {
x = clamp(x, 0, 1); // x must be equal to or between 0 and 1
var result = 0;
for (var n = 0; n <= N; ++n)
result += pascalTriangle(-N - 1, n) *
pascalTriangle(2 * N + 1, N - n) *
Math.pow(x, N + n + 1);
return result;
}
// Returns binomial coefficient without explicit use of factorials,
// which can't be used with negative integers
function pascalTriangle(a, b) {
var result = 1;
for (var i = 0; i < b; ++i)
result *= (a - i) / (i + 1);
return result;
}
function clamp(x, lowerlimit, upperlimit) {
if (x < lowerlimit)
x = lowerlimit;
if (x > upperlimit)
x = upperlimit;
return x;
}
Inverser Smoothstep
Die Umkehrung von smoothstep() kann bei bestimmten Operationen in Computergrafiken nützlich sein, wenn ihr Effekt umgekehrt oder kompensiert werden muss. Im Fall der Gleichung 3. Ordnung gibt es eine analytische Lösung für die Inverse, die lautet:
Dies ergibt sich als die Umkehrung von , deren Maclaurin-Reihe bei endet , was dieselbe Funktion bedeutet und ausdrückt. Die Reihenentwicklung der Inversen hingegen endet nicht.
In GLSL:
float inverse_smoothstep(float x) {
return 0.5 - sin(asin(1.0 - 2.0 * x) / 3.0);
}
Verweise
Externe Links