Плавный шаг

Семейство функций интерполяции и фиксации
График функций smoothstep( x ) и smootherstep( x ) с использованием 0 в качестве левого края и 1 в качестве правого края

Smoothstep — это семейство сигмовидных интерполяционных и ограничивающих функций, обычно используемых в компьютерной графике , [1] [2] игровых движках , [3] и машинном обучении . [4]

Функция зависит от трех параметров: входного x , «левого края» и «правого края», причем левый край предполагается меньшим, чем правый край. Функция получает вещественное число x в качестве аргумента и возвращает 0, если x меньше или равен левому краю, 1, если x больше или равен правому краю, и плавно интерполирует, используя полином Эрмита , между 0 и 1 в противном случае. Градиент функции smoothstep равен нулю на обоих краях. Это удобно для создания последовательности переходов с использованием smoothstep для интерполяции каждого сегмента в качестве альтернативы использованию более сложных или дорогих методов интерполяции.

В HLSL и GLSL smoothstep реализует кубическую интерполяцию Эрмита после фиксации : С 1 ( х ) {\displaystyle \operatorname {S} _{1}(x)}

плавный шаг ( х ) = С 1 ( х ) = { 0 , х 0 3 х 2 2 х 3 , 0 х 1 1 , 1 х {\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}}}

Предположим, что левый край равен 0, правый край равен 1, причем переход между краями происходит там, где 0 ≤ x ≤ 1.

Ниже приведен пример реализации модифицированного C/C++, предоставленный AMD [5] .

float smoothstep ( float edge0 , float edge1 , float x ) { // Масштабируем и фиксируем x в диапазоне 0..1 x = clamp (( x - edge0 ) / ( edge1 - edge0 ));                   вернуть х * х * ( 3.0f - 2.0f * х ); }         float clamp ( float x , float нижний предел = 0.0f , float верхний предел = 1.0f ) { if ( x < нижний предел ) return нижний предел ; if ( x > верхний предел ) return верхний предел ; return x ; }                         

Общая форма для smoothstep , снова предполагая, что левый край равен 0, а правый край равен 1, имеет вид

С н ( х ) = { 0 , если  х 0 х н + 1 к = 0 н ( н + к к ) ( 2 н + 1 н к ) ( х ) к , если  0 х 1 1 , если  1 х {\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}{nk}}(-x)^{k},&{\text{if }}0\leq x\leq 1\\1,&{\text{if }}1\leq x\\\end{cases}}}

С 0 ( х ) {\displaystyle \operatorname {S} _{0}(x)} идентична функции зажима :

С 0 ( х ) = { 0 , если  х 0 х , если  0 х 1 1 , если  1 х {\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}}}

Характерная S-образная сигмоидальная кривая получается только при целых числах n ≥ 1. Порядок полинома в общем гладком шаге равен 2 n + 1. При n = 1 наклоны или первые производные гладкого шага равны нулю на левом и правом краю ( x = 0 и x = 1), где кривая присоединяется к постоянным или насыщенным уровням. При более высоком целом числе n вторые и более высокие производные равны нулю на краях, что делает полиномиальные функции максимально плоскими, а сращивание с предельными значениями 0 или 1 более плавным. С н ( х ) {\displaystyle \operatorname {S} _{n}(x)}

Вариации

Кен Перлин предложил [6] улучшенную версию обычно используемой функции первого порядка smoothstep, эквивалентную второму порядку ее общей формы. Она имеет нулевые производные 1-го и 2-го порядка при x = 0 и x = 1:

smootherstep ( x ) = S 2 ( x ) = { 0 , x 0 6 x 5 15 x 4 + 10 x 3 , 0 x 1 1 , 1 x {\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}}}

Реализация эталона C/C++:

float smootherstep ( float edge0 , float edge1 , float x ) { // Масштабируем и фиксируем x в диапазоне 0..1 x = clamp (( x - edge0 ) / ( edge1 - edge0 ));                  вернуть х * х * х * ( х * ( 6.0f * х - 15.0f ) + 10.0f ); }               float clamp ( float x , float нижний предел = 0.0f , float верхний предел = 1.0f ) { if ( x < нижний предел ) return нижний предел ; if ( x > верхний предел ) return верхний предел ; return x ; }                         

Источник

Уравнение 3-го порядка

Начнем с общей полиномиальной функции третьего порядка и ее первой производной :

S 1 ( x ) = a 3 x 3 + a 2 x 2 + a 1 x + a 0 , S 1 ( x ) = 3 a 3 x 2 + 2 a 2 x + a 1 . {\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}}}

Применяем желаемые значения для функции в обеих конечных точках:

