little things of mine

from los angeles, california

Category: 開発

PyOpenGLでHDRピクセル

久々に開発ネタです. 最近仕事で必要になり,10年ぶりくらいにOpenGLを触っています.PythonからPyOpenGL経由です.GPU出現以降のmodern OpenGLは真面目に書いたことがなかったので,勉強すること盛り沢山. PyOpenGL — The Python OpenGL Binding PyOpenGLでHDRIを扱う時にちょっと引っかかった問題があったので,忘備録を兼ねてここにまとめます.数年前からリアルタイムでもHDRレンダリングが流行っていたので,知っている人には今更な話題ですが... 解決にあたって@K240さんに多大なる助言を戴きました.有難うございます. さて,今時のVFXたるもの,ピクセル値はHDRがディフォルトです.[0, 1.0]ということはまずない.ライティングや反射マップにはほぼ必ずHDRIが使われるので,ハイライト部分は1.0を超えます.OpenGLでも普通に1.0を超える値は使えますし,GLSLシェーダでもfloating pointで計算ができます. ところが,一度ディスプレイバッファに値が書き込まれてしまうと,どうやらピクセル値は[0, 1.0]にclampされてしまうようなのです.具体的には,glReadPixels()を使って得られる値がclampされています.glCopyTexImage2D()なんかも同じ.これは困る. さらに調べを進めると,どうやらmodern OpenGLにはframe buffer object(FBO)という物があり,オフスクリーンの描画用バッファとして使え,更にデータタイプとして32-bit floating pointが指定できます.つまり,一度このFBOに描画することでシェーダを実行し,そこから値をコピーすることで生の計算結果を取得できます.ただしこのFBOはオフスクリーンなので,結果を画面に表示するには再度ディスプレイバッファに描画してやる必要があります. 計算結果をコピーするにはglGetTexImage()という関数を使うのですが,C言語ではこの関数は値を返さず,結果の書込み先としてポインタを渡すことになっています.しかしPythonにはポインタがありませんから,関数が値を返します.つまり次のように書きます.glGet*()やglGen*()系の関数は大抵こういう仕様になっています. result = glGetTexImagef(GL_TEXTURE_2D, 0, GL_RGBA) そして,ここでハマったのですが,上記で得たresultは三次元配列で,そのレイアウトは[y][x][c](cはチャンネル)となっています.てっきり[x][y][c]だと思い込んでいたので,場所が一致せずに悩んでしまいました... 以下にサンプルコードを置いておきます.これは@K240さんがC++で書いて下さったコードをPythonに移植したものです.実行して表示される画面を左クリックすると,その場所の生ピクセル値がコンソールに出力されます. hdr_pixels.py 今回,GPUで色の計算(カラースペース変換とか)をやってみたのですが,さすがに速いですね.大きな画像だと普通にやるよりマジで何十倍も速いです.Pythonだと何百倍じゃないでしょうか.昔から3Dをリアルタイムでやる事にあまり興味はないのですが,2Dの画像処理を高速化するためにGPUを使うのは楽しそうだと思っています.コンプ作業が楽しくなりそう. 最近だとOpenCLとか使うんでしょうね?もう少し重たい計算もやってみたくなりました. [2011/4/6 追記] どうやらPyOpenGLのglGetTexImage()にはバグがあるようで,テクスチャが正方形でない時に関数が返す配列がおかしいです.ご注意下さい.

オープンソースなCG関係ライブラリ

思いついたので集めてみました. オープンソースと言うと幅が広いですが,自分が今まで見た事のあるVFX/CG系の会社やツールなどで実際に使用実績があり,プロジェクトの種類が(広い意味で)CG関係の物です.boostやQtなどのように一般に広く使われている物,CgやCUDA,FBXのようなフリーでもオープンソースではない物は除いてあります. * 画像・テクスチャ関係 OpenEXR OpenImageIO Ptex OpenFX OpenCV * シーングラフ OpenSceneGraph COLLADA * ジオメトリフォーマット Houdini GPD library GTO HDF5 Alembic * シミュレーションエンジン Bullet Physics Library ODE SOFA * 幾何学関係 Sony Vector Math Library Sony SIMD Math Library CGAL ANN こんなもんでしょうか.結構ありますね.最近は各スタジオが色々公開してますから,普及したらもっと増えるかな.あとはオーディオ関係もいくつかありましたが,良く知らないので除外しました. あ,「どれがどこ(なに)で使われているの?」系の質問は無しの方向でお願いします(笑).

