WIZ-CODE.blog

JavaScriptやAjaxをテーマとしたブログです。

*

グラフィックスとPixiJS

      2022/05/16

VolTubeではビジュアライザー風のエフェクトを表現するのに、PixiJSというグラフィックス・ライブラリを使用しました。PixiJSは主に2Dのグラフィックを表示するのに使われ、よりパフォーマンスのよいWebGLでのレンダリングを選択可能な点が特徴です。

VolTubeの動画コンテンツページの一部

JavaScriptで2Dの描画を行う場合、ほぼすべてのブラウザが対応しているCanvas APIがまず候補になります。または、Canvasを生で扱うよりEaselJS(CreateJS)のようなライブラリを導入するかもしれません。アニメーション主体ならGSAPでしょうか。実際に自分がVolTubeのグラフィック/エフェクトの実装で初めに使用したのはCanvasでした。

しかし、CanvasはCPUの処理能力に頼るため、グラフィックの負荷が上がるとWebサイト全体のパフォーマンスに影響してしまいます。VolTubeの場合、ライブラリに頼らず生のコードを書いていたので、ある程度パフォーマンス・チューニングができましたが、それでもFPSの低下が避けられず、開発が進むにつれて負荷が増え続けていくなか、グラフィックスをCanvasに頼るのが困難になってきました。そこで目をつけたのが、レンダリングにGPUを経由するWebGLレンダラーを実装したPixiJSです。こちらに切り替えたところ効果は絶大で、それまで重かったアニメーションやエフェクトがサクサクと動作し、ブラウザのレンダリングへの影響を抑えつつ、高いFPSを保つことができるようになりました。

では初めから2D描画をPixiJSにすべきだったかというとそうでもなく、メリットばかりではありませんでした。WebGLがもともと3D描画用のAPIであるため、Canvasに比べて2D描画の精度が低く、特に線や円などの図形を2D描画した際ジャギーが現れ、アンチエイリアスをオンにしてもあまり効果がなく処理の荒さが目立ちます。また、PixiJSはぼかしなどの豊富なフィルターをプラグインに備えていますが、CanvasでいうshadowBlurと同じくフィルターの種類によってはパフォーマンスを悪化させるので多用ができません。描画の粗さについては、PixiJSが本来2Dゲーム用に画像スプライトの処理に特化したものなので、プロジェクト内であくまで補助的なものとみなされているためではと思います。

ただし、アンチエイリアスについては、有志によるプラグインがGithubで公開されていて、自分はgraphics-smoothというプラグインを使用しています。テクスチャが未実装な点など、プロジェクトは完全ではなく現在進行形です。

WebGLを理解できていればグラフィックスの問題を自分なりに解決できたかもしれませんが、Canvasと異なりWebGLのAPIは頂点シェーダなど、より専門的な知識が必要で、CanvasでいうfillRect()のような直感的なメソッドもありません。WebGLユーザーの大半は自分と同じように何らかのライブラリを通じてWebGLを利用し、生のWebGLを扱うことは少ないのではないでしょうか。ひとまずグラフィックスの問題は、受け身の姿勢ですが当のGithubリポジトリの改善に期待することにします。ちなみに自分は以前3Dシューティングゲームを作ったことがあり、こちらにはThree.jsというWebGLの老舗ライブラリを使いました。よかったらプレイして見てみてください(PC用ゲームです)。

VolTubeのグラフィック作成で大いに参考になったのが、ICS MEDIAさんの「CSS3とHTML5 Canvasで作るモーショングラフィック」で、CanvasとCSS3を用いたデモですが、コードを書き換えればPixiJSにも適用できるものです。曲線のスムーズなアニメーションにパーリンノイズという関数を用いています。なおVolTubeのエフェクトにはパーリンノイズの他、シンプレックスノイズを使用しています。当ページのデモを見ていただくと、複数の曲線が非常になめらかにアニメーションしているのがわかると思います。しかしこれはCanvasだから可能な点で、PixiJSで同じことをしようとすると曲線にジャギーが現れた見た目のよくないグラフィックになる可能性があります。

グラフィックスをCanvasからPixiJSに変更したことで困った点としては、PixiJSを勉強するのに正規のドキュメントが英文サイトしかない点です。日本語サイトは入門系の記事が多く情報量もまだそう多くない印象で、英文サイトの情報量もそれほど多いとは思いません。これは数年前のQiitaの記事でも指摘されています。実装面ではPixiJSの機能面の不足に悩みました。前述のとおり、PixiJSのWebGLレンダラーはWebGLの特性により直線しか描けないので、曲線や円形図形はどうしてもなめらかな仕上がりにできません。あと自分が困ったのはグラデーション機能がない点です。ただし、グラデーションはPixiJSのテクスチャにグラデーション処理を施したCanvas要素を設定することで効果を追加できます。なお、前述のプラグインgraphics-smoothを使用すると、線形図形のテクスチャが現時点で未実装のため、線形のエフェクトはグラデーションが表示されません。一方でプラグインを使用しなければグラデーションを表示できますが、代わりに図形描画が荒くなります。いまのところトレードオフの状態です。

しかし、PixiJSの高いパフォーマンスによって、VolTubeのグラフィックが処理落ちせずに実装できたのはありがたいことです。実際のところWebサイトで2Dグラフィックが必要な箇所はCanvasで十分な例がほとんどでしょうが、Webサイトでも今後凝ったエフェクトの演出やゲームなどの高負荷なグラフィックス処理が必要とされるケースが多くなると思いますから、PixiJSのようなWebGLで2D描画する活躍の場は増えていくのではないでしょうか。

今後もPixiJS関連で思いつくことがあれば記事にしていこうと思います。

 - JavaScript/Ajax , , ,