スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
[Houdini] VEX の習得
今更ながら VEX の勉強をしています。

先日、VEX メインの某チュートリアルを見ながら
同じものを VOP で実装しようと頑張ってみたのですが、途中で明らかに限界を感じました。
VOP も時には便利なのですが、足し算や掛け算をするだけの為にノードを接続していくのは手間が多すぎるし
何よりも for や if などの分岐の実現があまりに大変で見難いです。

これ以上あまり多くの言語を習得する事は少し敬遠していたのですが
これをきっかけに VEX も習得せねば、と一念発起して勉強することにしました。

そしてとりあえずこんな動画を作ってみました。



結果だけ見ると大したものではなく、
これくらいなら Attract などを使えば一瞬で作れそうなものですが、得られたものは大きいです。
基本的には最も近いポイントを探して避けたり止まったりするだけなのですが、
おかげで VEX の基本的な書き方は大体把握できました。

これを作りながら気づいた、VEX だと非常に手間が省けるもう1つの事が、
今までは VOP で Point Cloud Open や Primitive Attribute の入力でノードを使用する場合は
File パラメータを Promote して op:`opinputpath(".",0)` と入力して…とわざわざ行なっていたのですが
VEX では整数で入力のインデックスを用いることでそのままノードが指定できるようです。
これは非常に便利だし分かりやすいです。

丁度 Houdini の最近のバージョンでは Wrangle や VEXpression といった、
VEX を利用した仕組みが増えてきているので、特に多岐に渡る目的で活用できます。

実際、最近久しぶりに Houdini を使って仕事をさせてもらっているのですが(なんと約半年ぶり)、
ここで身につけた知識が既にすごく役立っています。

ソフトウェアになんだかんだ機能がついて色々なことが簡単にできます、というのもいいのですが
結局は低水準なところまで手が届くのが一番だなぁと感じます。

今度は簡単なシェーダーも VEX で書いてみたいと思います。
スポンサーサイト
事の発端は今から数年前。
ニコニコ動画で見たこの動画に興味を抱きました。



調べてみたところ、Wikipedia の遺伝的アルゴリズムの説明が
非常に分かりやすく、なぜこのようなことができるのか、
果てはどのようなコードを書けばいいのかまで分かります。

というわけで詳しい仕組みなどは割愛するので
もし気になるなら上のリンク先をご覧ください。
意外にも仕組みは単純です。

差し当たり当時このページを見ながらC言語で簡単に実装してみることはできました。
そして Maya で似たようなものはできないものかと思ってはみたものの、
そもそも Maya では1つのオブジェクトにデフォーマとダイナミクスの両方を適用する
ということさえできないため、即座に断念していました。

数ヶ月前、Houdini で簡単に再帰ができることが分かったときに、
このソフトなら同じようなものが作れると確信しました。
Houdini ではデフォーマとダイナミクスの両方を適用するのも造作ないことです。

しかしまだ当時はどうすれば実装できるかまでは分からなかったため、
もっと Houdini の理解が深まってきてから作ってみようと考えていました。

そして最近になって大分理解が深まってきたため、
空いた時間に少しずつ進めてきた結果…

ついに先日、それらしいものが完成しました。



シンプルな八角柱のオブジェクトに3本の Bone を仕込み、
そのうちの2本の回転情報を変数として
参考にさせていただいた上の動画と同様に、
単位時間あたりの最大移動距離を遺伝的アルゴリズムで最適化しました。

Point や Detail などの外部から値を読み込む基本的な Expression を除いて
一切コードは書いておらず、全てノードのコネクションだけで実装しています。

img20120722.gif

この動画で使用しているアルゴリズムでは
遺伝子の個体数4、各遺伝子の成分数6、
選択方式はルーレット選択(適応度は移動距離の2乗)、エリート選択あり、
交叉方式は二点交叉、突然変異率10%です。

これで比較的速く収束するようになったものの、
こんなにシンプルな問題でも
ほぼ最適解となった第216世代までは計算に約78分もかかってしまいました。

恐らくもう少し工夫するだけで計算時間を大幅に短縮できるはずなので、
計算時間が短縮できてきたらもっと複雑な形状でも作ってみたいと思っています。

Houdini での条件分岐,ループや再帰などの計算の流れは
ある程度自由に操作できるようになりました。
まだ使い方のよくわからないノードも沢山ありますが、
もう Houdini 初心者から脱却できてきたのではないかと思います。


…ところで「こんなの映像制作の何の役に立つんだ」と思われる方もいるかもしれませんが。
はい、その通り何の役にも立ちません。

しかし今回は Houdini を自由に操れるようになることが目的なので
それは無事に達成することができたし、
進化的アルゴリズムを Houdini で実装するということ自体は決して無駄ではなく、
この本旨はあらゆるパラメータの値を自己学習させるということだと思っています。

エフェクトアーティストがパラメータの値を何度も変えて試行錯誤することなく
最適なパラメータを勝手に割り出してくれるようになれば
少なからず役の立つものになるはずなのではないかと思います。

これで既に土台はできたので、少しずつ応用してもっと興味深いものを作っていきたいです。

Houdini から obj データを Export する際の
データサイズを極力削減する方法を考察してみました。
基本的には非可逆圧縮のようなものなので多少
品質が落ちることは覚悟の上です。

まずは Vertex (頂点) の座標値。
X, Y, Z の3つの値がありますが、各々が小数点以下8桁もあります。
場合によっては第3位や第4位くらいまで正確な値じゃないと困る
という場合はあるかもしれませんが
8桁も必要な場合はまず無いと思うので、これを丸めます。

