2009年04月26日

Blender Partyに参加しました

昨日25日に東京の神保町で行われたBlender Party @Tokyo,Japan 2009に参加させていただきました。
当日は天気があいにくの雨で、強風などの注意も必要という天気予報でしたので、電車が止まったりしないか不安でしたが、無事に開始時間に会場に到着できました。

私はどちらかというとコミュニケーション能力があまり高い方ではなくて、初対面の方とお話したりするのは得意ではないのですが、yamyamさん、真猿さん、藤堂+さんなどと同席させていただいて、色々とお話を聞くことができました。
私はまだBlender関連のサイトを十分に把握できていなくて、ハンドルネームを聞いてもその方がどのようなサイトを運営されているのか、どのような作品を作られているのかが分からなかったりして、少々とまどってしまいました
。事前にもう少し調べておけばよかったかなと反省しています。

イベントの方は、上映会、実演共にとても楽しめました。実演をされたトニーさん、ekakiyaさん、shigeさん、大変勉強になりました。ありがとうございました。

そして、前回の記事に書いたようにVFXコンテストに私も応募させていただいていたのですが、なんと審査員特別賞の3番目に選んでいただきました。少しでもイベントを盛り上げることに役に立てたら...というつもりで作ったのに、賞品をいただいてしまって、なんだかとても申し訳ない気持ちです。(賞品はほとんどが関係者の方の自腹とのことです。)投票していただいた皆様、賞品を用意していただいた皆様、本当にありがとうございました。
ちなみに1番となったのは、FDTKさんの「BLUE HERO & Making」、2番はnaokiさんの「Polt」 という作品です。おめでとうございます。

当日の様子をライブ中継した動画がこちらで見られるということです。私も少し拝見させていただきながら、この記事を書いています。

オフ会というものに参加したのは今回が初めてなのですが、Blenderという共通する言語のある人と直接会うことができ、とても貴重な体験をさせていただくことができました。このような会を開催して下さった皆さんに、とても感謝しています。幹事をされたまんださん、グリマーさん、daywalkerさん、ありがとうございました。

posted by mato at 21:26| Comment(2) | Blender | このブログの読者になる | 更新情報をチェックする

2009年04月21日

BPTJ2009のVFXコンテスト

4月25日(土)18:00から、Blender Party @Tokyo,Japan 2009 が東京の神保町 ダイニングカフェ・エスペリアで開催されます。私も参加させていただく予定です。Blender Patyについての詳細はこちらをご参照ください。

これに合わせて行われているVFXコンテストに私も応募させていただきました。コンテストにエントリーされている全ての動画は、こちらで確認できます。

私が応募した動画はこちらになります。
動画の中で使用しているのは、Poser用フィギュアとして公開している「くるる」をBlender用に移植している途中段階のものです。まだ、色々と設定が詰まっていないので正式に公開していませんが、このブログでも以前サンプルデータとして使ったりしています。

作成した動画は16秒と短めです。内容は、机の上でフィギュアになりきっているつもりのくるるさんが、カメラに見つかって焦っているというシーンを作りました。
pic090421_16.jpg

ちなみにくるるさんのまわりにある本物のフィギュアですが、こちらはスペインのリヤドロという陶器のフィギュアです。ちょっと値段が高めですが、デパートの洋食器などの贈答品の売り場に置かれていることがあります。もし実物を見ていただけたら、その造型の素晴らしさに驚かれるのではないかと思います。機会があったら、探してみてください。

ということで、今回は少しプログラミングのことから離れて、応募した動画のことを書いてみようと思います。
このコンテストのテーマとなっているのが、実写映像と3DCGの合成です。私はカメラトラッキング(マッチムーブ)ソフトというものを初めて使用しました。カメラトラッキングのために使用したのはVoodooというソフトウェアです。
pic090421_01.jpg pic090421_04.jpg

カメラトラッキング自体が今回初めて体験するものだったのですが、少しだけ使ってみた範囲では、なかなか思い通りのカメラ設定を得るのは難しいように感じました。使用する素材の動画の内容によって状況がかなり変わってくると思いますが、
  1. エンコードによって画質が落ちている場合、得られるカメラデータの精度も落ちる。
  2. 短い時間ならきちんとしたカメラデータが得られる動画でも、ある程度以上の長さをまとめて解析しようとするとうまくいかない。
