График функций smoothstep (x) и smoothstep (x) с использованием 0 в качестве левого края и 1 в качестве правого края
Плавный шаг это семья сигмовидный интерполяция и зажим функции, обычно используемые в компьютерная графика[1][2], движки видеоигр[3], и машинное обучение[4].
Функция зависит от трех параметров, вход Икс, «левый край» и «правый край», причем левый край считается меньше правого. Функция получает действительное число Икс в качестве аргумента и возвращает 0, если Икс меньше или равно левому краю, 1, если x больше или равно правому краю, и плавно интерполирует, используя Многочлен Эрмита, от 0 до 1 в противном случае. Градиент плавный шаг функция равна нулю на обоих краях. Это удобно для создания последовательности переходов с помощью плавный шаг для интерполяции каждого сегмента в качестве альтернативы использованию более сложных или дорогостоящих методов интерполяции.
В HLSL и GLSL, плавный шаг реализует
, кубический Эрмита интерполяция после зажим:
![{ 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 {case}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/1acfe04c2d224ce3adcf4daa0a62716494cace09)
Предполагая, что левый край равен 0, правый край равен 1, с переходом между краями, когда 0 ≤ Икс ≤ 1.
Пример реализации C / C ++, предоставленный AMD[5] следует.
плавать плавный шаг(плавать край0, плавать край1, плавать Икс) { // Масштабирование, смещение и насыщение x до диапазона 0..1 Икс = зажим((Икс - край0) / (край1 - край0), 0.0, 1.0); // Вычислить полином возвращаться Икс * Икс * (3 - 2 * Икс);}плавать зажим(плавать Икс, плавать Нижний предел, плавать верхний предел) { если (Икс < Нижний предел) Икс = Нижний предел; если (Икс > верхний предел) Икс = верхний предел; возвращаться Икс;}
Общий вид для плавный шаг, снова предполагая, что левый край равен 0, а правый край равен 1,
![{ displaystyle operatorname {S} _ {n} (x) = { begin {case} 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 {case}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/41986e1391d91327a1569d54ba03dda2f7a43401)
идентичен функция зажима:
![{ displaystyle operatorname {S} _ {0} (x) = { begin {case} 0 & { text {if}} x leq 0 x & { text {if}} 0 leq x leq 1 1 & { text {if}} 1 leq x end {case}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/b2f5cda152a8e7ab8a47e6c123f6a50dcdcb0ddc)
Характерная S-образная сигмовидная кривая получается с
только для целых чисел п ≥ 1. Порядок полинома в общем гладком шаге равен 2.п + 1. С п = 1, наклоны или первые производные плавный шаг равны нулю на левом и правом краю (Икс = 0 и Икс = 1), где кривая добавляется к константе или насыщенный уровни. С большим целым числом п, вторая и более высокие производные равны нулю на краях, что делает полиномиальные функции как можно более плоскими, а стыковку до предельных значений 0 или 1 более гладкими.
Вариации
Кен Перлин предлагает[6] улучшенная версия функции smoothstep, которая имеет нулевой 1-й и 2-й порядок производные в Икс = 0 и Икс = 1:
![{ displaystyle operatorname {smoothstep} (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 {case}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/6e0ae86f62c96d1cbf82370e05c827670394fe75)
Эталонная реализация C / C ++:
плавать более плавный шаг(плавать край0, плавать край1, плавать Икс) { // Масштабировать и фиксировать x до диапазона 0..1 Икс = зажим((Икс - край0) / (край1 - край0), 0.0, 1.0); // Вычислить полином возвращаться Икс * Икс * Икс * (Икс * (Икс * 6 - 15) + 10);}плавать зажим(плавать Икс, плавать Нижний предел, плавать верхний предел) { если (Икс < Нижний предел) Икс = Нижний предел; если (Икс > верхний предел) Икс = верхний предел; возвращаться Икс;}
Источник
Уравнение 3-го порядка
Начиная с общего третьего порядка многочлен функция и ее первая производная:
![{ displaystyle { begin {alignat} {9} operatorname {S} _ {1} (x) && ; = ; && a_ {3} x ^ {3} && ; + ; && a_ {2} x ^ {2} && ; + ; && a_ {1} x && ; + ; && a_ {0}, & имя оператора {S} _ {1} '(x) && ; = ; && 3a_ {3 } x ^ {2} && ; + ; && 2a_ {2} x && ; + ; && a_ {1}. & end {alignat}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/398f743902b2764774a00a6f8f512aae08e559a8)
Применение желаемых значений для функции на обеих конечных точках:
![{ displaystyle { begin {alignat} {13} operatorname {S} _ {1} (0) && ; = ; && 0 quad && Rightarrow && quad 0 ; && + && ; 0 ; && + && ; 0 ; && + && ; a_ {0} && ; = ; && 0, & имя оператора {S} _ {1} (1) && ; = ; && 1 quad && Rightarrow && quad a_ {3} ; && + && ; a_ {2} ; && + && ; a_ {1} ; && + && ; a_ {0} && ; = ; && 1. & конец {выровненный}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/25f912e9e501e2385f699c1b94a389f4a3769469)
Применение желаемых значений для первой производной функции на обеих конечных точках:
![{ displaystyle { begin {alignat} {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 {alignat}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/f28778229879236c3a4bf0f14949e39bca98af8c)
Решение системы из 4 неизвестных, образованных последними 4 уравнениями, приводит к значениям коэффициентов полинома:
![{ displaystyle a_ {0} = 0, quad a_ {1} = 0, quad a_ {2} = 3, quad a_ {3} = - 2.}](https://wikimedia.org/api/rest_v1/media/math/render/svg/cb4d0b78d2568adfe2255ec598c5553baae7147f)
Это приводит к третьему порядку "плавный шаг" функция:
![{ displaystyle operatorname {S} _ {1} (x) = - 2x ^ {3} + 3x ^ {2}.}](https://wikimedia.org/api/rest_v1/media/math/render/svg/0a4fb0a271d632a2666b1c6a8d49dc400b0f1b81)
Уравнение 5-го порядка
Начиная с общего пятого порядка многочлен функция, ее первая производная и ее вторая производная:
![{ displaystyle { begin {alignat} {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}, & имя оператора {S} _ {2} '(x) && ; = ; && 5a_ {5} x ^ {4} && ; + ; && 4a_ {4} x ^ {3 } && ; + ; && 3a_ {3} x ^ {2} && ; + ; && 2a_ {2} x && ; + ; && a_ {1}, & имя оператора {S} _ {2} ' '(x) && ; = ; && 20a_ {5} x ^ {3} && ; + ; && 12a_ {4} x ^ {2} && ; + ; && 6a_ {3} x && ; + ; && 2a_ {2}. & End {alignat}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/a6b00014d08f5714360e43b26f2de1acc31da5ea)
Применение желаемых значений для функции на обеих конечных точках:
![{ displaystyle { begin {alignat} {17} operatorname {S} _ {2} (0) && ; = ; && 0 ; ; ; ; ; && Rightarrow && ; ; ; ; ; 0 ; && + && ; 0 ; && + && ; 0 ; && + && ; 0 ; && + && ; 0 ; && + && ; a_ {0} && ; = ; && 0, & имя оператора {S} _ {2} (1) && ; = ; && 1 ; ; ; ; ; && Rightarrow && ; ; ; ; ; a_ {5} ; && + && ; a_ {4} ; && + && ; a_ {3} ; && + && ; a_ {2} ; && + && ; a_ {1 } ; && + && ; a_ {0} && ; = ; && 1. & end {alignat}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/f24891184b7c8ddb3f4477d9e0e3540cc346e346)
Применение желаемых значений для первой производной функции на обеих конечных точках:
![{ displaystyle { begin {alignat} {15} operatorname {S} _ {2} '(0) && ; = ; && 0 ; ; ; ; && Rightarrow && ; ; ; ; 0 ; && + && ; 0 ; && + && ; 0 ; && + && ; 0 ; && + && ; a_ {1} ; && = ; && 0, & имя оператора {S} _ {2} '(1) && ; = ; && 0 ; ; ; ; && Rightarrow && ; ; ; ; 5a_ {5} ; && + && ; 4a_ {4} ; && + && ; 3a_ {3} ; && + && ; 2a_ {2} ; && + && ; a_ {1} ; && = ; && 0. & End {выровнено }}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/ee8d629dba0b2f0158b1d5a29090aeab69eacf7f)
Применение желаемых значений для второй производной функции на обеих конечных точках:
![{ displaystyle { begin {alignat} {15} operatorname {S} _ {2} '' (0) && ; = ; && 0 ; ; ; ; && Rightarrow && ; ; ; ; 0 ; && + && ; 0 ; && + && ; 0 ; && + && ; 2a_ {2} ; && = ; && 0, & имя оператора {S} _ {2 } '' (1) && ; = ; && 0 ; ; ; ; && Rightarrow && ; ; ; ; 20a_ {5} ; && + && ; 12a_ {4} ; && + && ; 6a_ {3} ; && + && ; 2a_ {2} ; && = ; && 0. & End {alignat}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/e3119705ff40b28734a72b72ecb2e3162dd0ae61)
Решение системы из 6 неизвестных, образованной последними 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.}](https://wikimedia.org/api/rest_v1/media/math/render/svg/70a0f77d5d4119c09b0f8de5feb1bf2891dc5cf2)
Это приводит к пятому порядку "плавный шаг" функция:
![{ displaystyle operatorname {S} _ {2} (x) = 6x ^ {5} -15x ^ {4} + 10x ^ {3}.}](https://wikimedia.org/api/rest_v1/media/math/render/svg/154860fcda586dc6a1d90cc522cd9f0fc737c882)
Уравнение 7-го порядка
Используя аналогичные методы, найдено уравнение 7-го порядка:
![{ displaystyle operatorname {S} _ {3} (x) = - 20x ^ {7} + 70x ^ {6} -84x ^ {5} + 35x ^ {4}.}](https://wikimedia.org/api/rest_v1/media/math/render/svg/fdd5f0ed086d336d4323a0ea3f43207c4cdc29b5)
Обобщение на уравнения высшего порядка
Полиномы плавного шага являются обобщенными, причем 0 ≤ Икс ≤ 1 как
![{ displaystyle { begin {align} operatorname {S} _ {N} (x) & = x ^ {N + 1} sum _ {n = 0} ^ {N} { binom {N + n} {n}} { binom {2N + 1} {Nn}} (- x) ^ {n} qquad N in mathbb {N} & = sum _ {n = 0} ^ {N} (-1) ^ {n} { binom {N + n} {n}} { binom {2N + 1} {Nn}} x ^ {N + n + 1} & = sum _ {n = 0} ^ {N} { binom {-N-1} {n}} { binom {2N + 1} {Nn}} x ^ {N + n + 1}, конец {выровнено}} }](https://wikimedia.org/api/rest_v1/media/math/render/svg/eafc3198904574d0bb5c3cd8c51d23c153a4f5fc)
куда N определяет порядок полученной полиномиальной функции, который равен 2N + 1. Первые семь полиномов гладкого шага, где 0 ≤ Икс ≤ 1, являются
![{ displaystyle { begin {align} operatorname {S} _ {0} (x) & = x, operatorname {S} _ {1} (x) & = - 2x ^ {3} + 3x ^ {2}, имя оператора {S} _ {2} (x) & = 6x ^ {5} -15x ^ {4} + 10x ^ {3}, имя оператора {S} _ {3} ( x) & = - 20x ^ {7} + 70x ^ {6} -84x ^ {5} + 35x ^ {4}, имя оператора {S} _ {4} (x) & = 70x ^ {9} -315x ^ {8} + 540x ^ {7} -420x ^ {6} + 126x ^ {5}, имя оператора {S} _ {5} (x) & = - 252x ^ {11} + 1386x ^ {10} -3080x ^ {9} + 3465x ^ {8} -1980x ^ {7} + 462x ^ {6}, имя оператора {S} _ {6} (x) & = 924x ^ {13} - 6006x ^ {12} + 16380x ^ {11} -24024x ^ {10} + 20020x ^ {9} -9009x ^ {8} + 1716x ^ {7}. конец {выровнено}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/db3448186e062068eacfddf0a05fe126afe6c289)
Можно показать, что полиномы плавного шага
переход от 0 к 1, когда Икс переходы от 0 к 1 можно просто сопоставить нечетная симметрия многочлены
![{ 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,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/7d228d41adccf31c17369471dc5be538e16c12ba)
куда
![{ displaystyle operatorname {S} _ {N} (x) = { tfrac {1} {2}} operatorname {R} _ {N} (2x-1) + { tfrac {1} {2} }}](https://wikimedia.org/api/rest_v1/media/math/render/svg/8959b9e1787364166814e35eb7d3dd002029c330)
и
![{ displaystyle operatorname {R} _ {N} (- x) = - operatorname {R} _ {N} (x).}](https://wikimedia.org/api/rest_v1/media/math/render/svg/c94dd6f92a9616118b7d52d441dd5fa29e7c8190)
Аргумент RN(Икс) равно −1 ≤ Икс ≤ 1 и добавляется к константе −1 слева и +1 справа.
Реализация
в Javascript:[7]
// Обобщенный плавный шагфункция генералSmoothStep(N, Икс) { Икс = зажим(Икс, 0, 1); // x должен быть равен или находиться в диапазоне от 0 до 1 вар результат = 0; за (вар п = 0; п <= N; ++п) результат += паскальТреугольник(-N - 1, п) * паскальТреугольник(2 * N + 1, N - п) * Математика.пау(Икс, N + п + 1); возвращаться результат;}// Возвращает биномиальный коэффициент без явного использования факториалов,// что нельзя использовать с отрицательными целыми числамифункция паскальТреугольник(а, б) { вар результат = 1; за (вар я = 0; я < б; ++я) результат *= (а - я) / (я + 1); возвращаться результат;}функция зажим(Икс, Нижний предел, верхний предел) { если (Икс < Нижний предел) Икс = Нижний предел; если (Икс > верхний предел) Икс = верхний предел; возвращаться Икс;}
Обратный плавный шаг
Обратный к smoothstep () может быть полезен при выполнении определенных операций в компьютерной графике, когда его эффект необходимо отменить или компенсировать. В случае уравнения 3-го порядка существует аналитическое решение обратной задачи, а именно:
![{ displaystyle operatorname {InvS} _ {1} (x) = 1/2- sin ( operatorname {asin} (1-2x) / 3)}](https://wikimedia.org/api/rest_v1/media/math/render/svg/497f29c6b7c9e283fc4c531dfedd95ca38d59c51)
Это возникает как обратное
, чей Серия Маклорена заканчивается в
, смысл
и
выражают ту же функцию. С другой стороны, разложение обратного в ряд не прекращается.
В GLSL:
плавать inverse_smoothstep(плавать Икс) { возвращаться 0.5 - грех(как в(1.0 - 2.0 * Икс) / 3.0);}
Рекомендации
внешняя ссылка