パラパラ画像で3D表示させる、あのパラパラした画像の作り方を調べて作ってFlutterで表示させてみた

これは「弁護士ドットコムアドベントカレンダー」 の 21 日目の記事です。

20 日目の記事は @blkclct さんでした。

# 概要

今年も業務とはまったく関係ないネタを書きます。すみません。

Amazonで買い物するとたまに表示される、パラパラ画像で回転する3D商品が表示されるあの元画像どうやって作るのか、サーバサイドエンジニアには想像もつかなかったので調べて作りました。
今回は、アニメ風キャラクターを正面から背面まで回転させるパラパラ画像を作ってみます。
これで、3Dまったくわからんサーバサイドエンジニアでも3Dデータさえどうにかできれば、自分のWebアプリが豪華になります。たぶん。
あとついでにFlutterで表示させてみました。

# 3Dデータを用意する

はい。
いきなりの難題です。
3Dデザイナーでもなければなかなか敷居が高いです。
しかしこのご時世、意外となんとかなります。
フリーで落ちているものを使ってもいいし、有料のものを使っても構いません。

しかし今回は作ります。作れます。
そう、[VRoidStudio](https://vroid.com/studio)ならね。

以下のモデルをさくっと作成しました。
簡単なものでよければプリセットから選んで適当に色を変えるだけで終了です。

![test17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/578654ec-5020-b789-b508-c47b70bcb4b6.png)


そしてこのデータを **VRM** 形式で出力します。
VRMについては以下を参考にしてください。

[VRMコンソーシアム](https://vrm-consortium.org/)

# BlenderでVRMファイルを読み込む

## Blenderインストール

Blender は3DCGアニメーションを作成するための統合環境アプリケーションです。最近話題になっているので小耳に挟んだエンジニアもいるかと思います。
以下からダウンロードしてインストールしてください。
なお、使用するバージョンによってUIが微妙に変わっているので適時読み替えてください。

[Blender 2.93 LTS](https://www.blender.org/download/lts/2-93/)

## VRMアドオンインストール

標準ではVRMファイルを読み込めないので、アドオンを設定します。
以下のgithubにアドオン本体とインストール方法が詳しく載っているので、見ながら設定します。

[VRM Addon for Blender](https://github.com/saturday06/VRM_Addon_for_Blender)

## VRMファイル読み込み

VRoidStudioで出力したVRMファイルをインポートしてください。
そうすると以下の画面が出てくると思います。

![test1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/158ce140-9dfb-6fc3-eafa-3d62094532ff.png)

環境によっては初期表示で[ソリッドモード](https://docs.blender.org/manual/ja/latest/editors/3dview/display/shading.html#solid)になっていることもあるので、[レンダープレビューモード](https://docs.blender.org/manual/ja/latest/editors/3dview/display/shading.html#rendered)にしてください。

![test1 - コピー (2)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/ef63ccf5-1941-7806-76ff-7c92adc435de.jpeg)

# カメラを設定する

カメラを正面に据えるように設定します。
カメラの距離と高さは感覚で設定します。
ついでに、表示を`Animation`にしておいてください。

![test2_LI (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/6b680aac-fac3-6878-aa3b-2763519b12b6.jpeg)

カメラの回転は`XYZオイラー角`で、`X軸を90度`に設定してください。


# 回転アニメーションを作る

回転アニメーションを作成します。
アニメショーンというと難しそうですが、回転させるだけなら簡単です。
今回は60fpsでアニメーションを作成します。

## 1フレーム目を指定する

![test9_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/c0186669-80fd-3c47-80ce-44406b3fa22c.jpeg)

`シーンコレクション`の`Armature`を選択してください。
これでモデル全体が選択された状態になります。

画面の下の方に表示されているシーケンサーの`1`の位置にカーソルが来るように選択してください。
その状態で、トランスフォームの回転Z軸を0度にしておき、右側の`・`をクリックしてください。画像の通りに`◇`に変わると思います。

## 60フレーム目を指定する

間をすっ飛ばして60フレーム目を指定します。
1フレームづつ設定しても良いですが、プログラム側でアニメーション補完をしてもらうので60フレーム目を指定します。

![test8_LI (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/d986e2c2-539b-e30b-0db0-d1c08b505d9f.jpeg)

シーケンサーで60フレーム目にカーソルを合わせます。
その状態でZ軸に`180`を指定して先ほどと同じように右側の`・`をクリックしてください。画像の通りに`◇`に変わると思います。

これで設定完了です。
シーケンサーの再生マーク`▶`を押すと回転する様子が分かると思います。

## 再生時間を指定する

今回のアニメーションは1フレームから60フレームなので、終了を60フレームに指定します。

![test12_LI (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/bd77ec42-d43c-c0d3-5782-4a4d556dad9d.jpeg)

# アニメーションを画像として出力する

パラパラ画像として出力します。

## 背景を透過させる

パラパラ画像にしたときの背景が透過になるように設定します。

![test12_LI (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/0c2b3c9f-2eb0-9446-aac3-e42501e65515.jpeg)

レンダープロパティの赤い印がついている`透過`チェックボックスをONにしてください。
これで、モデルが表示されている画面も透過されている背景マークに変わるはずです。

## アニメーションレンダリングする

アニメーションレンダリングをしてパラパラ画像を出力させます。

![test13_LI (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/38af0c19-b91d-b424-1b18-e54852991a20.jpeg)

これを行うとアニメーションレンダリングプレビュー画面が表示され、レンダリングされている様子が見れると思います。

![test14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/bf502137-377b-f121-b436-653e7790fe28.png)

このレンダリングが完了したら、設定した出力さきに出力されています。
Windowsの場合はCドライブの直下に`tmp`というディレクトリで作られていると思います（バージョンや環境によって異なる可能性が高い箇所なので、確認してください）。

![test15 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/deaf5816-3f38-07f4-7c12-bb4d7d5d0f2d.png)

## サイズを削減する

今回私が出力した画像は、1枚1MBありました。非常に大きいです。
なので、世の中に色々ある画像サイズ削減サービスで削減してください。
無料のものは広告が沢山でたり、制限あったり、ポリシー微妙だったりするので、自分に合ったものを選択してください。

![test16 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/230ff37e-32f3-586f-8200-dd89dc939c31.png)

上手いこと削減できると、上記のように劇的にサイズが小さくなります。

お疲れ様でした！
これにて3Dアニメーションの元となるパラパラ画像が完成です。

# Flutterでパラパラ画像をアニメーションさせる

## 動かし方

以下のYoutube動画と、そのチャンネルに載っているGithubリンクを参考にしてください。

<iframe width="560" height="315" src="https://www.youtube.com/embed/4KB8grp4O-Y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Githubにあるコードを実行しても動かないので、自分であれこれ修正する必要があります。
具体的にはFlutterのNullSafty周りの対応を入れる必要があります。
差分が結構出てQiitaに乗せると量が多くなりすぎてしまうため、申し訳ないですがFlutterのエラーを見ながら根気よく修正してください。

## 初回アクセス時の速度

上記コードでは初回アクセス時の体験が悪いです。
原因は、動かそうとしたその時点から画像ロードが走るためです。
快適にするには事前ロードをする必要があります。

[precacheImage](https://api.flutter.dev/flutter/widgets/precacheImage.html)

`precacheImage`を利用することで事前ロードが可能になります。
これを使って`initiState`で事前ロードするようにしてください。

# まとめ

![test_anim-min.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538525/b68546e3-f775-0100-721f-34b8f1914419.gif)

自分の操作が下手なのでちょっと動きがカクカクしてますが、上記のようにまるで3Dモデルをそのまま読み込んでるかのように見えます。

これで3Dまったくわからんエンジニアでもパラパラ画像で3D表示をさせるデータを作成ができるようになりました。
細かい手順や説明を入れるとかなり長くなってしまうので、所々省略してあるのはご容赦ください。

普段とはまったく違う技術領域を触るのはとても楽しいですね。
普段サーバサイドをやっている方も、是非やってみていただければと思います！

明日は、@choreさんです。お楽しみにしてください。