例えば小数点第2位で丸める場合、ジオメトリの後に Point ノードを接続して Position を各々

round($TX * 100)/100, round($TY * 100)/100, round($TZ * 100)/100

に設定します。

img20120327_01.gif

Details View を見てもちゃんと丸められるので一見問題なさそうですが、
実際に Export すると2進数に丸められてしまうため 0.5 や 0.25 といった数でない限り
結局8桁になってしまいます。

img20120327_02.gif

差し当たり考えた解決策として、以下のいずれかによって解決できます。

①整数で出力し、入力側でスケーリングをかける
②外部からファイルを書き換える

①は上の例で言えば "/100" を入れずに 100 倍にスケーリングされた状態で出力し、
obj ファイルをインポートするときにで 0.01 倍にスケーリングをかけるだけです。
②は適当な言語でファイルを読み書きして空白を頼りに数字を取り出して丸めて上書き。
差し当たり Python で作ってみたのがこちらです。
小数点第二位で丸めてくれます。

import sys
file = open('test.obj', 'r+')
lineList = file.readlines()
file.seek(0)
for line in lineList:
write = ''
elemList = line.split(' ')
if elemList[0] == 'v':
write = 'v '
for elem in elemList[1:]:
num = round(float(elem),2)
write += str(num) + ' '
write += '\r\n'
else:
write += line
file.writelines(write)
file.truncate()
file.close()


さて、次は平面の定義部です。
頂点の番号・テクスチャ座標・法線ベクトルがありますが
透明や単色の液体などはテクスチャ座標を必要としないので省略できます。
法線ベクトルも、液体などの全てソフトエッジでいいものや
前回紹介したような幾何学図形などの全てハードエッジでいいものなどは
インポート側で調節がきくはずなのでわざわざ記述する必要はありません。
特にこの両方を省略すれば間の "/"(スラッシュ)の記述もなくなるため
例えば全て1桁の場合は 1/5 の記述で済むことになります。

テクスチャ座標をなくす方法は以下のいずれか。
① Attribute SOP を接続して Point の Delete Attributes に "uv" と入力
② Point SOP を接続して Keep Texture を No Texture に変更
③ UVTexture SOP を接続して Apply To を Vertex texture に変更

法線ベクトルをなくす方法は以下のいずれか。
① Attribute SOP を接続して Point の Delete Attributes に "N" と入力
② Point SOP を接続して Keep Normal を No Normal に変更

もちろん両方をなくす場合の Attribute SOP や Point SOP は同一のもので構いませんし
元々アトリビュートを持っていない場合はこれを行う必要さえありません。


仮に適当な分割数のポリゴンの Utah Teapot に対して
これら全てを行なったものと行なっていないものを比較すると
878,579 byte だったものが 212,934 byte に。
75 %以上もの削減に成功しました。

これでもまだ重いという場合は、明らかに品質が落ちる可能性が高いですが
恐らく Poly Reduce SOP でポリゴン数自体を減らすしかないと思います。


Houdini を始めてみました。
実は数ヶ月ほど前から使い始めてはいたのですが
最初はインターフェースの操作を覚えて、
それからしばらく簡単にセットアップできる範疇で適当に流体を作って遊んで
その後は SOP, POP, DOP の各ノードを1つずつマニュアルを見て日本語訳してメモをとりながら
ノードのはたらきを把握していきました。

そして多少はオリジナリティのあるものを作れるようになってきたため
やっとこうしてブログの記事にできるようになった次第です。

さて、先日とあるブログのリンクを辿ったりしながらこちらのページを発見して分かったことには
POP の性質をうまく利用すればなんとたった3つのノードを接続して
いくつか適切な設定を施すだけで"再帰"が実現できるとのこと!
これはすごいことです。

Houdini には "L-system" という SOP だけでフラクタル図形を作成することもできるのですが
恐らくあまり自由に何でも作れるというわけでないことと
設定の方法がかなり独特なので敬遠していました。

しかし POP を利用したこの方法ならかなり自由にフラクタル図形が作成できそう。
というわけで作ってみました。



フラクタルの王道 Sierpinski Gasket の正四面体バージョン、再帰回数は8回です。
立方体の場合はメンガーのスポンジというらしいです。

Houdini でも Flipbook という Maya の Playblast のような機能はあるのですが
上の動画では Maya にインポートしてから Playblast しています。

img_20120315_1.png

POP ネットワークはこんなかんじ。
外部(SOP)から正四面体の情報を入力させて計算するようにしているので
入力を切り替えれば他の形でもできるはずです。
ただしこのネットワークではご覧の通り
Velocity ノードを頂点数分つながないといけないのでそこが問題です。
可変長の Vector 型配列みたいなかんじで格納できればいいのですが
何か方法があるのでしょうか。。

ずいぶん前に Maya で MEL や Expression を利用して幾何学的なものを作ろうと
一念発起したことがありましたが、
Houdini ならプログラミングなんてできなくてもパズル感覚でこういったものを作ることができます。
流体などのシミュレーションが強みであるソフトウェアだと思っていましたが
実はこういった幾何学的なもののモデリングなんかに関してもうってつけだと思います。

Houdini、楽しいです。
また何か興味深いものができたら記事にしようと思います。
Profile
HN らい

都内某社テクニカルディレクター
都内某専門学校講師
都内某企業講師
元中国某社S3Dスーパーバイザー
Contact
(ENGLISH OK. 可以用中文。)
Categories
Archives
RSS Link
QR Code