というようなことを、実際に作業した中で体験しました。

一度解析が終わった後で、さらにデータを修正することでカメラデータの精度を向上させることもできるようですが、今回はそこまでする時間の余裕がありませんでした。机の上を撮影した動画はいくつか試した中では比較的良好なカメラのデータが得られました。上の画像に映っている猫の動画では、映像とカメラの動きが今ひとつ一致しませんでした。


カメラトラッキングを使っていることというのが今回の動画で一番の重要項目ですが、それ以外にも何点か工夫している部分がありますので、ここからはその辺りについて書いてみたいと思います。

まず、キャラクターの髪、衣服にはクロスシミュレーションを使用していますが、メッシュの形状自体をシミュレーションするのではなく、より少ない頂点数のメッシュでシミュレーションを行い、実際の形状の変形はそれらのシミュレーション用のメッシュに追従させたアーマチュアによって行っています。
pic090421_15.jpg

このように実際にレンダリングするメッシュとシミュレーションのメッシュを分離するという方式は、そのままシミュレーションするよりもセットアップに手間はかかりますが、一度設定を完了してしまえば色々と応用ができる可能性があります。
  1. IPOカーブにベイクすることで自由に編集できる。
  2. 同じシミュレーション設定で全く別の形状を動かすことができる。
今回、衣服のシミュレーションを普通に行うとキャラクターがくしゃみをする動作の反動で激しく変形しすぎてしまい、パラメータの調整だけでは制御が難しい感じになりました。これに対して、シミュレーション用のメッシュで裾の部分を本来よりもかなり長めに伸ばすことで、変形を抑えるようにしています。
pic090421_06.jpg pic090421_07.jpg

髪についてはシミュレーション結果をそのまま使用していますが、服の方はキャラクターのボディーが貫通する部分がかなりあったため、シミュレーションした結果をIPOカーブで編集できるようにベイクし、手動でキーフレームの調整を行っています。

以前、Vimeoにアップした動画では一定の間隔でキーフレームを間引くようにして、残したキーフレームを調整するというような方法を行いました。
しかし、今回の動画では瞬間的にかなり大きな変動が起こるため、キーフレームを間引くことはせず、全フレームにキーフレームを打った状態のままで使用しています。この場合、問題の起こっている部分のキーフレームを全て手作業で修正するというのは困難なため、
  1. まず、ボディーが服を貫通しているフレーム位置を調べ、特定のボーンについてある程度の範囲にわたってキーフレームを削除する。
  2. ボディーが服を貫通しないようにボーンの回転を調整し、適当な位置にキーフレームを打つ。
というような形で修正しました。
pic090421_08.jpg

この辺りについては、NLAエディタを使用すれば変形を修正するためだけのアクションを作成することもできますし、もっとうまく修正する方法があるかもしれません。


そして、もう一つ工夫した点を上げるとすると、髪のレンダリングの部分でアンチエイリアスがうまく利かなかったのを修正していることです。これについては、もしかすると何かのスイッチで解消できるのを私が知らないだけだったのかもしれませんが、「Render」パネルのOSAの値を変えたり、マテリアルの「Links and Pipeline」パネルでFull Osaを使用してもうまく回避できませんでした。

下の画像を見ていただくと、影の暗い部分の形がフレームごとに全く違う位置、形状になっているのがわかると思います。動画として再生する場合、この部分はちらちらと明滅するように表示され、せっかくカメラトラッキングで実写映像と動きを合わせていても、映像的にとても違和感のあるものになってしまいます。
pic090421_09.jpg

これに対する解決策としては、一旦倍の解像度でレンダリングしたものをもとの解像度に縮小する、ということでかなり改善できました。
pic090421_10.jpg

ただし、画像全体に対してこれを行ってみたところ、髪以外の部分では元のレンダリングにくらべて画像がぶれているような感じになってしまい、これはこれでちょっと問題があるという状況になりました。最終的には、髪だけを部分レンダリングしたものをアニメーション出力し、元の画像と2倍にレンダリングしたものを合成しています。
pic090421_11.jpg pic090421_12.jpg

pic090421_13.jpg pic090421_14.jpg

