Articulo de referencia

Paso suave

Un gráfico de las funciones smoothstep( x ) y smootherstep( x ), usando 0 como borde izquierdo y 1 como borde derecho. Smoothstep es una familia de funciones de interpolación y ...

Un gráfico de las funciones smoothstep( x ) y smootherstep( x ), usando 0 como borde izquierdo y 1 como borde derecho.

Smoothstep es una familia de funciones de interpolación y limitación tipo sigmoide comúnmente utilizadas en gráficos por computadora , [ 1 ] [ 2 ] motores de videojuegos , [ 3 ] y aprendizaje automático . [ 4 ]

La función depende de tres parámetros: la entrada x , el borde izquierdo y el borde derecho, asumiendo que el borde izquierdo es menor que el derecho. La función recibe un número real x como argumento. Devuelve 0 si x es menor o igual que el borde izquierdo y 1 si x es mayor o igual que el borde derecho. En caso contrario, interpola suavemente mediante la interpolación de Hermite y devuelve un valor entre 0 y 1. La pendiente de la función smoothstep es cero en ambos bordes. Esto resulta útil para crear una secuencia de transiciones utilizando smoothstep para interpolar cada segmento, como alternativa a técnicas de interpolación más sofisticadas o costosas.

En HLSL y GLSL , smoothstep implementa elS1(incógnita){\displaystyle \operatorname {S} _{1}(x)}, la interpolación cúbica de Hermite después de la sujeción :

