Glatter Schritt - Smoothstep

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