本来ならば、髪の部分だけを2倍にレンダリング、縮小を行った画像をオリジナルに合成すればいいのですが、今回は試しに全体を2倍サイズでレンダリングしてみたものが既に作成済みだったため、上のNode Editorの画面では髪の部分レンダリングはアルファ値のみを使用しています。
posted by mato at 01:16| Comment(2) | Blender | このブログの読者になる | 更新情報をチェックする

2009年04月13日

vectexをマルチスレッドレンダリング対応にする(2)

前回、Blenderのマルチスレッドレンダリングで排他制御を行う関数をテクスチャプラグインから使用できるようにしました。Blenderの内部ではBLI_lock_thread()、BLI_unlock_thread()という関数名になっていましたが、実際にエクスポートしている関数はlock_thread()、unlock_thread()という名前にしてあります。あとは、vectexのソースコードの中から、マルチスレッドレンダリング時に問題が起こっている部分を探し出して、その部分をエクスポートした関数で挟み込むだけです。

と、言葉で書くと簡単そうなのですが、このプログラムがどんな風に動作しているのか全然わからない状態では問題のある場所を探すのは難しそうです。それほど行数が多いわけではないのですが、vectexの内部で重要な役割を果たしているミップマップの処理は、レンダリング時のカメラの設定次第で(描画されるポリゴンの面積がどのような状態になるかによって)挙動が変化するので、ソースコードを眺めるだけで処理の流れを追うのは難しそうです。

ありがたいことに、vectexのソースコードには開発時に使われたデバッグ用のコードがそのまま残っています。コンパイル時にMakefileの一部を修正すると、ソースコードに埋め込まれたマクロが有効になって、Blenderを起動させたコンソールにデバッグ用の文字列を出力させることができます。

INC=-fPIC -shared -O -ansi -Iblender -Iagg-2.5/include -Iexpat-1.95.8/lib
# -DDEBUG

この部分で「#」を削除して、「-DDEBUG」をINCの定義のオプションに追加します。

INC=-fPIC -shared -O -ansi -Iblender -Iagg-2.5/include -Iexpat-1.95.8/lib -DDEBUG

pic090413_01.jpg pic090413_02.jpg

「DEBUG」定数が設定されるとvectex.hに書かれたマクロが有効になり、vectex.c、vectex_agg.cppの各関数内に埋め込まれたマクロがprintf()関数に展開されます。
pic090413_03.jpg
#ifdef DEBUG
#define MSG0(F)         printf(F);
#define MSG1(F,A)       printf(F, (A));
#define MSG2(F,A,B)     printf(F, (A), (B));
#define MSG3(F,A,B,C)   printf(F, (A), (B), (C));
#define MSG4(F,A,B,C,D) printf(F, (A), (B), (C), (D));
#else
#define MSG0(F)
#define MSG1(F,A)
#define MSG2(F,A,B)
#define MSG3(F,A,B,C)
#define MSG4(F,A,B,C,D)

#endif
例えば、vectex.cの中のcreate_tile_set()という関数の中には、2つのMSGマクロが埋め込まれています。
pic090413_13.jpg
...
MSG0("[create_tile_set]\n");
...   
MSG2("- created tile set max_pow=%d size=%d\n", instance->tile_set_max_power, size);
...
この関数create_tile_set()が実行されると、コンソール画面に「create_tile_set」「-created tile set max_pow= xxx size= xxx」というように表示されることになります。逆に言えば、コンソール画面に表示される内容から、ソースコードのどの部分が実行されたのかがわかるということになります。

ということで、早速、DEBUGモードでコンパイルされたvectexを使用して、vectexに付属のサンプルtest-static.blendでのレンダリングの過程を調べてみたいと思います。
Blenderを起動し、test-static.blendを開いた直後のコンソール画面です。
pic090413_04.jpg
[plugin_tex_getversion]
[plugin_getinfo]
[plugin_init]
[plugin_instance_init]
- plugin started enabled
[create_instance]
[create_backend]
- open ok
[create_tile_set]
- created tile set max_pow=8 size=9
> creating tile #8 res=256 [0,0]