paso suave(incógnita)=S1(incógnita)={0,incógnita03incógnita22incógnita3,0incógnita11,1incógnita{\displaystyle \operatorname {smoothstep} (x)=S_{1}(x)={\begin{cases}0,&x\leq 0\\3x^{2}-2x^{3},&0\leq x\leq 1\\1,&1\leq x\\\end{cases}}}

Suponiendo que el borde izquierdo es 0, el borde derecho es 1, y que la transición entre los bordes tiene lugar donde 0 ≤ x ≤ 1.

A continuación se muestra una implementación de ejemplo modificada en C/C++ proporcionada por AMD [ 5 ] .

float smoothstep ( float edge0 , float edge1 , float x ) { // Escalar y limitar x al rango 0..1 x = clamp (( x - edge0 ) / ( edge1 - edge0 ));return x * x * ( 3.0f - 2.0f * x ); }float clamp ( float x , float lowerlimit = 0.0f , float upperlimit = 1.0f ) { if ( x < lowerlimit ) return lowerlimit ; ​​if ( x > upperlimit ) return upperlimit ; ​​return x ; }

La forma general para smoothstep , asumiendo nuevamente que el borde izquierdo es 0 y el borde derecho es 1, es

Snorte(incógnita)={0,si incógnita0incógnitanorte+1k=0norte(norte+kk)(2norte+1nortek)(incógnita)k,si 0incógnita11,si 1incógnita{\displaystyle \operatorname {S} _{n}(x)={\begin{cases}0,&{\text{if }}x\leq 0\\x^{n+1}\sum _{k=0}^{n}{\binom {n+k}{k}}{\binom {2n+1}{n-k}}(-x)^{k},&{\text{if }}0\leq x\leq 1\\1,&{\text{if }}1\leq x\\\end{cases}}}

S0(incógnita){\displaystyle \operatorname {S} _{0}(x)}es idéntico a la función de sujeción :

S0(incógnita)={0,si incógnita0incógnita,si 0incógnita11,si 1incógnita{\displaystyle \operatorname {S} _{0}(x)={\begin{cases}0,&{\text{if }}x\leq 0\\x,&{\text{if }}0\leq x\leq 1\\1,&{\text{if }}1\leq x\\\end{cases}}}

La curva sigmoide característica en forma de S se obtiene conSnorte(incógnita){\displaystyle \operatorname {S} _{n}(x)}Solo para enteros n ≥ 1. El orden del polinomio en el paso suave general es 2 n + 1. Con n = 1, las pendientes o primeras derivadas del paso suave son iguales a cero en los bordes izquierdo y derecho ( x = 0 y x = 1), donde la curva se une a los niveles constantes o saturados . Con enteros n mayores , las segundas y superiores derivadas son cero en los bordes, lo que hace que las funciones polinómicas sean lo más planas posible y la unión a los valores límite de 0 o 1 sea más fluida.

Variaciones

Ken Perlin sugirió [ 6 ] una versión mejorada de la función smoothstep de primer orden comúnmente utilizada, equivalente al segundo orden de su forma general. Tiene derivadas de primer y segundo orden nulas en x = 0 y x = 1:

paso más suave(incógnita)=S2(incógnita)={0,incógnita06incógnita515incógnita4+10incógnita3,0incógnita11,1incógnita{\displaystyle \operatorname {smootherstep} (x)=S_{2}(x)={\begin{cases}0,&x\leq 0\\6x^{5}-15x^{4}+10x^{3},&0\leq x\leq 1\\1,&1\leq x\\\end{cases}}}

Implementación de referencia en C/C++ :

float smootherstep ( float edge0 , float edge1 , float x ) { // Escalar y limitar x al rango 0..1 x = clamp (( x - edge0 ) / ( edge1 - edge0 ));return x * x * x * ( x * ( 6.0f * x - 15.0f ) + 10.0f ); }float clamp ( float x , float lowerlimit = 0.0f , float upperlimit = 1.0f ) { if ( x < lowerlimit ) return lowerlimit ; ​​if ( x > upperlimit ) return upperlimit ; ​​return x ; }

Origen

ecuación de tercer orden

Partiendo de una función polinómica genérica de tercer orden y su primera derivada :

S1(incógnita)=a3incógnita3+a2incógnita2+a1incógnita+a0,S1(incógnita)=3a3incógnita2+2a2incógnita+a1.{\displaystyle {\begin{alignedat}{9}\operatorname {S} _{1}(x)&&\;=\;&&a_{3}x^{3}&&\;+\;&&a_{2}x^{2}&&\;+\;&&a_{1}x&&\;+\;&&a_{0},&\\\operatorname {S} _{1}'(x)&&\;=\;&&3a_{3}x^{2}&&\;+\;&&2a_{2}x&&\;+\;&&a_{1}.&\end{alignedat}}}

Aplicando los valores deseados para la función en ambos extremos:

S1(0)=00+0+0+a0=0,S1(1)=1a3+a2+a1+a0=1.{\displaystyle {\begin{alignedat}{13}\operatorname {S} _{1}(0)&&\;=\;&&0\quad &&\Rightarrow &&\quad 0\;&&+&&\;0\;&&+&&\;0\;&&+&&\;a_{0}&&\;=\;&&0,&\\\operatorname {S} _{1}(1)&&\;=\;&&1\quad &&\Rightarrow &&\quad a_{3}\;&&+&&\;a_{2}\;&&+&&\;a_{1}\;&&+&&\;a_{0}&&\;=\;&&1.&\end{alignedat}}}

Aplicando los valores deseados para la primera derivada de la función en ambos extremos:

S1(0)=00+0+a1=0,S1(1)=03a3+2a2+a1=0.{\displaystyle {\begin{alignedat}{11}\operatorname {S} _{1}'(0)&&\;=\;&&0\quad &&\Rightarrow &&\quad 0\;&&+&&\;0\;&&+&&\;a_{1}\;&&=\;&&0,&\\\operatorname {S} _{1}'(1)&&\;=\;&&0\quad &&\Rightarrow &&\quad 3a_{3}\;&&+&&\;2a_{2}\;&&+&&\;a_{1}\;&&=\;&&0.&\end{alignedat}}}

Al resolver el sistema de 4 incógnitas formado por las últimas 4 ecuaciones, se obtienen los valores de los coeficientes del polinomio:

a0=0,a1=0,a2=3,a3=2.{\displaystyle a_{0}=0,\quad a_{1}=0,\quad a_{2}=3,\quad a_{3}=-2.}

Esto da como resultado la función "smoothstep" de tercer orden :

S1(incógnita)=2incógnita3+3incógnita2.{\displaystyle \operatorname {S} _{1}(x)=-2x^{3}+3x^{2}.}

Tenga en cuenta que esta es una de las funciones base de una spline cúbica de Hermite .

ecuación de quinto orden

Partiendo de una función polinómica genérica de quinto orden , su primera derivada y su segunda derivada:

S2(incógnita)=a5incógnita5+a4incógnita4+a3incógnita3+a2incógnita2+a1incógnita+a0,S2(incógnita)=5a5incógnita4+4a4incógnita3+3a3incógnita2+2a2incógnita+a1,S2(incógnita)=20a5incógnita3+12a4incógnita2+6a3incógnita+2a2.{\displaystyle {\begin{alignedat}{13}\operatorname {S} _{2}(x)&&\;=\;&&a_{5}x^{5}&&\;+\;&&a_{4}x^{4}&&\;+\;&&a_{3}x^{3}&&\;+\;&&a_{2}x^{2}&&\;+\;&&a_{1}x&&\;+\;&&a_{0},&\\\operatorname {S} _{2}'(x)&&\;=\;&&5a_{5}x^{4}&&\;+\;&&4a_{4}x^{3}&&\;+\;&&3a_{3}x^{2}&&\;+\;&&2a_{2}x&&\;+\;&&a_{1},&\\\operatorname {S} _{2}''(x)&&\;=\;&&20a_{5}x^{3}&&\;+\;&&12a_{4}x^{2}&&\;+\;&&6a_{3}x&&\;+\;&&2a_{2}.&\end{alignedat}}}

Aplicando los valores deseados para la función en ambos extremos:

S2(0)=00+0+0+0+0+a0=0,S2(1)=1a5+a4+a3+a2+a1+a0=1.{\displaystyle {\begin{alignedat}{17}\operatorname {S} _{2}(0)&&\;=\;&&0\;\;\;\;\;&&\Rightarrow &&\;\;\;\;\;0\;&&+&&\;0\;&&+&&\;0\;&&+&&\;0\;&&+&&\;0\;&&+&&\;a_{0}&&\;=\;&&0,&\\\operatorname {S} _{2}(1)&&\;=\;&&1\;\;\;\;\;&&\Rightarrow &&\;\;\;\;\;a_{5}\;&&+&&\;a_{4}\;&&+&&\;a_{3}\;&&+&&\;a_{2}\;&&+&&\;a_{1}\;&&+&&\;a_{0}&&\;=\;&&1.&\end{alignedat}}}

Aplicando los valores deseados para la primera derivada de la función en ambos extremos:

S2(0)=00+0+0+0+a1=0,S2(1)=05a5+4a4+3a3+2a2+a1=0.{\displaystyle {\begin{alignedat}{15}\operatorname {S} _{2}'(0)&&\;=\;&&0\;\;\;\;&&\Rightarrow &&\;\;\;\;0\;&&+&&\;0\;&&+&&\;0\;&&+&&\;0\;&&+&&\;a_{1}\;&&=\;&&0,&\\\operatorname {S} _{2}'(1)&&\;=\;&&0\;\;\;\;&&\Rightarrow &&\;\;\;\;5a_{5}\;&&+&&\;4a_{4}\;&&+&&\;3a_{3}\;&&+&&\;2a_{2}\;&&+&&\;a_{1}\;&&=\;&&0.&\end{alignedat}}}

Aplicando los valores deseados para la segunda derivada de la función en ambos extremos:

S2(0)=00+0+0+2a2=0,S2(1)=020a5+12a4+6a3+2a2=0.{\displaystyle {\begin{alignedat}{15}\operatorname {S} _{2}''(0)&&\;=\;&&0\;\;\;\;&&\Rightarrow &&\;\;\;\;0\;&&+&&\;0\;&&+&&\;0\;&&+&&\;2a_{2}\;&&=\;&&0,&\\\operatorname {S} _{2}''(1)&&\;=\;&&0\;\;\;\;&&\Rightarrow &&\;\;\;\;20a_{5}\;&&+&&\;12a_{4}\;&&+&&\;6a_{3}\;&&+&&\;2a_{2}\;&&=\;&&0.&\end{alignedat}}}

Al resolver el sistema de 6 incógnitas formado por las últimas 6 ecuaciones, se obtienen los valores de los coeficientes del polinomio:

a0=0,a1=0,a2=0,a3=10,a4=15,a5=6.{\displaystyle a_{0}=0,\quad a_{1}=0,\quad a_{2}=0,\quad a_{3}=10,\quad a_{4}=-15,\quad a_{5}=6.}

Esto da como resultado la función "smootherstep" de quinto orden :

S2(incógnita)=6incógnita515incógnita4+10incógnita3.{\displaystyle \operatorname {S} _{2}(x)=6x^{5}-15x^{4}+10x^{3}.}

ecuación de séptimo orden

Aplicando técnicas similares, se obtiene la ecuación de séptimo orden:

S3(incógnita)=20incógnita7+70incógnita684incógnita5+35incógnita4.{\displaystyle \operatorname {S} _{3}(x)=-20x^{7}+70x^{6}-84x^{5}+35x^{4}.}

Generalización a ecuaciones de orden superior

Los polinomios Smoothstep se generalizan, con 0 ≤ x ≤ 1 como

Snorte(incógnita)=incógnitanorte+1norte=0norte(norte+nortenorte)(2norte+1nortenorte)(incógnita)nortenortenorte=norte=0norte(1)norte(norte+nortenorte)(2norte+1nortenorte)incógnitanorte+norte+1=norte=0norte(norte1norte)(2norte+1nortenorte)incógnitanorte+norte+1,{\displaystyle {\begin{aligned}\operatorname {S} _{N}(x)&=x^{N+1}\sum _{n=0}^{N}{\binom {N+n}{n}}{\binom {2N+1}{N-n}}(-x)^{n}\qquad N\in \mathbb {N} \\&=\sum _{n=0}^{N}(-1)^{n}{\binom {N+n}{n}}{\binom {2N+1}{N-n}}x^{N+n+1}\\&=\sum _{n=0}^{N}{\binom {-N-1}{n}}{\binom {2N+1}{N-n}}x^{N+n+1},\\\end{aligned}}}

donde N determina el orden de la función polinómica resultante, que es 2 N + 1. Los primeros siete polinomios de paso suave, con 0 ≤ x ≤ 1, son

S0(incógnita)=incógnita,S1(incógnita)=2incógnita3+3incógnita2,S2(incógnita)=6incógnita515incógnita4+10incógnita3,S3(incógnita)=20incógnita7+70incógnita684incógnita5+35incógnita4,S4(incógnita)=70incógnita9315incógnita8+540incógnita7420incógnita6+126incógnita5,S5(incógnita)=252incógnita11+1386incógnita103080incógnita9+3465incógnita81980incógnita7+462incógnita6,S6(incógnita)=924incógnita136006incógnita12+16380incógnita1124024incógnita10+20020incógnita99009incógnita8+1716incógnita7.{\displaystyle {\begin{aligned}\operatorname {S} _{0}(x)&=x,\\\operatorname {S} _{1}(x)&=-2x^{3}+3x^{2},\\\operatorname {S} _{2}(x)&=6x^{5}-15x^{4}+10x^{3},\\\operatorname {S} _{3}(x)&=-20x^{7}+70x^{6}-84x^{5}+35x^{4},\\\operatorname {S} _{4}(x)&=70x^{9}-315x^{8}+540x^{7}-420x^{6}+126x^{5},\\\operatorname {S} _{5}(x)&=-252x^{11}+1386x^{10}-3080x^{9}+3465x^{8}-1980x^{7}+462x^{6},\\\operatorname {S} _{6}(x)&=924x^{13}-6006x^{12}+16380x^{11}-24024x^{10}+20020x^{9}-9009x^{8}+1716x^{7}.\\\end{aligned}}}

El derivado deSnorte(incógnita){\displaystyle \operatorname {S} _{N}(x)}es

ddincógnitaSnorte(incógnita)=(2norte+1)(2nortenorte)(incógnitaincógnita2)norte.{\displaystyle {\begin{aligned}\operatorname {d \over dx} {S}_{N}(x)&=(2N+1){\binom {2N}{N}}(x-x^{2})^{N}.\\\end{aligned}}}

Se puede demostrar que los polinomios de paso suaveSnorte(incógnita){\displaystyle \operatorname {S} _{N}(x)}que la transición de 0 a 1 cuando x transiciona de 0 a 1 se puede mapear simplemente a polinomios de simetría impar

Rnorte(incógnita)=(01(12)norted)10incógnita(12)norted,{\displaystyle \operatorname {R} _{N}(x)=\left(\int _{0}^{1}{\big (}1-u^{2}{\big )}^{N}\,du\right)^{-1}\int _{0}^{x}{\big (}1-u^{2}{\big )}^{N}\,du,}

dónde

Snorte(incógnita)=12Rnorte(2incógnita1)+12{\displaystyle \operatorname {S} _{N}(x)={\tfrac {1}{2}}\operatorname {R} _{N}(2x-1)+{\tfrac {1}{2}}}

y

Rnorte(incógnita)=Rnorte(incógnita).{\displaystyle \operatorname {R} _{N}(-x)=-\operatorname {R} _{N}(x).}

El argumento de R N ( x ) es −1 ≤ x ≤ 1 y se agrega a la constante −1 a la izquierda y +1 a la derecha.

Una implementación deSnorte(incógnita){\displaystyle \operatorname {S} _{N}(x)}en JavaScript : [ 7 ]

// Función de paso suave generalizada generalSmoothStep ( N , x ) { x = clamp ( x , 0 , 1 ); // x debe ser igual o estar entre 0 y 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 ; }// Devuelve el coeficiente binomial sin el uso explícito de factoriales, // que no se pueden usar con enteros negativos. function pascalTriangle ( a , b ) { var result = 1 ; for ( var i = 0 ; i < b ; ++ i ) result *= ( a - i ) / ( i + 1 ); return result ; }función clamp ( x , límite inferior , límite superior ) { si ( x < límite inferior ) x = límite inferior ; si ( x > límite superior ) x = límite superior ; retornar x ; }

Propiedades del dominio de frecuencia

Nuestra función smoothstep original se puede reescribir de la siguiente manera, en términos de la función escalón de Heaviside :

S1(incógnita)=H(incógnita)(3incógnita22incógnita3)H(incógnita1)(3incógnita22incógnita31){\displaystyle S_{1}(x)=H(x)\left(3x^{2}-2x^{3}\right)-H(x-1)\left(3x^{2}-2x^{3}-1\right)}

Realizando alguna manipulación algebraica,

S1(incógnita)=H(incógnita)(126incógnita3+62incógnita2)H(incógnita1)(126(incógnita1)362(incógnita1)2){\displaystyle S_{1}(x)=H(x)\left(-{\frac {12}{6}}x^{3}+{\frac {6}{2}}x^{2}\right)-H(x-1)\left(-{\frac {12}{6}}\left(x-1\right)^{3}-{\frac {6}{2}}\left(x-1\right)^{2}\right)}

dando una transformada de Laplace de:

S1(s)=12+12miss4+6+6miss3{\displaystyle S_{1}(s)={\frac {-12+12e^{-s}}{s^{4}}}+{\frac {6+6e^{-s}}{s^{3}}}}

Esto tiene una atenuación asintótica de 60 dB/década (proveniente de la1/s3{\displaystyle 1/s^{3}}término), en contraposición a los 20 dB/década de un paso de Heavyside, o a los 40 dB/década de una interpolación lineal (S0(incógnita){\displaystyle S_{0}(x)}) - mostrando que los órdenes superiores de continuidad dan como resultado un espectro de frecuencia más localizado. Esto puede ser importante para sistemas discretos, donde estar limitado en banda es importante para reducir el aliasing , según el teorema de muestreo de Nyquist-Shannon .

Se puede realizar un análisis similar para cada uno.Snorte(incógnita){\displaystyle S_{N}(x)}donde la atenuación es de 20(2 + N) dB/década.

Paso suave inverso

La inversa de smoothstep() puede ser útil al realizar ciertas operaciones en gráficos por computadora cuando su efecto necesita ser revertido o compensado. En el caso de la ecuación de tercer orden, existe una solución analítica para la inversa, que es:

InvS1(incógnita)=1/2pecado(asin(12incógnita)/3){\displaystyle \operatorname {InvS} _{1}(x)=1/2-\sin(\operatorname {asin} (1-2x)/3)}

Esto surge debido a la funciónF(incógnita)=1/2pecado(3asin(0,5incógnita))/2{\displaystyle \operatorname {f} (x)=1/2-\sin(3\operatorname {asin} (0.5-x))/2}es equivalente a la función3incógnita22incógnita3=S1(incógnita){\displaystyle 3x^{2}-2x^{3}=S_{1}(x)}en el rango1/2incógnita3/2{\displaystyle -1/2\leq x\leq 3/2}Por otro lado, la inversa no tiene un equivalente polinómico exacto.

En GLSL:

float inverse_smoothstep ( float x ) { return 0.5 - sin ( asin ( 1.0 - 2.0 * x ) / 3.0 ); }

Referencias

  1. Smoothstep en Microsoft Developer Network .
  2. Especificación del lenguaje GLSL, versión 1.40 .
  3. Documentación de SmoothStep, el motor de juegos de Unity .
  4. Hazimeh, Hussein; Ponomareva, Natalia; Mol, Petros; Tan, Zhenyu; Mazumder, Rahul (2020). La capa de conjunto de árboles: la diferenciabilidad se encuentra con la computación condicional (PDF) . Conferencia internacional sobre aprendizaje automático. PMLR.
  5. Natalya Tatarchuk (2003). "Técnicas avanzadas de sombreado en tiempo real" . AMD . pág. 94. Archivado del original el 30 de mayo de 2021. Consultado el 16 de abril de 2022 . 
  6. Texturizado y modelado, tercera edición: un enfoque procedimental .
  7. Ecuación general de paso suave .
  • Utilizando smoothstep (del lenguaje de sombreado RenderMan ) por el profesor Malcolm Kesson.
  • Trucos de interpolación de Jari Komppa
  • Swift Interpolation Playground demuestra smoothStep() , smootherStep() y smoothestStep() en un entorno de pruebas de Swift creado por Simon Gladman.
  • Paso suave inverso por Íñigo Quilez
Obtenido de " https://en.wikipedia.org/w/index.php?title=Smoothstep&oldid=1356968454 "