S 1 ( 0 ) = 0 0 + 0 + 0 + a 0 = 0 , S 1 ( 1 ) = 1 a 3 + a 2 + a 1 + a 0 = 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}}}

Применяем требуемые значения для первой производной функции в обеих конечных точках:

S 1 ( 0 ) = 0 0 + 0 + a 1 = 0 , S 1 ( 1 ) = 0 3 a 3 + 2 a 2 + a 1 = 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}}}

Решение системы из 4 неизвестных, образованной последними 4 уравнениями, приводит к значениям коэффициентов полинома:

a 0 = 0 , a 1 = 0 , a 2 = 3 , a 3 = 2. {\displaystyle a_{0}=0,\quad a_{1}=0,\quad a_{2}=3,\quad a_{3}=-2.}

В результате получается функция «smoothstep» третьего порядка :

S 1 ( x ) = 2 x 3 + 3 x 2 . {\displaystyle \operatorname {S} _{1}(x)=-2x^{3}+3x^{2}.}

Уравнение 5-го порядка

Начнем с общей полиномиальной функции пятого порядка, ее первой производной и второй производной:

S 2 ( x ) = a 5 x 5 + a 4 x 4 + a 3 x 3 + a 2 x 2 + a 1 x + a 0 , S 2 ( x ) = 5 a 5 x 4 + 4 a 4 x 3 + 3 a 3 x 2 + 2 a 2 x + a 1 , S 2 ( x ) = 20 a 5 x 3 + 12 a 4 x 2 + 6 a 3 x + 2 a 2 . {\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}}}

Применяем желаемые значения для функции в обеих конечных точках:

S 2 ( 0 ) = 0 0 + 0 + 0 + 0 + 0 + a 0 = 0 , S 2 ( 1 ) = 1 a 5 + a 4 + a 3 + a 2 + a 1 + a 0 = 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}}}

Применяем требуемые значения для первой производной функции в обеих конечных точках:

S 2 ( 0 ) = 0 0 + 0 + 0 + 0 + a 1 = 0 , S 2 ( 1 ) = 0 5 a 5 + 4 a 4 + 3 a 3 + 2 a 2 + a 1 = 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}}}

Применяем желаемые значения для второй производной функции в обеих конечных точках:

S 2 ( 0 ) = 0 0 + 0 + 0 + 2 a 2 = 0 , S 2 ( 1 ) = 0 20 a 5 + 12 a 4 + 6 a 3 + 2 a 2 = 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}}}

Решение системы из 6 неизвестных, образованной последними 6 уравнениями, приводит к значениям коэффициентов полинома:

a 0 = 0 , a 1 = 0 , a 2 = 0 , a 3 = 10 , a 4 = 15 , a 5 = 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.}

В результате получается функция «smootherstep» пятого порядка :

S 2 ( x ) = 6 x 5 15 x 4 + 10 x 3 . {\displaystyle \operatorname {S} _{2}(x)=6x^{5}-15x^{4}+10x^{3}.}

Уравнение 7-го порядка

Применяя аналогичные методы, получаем уравнение 7-го порядка:

S 3 ( x ) = 20 x 7 + 70 x 6 84 x 5 + 35 x 4 . {\displaystyle \operatorname {S} _{3}(x)=-20x^{7}+70x^{6}-84x^{5}+35x^{4}.}

Обобщение на уравнения более высокого порядка

Многочлены Smoothstep обобщаются, при этом 0 ≤ x ≤ 1

S N ( x ) = x N + 1 n = 0 N ( N + n n ) ( 2 N + 1 N n ) ( x ) n N N = n = 0 N ( 1 ) n ( N + n n ) ( 2 N + 1 N n ) x N + n + 1 = n = 0 N ( N 1 n ) ( 2 N + 1 N n ) x N + n + 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}}}

где N определяет порядок результирующей полиномиальной функции, который равен 2 N + 1. Первые семь полиномов smoothstep, при 0 ≤ x ≤ 1, равны

S 0 ( x ) = x , S 1 ( x ) = 2 x 3 + 3 x 2 , S 2 ( x ) = 6 x 5 15 x 4 + 10 x 3 , S 3 ( x ) = 20 x 7 + 70 x 6 84 x 5 + 35 x 4 , S 4 ( x ) = 70 x 9 315 x 8 + 540 x 7 420 x 6 + 126 x 5 , S 5 ( x ) = 252 x 11 + 1386 x 10 3080 x 9 + 3465 x 8 1980 x 7 + 462 x 6 , S 6 ( x ) = 924 x 13 6006 x 12 + 16380 x 11 24024 x 10 + 20020 x 9 9009 x 8 + 1716 x 7 . {\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}}}

