!!!独り言日記 !!wxAUI(2008/05/29) 今までwxWidgets 2.6.2を使ってたのですが、wxWidgets 2.8.7にアップしてみました(ただ単に面倒くさかったので更新してませんでした)。 で「wxAUI」というのを使うことで、いとも簡単にドッキングウィンドウが実現できますね。 以下のような感じ。 {{flvplayer http://ft-lab.ne.jp/files/tool/docking_window_20080529.flv,width=550,height=400}} 実装方法は以下な感じ(ノーマルなstaticライブラリの場合は「wxmsw28_aui.lib」、Unicodeでのstaticライブラリの場合は「wxmsw28u_aui.lib」がビルド時に必要です。)。 // ヘッダの指定 #include "wx/aui/aui.h" ... // ドッキング用のマネージャクラス。これはヘッダ部に定義のこと。 wxAuiManager m_auiMgr; ... //------------------------------------ // 初期化処理(thisのコンストラクタで呼ぶとよい) //------------------------------------ // ドッキングの土台となるwxWindow派生クラスを指定 m_auiMgr.SetManagedWindow(this); // パネル1を中心位置に配置する。これはフローティングにはならない。 m_auiMgr.AddPane(pPanel1, wxCENTER, wxT("ビュー部")); // パネル2を下部に配置する。フローティング対象。 // ただし、thisのウィンドウの下部以外はくっつかないように制限。 wxAuiPaneInfo info; info.Name(wxT("tb2")); // 名称 info.Caption(wxT("ログ表示")); // キャプション文字列を指定 info.Bottom(); // 配置は下 info.LeftDockable(false); // 左へのドック収納を禁止 info.RightDockable(false); // 右へのドック収納を禁止 info.TopDockable(false); // 上へのドック収納を禁止 m_auiMgr.AddPane(pPanel2, info); // 更新処理 m_auiMgr.Update(); なお、このm_auiMgrを解放するにはthisのデストラクタのタイミングで m_auiMgr.UnInit(); を呼ぶようにします。 pPanel1、pPanel2はそれぞれwxWindow派生クラス(wxPanelなど)のポインタです。 ここでは、pPanel1はプレビュー用のOpenGL領域、pPanel2はログのテキスト表示領域(wxTextCtrl)としました。結果は上のムービーの通り。 「AddPane」の第二引数にwxAuiPaneInfoに格納した情報を渡すことにより、フローティングできないようにしたりくっつく位置の禁止を行ったりできます。 たったこれだけ。なんという簡単さなんでしょう。昔々、MFCでこの実装をしてかなり苦労した覚えがあります。 これでかなりGUI開発をショートカットできそうですね。 wxWidgets 2.6系ではついてなかった機能なので、これだけでも2.8系にする価値がありますねぇ。 !!OpenGLでのミップマップ(2008/05/28) OpenGLでのミップマップを触ってみました。 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, // テクスチャの幅 height, // テクスチャの高さ 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte *)pData // RGBA情報の入ったバッファの先頭ポインタ ); のようにバインドされたテクスチャに色情報を指定する部分をglu関数で gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, // テクスチャの幅 height, // テクスチャの高さ GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte *)pData // RGBA情報の入ったバッファの先頭ポインタ ); とすると、バインドされたテクスチャに自動的に縮小されたイメージが格納されます(この関数の中身ではglTexImage2Dの第二引数を0、1、2、、、のようにして縮小していった画像を順に格納していってる模様)。 ただし、テクスチャ画像は幅・高さともに2の累乗であること。 そして、テクスチャを描画するときに glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); の代わりに glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); を指定するだけ。 結果は {{ref_image mipmap_01_20080528.png}} が {{ref_image mipmap_02_20080528.png}} のようになって効果絶大ですね。 元画像は256 x 512 pixelのものです。これは「毛」の表現をしてまして、一本一本は1ピクセルの細いものです。テクスチャサイズが大きいと上の画像のようにジャギってしまうというもの。こういうパターンではミップマップとは相性がよさそうです。というか、今のレンダラにこのミップマップ機能も内蔵したいと思いました。 後は、グラフィックカード依存がどこまであるのかの調査もいりそうではあります。 !!肌テクスチャを作ってみる(2008/05/24) 実際の写真の人の顔から肌のテクスチャを作る、という何やってるのかわからないことをここ数日やってます。以下のような感じで生成できました。 {{ref_image skin_img_20080524.png}} しかし、手術をしているかような作業ですねぇ。ちなみに上記はプログラムにて自動化してます。 顔写真から肌と思われる部分をサンプリングし、それを重ねて重ねてぼかして、重ねて、、、でつなぎ目を目立たないようにしてようやく汎用的に使えそうな肌テクスチャに。 ただ、人によってまたは光の当たり方によって肌の感じは違うわけですのでそのあたりに柔軟に対応できるか、が焦点であります。おそらく個人個人で肌は違うので、オーダーメイドにはなりそうですね。 !!PC戻ってきました(2008/05/24) 修理に出していた自宅ノートPCが返ってきました。 これで、自宅でもようやくPCがいじれるように。いろいろ中断していたものも徐々に再開できればと思ってます(でも、今月〜来月は締め切りがあるのがあるので鈍いのは変わらないですが。この件でちょっとお願いしたいことがあって、、、これはまたこの日記に書きます)。 後、放置していたメールのレスもしていきますので今しばらくお待ちくださいませ。 え〜、3週間で3000件くらいあるのですが・・・ほとんどはスパムなので今メールゲット&フィルタリング中です。 PCが戻ってこない間は仕事場で仕事をしているか、自宅ではずっとペルソナ3(フェスのほうの本編)で再度遊んでました。 ペルソナ4は7/10発売とのことで楽しみです。 !!メタセコのPython(2008/05/21) 3D関連のプログラムでちょっとしたことを調査する場合にメタセコは大活躍中です(メタセコ+SAIで私はもうモデリングは何もいらないかもしれん。両方ともユーザ登録済みですが元は十分取れてますねぇ)。 選択されている頂点番号を知りたいのですが、これくらいならPythonでできるかということで、Pythonを一寸たりとも触ったことがなかったのですがいじってます。 いや〜、forのルールが違うんすね。 # ドキュメントを取得 doc = MQSystem.getDocument() # オブジェクト数を取得 objCou = doc.numObject MQSystem.println("オブジェクト数 : " + str(objCou)) # 0番目のオブジェクトを取得 obj = doc.object[0] # オブジェクトの頂点数を取得 verCou = obj.numVertex MQSystem.println("頂点数 : " + str(verCou)) # オブジェクトの面数を取得 polyCou = obj.numFace MQSystem.println("面数 : " + str(polyCou)) #1つめのオブジェクトにおける選択頂点を調べる for i in range(len(obj.vertex)): if obj.vertex[i].select: MQSystem.println("選択頂点番号" + str(i)) こんな感じでOKかな? プログラミング言語は3日もあればある程度使えるようになる、というのは持論ですが、基本は変数の扱いと制御文(forやifなど)をおさえると後はどれも同じ、というのは助かります。ただ、Pythonは若干違いますね(PerlやsmallTalk的な違和感が(^_^;;。覚えりゃなんでも同じではありますけど)。 そんな感じで英語も覚えることができればいいのですが、、、相変わらず英語はからっきしダメです。 でも、Pythonは割とすんなり使えそうです。ということで初心者向けの本を買ってこよう。 !!wxWidgetsのwxGLCanvas(2008/05/19) wxWidgetsにて、複数のOpenGL領域を持たせる、ということをしているとどうも終了時に不安定になりました。wxGLCanvasをオーバーライドしていたのですが、ソースを見てみると glcanvas.cpp内のwxGLContextデストラクタにて wxGLContext::~wxGLContext() { if (m_glContext) { wglMakeCurrent(NULL, NULL); wglDeleteContext(m_glContext); } } のように実装しています。OpenGLの解放処理はデストラクタでやるのは危険ですねぇ。 ここの2回目の「wglDeleteContext」で死んでしまうようで。 後、個人的にNULLチェックをしているのであれば、Delete後にm_glContextにNULLを入れるほうが好みだったり。デストラクタなんで2回は呼ばれないですけども。 1つのOpenGL領域だけなら問題ないのですが、複数のものを使う場合はこの部分は鬼門かも。 wxWidgetsに手を加えるのもおっくうなので、自前で実装するほうが安定しそうな気がします(それよりも、複数のOpenGL領域を使わない設計のほうがいいかもしれませんね)。 ちなみに、wxWidgetsの場合はwxWindowクラスをthisとした場合に HWND hwnd = (HWND)(this->GetHandle()); とすると、ネイティブなWindowハンドルをゲットできます。 これがあればなんとかOpenGL領域を独自実装できるので、このような いざというときの救済策はうれしいところ。 追記: この問題はどうもドライバも関係しているらしく「ドライバを新しいのに変える(GeForce6600GTのボードです)」「マシン再起動」で発生しなくなりました。う〜んグラフィックカード依存か、こいつはやっかいですねぇ。wxGLCanvasを破棄して、独自実装に置き換えちゃったよ(汗)。 !!まだパソコン修理中(2008/05/15) 壊れたVAIOノートの療養中なんですが、SONYのサポートセンターから電話がありまして「動いてますよ?」とのこと。 動かないのを確認してたんですが、原因はなんなのでしょうね。でも、無事でなにより。 それよりも、たまたま家にいたときの電話だったのでよかったのですが、ほとんど外出しているので連絡取れないのがちとすれ違いになりそうで怖いです(^_^;;。 でも、丁寧に対応してくれて助かりました。 かれこれ自宅ではPCのない環境で一週間は経過したのですが、意外と問題はないです(仕事中にPCとにらめっこしてるってのもあるけど)。 自宅では新聞を取っているのですが、新聞は今までよりよく見るようになりましたねぇ。 いつもは起きてすぐにPCを立ち上げる、という廃人状態だったので(朝一番にすることはメールチェックが多いです) PCが壊れたことにより一般人に近づいたかもしれない。 仕事ではwxWidgetsと戯れていますが、一部にて画像認識を行いたいところがあります。ここにてOpenCVを使うことにしました。しかし、レンダラが一時中断中ですので手がほしいところです(レンダラは別プロジェクト)。もうちょっとで整理がつくと思いますので、どうするかをジャッジできればと。仕事の優先度があるので難しいですが、せっかく時間を作ってもタイムリミットがくればストップしてしまう体制をなんとかしたいもんです。 こりゃキャパ不足ですねぇ。 とりあえず、レンダラは自宅PCが復帰すれば若干進展すると思いますので、そのタイミングでなんとかまとめておきたいです。 !!感動した(2008/05/09) modoってモデラーかと思ってたんですが、ギャラリー見てみたらレンダラもすごいっすね。 8スレッド(8コア)のレンダリングで27秒だそうな。 http://www.luxology.com/common/qt/LuxQT.aspx?u=http://content.luxology.com/modo/302/video/C9-rendering.mp4&w=724&h=532 これは無理だろうけど追いつきたいです(^_^;;。 レンダリングでの走査方法なんですが、ブロックとして扱うのはいろいろ利点があります。今作ってるレンダラはライン(上から下の走査)なんですが、別途Maxwellみたいに何回もスクリーンを走査するモードも設けてます。 けど、後者は最適化が難しい部分があって、私が実装するのに限ってかもしれませんが、ブロックやラインでレンダリングするよりも速度が落ちてしまいます。 ところで、modoのレンダリングムービーではガンマが1.2のようなんですがどれがデフォルト値として適切なんだろうか(カメラ(hdr撮影時)で言うと、1.8か2.2が多いと聞いたんですが・・・)。 !!PhysX SDK v2.8.1(2008/05/09) nVIDIAからメール来てました。今まで特にユーザ登録してないのになぜ? と思ったら、AGEIA(今はnVIDIAに買収されてます)から引き継いだんでしょうね。PhysX SDKの案内がありました。 http://developer.nvidia.com/object/physx_downloads.html 久しく触ってないのですが、今は 2.8.1だそうです。 ソフトウェアだけでも十分速いですので、遊ぶのにはいろいろ使えそうです(ハードを持ってるけど、これは失敗だと思う。流れ的にGPUでの物理演算に移行するのかもしれないですね)。 ですが、ライセンス体系はどう移行したのでしょうか(まだ確認してません)。 !!パソコン修理中(2008/05/08) 壊れたノートPCを修理に出してきました。直るまで3〜4週間かかるそうです。 ということで、家ではパソコンなし、仕事場ではフルに使ってますが終電までという制限あり、な状態です。 メールは仕事場から見ることはできますが、修理中の自宅ノートとごっちゃになると困りますのでレスは1ヶ月後になりそうです。お手数をおかけしますがご了承くださいませ。 しかし、迷惑メールが多いです。9.9割方迷惑メールなんですが・・・。フィルタリングして自動分類していますが、たまに迷惑でないメールが迷惑に入っていたりと完全ではないですね。 後、急遽な仕事があるのでwxWidgetsと格闘中。さくっとアプリを作り上げるのにはかなり助かってます。しかし、人手が足りないです。仕事の絞り込みも行っているのですが、どうも依頼のある内容は自分でしかできないことが多いので作業が集中してしまいます(ありがたいことではあるのですが、分散できない(^_^;;)。 !!サンプリングの最適化?(2008/05/06) 偶然ではあるのですが、ノイジーなものを緩和する方法というかサンプリング手段が実装できました。 と思ったらウソついてました、すみません(汗)。 サンプリング数が3倍になっただけでした・・・。おぅっ。 !!パソコンがぶっ壊れた(2008/05/06) レンダリングのしすぎか寿命か、いつも使っているノートPCが起動しなくなってしまいました。しばらくは治療に出さねば。 でも、5年以上活躍してもらいましたので感謝してます。VAIOノートです。例のバッテリーが発火対象になっているやつ(^_^;。ご丁寧にSONYの方から電話連絡をいただきまして、いつでもバッテリー交換しますよとおっしゃってました。ネットもso-netだし、テレビもSONY製だし、PS2持ってるし、自宅からSONY本社まで歩いていけるし(関係ないか)、と一ユーザではあるのですがお世話様々です。 幸い、大事なプログラムのソースは分散させておいてますのでレンダラソースや仕事のソース類は無事です(遠距離環境にアップロードした後にパソコンを再起動したら、起動しなくなったのでギリギリセーフ)。バックアップはとっておくもんですね。 それと、本日はまだGW中でした(気づいてなかった)。連絡を送っちゃったお客さんごめん、GW明けにでもゆっくりお返事いただければと。 日記が連絡網になってしまった・・・まぁいいや。 !!アルベド(2008/05/04) http://kobam.hp.infoseek.co.jp/meteor/albedo.html を見ると、どうも色だけでアルベドが判断できるとは限らない感じ。 砂や砂漠で25〜40%だと(白っぽいのでもっと高いもんだと思ってましたが)、色判断では厳しいか。 後、ちと用語が難解なんですがSSSで使う(<実装予定)「吸収」はabsorptionとなってるので用語の整理をしないといけなかなぁ。 マテリアルを何気に整理してみると(一応関係ありそうなパラメータだけ仮でつけてます、機能してないけど)、SSS関連で吸収、散乱、吸収の色、吸収の距離、なんてとてもじゃないけど調整し辛そうでカオス化してます(^_^;;。SSSではアルベドマップというのを使う、なんてのがCG Magicに書いてましたので とりあえずはSSS到達までは時間がかかりそうです。パストレのごり押しではSSSの実験をしてみたのですが、たしかに時間がかかりますね、というかトラバース回数が増えること増えること。 普通のパストレでの吸収の挙動も、SSSでのアルベドマップとなんとか一緒に扱えるといいのですが・・・。 ここで書いている内容は 自分の健忘録という意味もありますが、(おせっかいかもしれませんが)Shadeでもぜひ!という意味合いもあります。過去掘っていたポリゴンモデリングに関してやボーンなどの「これだけはほしい」といった内容は、自分の調べたことで現状不便だと感じたことに関して、開発のほうに(手渡しで)渡してあったりします。採用してくれるかどうかは開発チーム次第ではありますが。 もちろん、メールにて個人的にいただいた「これもついでにお願い!」は伝えさせていただきました。 レンダラに関しては、たまたま仕事と私事がちょうどバッティングしているネタだったので書いてます(今は守秘義務もない状態のプロジェクトなんである程度は公開してOKなんですよ)。技術としてはたいしたことはしてないので、これらもフィードバック予定にしてます(ウソ書いてたらゴメン、というかさすがにそれは自己判断でなんとか見抜いてくださいませ。あくまで自分の「独り言」ですので)。 誰かがやらないと、、、と思って何年もたってるので、まぁちとおせっかいがてら。 クリエイターとしての作品を通しての突っつきは、誰かやって(汗) !!閉鎖空間でのテスト(2008/05/03) 光が届きにくい閉鎖空間でのレンダリングテスト。Celeron 1GHz/Mem512MBのWinXP(ノートPC)にて。スクリーン左上の小さい窓と右上の横長の窓以外は閉鎖しています。背景はhdrを使ったIBLです。それ以外に光源はありません。壁や床・天井は鏡面反射0、反射0です(純粋に拡散反射のみになるようにしてます)。 ↓Shade10 追跡レベル 20 / レイトレの画質 50にて、2340秒(39分)。 {{ref_image shade_50samp_39min_20080503.png}} Shadeではやはり光が届きませんね。球が発光しているように見えるのは拡散反射の色を青に近づけているため。拡散反射を黒くしていないのはわざとです。独自レンダラでどうも透明体の場合の色の反映が弱いので、、、このへんの理論をもうちょっと整理する必要がありそうです。 球は左から透明度1.0 / 0.8 / 0.6 / 0.3。 ↓独自レンダラ 追跡レベル20 / 50samples/pixelにて、237秒(約4分)。 {{ref_image srender_50samp_237sec_20080503.png}} これではノイジーなのでサンプリング数を1000にしてみました。 ↓独自レンダラ 追跡レベル20 / 1000samples/pixelにて、3101秒(約51分)。 {{ref_image srender_1000samp_3101sec_20080503.png}} 後、フレネル効果を忘れてました。実装せねば。 それと、透明体の場合の色についてもっと直感的になるように調整。 後、これも思い違いしてましたが Shadeの場合は追跡レベルを上げればサンプリング数も増加するような動きをしていますね、トレースの再帰による影響だけではないみたい。もちろん、それで時間を食うのですがこれだと純粋にサンプリング数で比較する、といったことはできないのかも。 !!デフューズアルベド(デフューズリフレクタンス)について(2008/05/01) アルベドとは光がある一点に入射したときにどれだけの光が反射するかの比率ですが、 「デフューズアルベド」というと名前の通りデフューズでの「反射する光の量/入射する光の量」です。 単純に言えば、白い服は光をかなりの確率で跳ね返します。黒い服は吸収します(反射しにくいです)。 というのをレンダラに取り入れているのですが、例によってShadeとの比較です。 Pentium4 2.8GHz/Mem512MBおWinXPマシンにて。 以下は、透明度マッピングの実験も兼ねてます。どうもShadeの「トリム」という考えは個人的には「透明度」であらわせばいいやん的なイメージがあるので、透明度で表現してます(透明度1.0の部分は通り抜けることになります)。 ということで独自レンダラでは、トリムという概念はないです(DirectXなら透明度の逆のアルファであらわしますよね)。 ↓Shadeにてレンダリング。品質50でレンダリング時間39秒。 {{ref_image shade_trans_50samp_39sec_20080501.png}} ↓独自レンダラにてレンダリング。50samples/pixelでレンダリング時間24秒。 {{ref_image trans_50samp_24sec_20080501.png}} ふと思ったのですが、Shadeは「吸収」という概念がないのかもしれない。 個人的には、この吸収という概念は非常に大事だと思ってます。それがリアルにつながるんでないかなと。 単純計算では、デフューズの色が(Red, Green, Blue)で与えられているとすると (Red + Green + Blue) / 3 として、これをデフューズアルベドとしてます(が、正しくは明度を求めた方がいいかも)。ただ、原色バリバリで表現したい場合もあるでしょうからアルベド自身をデフューズと切り離したほうがいいのだろうか。 ただ、実はこの部分はマニュアル(PhotonMap本やCGMagicなど)とは違う考え方を行ってます。RGBによって吸収の挙動が変わるというのは独自ではあるのですが、なんで論じてないのだろう・・・(フォトンの説明では書いてますね)。 間違ってるのかな、でも、こっちのほうがリアルっぽいんだよなぁ。 どれが正しいか分からなくなれば現実と比較するしかないですが、いずれは恒例のコーレルボックスでも試してみるかな。