スレッド数を1にしてレンダリングしてみます。
pic090413_05.jpg
- growing tile set max_pow=10 size=29 old_size=9
> creating tile #26 res=1024 [3,1]
> creating tile #11 res=512 [1,0]
> creating tile #27 res=1024 [3,2]
> creating tile #12 res=512 [1,1]
> creating tile #9 res=512 [0,0]
> creating tile #7 res=128 [0,0]
> creating tile #28 res=1024 [3,3]
> creating tile #13 res=1024 [0,0]
> creating tile #6 res=64 [0,0]
> creating tile #5 res=32 [0,0]
> creating tile #4 res=16 [0,0]
> creating tile #3 res=8 [0,0]
> creating tile #22 res=1024 [2,1]
> creating tile #23 res=1024 [2,2]
> creating tile #18 res=1024 [1,1]
> creating tile #17 res=1024 [1,0]
> creating tile #25 res=1024 [3,0]
> creating tile #21 res=1024 [2,0]
> creating tile #1 res=2 [0,0]
> creating tile #0 res=1 [0,0]
> creating tile #2 res=4 [0,0]
- growing tile set max_pow=11 size=93 old_size=29
> creating tile #70 res=2048 [5,1]
> creating tile #78 res=2048 [6,1]

1枚の画像をレンダリングするだけで、かなりたくさんのテクスチャが生成されているようです。

今度は、test-static.blendを読み込んでスレッド数4でレンダリングします。レンダリングが途中でフリーズした状態のコンソール画面へのデバッグ出力です。
pic090413_06.jpg
[plugin_tex_getversion]
[plugin_getinfo]
[plugin_init]
[plugin_instance_init]
- plugin started enabled
[create_instance]
[create_backend]
- open ok
[create_tile_set]
- created tile set max_pow=8 size=9
> creating tile #8 res=256 [0,0]
- growing tile set max_pow=10 size=29 old_size=9
> creating tile #27 res=1024 [3,2]
> creating tile #26 res=1024 [3,1]
> creating tile #11 res=512 [1,0]
> creating tile #7 res=128 [0,0]
何回かレンダリングすると、その時々で出力される内容は変わりますが、「creating tile ...」というようにデバッグ出力している関数、あるいはそこから呼ばれている関数を実行している途中でレンダリングがフリーズしているようです。

「creating tile」という文字列が出力されるMSGマクロは一つだけで、449行目のget_tile()という関数の中です。get_tile()関数の中を見てみると、memory_alloc()、memcpy()、memory_free()などのメモリ処理に関わる関数がたくさん使われています。
pic090413_07.jpg pic090413_08.jpg

この関数の中のどこかで問題が起こっていそうなのでそれを調べてみてもいいのですが、とりあえずはこの関数を呼び出している部分を探して、get_tile()関数の呼び出し部分をlock_thread()、unlock_thread()で囲んでみたいと思います。検索してみると、get_tile()関数を呼び出しているのは507行目と547行目の2ヶ所だけで、sample()という関数の中です。
pic090413_09.jpg pic090413_11.jpg
...
lock_thread(LOCK_IMAGE);
int index = get_tile(instance, x, y, power);
unlock_thread(LOCK_IMAGE);
...
このようにlock_thread()、unlock_thread()関数、LOCK_IMAGE定数を使うには、これらのプロトタイプ宣言が書かれているutil.hをインクルードする必要があります。
...
#include "plugin.h"
#include "util.h"

#include "vectex.h"
...
vectex.cを以上のように修正し、vectexのソースコードのblenderフォルダ内にあるutil.hを前回作成したBlender修正版のものに置き換えれば、コンパイルの準備が完了です。コンパイルしてできたvectex.soファイルをBlender修正版で読み込んでtest-static.blendをレンダリングしてみると、スレッド数4でも問題なくレンダリングが完了しました。
pic090413_12.jpg

lock_thread()、unlock_thread()関数を使用する場所については、get_tile()関数の中をもっと調べて本当に問題の起こっている部分だけを囲むようにした方がいいのかもしれませんが、動作に問題がなければこのままでもよさそうです。

こちらに今回の修正版vectexを置いておきます。

vectex_modified2.zip

このvectexは前回作成した修正版Blender専用となります。通常のBlenderからは使用できませんのでご注意ください。
posted by mato at 22:03| Comment(0) | Blender | このブログの読者になる | 更新情報をチェックする
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。