Дифференциал равен S N ( x ) {\displaystyle \operatorname {S} _{N}(x)}

d d x S N ( x ) = ( 2 N + 1 ) ( 2 N N ) ( x x 2 ) N . {\displaystyle {\begin{aligned}\operatorname {d \over dx} {S}_{N}(x)&=(2N+1){\binom {2N}{N}}(x-x^{2})^{N}.\\\end{aligned}}}

Можно показать, что полиномы smoothstep , которые переходят от 0 к 1, когда x переходит от 0 к 1, можно просто отобразить в полиномы нечетной симметрии S N ( x ) {\displaystyle \operatorname {S} _{N}(x)}

R N ( x ) = ( 0 1 ( 1 u 2 ) N d u ) 1 0 x ( 1 u 2 ) N d u , {\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,}

где

S N ( x ) = 1 2 R N ( 2 x 1 ) + 1 2 {\displaystyle \operatorname {S} _{N}(x)={\tfrac {1}{2}}\operatorname {R} _{N}(2x-1)+{\tfrac {1}{2}}}

и

R N ( x ) = R N ( x ) . {\displaystyle \operatorname {R} _{N}(-x)=-\operatorname {R} _{N}(x).}

Аргумент RN ( x ) равен −1 ≤ x ≤ 1 и добавляется к константе −1 слева и +1 справа.

Реализация на Javascript: [7] S N ( x ) {\displaystyle \operatorname {S} _{N}(x)}

// Обобщенная функция smoothstep generalSmoothStep ( N , x ) { x = clamp ( x , 0 , 1 ); // x должен быть равен или находиться в диапазоне от 0 до 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 ; }                                              // Возвращает биномиальный коэффициент без явного использования факториалов, // которые нельзя использовать с отрицательными целыми числами function pascalTriangle ( a , b ) { var result = 1 ; for ( var i = 0 ; i < b ; ++ i ) result *= ( a - i ) / ( i + 1 ); return result ; }                            функция clamp ( x , нижний предел , верхний предел ) { если ( x < нижний предел ) x = нижний предел ; если ( x > верхний предел ) x = верхний предел ; вернуть x ; }                    

Обратный сглаженный шаг

Обратное значение smoothstep() может быть полезным при выполнении определенных операций в компьютерной графике, когда его эффект необходимо обратить или компенсировать. В случае уравнения 3-го порядка существует аналитическое решение для обратного значения, которое выглядит так:

InvS 1 ( x ) = 1 / 2 sin ( asin ( 1 2 x ) / 3 ) {\displaystyle \operatorname {InvS} _{1}(x)=1/2-\sin(\operatorname {asin} (1-2x)/3)}

Это возникает как обратная функция , ряд Маклорена которой заканчивается в , что означает и выражает ту же функцию. С другой стороны, разложение в ряд обратной функции не заканчивается. f ( x ) = 1 / 2 sin ( 3 asin ( 0.5 x ) ) / 2 {\displaystyle \operatorname {f} (x)=1/2-\sin(3\operatorname {asin} (0.5-x))/2} 3 x 2 2 x 3 = S 1 ( x ) {\displaystyle 3x^{2}-2x^{3}=S_{1}(x)} f {\displaystyle \operatorname {f} } S 1 {\displaystyle \operatorname {S} _{1}}

В ГЛСЛ:

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

Ссылки

  1. ^ Smoothstep в Microsoft Developer Network.
  2. ^ Спецификация языка GLSL, версия 1.40.
  3. ^ Документация игрового движка Unity SmoothStep.
  4. ^ Хазимех, Хуссейн; Пономарева, Наталья; Мол, Петрос; Тан, Женью; Мазумдер, Рахул (2020). Слой ансамбля деревьев: дифференцируемость встречает условные вычисления (PDF) . Международная конференция по машинному обучению. PMLR.
  5. ^ Наталья Татарчук (2003). «Advanced Real-Time Shader Techniques». AMD . стр. 94. Архивировано из оригинала 2021-05-30 . Получено 2022-04-16 .
  6. ^ Текстурирование и моделирование, третье издание: процедурный подход.
  7. ^ Общее уравнение плавного шага.
  • Использование Smoothstep (в RenderMan Shading Language ) профессора Малкольма Кессона.
  • Трюки интерполяции от Яри Комппы
  • Swift Interpolation Playground демонстрирует smoothStep() , smootherStep() и smoothestStep() в Swift Playground Саймона Гладмана
  • Обратный сглаженный шаг Иниго Килеса
Retrieved from "https://en.wikipedia.org/w/index.php?title=Smoothstep&oldid=1230247942"