Curves & interpolation

Smoothstep / Smootherstep

スムーズステップ

両端で滑らかにつながるフェードを作る。

8 / 10

Interactive demo

Preparing the demo…

Smoothstep / Smootherstep

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

0 から 1 への変化を、両端で傾きが 0 になる S 字カーブでつなぐ関数です。境界を柔らかくぼかしたり、動きの開始と停止を穏やかにしたりする、シェーダーとゲームプログラミングの定番部品です。さらに滑らかな 5 次版を smootherstep と呼びます。

ゲームでの使いどころ

  • 柔らかい境界:スポットライトの縁、ディゾルブの焼けた縁、霧の開始距離、選択範囲のハイライト。境界を smoothstep(edge0, edge1, x) でぼかすのはシェーダーの常套句です。
  • フェードイン・アウト:UI、音量、画面遷移。線形だと始まりと終わりが唐突に感じられます。
  • 移動の加減速:エレベーター、ドア、カメラの移動。デモ左の昇降機のように、端でふわっと止まります。
  • ノイズの補間:値ノイズやパーリンノイズで、格子の間をつなぐ重みとして使います。

しくみ

smoothstep(e0,e1,x)=3t2−2t3,t=clamp ⁣(x−e0e1−e0, 0, 1)\text{smoothstep}(e_0, e_1, x) = 3t^2 - 2t^3, \qquad t = \text{clamp}\!\left(\frac{x - e_0}{e_1 - e_0},\, 0,\, 1\right)

まず xx を範囲 [e0,e1][e_0, e_1] で 0〜1 に写し(Inverse Lerp + clamp)、それを 3 次式に通します。この 3 次式は、次の 4 条件を満たす唯一の 3 次多項式です。

f(0)=0,f(1)=1,f′(0)=0,f′(1)=0f(0) = 0,\quad f(1) = 1,\quad f'(0) = 0,\quad f'(1) = 0

両端で傾き(速度)が 0 なので、動き出しと停止が穏やかになります。ただし 2 階微分(加速度)は両端で ±6\pm 6 と 0 にならないため、動き出しの瞬間に加速度が跳ねます。これも 0 にしたのが Ken Perlin の smootherstep です。

smootherstep(t)=6t5−15t4+10t3\text{smootherstep}(t) = 6t^5 - 15t^4 + 10t^3
関数端での速度端での加速度主な用途
線形(clamp)1(急に動き出す)—単純な割合
smoothstep0±6(跳ねる)境界のぼかし、一般的なフェード
smootherstep00法線を使うノイズ補間、非常に滑らかな動き

実装のポイント

  • 幅を画面サイズに合わせる:シェーダーで境界をアンチエイリアスしたいときは、ぼかし幅に fwidth(x) を使うと、どの距離から見ても 1〜2 ピクセルの柔らかさになります。
  • 逆向きの範囲:GLSL 仕様では edge0 >= edge1 の結果は未定義です。逆にしたいときは 1.0 - smoothstep(...) と書きます。

つまずきやすい点

  • 境界の位置がずれる:smoothstep(e0, e1, x) の 0.5 の位置は (e0+e1)/2(e_0 + e_1)/2 です。「半径 r の円を幅 w でぼかす」なら smoothstep(r - w, r + w, d) のように中心をそろえます。
  • 動きの時間が延びて見える:同じ所要時間でも、両端が遅いぶん中央は線形の 1.5 倍の速さになります。移動量が大きいと中央が速すぎると感じることがあります。
  • 繰り返し適用:smoothstep(smoothstep(t)) のように重ねると、さらにメリハリの強い S 字になります。意図的な効果として使うこともあります。

デモで試すこと

  1. 左の 3 台の昇降機を見比べてください。線形(赤)は上下端でガクッと止まり、smoothstep 系はふわっと止まります。
  2. 右の柱は、動く光の輪からの距離に関数をかけて高さを決めています。「右の柱に使う関数」を線形にすると、盛り上がりの縁が角ばった円錐になります。
  3. edge0 と edge1 を近づけると境界が鋭く、離すとなだらかになります。

References

The Book of Shaders — Shaping Functions ↗

A general reference for this subcategory.