Starling2.1新機能DistanceFieldスタイルをスプライトシートアニメに適用してみた


こちらはFlasherアドベントカレンダーその2の19日目の記事です。4日遅れました。ええ。
http://qiita.com/advent-calendar/2016/flasher2

この記事の続き(アウトラインをさらに綺麗にした)がこちらにあります。
http://qiita.com/harayoki/items/f88c439c18bc1881ace1

デモと基本的な解説

Starling2.1新機能としてDistanceFieldスタイルというものが実装されました。低解像度のビットマップフォントを拡大表示してもジャギが目立たずスムースになるというものです。

そしてあまり知られていなそうですが、このスタイル指定はフォントだけでなく、通常の画像(ただし単色)にも適用可能です。Starlingマニュアルでも画像に適用する例は説明されているのですが、これをさらに発展させてスプライトシートアニメに適用してみたので記事にまとめて見ます。

実際にhtml+swfで動かしているデモがここにあります。
右がDistanceFieldを適用したスプライトシートアニメで、左がノーマルなものです。
https://harayoki.github.io/StarlingDemoDistanceFieldStyle/demo1/index.html

スマホだと見れないと思うんで、youtubeにもあげておきました。


最大で10倍程度の拡大率で表示しています。ニョロニョロしているものの、ジャギーが低減されているのがわかりますね。ただし目の当たりなど細かいところは潰れてしまっています。
こちらのヘキサドライブ様のブログの記事を見ますともっと綺麗にエッジが出ていますので、後述する前処理の画像変換とランタイムのパラメータを突き詰めればもっといい感じになるのかもしれません。 http://hexadrive.jp/lab/demo/610/
そもそも元画像にも問題があるのかもしれませんが、このニョロニョロ状態でも使いどころはありそうだなと思います。

作り方

※より綺麗に書き出す方法があったので別記事まとめ直します。コメント欄参照。

まず何でもいいのですが単色のスプライトアニメを用意します。ここではAnimateCCを使って作りました。

スプライト書き出しは背景が透明でなく白、キャラクター部分は黒になるようにします。背景色はここで指定、黒くするのはMovieクリップに着色しました。またこの後の画像変換で必要になるので余白を多くとります。適当にボーダーとシェイプの余白を32pxにしてあります。後は普段通りで良いです。拡大時のジャギーの確認をするためのものなので、キャラクターはそこそこ小さめの書き出しにしてあります。

この記事の例ではDistanceFieldスタイルをアニメーションに適用していますが、アニメーションなしのスプライトシートでも手順は同じですし、一枚画像でも構いません。

このまま画像を書き出します、(が、エッジにアンチエイリアスが入っているのは後続の処理を考えるとよくないかもしれません。。)

今回はこのような画像が得られました。
https://github.com/harayoki/StarlingDemoDistanceFieldStyle/blob/qiita161223/material/whiteMan.png

この画像をStarling2.1のutil/field_agentフォルダに入っているrubyスクリプトで、DistanceFieldスタイル用の前処理をかけて変換します。rubyとimagemagicが必要ですが、付属のREADMEにwin/macともに導入の仕方が書いてあります。自分の場合Macでrubyは最初から入っていたのでImagemagicのみ追加でbrew installしました。

MacOS already comes with Ruby, so you only need to install ImageMagick.
For that, my recommendation is to first install [Homebrew][4], a fantastic package manager for macOS.
Once ready, you can install ImageMagick (like many other tools and libraries) with the following terminal command:

    brew install imagemagick

You can also optionally make the script executable, which will allow you to call it directly (without passing it to Ruby).

    cd /path/to/starling/util/field_agent
    chmod u+x field_agent.rb

Starlingのマニュアルには下記のように実行するようにありますが、

ruby field_agent.rb hoge.png hoge-df.png --scale 0.25 --auto-size

今回はこのようにパラメータを変えました。

ruby field_agent.rb hoge.png hoge-df.png --scale 1.00

縮小をなくしたのはスプライトシート設定の座標とズレなくするためです。またオートサイズ指定があると余白のトリミングが行われ、これもスプライトシート設定の座標とずれてしまうからです。他にもこのコマンドにはオプション引数があり、ここのパラメータの渡し方が直接最終画像クオリティに響きますので、もっと慎重にやるべきですが、とりあえずテストなのでこのままいきます。

このような寝ぼけた画像が得られます。
https://github.com/harayoki/StarlingDemoDistanceFieldStyle/blob/qiita161223/material/whiteMan_df.png

動かし方

出来上がった画像にファイル名が合うように若干XMLを書き換えて、
https://github.com/harayoki/StarlingDemoDistanceFieldStyle/blob/qiita161223/docs/assets/whiteMan_df.xml

両者をStarlingに読み込んで表示します。
通常のスプライトアニメ(Starling.MovieClip)と同じ扱いで良いですが、

mc.style = new DistanceFieldStyle();

の1文だけ付け加えてやります。

デモのソースはこのあたりにあります。
https://github.com/harayoki/StarlingDemoDistanceFieldStyle/blob/qiita161223/src/StarlingMain.as
その他素材も一緒に上がっています。
https://github.com/harayoki/StarlingDemoDistanceFieldStyle/tree/qiita161223/material

動作までは、とりあえず以上です。

その他

文字に適用する場合の説明が公式フォーラムやマニュアルにあります。
嬉しい副作用として、パフォーマンス低下ほとんどなしに、縁取りや影や光彩を追加できます。
http://forum.starling-framework.org/topic/new-feature-distancefieldstyle

<装飾面での考察は別記事でそのうち)