世界を動かす技術を、日本語で。

SVGフィルターを用いた手描きの動きのシミュレーション

概要

  • 手描きアニメ のような「 jitter(ジッター)」効果の仕組みを解説
  • SVGフィルター を使い、静止画に動きを加える方法
  • feTurbulencefeDisplacementMap の組み合わせによるエッジの歪み
  • JavaScript によるパラメータのアニメーション制御
  • Web上 で再現するための実践的な手順

手描き風「ボイリング」エフェクトの仕組み

  • アニメやイラストで見られる 「ボイリング(boiling)」「ラインボイル(line boil)」 と呼ばれる効果
  • 同じフレームを 何度も手描き し、微妙なズレを重ねて動きを演出
  • 静止画でも動きを感じさせる、視覚的に魅力的な表現手法
  • ARTEドキュメンタリー のピザの材料紹介アニメーションにも採用例
  • 本記事では、 Web上での再現方法 にフォーカス

エフェクトの分解と再現方法

  • 効果の要素を2つに分解
    • エッジの歪み :輪郭をなめらかでなく、 有機的に揺らす 表現
    • アニメーション :歪みパラメータを 時間経過で変化 させ、動きを生み出す
  • Webでは SVGフィルター を活用
    • feTurbulence でノイズ(乱流)テクスチャ生成
    • feDisplacementMap でノイズを元画像に適用し、 ピクセル単位で歪ませる
  • SVGフィルターの基本構成
    • ノイズ生成→画像歪み→SVG要素に適用
    • サンプルコード:
      <svg width="400" height="400" viewBox="0 0 400 400">
        <defs>
          <filter id="distortionFilter">
            <feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="2" seed="1" result="noise" />
            <feDisplacementMap in="SourceGraphic" in2="noise" scale="20" xChannelSelector="R" yChannelSelector="G" />
          </filter>
        </defs>
        <image x="0" y="0" width="400" height="400" href="/image.jpg" filter="url(#distortionFilter)" />
      </svg>
      

JavaScriptによるアニメーション制御

  • SVGフィルターの属性 をJavaScriptで定期的に更新
  • 例: baseFrequencyscale などの値を、 100msごと に変化
  • オフセット配列(例:[-0.02, 0.01, -0.01, 0.02])を用いて 揺れをループ
  • スライダーで 揺れの強さ を動的に調整可能
    • 0で揺れ無し、1で最大揺れ
  • SVG画像やラスター画像 どちらにも適用可能

実践と応用

  • 調整次第で、微細なジッターから大きな歪みまで表現可能
  • やりすぎ注意 :過剰な歪みは元画像が判別不能になる場合も
  • ARTEシリーズ など、実際のアニメーション作品でも活用例多数
  • SVGフィルター+JavaScript で、 静止画に命を吹き込む 技術

まとめ

  • 「ボイリング」効果 は、 ノイズ生成(feTurbulence)ピクセル歪み(feDisplacementMap) の組み合わせで再現
  • JavaScript でパラメータを動的に変更し、 手描き風の動き を実現
  • SVGフィルター を使えばWeb上でも 手軽に実装可能
  • 微調整が肝心 :さりげない揺れで 温かみや個性 を演出
  • 創作の幅が広がる、Webアニメーションの新たな手法

Hackerたちの意見

こちらも参照: https://en.wikipedia.org/wiki/Squigglevision

そうそう、すぐにスキグルビジョンとホームムービーズを思い出したよ。(https://www.youtube.com/watch?v=CJcBL9JPfZw) 記事に書いてあったノイジーな変位マップと同じアルゴリズムを使ってたのかな?

この技術、知っておくと面白いよね。SVGには意外と多くの機能があるんだ。でも、その効果は、生成される方法のせいで、熱気の歪みみたいな感じで、微かなきらめきがないんだよね。完全にラスター的な性質で、AFAICT(私の見解では)、GPUシェーダーとして実装されている可能性が高いよ(パフォーマンス的にはいいことだね)。不安定な人間の手のような効果は、曲率に対して垂直方向にノードを振動させて、制御点にランダムなジッターを加えることで実現できそう。

2段落目を読み返さなきゃいけなかったよ。熱のゆらぎがGPUシェーダー効果だなんて言ってないよね?「自然の中で」って言葉が全然助けにならなかった!

ドクター・カッツ。

最近の子供たちは、ドクター・カッツを知らないんだね…

ホームムービーズ!

甘いイエス様、ポテトが降ってきますように!

すごくクール!約2週間前のこの投稿を思い出したよ。[1] https://news.ycombinator.com/item?id=44498133 これとあなたのアプローチを組み合わせられないかな?

きれいなサイトで、良い内容だけど、見てたらスマホが溶岩になっちゃったよ!

素晴らしいね、SVGにはまだまだ未開拓の能力がたくさんあって、主にウェブのアイコンに使うのはもったいない気がする。

魅力的な揺れ方!Wobblepaint(PICO-8のクリエイターが作った描画ツール)に似てるね。https://www.lexaloffle.com/bbs/?tid=40058

自分はkurnell.aiで手作業でやったんだけど、計算でこれができるなんてすごいね :) フレームをエンコードして、状態間を移動するためのステートマシンを作るのにrive.appを使ったよ。もっとシンプルにできるかもしれないな。

SVGエフェクトを使ってみたことがあるけど、めっちゃパワフルだよね。でも、あんまり使うのはおすすめしないかな。FirefoxがSVGフィルターグラフに対してある程度GPUアクセラレーションをしてるみたいだけど、実際には見た目がシンプルなグラフを作ろうとすると、webrender.allをオンにしてもCPUに戻っちゃうことが多いんだ。これはちょっと残念。特にfeTurbulenceは結構役立つから、いろんなことに使えるんだよね。自分が使いたかったのは、グラデーションをもっと粒状にして、バンディングを目立たなくするためだったんだけど、残念ながらすぐにノートパソコンのCPUコアが全部使われちゃった :)

「GIFのようなSVG」から。(https://news.ycombinator.com/item?id=44498133#44501917) : > /? svgアニメーション: https://hn.algolia.com/?dateRange=all&page=0&prefix=false&qu...