Alembic

SIGGRAPH2010開催中のホットニュース. Alembic こちらでtaikomatsuさんが和訳されています. Alembic – memlog AlembicはILMとSPIが共同で開発及び公開した,アニメーションをシーケンシャルジオメトリにbakeするためのC++ライブラリです.”alembic”という単語には浄化器,蒸留器という意味があるそうで,必要な物だけを抽出する,というようなニュアンスですね. ライティングやエフェクトはアニメーションされたシーンを元にして作業するのが普通なのですが,アニメーターがアニメートしたままの状態だと,リグやその他たくさんのアニメーション以外には必要のないデータも含んでいるし,何しろリグを毎回プロセスするのは色んな作業の邪魔になります.エフェクトなんかはそうでなくても重い作業が多いですからね.シーンも不安定になります.そもそもツールが別でリグが渡らない事も多い.そのため,ある程度の規模のスタジオでは,内部で特定のデータフォーマットを使ってbakeしたアニメーションをやり取りする事が多いのですが,Alembicはそのデータフォーマットとして使う事ができます. シーケンシャルジオメトリのデータフォーマットは,今までこれといった決めてがなくて各スタジオがそれぞれ試行錯誤していると思います.GTOもかなり良さそうに思っていたのですが,AlembicはILMが絡んでいる事からして,GTOを更に改良した物(GTOは元々ILMで使われていた)と考えていいのかも?だとするとこれは良い候補になりそう. ただ,こう言ったプロセスは,ある程度のパイプラインがあって,開発サポートが期待でき,大きなシーンやショット数をこなす必要がある場合に必要になる事だと思うので,規模の小さな場合は逆に手間になってしまう可能性もあると思います.あと,日本の某社の方に教えられたのですが,小さい所ではストレージとネットワークがネックになってしまうとも言っておられました. 今の所,ライブラリの使用例としてMayaのimporter/exporterプラグイン,PRManのprocedural primitive DSO,GTOからのコマンドラインコンバータ,その他ユーティリティがライブラリと一緒に公開されているようです.Pythonバインディングも一応あるようですが,これはまだまだこれからという雰囲気. Houdiniのプラグインもないが,これは自前でやれという事か.

Open Shading Language

OSLのソースと詳細がアップされたようです. fxguide quick takes » Sony Releases Open Source Shading Language openshadinglanguage – Project Hosting on Google Code ドキュメントのみサラッと読んでみましたが,RSLとは見た目こそ似ているものの,設計は随分違いますねえ.このままPRManが今のまま同じ仕様をサポートするのは難しいでしょう.まあ,逆に言えば古いしがらみに捕らわれていない分,新しい事ができる土台になると思います.シェーダがclosureであるとか,light samplingはレンダラ側でやるとか,色々と興味深い. ソースコードにはコンパイル済みシェーダの実行環境もライブラリとして含まれています.これを使って自分のレンダラにOSLを組み込む事ができますし,relightingツールなんかも作れそうですね. 今後の成長が楽しみであります.

OpenImageIO

同僚から,非常に興味深いライブラリを教えてもらいました. OpenImageIO Wiki いわゆる画像ファイルの入出力ライブラリで,OpenEXRやTIFF等,CG作業で良く使われるフォーマットに対応しています.各フォーマットのサポートは対応する外部ライブラリをプラグインする形で実現されますが,このAPIを通す事ですべてのフォーマットを一元的に扱う事ができます. と,これだけなら良くあるマルチフォーマット対応の画像ライブラリと同じで,特筆するような物ではないのですが,実はこのライブラリ,画像ファイルの部分読み,image cachingに加えてfiltered mipmap lookupまでサポートしているのです! なんとマニアックな機能… と思ったのですが,それもそのはず,オリジナルの著者はLarry Gritzでした.恐らくは先日いくつかのオープンソースプロジェクトを公開した,某スタジオの某レンダラで使われているんだろうと推測されます. ざっと眺めた所,まだ改善の余地はたくさんありそうですし,実装されていない機能もあるようですが,賢いimage cachingを書くのはとても大変ですから,レンダラや自前の画像ビューアを書く時にはかなりの作業量を減らす事ができると思います. 画像の入出力って意外と面倒なんですよね.ずっと「コレ」っていうライブラリを探していたんですが,今のところ開発もアクティブみたいだし,どうやらこれが決定版になりそう. ライセンスはmodified BSD,商用利用もOKだそうです.