トレンド&テクノロジー / サイエンスCG最前線!
第4回:心臓シミュレーションを可視化する(前編)
- Maya
- コラム
- 中級者
- 建築・製造・広告
約1年ぶりの寄稿となってしまいました、サイアメントの瀬尾です。
かなり大変だったプロジェクトが先日無事に公開されました。今回は、まさにサイエンスCGの最前線である「データの可視化」について、このプロジェクトを通じて掘り下げてお話しします。
まずは、何はともあれ、完成した作品をご覧下さい!
マルチスケール・マルチフィジックス心臓シミュレータ UT-Heart
東京大学が中心となり、理化学研究所や富士通の協力によって開発された心臓シミュレータ「UT-Heart(http://www.sml.k.u-tokyo.ac.jp/)」。その緻密で膨大なシミュレーションデータを完全に正確に、そして美しく、楽しく可視化、映像化させて頂きました。
…と言うと何とも美しい流れに聞こえますが、実際にはこんなに一直線にものごとは進みません。と言いますか、ストーリーを作ってから「じゃあこのストーリー(絵コンテ)通りの映像作っておいてね。」とデザイナーやプロダクションに丸投げすると悲劇が起こります。
技術的に何が出来て、何が難しくて、どのくらいの時間がかかりそうか、と言った課題を最初から分かった上でストーリーを作ることが不可欠です。これが、3DCGのことを何も分かっていない状態で、ただ格好良いストーリー、演出を並べると、「いや、それ、確かに格好良いですけれどもどうやって映像にするんでしょうか…」と言う事態になったり、「え、3DCGってなんでも簡単に出来るんじゃないの?」という事態に陥ります。これはサイエンスCGに限ったことではなく、割とどこでも良く見られる光景だと思いますが。
このUT-Heartの心臓は映像の冒頭にもあるように、小さな四面体がぎっしりと詰まって出来ており、有限要素法によって動きの計算が行われています。と言うわけで、シミュレーションデータは、数万頂点の座標と、十数万の各四面体の頂点番号と、各頂点や四面体に紐付いているエネルギーや圧力などの情報が記録されている長~い数値ファイルです。
まずは、データ構造を理解した上でMayaに取り込むところから始めなければいけません。もっと言えば、そもそも取り込めるのか、と言うところから始まるわけですが、まぁこれはデータをこねくり回して最も簡単なobjファイルあたりで掃き出すようにスクリプトを書けば出来ないことはないでしょうから、何とかなる気がします。
一応、研究者の先生方が普段使われている可視化ソフトウェアから表面ポリゴンだけを取りだしてVRMLフォーマットでExportが出来る、とのことで、とりあえずVRMLで出力。Mayaは何故か未だにVRMLをダイレクトには読み込めず、wrl2maを間に挟むか、他のソフトウェアでobjなどに変換しないといけないので(何とかしてほしいことの1つです…)、objに変換。スクリプト1行も書かずに取り込むだけ取り込んでみました。すると…
原点のあたりに小さく何かが見えます。拡大してみると…
ありました!心臓!!
…あまりにも小さすぎて、且つWorld Upと心臓の上下方向とが全く合っておらず、これでCG映像を作るのは相当大変、と言うことが一瞬にして分かりました。 しかも、VRML出力をした、と言うことは、各頂点に紐付けられていたエネルギー消費量などの値は全て削除されてしまっており、後から紐付けようにも可視化ソフトウェア上でどのような表面抽出アルゴリズムが使われたのかがわからないため、もともとのどの頂点がVRMLフォーマットでどの頂点になったのか知る由もなく、手も足も出ない悲壮感が漂ってきました。
最初から頂点カラーを付けておけばまぁ何とかなると言えばなるのですが、Mayaはobjファイルの頂点カラーを読み込んでくれません。…と、ここでAutodeskの方からご指摘を頂いたのですが、objファイルフォーマットは公式には頂点カラーはサポートしていないそうです。なるほど、非公式ならしょうがない…と思ったのですが、しかしですね、Autodeskの無料の製品でMeshMixerと言うソフトがあるのですが、MeshMixerでは頂点カラー付きobjファイルを読み込めるだけでなく、ファイルの保存で「OBJ Formt with Per-Vertex Color (*.obj)」と言う選択肢があって、頂点カラー付きobjファイルで出力することもきちんとできます。
つまりどういうことかと言いますと、同じメーカーのソフトを使っているのに、同じファイル形式でもMeshMixerで出力されたファイルを、最新版のMayaでも正しく読み込んでくれないと言う事態が起こります。
研究者用のソフトウェアでは、3DメッシュをVRML形式で出力出来ることが比較的多く、前述のwrl2maを用いるとMaya Ascii形式に変換してくれるのですが、ちょっと大きなファイルになるといつまで経っても変換が終わらないのと、ヘルプファイルによると頂点カラーをサポートしているはずなのですが、何故か私のところではいつも頂点カラーが付きません(私の環境がたまたまわるいのかもしれません…)。
ので、他のソフトでVRMLを頂点カラー付きobjファイルに変換するのですが、MeshMixerでは読み込めて、Mayaでは読み込めない、と言う悲しいことになります。
objファイルフォーマットってWavefront(Autodeskが買収)が作ったフォーマットなので、と言うことはAutodeskの製品でobjが読み込めるのであれば、複数のソフトウェア間で最も古い最新版のソフトに合わせる形で同じように読み込めて欲しいわけですが、Mayaでは何をどうやってもobjファイルの頂点カラーが無視されます。スクリプトを数十行書けば読み込める話ではあるので、標準機能として改善することは特に難しくないと思うのですが…。
ただ、仮に頂点カラーを読み込めたとしても、やっぱりここの色はもうちょっと明るくして、とか、色の数をもっと増やして、とかを後からその場で自由にいじることは出来ません。
…これは1から全てスクリプトを書かなければ…
と、ここで、私はそのまた昔、中学生のときにパソコン部に所属し、Cやらアセンブラやらを勉強して一応は自分でレイトレーシングやボクセルレンダリングやらのプログラムを書いていました(当時の3DCG画像などはこちら)。だったら自分で勉強すれば良さそうなものですが、勉強するにもあまりにも久しぶり過ぎてどこから手を付ければ良いのか全く分からない状態でした。
そこで今回、中学時代のパソコン部の伝手を辿って行き着いたのが、パソコン部の1学年先輩だった小田啓太さん。現在はプロのプログラマーで、Pythonもバリバリ書かれ、アルゴリズム考案などもこなしていらっしゃる偉大なる先輩です。
MayaがPythonにフル対応していることのメリットは非常に大きく、Mayaの機能に繋ぐ部分以外はMayaのことは何も知らなくてもコードを書くことが出来ます。Pythonは世界中で使われている言語ですので、ノウハウやテクニックも山のようにあります。
今回のように数値データを扱う案件の場合、特にその恩恵は大きく、私がこれまでのMayaの経験や知識などから、「このようなリストでデータを取り出せるようにしておいて頂ければ、最後の部分は私がコードを書いて、Mayaの中に取り込めるのですが…」とお願いすると、小田さんがあっと言う間に該当部分のコードを書いて下さいました。
小田さんのあまりにも美しいコードを目の当たりにし、コードを紐解いていくことで、私自身もある程度、基礎的な部分ではありますがPythonコードを書けるようになりました。
これで何もかもが上手くいく!…はずだったのですが、今度はMayaの仕様・制限に悩まされることになります。
…と思ったのですが、全く上手くいきませんでした。結論から言いますと、Mayaが完全にフリーズしました。試しにkey frameを打たずに100フレーム分動かしてみるとサクサク動く。ところが、key frameを打とうとすると100%フリーズする。
最初は訳が分からなかったのですが、色々調べていくうちにこれがMayaの限界であることがわかりました。私はMaya以外の3DCGソフトウェアに関してはほとんど知らないのですが、Mayaの場合、頂点にkey frameを打つと全ての頂点に1つずつアニメーションカーブのノードが作られるのですが、Mayaはノードが増えると急激に処理が重くなり、2000ノードくらいまでは何とかいけるのですが、私の環境では5000ノードでは確実に動かなくなります。
せっかくデータの受け渡しが出来たのに、Mayaの仕様でアニメーションが作れない…。
色々あれこれ検討した結果、最終的にはGeometry Cacheを取って解決することが出来ましたが、複数オブジェクトを1つのオブジェクトとして認識させたりするところに工夫が必要だったりと、なかなかに大変でした。
こうして何とか心臓1拍分の動きを完全にMayaに取り込むことが出来たわけですが、途中で滑らかに心拍数を変えようと思った場合、Animation Clipであればカーブを1本描けば自由に滑らかにループの速度を変えられるのに、何故かGeometry Cacheの場合には速度一定の単純なループ再生しか出来ず、ここでもMayaの仕様に一苦労しました。
動きだけならまだしも、頂点カラーアニメーションはMayaの標準機能ではどうにもならず、結局、フリーのカスタムノードをフル活用して何とか実現しました。
最終的にはこのように心臓を動かしながら、その場で頂点カラーをRampで調整出来るようなワークフローを作りました。デザイナーがデザインの観点から操作し易い方法を私なりに考えて作りました。
今回諦めなければいけなかったのが、Particle Instancerを用いたInstanced objectの複雑な制御。Instance化したいオブジェクトの動きが単なる回転ではなく親子構造になっていて、親だけが動いたり子も動いたりといくつかに場合分けされるケースがあったのですが、Paritcle Instancerでは親オブジェクトのPivot位置で親オブジェクトしか動かすことが出来ません。せめて、Particleの情報をDriven Keyあたりに接続出来るようにしてくれれば良いのですが、そのような自由度は無いようで、泣く泣く諦めました。気合いでカスタムノード作れば出来た…のかもしれませんが。
これは数値の可視化にとって致命的です。
いわゆるData Visualizationの世界では、数値情報を色に置き換えるのはごく当たり前に行われている手法です。と、言いますか、基本中の基本です。3DCGで大量のデータを扱う場合にはParticleで制御するのが常套手段だと思いますが、Particle Instancerに個別の色(そして実は透明度も…)を指定出来ないと言うことは、MayaではData Visualizationは出来ない、と言う結論になります。
結局これについてはV-Rayを採用することで解決したのですが、V-RayでもRendermanでも3Delightでも出来るのにMental Rayだけが未だに対応していないのはとても残念でした。
但し、レンダラで解決したとは言ってもビューポート上では色は反映されず、レンダリングしてみないと結果が分からない状態でしたので、調整するのにも一苦労でした。
すると今度はV-Rayにおいて、Particle InstancerのVisibilityのon, offを制御すると色の対応がメチャクチャになったり、Instanced objectとしてNurbs curveを指定すると、Curve Renderを有効にしているのにInstanced objectには反映されなかったりと、Mayaの仕様、Mayaの限界、Mental Rayの仕様、V-Rayのバグと、とにかく次から次へと問題が山積みで、シーンのセットアップだけでも相当大変でした。Mayaの深いところまで意識したCG映像制作は今回が初めてだったのですが、5分間の映像でこれだけ仕様やバグに悩んだと言うことは、大作ハリウッド映画クラスのVFXチームなんかは一体どれだけ大変なのだろう…なんて思ったりしました。
かなり大変だったプロジェクトが先日無事に公開されました。今回は、まさにサイエンスCGの最前線である「データの可視化」について、このプロジェクトを通じて掘り下げてお話しします。
まずは、何はともあれ、完成した作品をご覧下さい!
マルチスケール・マルチフィジックス心臓シミュレータ UT-Heart
東京大学が中心となり、理化学研究所や富士通の協力によって開発された心臓シミュレータ「UT-Heart(http://www.sml.k.u-tokyo.ac.jp/)」。その緻密で膨大なシミュレーションデータを完全に正確に、そして美しく、楽しく可視化、映像化させて頂きました。
数値データをMayaに取り込む
先生方と何度も打ち合わせを行い、短い時間の中でエッセンスを凝縮したストーリーを作り、映像化するために必要な技術的課題を1つずつクリアしながら作品を作り上げていきました。…と言うと何とも美しい流れに聞こえますが、実際にはこんなに一直線にものごとは進みません。と言いますか、ストーリーを作ってから「じゃあこのストーリー(絵コンテ)通りの映像作っておいてね。」とデザイナーやプロダクションに丸投げすると悲劇が起こります。
技術的に何が出来て、何が難しくて、どのくらいの時間がかかりそうか、と言った課題を最初から分かった上でストーリーを作ることが不可欠です。これが、3DCGのことを何も分かっていない状態で、ただ格好良いストーリー、演出を並べると、「いや、それ、確かに格好良いですけれどもどうやって映像にするんでしょうか…」と言う事態になったり、「え、3DCGってなんでも簡単に出来るんじゃないの?」という事態に陥ります。これはサイエンスCGに限ったことではなく、割とどこでも良く見られる光景だと思いますが。
このUT-Heartの心臓は映像の冒頭にもあるように、小さな四面体がぎっしりと詰まって出来ており、有限要素法によって動きの計算が行われています。と言うわけで、シミュレーションデータは、数万頂点の座標と、十数万の各四面体の頂点番号と、各頂点や四面体に紐付いているエネルギーや圧力などの情報が記録されている長~い数値ファイルです。
まずは、データ構造を理解した上でMayaに取り込むところから始めなければいけません。もっと言えば、そもそも取り込めるのか、と言うところから始まるわけですが、まぁこれはデータをこねくり回して最も簡単なobjファイルあたりで掃き出すようにスクリプトを書けば出来ないことはないでしょうから、何とかなる気がします。
一応、研究者の先生方が普段使われている可視化ソフトウェアから表面ポリゴンだけを取りだしてVRMLフォーマットでExportが出来る、とのことで、とりあえずVRMLで出力。Mayaは何故か未だにVRMLをダイレクトには読み込めず、wrl2maを間に挟むか、他のソフトウェアでobjなどに変換しないといけないので(何とかしてほしいことの1つです…)、objに変換。スクリプト1行も書かずに取り込むだけ取り込んでみました。すると…
原点のあたりに小さく何かが見えます。拡大してみると…
ありました!心臓!!
…あまりにも小さすぎて、且つWorld Upと心臓の上下方向とが全く合っておらず、これでCG映像を作るのは相当大変、と言うことが一瞬にして分かりました。 しかも、VRML出力をした、と言うことは、各頂点に紐付けられていたエネルギー消費量などの値は全て削除されてしまっており、後から紐付けようにも可視化ソフトウェア上でどのような表面抽出アルゴリズムが使われたのかがわからないため、もともとのどの頂点がVRMLフォーマットでどの頂点になったのか知る由もなく、手も足も出ない悲壮感が漂ってきました。
最初から頂点カラーを付けておけばまぁ何とかなると言えばなるのですが、Mayaはobjファイルの頂点カラーを読み込んでくれません。…と、ここでAutodeskの方からご指摘を頂いたのですが、objファイルフォーマットは公式には頂点カラーはサポートしていないそうです。なるほど、非公式ならしょうがない…と思ったのですが、しかしですね、Autodeskの無料の製品でMeshMixerと言うソフトがあるのですが、MeshMixerでは頂点カラー付きobjファイルを読み込めるだけでなく、ファイルの保存で「OBJ Formt with Per-Vertex Color (*.obj)」と言う選択肢があって、頂点カラー付きobjファイルで出力することもきちんとできます。
つまりどういうことかと言いますと、同じメーカーのソフトを使っているのに、同じファイル形式でもMeshMixerで出力されたファイルを、最新版のMayaでも正しく読み込んでくれないと言う事態が起こります。
研究者用のソフトウェアでは、3DメッシュをVRML形式で出力出来ることが比較的多く、前述のwrl2maを用いるとMaya Ascii形式に変換してくれるのですが、ちょっと大きなファイルになるといつまで経っても変換が終わらないのと、ヘルプファイルによると頂点カラーをサポートしているはずなのですが、何故か私のところではいつも頂点カラーが付きません(私の環境がたまたまわるいのかもしれません…)。
ので、他のソフトでVRMLを頂点カラー付きobjファイルに変換するのですが、MeshMixerでは読み込めて、Mayaでは読み込めない、と言う悲しいことになります。
objファイルフォーマットってWavefront(Autodeskが買収)が作ったフォーマットなので、と言うことはAutodeskの製品でobjが読み込めるのであれば、複数のソフトウェア間で最も古い最新版のソフトに合わせる形で同じように読み込めて欲しいわけですが、Mayaでは何をどうやってもobjファイルの頂点カラーが無視されます。スクリプトを数十行書けば読み込める話ではあるので、標準機能として改善することは特に難しくないと思うのですが…。
…と、書いてこの原稿をAutodeskに送ったら、なんとAutodesk直々に頂点カラー付きobjファイルのimporter MELスクリプト&DLLを書いて下さいました!!AutodeskさんGood Job!!
MELスクリプト版は最近のMayaであれば動くはずです。DLL版はMaya 2013 Ext以降のみでの動作ですが、MELスクリプトを参考にすれば各自でプラグインとして書けるかと思います。
スクリプト&DLLはこちらになります。
ただ、仮に頂点カラーを読み込めたとしても、やっぱりここの色はもうちょっと明るくして、とか、色の数をもっと増やして、とかを後からその場で自由にいじることは出来ません。
…これは1から全てスクリプトを書かなければ…
Python
そこで、Pythonでスクリプトを書くことにしました。と、ここでまた大きな壁にぶつかります。そうです、私はこの時点でPythonに触れたことが一度もなかったのです…。と、ここで、私はそのまた昔、中学生のときにパソコン部に所属し、Cやらアセンブラやらを勉強して一応は自分でレイトレーシングやボクセルレンダリングやらのプログラムを書いていました(当時の3DCG画像などはこちら)。だったら自分で勉強すれば良さそうなものですが、勉強するにもあまりにも久しぶり過ぎてどこから手を付ければ良いのか全く分からない状態でした。
そこで今回、中学時代のパソコン部の伝手を辿って行き着いたのが、パソコン部の1学年先輩だった小田啓太さん。現在はプロのプログラマーで、Pythonもバリバリ書かれ、アルゴリズム考案などもこなしていらっしゃる偉大なる先輩です。
MayaがPythonにフル対応していることのメリットは非常に大きく、Mayaの機能に繋ぐ部分以外はMayaのことは何も知らなくてもコードを書くことが出来ます。Pythonは世界中で使われている言語ですので、ノウハウやテクニックも山のようにあります。
今回のように数値データを扱う案件の場合、特にその恩恵は大きく、私がこれまでのMayaの経験や知識などから、「このようなリストでデータを取り出せるようにしておいて頂ければ、最後の部分は私がコードを書いて、Mayaの中に取り込めるのですが…」とお願いすると、小田さんがあっと言う間に該当部分のコードを書いて下さいました。
小田さんのあまりにも美しいコードを目の当たりにし、コードを紐解いていくことで、私自身もある程度、基礎的な部分ではありますがPythonコードを書けるようになりました。
これで何もかもが上手くいく!…はずだったのですが、今度はMayaの仕様・制限に悩まされることになります。
Mayaの限界?
心臓の表面の各頂点の座標をPython経由で自由に扱えるようになったので、頂点ごとに心臓1拍分のkey frameを打って見事心臓の動きをMaya内で再現!…と思ったのですが、全く上手くいきませんでした。結論から言いますと、Mayaが完全にフリーズしました。試しにkey frameを打たずに100フレーム分動かしてみるとサクサク動く。ところが、key frameを打とうとすると100%フリーズする。
最初は訳が分からなかったのですが、色々調べていくうちにこれがMayaの限界であることがわかりました。私はMaya以外の3DCGソフトウェアに関してはほとんど知らないのですが、Mayaの場合、頂点にkey frameを打つと全ての頂点に1つずつアニメーションカーブのノードが作られるのですが、Mayaはノードが増えると急激に処理が重くなり、2000ノードくらいまでは何とかいけるのですが、私の環境では5000ノードでは確実に動かなくなります。
せっかくデータの受け渡しが出来たのに、Mayaの仕様でアニメーションが作れない…。
色々あれこれ検討した結果、最終的にはGeometry Cacheを取って解決することが出来ましたが、複数オブジェクトを1つのオブジェクトとして認識させたりするところに工夫が必要だったりと、なかなかに大変でした。
こうして何とか心臓1拍分の動きを完全にMayaに取り込むことが出来たわけですが、途中で滑らかに心拍数を変えようと思った場合、Animation Clipであればカーブを1本描けば自由に滑らかにループの速度を変えられるのに、何故かGeometry Cacheの場合には速度一定の単純なループ再生しか出来ず、ここでもMayaの仕様に一苦労しました。
動きだけならまだしも、頂点カラーアニメーションはMayaの標準機能ではどうにもならず、結局、フリーのカスタムノードをフル活用して何とか実現しました。
最終的にはこのように心臓を動かしながら、その場で頂点カラーをRampで調整出来るようなワークフローを作りました。デザイナーがデザインの観点から操作し易い方法を私なりに考えて作りました。
今回諦めなければいけなかったのが、Particle Instancerを用いたInstanced objectの複雑な制御。Instance化したいオブジェクトの動きが単なる回転ではなく親子構造になっていて、親だけが動いたり子も動いたりといくつかに場合分けされるケースがあったのですが、Paritcle Instancerでは親オブジェクトのPivot位置で親オブジェクトしか動かすことが出来ません。せめて、Particleの情報をDriven Keyあたりに接続出来るようにしてくれれば良いのですが、そのような自由度は無いようで、泣く泣く諦めました。気合いでカスタムノード作れば出来た…のかもしれませんが。
Mental Rayの限界?
Mental Rayの仕様にも悩まされました。これはもう何年も世界中で多くのCGクリエーターの間で3DCGコミュニティなどで質問され続けているにも関わらず、悲しいことに未だに対応されていない事実なのですが、Mental RayではParticle InstancerにrgbPPの値をマテリアルのdiffuseなどにoverrideさせることが出来ません。何をどうやっても出来ません。私も改めて世界中のMayaコミュニティの方々に質問しましたが、「何をどうやっても出来ません。」と。これは数値の可視化にとって致命的です。
いわゆるData Visualizationの世界では、数値情報を色に置き換えるのはごく当たり前に行われている手法です。と、言いますか、基本中の基本です。3DCGで大量のデータを扱う場合にはParticleで制御するのが常套手段だと思いますが、Particle Instancerに個別の色(そして実は透明度も…)を指定出来ないと言うことは、MayaではData Visualizationは出来ない、と言う結論になります。
結局これについてはV-Rayを採用することで解決したのですが、V-RayでもRendermanでも3Delightでも出来るのにMental Rayだけが未だに対応していないのはとても残念でした。
但し、レンダラで解決したとは言ってもビューポート上では色は反映されず、レンダリングしてみないと結果が分からない状態でしたので、調整するのにも一苦労でした。
すると今度はV-Rayにおいて、Particle InstancerのVisibilityのon, offを制御すると色の対応がメチャクチャになったり、Instanced objectとしてNurbs curveを指定すると、Curve Renderを有効にしているのにInstanced objectには反映されなかったりと、Mayaの仕様、Mayaの限界、Mental Rayの仕様、V-Rayのバグと、とにかく次から次へと問題が山積みで、シーンのセットアップだけでも相当大変でした。Mayaの深いところまで意識したCG映像制作は今回が初めてだったのですが、5分間の映像でこれだけ仕様やバグに悩んだと言うことは、大作ハリウッド映画クラスのVFXチームなんかは一体どれだけ大変なのだろう…なんて思ったりしました。