2015年05月30日

PCLと深度バッファを用いたポリゴンモデルのボクセル化

とりあえずボクセル関係で出来そうなこととして、深度バッファを用いたポリゴンのボクセル化を試してみました。

流れ
1. モデル読込み
2. 最大長を指定して、読込んだモデルを囲むボクセルを生成(PCL)
3. Octreeを生成(PCL)

4. 1パスでカラー値と深度値をFBOに出力(OpenGL)
5. 2パスで、OctreeとRayが衝突した表面ボクセルのみを描画(PCL、OpenGL)
6. 3パスで1. と2. をMixして表示(OpenGL)

ここまでの結果
voxelize_001.png
カラーバッファだけの表示も可能
voxelize_002.png

7. 視点からRayを飛ばし、FBOの深度値を参照して深度値より手前にある色のついていないボクセルを削除、深度値付近のボクセルを、FBOのカラー値の色に設定。色を付けたことを示すためにラベルをインクリメント。(PCL)
8. OctreeとCloudの再構築(PCL)

正面から削除/色付けした結果
voxelize_003.png
前後方向から削除/色付けした後横から見た結果
voxelize_004.png

9. いくつかの視点から削除(PCL、OpenGL)

視点を変更することで、前後上下左右で隠れていた部分も削除/色付け可能
voxelize_006.pngvoxelize_007.png

10. 削除されていないかつ色がついていないボクセルを、近傍ボクセルに色がついていればその色に設定し、色がついたボクセルがひとつも見つからなければGUIで設定した基本色を設定(PCL)
(時間がかりすぎるので要最適化)
11. MagicaVoxelに対応している.voxもしくは.slab.voxファイルとして出力
 (.voxファイルは最大256色なので、パレットから似た色に変換)

実行結果
テストとして、[2]〜[4]のモデルを使用させていただき、ボクセル化してMagicaVoxelのレンダラで表示してみました。すべて最大長のボクセル数を512とした結果です。これより小さくするとナンバープレートが潰れたり微妙でした。計算はボクセル数多めにしておいて、出力時にうまく縮小するなどできるといいのかもしれません。

snap0000.png snap0001.png

snap0003.png snap0004.png

snap0002.png snap0005.png

ボクセル数が増えると使用メモリ量・処理時間ともに増えてなかなかつらいところです。

MagicaVoxelの.voxは8ビットと書いているように、ボクセルの座標も8ビット(0〜255)でしか指定できないので、最大でも255x255x255のサイズのボクセルしか構築できません。それ以上のサイズを使用する場合は、生データでサイズが大きくなりますがslabというファイルフォーマットを使用する必要があります。.voxのエクスポータを書いているとき、一部分しか出力されていなくて無駄に悩みました。

MagicaVoxelのレンダラで表示できるのはいいのですが、よく考えるとあまり使い道がないですね…。ポリゴンの方がきれいで軽いですし3Dプリンタなども使う予定はありませんし。マインクラフトとかに取り込めるんですかね。

メモ:マウス操作の操作性が悪いので改善する(距離に応じて移動/回転量を変更)

[1] http://www.naturalsoftware.jp/entry/2012/11/06/161132
[2] 軽自動車:http://seiga.nicovideo.jp/seiga/im4099340
[3] 頭蓋骨:http://flower-dam.com/wp/?p=3824
[4] らば式利根改二:http://www.nicovideo.jp/watch/sm24544789
続きを読む
web拍手 by FC2
posted by シンドラー at 13:07 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2015年05月25日

PCL 1.7.2のOctreeのテスト

Voxelで何かしようかなと思っているのですが、高速化のためにはOctreeなどデータ構造が大事かと思いますので、Point Cloud LibraryのOctreeを使用することにしました。本当はSparse Voxel Octreeのライブラリなどを使用した方がいいのだとは思いますので、機会があれば試してみたいと思います。

PCL 1.7.2の導入
公式は1.6.0のall-in-one-installersしかなかったですが、[1]で1.7.2のものを公開していただいていましたので、そちらを使用させていただきました。octreeのtutorialsは[2]にあります。今回必要なのはoctreeだけなので、includeやlibも最低限必要なものだけにしておきます。

インクルードのパス
$(PCL_ROOT)\include\pcl-1.7;
$(PCL_ROOT)\3rdParty\Eigen\Eigen3;
$(PCL_ROOT)\3rdParty\Boost\include\boost-1_57;

ライブラリのパス
$(PCL_ROOT)\lib;

ライブラリ(リリース)
pcl_octree_release.lib;

実行時に必要なライブラリ
$(PCL_ROOT)\bin\pcl_octree_release.dll

[3]を参考に、MagicaVoxelのVoxデータを読み込んでRaycastingで表示してみました。

ソースの一部(画像処理・レイの計算部分は省略)
#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>

int rayCastTest(const int width, const int height)
{
    int hit = 0;

    MV_Model mv;
    mv.LoadModel("voxel/doom.vox");

    // ポイントクラウドの作成(色情報のためのラベルのためPointXYZLを使用)
    pcl::PointCloud<pcl::PointXYZL>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZL>);

    // 画像とレイキャスティングの準備は省略

    // voxデータからポイントクラウドを生成
    cloud->width = mv.voxels.size();
    cloud->height = 1;
    cloud->points.resize (cloud->width * cloud->height);

    for (size_t i = 0; i < cloud->points.size (); ++i)
    {
        cloud->points[i].x = mv.voxels[i].x;
        cloud->points[i].y = mv.voxels[i].y;
        cloud->points[i].z = mv.voxels[i].z;
        cloud->points[i].label = mv.voxels[i].colorIndex;
    }

    // octreeの生成、解像度はoctreeのボクセルのサイズ?
    float resolution = 1.0f;
    pcl::octree::OctreePointCloudSearch<pcl::PointXYZL> octree (resolution);

    octree.setInputCloud (cloud);
    octree.addPointsFromInputCloud ();

    // レイとボクセルの衝突判定
    std::vector<int> k_indices;

    Eigen::Vector3f org, target, dir;
    for (int y=0; y<height; y++)
    {
        for (int x=0; x<width; x++)
        {
            // 画素からレイの到達先を計算
            // 視点位置と到達先からレイの方向を計算

            // octreeとvoxelの衝突判定(1回)
            int ret = octree.getIntersectedVoxelIndices(org, dir, k_indices, 1);
            if (ret > 0)
            {
                // 今回は1個目のindex固定(解像度によってはk_indicesが複数Indexを含む)
                int label = cloud->points[k_indices[0]].label;
                // パレットから色を取得して画像に設定
                color.r = mv.palette[label].r;
                color.g = mv.palette[label].g;
                color.b = mv.palette[label].b;
                hit++;
            }
        }
    }
    // 画像の保存
    return hit;
}
実行結果(MagicaVoxel付属のサンプルdoom.vox使用)
pcl_test_001.png
ボクセル数2万弱、1024x1024の画像で、レイキャスティングの時間だけで400msぐらいでした。どちらかというと、全部のレイと衝突判定するのではなく、全部のボクセルを枝刈りしながらレイに当たるか判定する陰面消去的な探索がしたいのですが、どうやるんですかね。

[1] http://unanancyowen.com/?p=712
[2] http://pointclouds.org/documentation/tutorials/#octree-tutorial
[3] http://voxel.codeplex.com/wikipage?title=Sample%20Codes
web拍手 by FC2
posted by シンドラー at 00:56 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする

2015年05月23日

Oculus SDK 0.6.0.0とGLUTのテスト

Oculus SDKがv0.6.0.0になっていろいろ変わりましたので、GLUTでのテストをしてみました。
最近はSDKのサンプルにOculusRoomTiny(GL)がありますので、あまり必要ないのかもしれません。

1. Extended modeで動かない
こちらGTX690ですが、Direct display modeにしないと、サンプルとか今回のものとかが動きませんでした。

2. FBO2枚に分離
前は1枚のFBOの左半分に左目、右半分に右目を描画していたのですが、2つに分かれたみたいです。

3. Mirrorテクスチャも必要?
追加でMirror用のFBOが増えていて、そこに描画してから転送しているような雰囲気でした。

実行結果
ミラー画面をキャプチャした画像です。
oculusv0.6.0.0_001.png

Directモードのおかげか、ポリゴン1枚しか描画していないからかわかりませんが、追従遅れなどはほぼ感じなかったです。

以下ソース
main_glut_v0.6.0.0.cpp
simple.vert
simple.frag
OculusRoomTiny(GL)からの転用が多いので、その辺のライセンスになるかと思います。何か問題が起こっても責任はとりません。

web拍手 by FC2
posted by シンドラー at 03:13 | Comment(0) | TrackBack(0) | Oculus Rift | このブログの読者になる | 更新情報をチェックする

2015年05月09日

Appleseedレンダリングエンジンのテスト その10

レンダリングが終わったのでYouTubeにアップロードしてみました。



レンダリング時間短縮のため、1パスしか飛ばしていないので結構ノイズが残ってしまっています。後、カメラは面倒だったのでフレーム間はオイラー角を線形補間しただけなので元のものと変わってしまっているかもしれません。

下記のものをお借りしました。

[1] モデル: ままま様 アラン・スミシー様 yon様
http://www.nicovideo.jp/watch/sm23664403
[2] モーション: あひるP様
http://www.nicovideo.jp/watch/sm25558790
[3] 曲: きむた様
http://ch.nicovideo.jp/suzukirin/blomaga/ar634504
[4] カメラ: 猫姫様
http://www.nicovideo.jp/watch/sm25399243
[5] スカイドーム: ussy様
http://www.nicovideo.jp/watch/sm10968092

web拍手 by FC2
posted by シンドラー at 23:37 | Comment(0) | TrackBack(0) | Rendering | このブログの読者になる | 更新情報をチェックする

2015年05月07日

Appleseedレンダリングエンジンのテスト その9

あっという間にGWが終わってしまいましたね。



というわけで、VMDファイルからカメラ情報を取得して.appleseedに埋め込むように修正しました。とりあえず全部流し込み動画を作成中ですが、1フレーム1分でも2800フレームで47時間弱とかかなりかかりますね。
web拍手 by FC2
posted by シンドラー at 18:37 | Comment(0) | TrackBack(0) | Rendering | このブログの読者になる | 更新情報をチェックする

2015年04月23日

Appleseedレンダリングエンジンのテスト その8

変形モーションブラーのテストです。一応アニメーションまでやりましたので一通り試しましたかね。



実行結果

tda_roku_blur01000.png

MMDBridge[1]はバージョンアップしてフレーム抜けもなくなって素晴らしいですね。モーションは[2]を使用させていただいております。約30秒の動画に差替えました(2015.4.25)。


静止画だとちょっとブレ過ぎかなと思ったのですが、アニメーションにすると結構自然に見えますね。

[1] http://mmdbridge.render.jp/
[2] 【MikuMikuDance】 好き!雪!本気マジック 【MMDモーショントレース】

web拍手 by FC2
posted by シンドラー at 23:19 | Comment(0) | TrackBack(0) | Rendering | このブログの読者になる | 更新情報をチェックする

2015年04月18日

Appleseedレンダリングエンジンのテスト その7

続きです。どうも肌が白っぽくなっているので表面下散乱ができるといいのですが、現状Disney MaterialのSubsurfaceパラメータだけでは難しいようでしたので、EDFを使ってなんとかならないかのテストです。肌の内側から赤っぽい光が発生していれば、表面下散乱のような効果になるのではないかということです。

まずは表面を肌色、EDFをRGB(0.9, 0.2, 0.1)にした球で試してみました。

edf_test_001.png

後はGUIを変更してその辺も選べるようにしました。

実行結果

前回の結果
tda_roku_blend_001.png

今回の結果
tda_roku_edf_002.png

前のよりは肌色っぽくなりました。

web拍手 by FC2
posted by シンドラー at 22:38 | Comment(0) | TrackBack(0) | Rendering | このブログの読者になる | 更新情報をチェックする

2015年04月08日

Appleseedレンダリングエンジンのテスト その6

続きです。複数BRDFを設定してBlendできるようにしてみました。現状Oren-NayarとAshikhminモデルの2つを対象としています。他にもたくさんありますが、今のところこれぐらいでいいかなといった感じです。

また、360度パノラマ画像でレンダリングできるかなと試してみたところ一応できた気がします。



GUIの画面
anttweakbar_gui_002.png

Oren-NayarモデルのパラメータとBlendのWeight設定、後はSpherical Cameraでの.appleseed出力などに対応してみました。

BSDF BlendでOren-NayarとAshikhminモデルを混合したレンダリング結果
tda_roku_blend_001.png

パノラマ画像
wo_spherical.png

web拍手 by FC2
posted by シンドラー at 22:10 | Comment(0) | TrackBack(0) | Rendering | このブログの読者になる | 更新情報をチェックする

2015年04月07日

Appleseedレンダリングエンジンのテスト その5

続きです。Appleseedでは色々なBSDFモデルが提供されているのですが、これまで出力していたのはOren-Nayer BRDFで出力していたので、DiffuseだけでSpecularがありませんでした。ここここなど、以前Specularで異方性も反映されるものとしてAshikhminモデルのテストをしていて、AppleseedにもAshikhmin-Shirley BRDFがありましたので、GUIでこの辺のパラメータを設定して.appleseedで出力するようにしてみました。

ashikhmin_gui_001.png

一応シェーダは昔書いてたやつを使いまわしていますので、大まかな確認はできますがAppleseedでの結果とは異なるので参考程度です。

また、マテリアル毎にパラメータを設定する必要があるので目安として赤いアウトラインを表示するようにしてみたのですが、CPU側で画像処理でやっているので重いです。

実行結果

anttweakbar_wo_normal1.jpg
前回の結果

ashikhmin_gui_002.png
今回の結果

ashikhmin_gui_003.png
ステージも変換して設置した結果

ちょっとアルミっぽい感じになりすぎていますので、Ashikhminモデルのみではなく、複数BSDFのBlendなどしないと調整不足な感じがします。ステージは[1]のオバケの木ステージを使用させていただきました。ステージはAshikhminにしない方が良かった気がします。GUIの方で選択もできるようにしますかね。

[1] http://emipon.net/

web拍手 by FC2
posted by シンドラー at 04:32 | Comment(0) | TrackBack(0) | Rendering | このブログの読者になる | 更新情報をチェックする

2015年04月02日

Appleseedレンダリングエンジンのテスト その4

Appleseedにはノーマルマッピングの機能がついていますので、試してみることにしました。3Dモデルにはノーマルマップを付けてくださっている場合とない場合があります。ある場合にはハイポリモデルで計算してノーマルマップだけ出力している場合があるので、そちらを用いた方がより正確なデータとなります。ない場合は仕方がないのでカラーマップから生成する場合が多いと思います。

カラーマップからノーマルマップを生成する方法として、GIMP[1]のノーマルマッププラグインやWeb上でノーマルマップを作成できるもの[2]や、Knald[3]というソフトウェアがありました。Knaldはモデルの読込などもできて良さそうでしたが、Freelancer Licenseで100ドルとのことです。ちゃんとしたノーマルマップが欲しい場合はこちらがいいのではないでしょうか。

というわけで、今回はAntTweakBar[4]の使い方に関するメモです。

1. std::stringを使って文字列の読書きを行う場合
コールバック関数を設定する必要があります。やり方は[5]に書いています。これをやっていなくてReadOnly状態になってて困りました。

2. 動的にメニューの追加/削除を行う方法
TwAddVarRWで、読書き可能な変数を初期化後なら割といつでも追加できます。削除したい場合はTwRemoveVarでできます。同じ名前のGUI変数は定義できないので、例えばデータの格納先だけを変えたい場合などは、TwRemoveVarで取り除いてからもう一度TwAddVarRWとやればできます。このやり方が正しいのかどうかはわかりませんが。

3. 数値が変わった場合などに何か処理を行う方法
数値を変更した際に特定の処理を行いたい場合には、コールバック関数を指定するためにTwAddVarCBを使います。変更されたときに呼び出される関数と、値を取得するときに呼び出される関数の2つを指定するとReadWrite状態にできます。引数の一つ目が設定/取得する変数の値で、二つ目がユーザが設定できるクライアントデータとなります[6]。

モデルを読み込んで各テクスチャ毎にノーマルマップを作成して出力するようにGUIを変更してみました。

手順
1. カラー画像をグレースケールに変換。α値があればそれを掛ける。
2. グレースケール画像をコントラスト伸長して0〜1の範囲に広げてこれを高さマップとする。
3. 差分フィルタを用いて高さの勾配を計算して法線ベクトルを計算する。
4. 画像として出力

至って普通のやり方ですね。

フィルタのサイズや法線ベクトルの勾配に掛けるスケール値、高さマップを反転するかどうかなどのパラメータをGUIで調整できるようにしました。

anttweakbar_001.png

高さマップの表示/非表示、バンプマッピングの有効/無効などもGUI上で設定できるようにしています。

anttweakbar_002.png

後ノーマルマップの設定をした.appleseedを出力するようにしました。

実行結果

tda_roku.jpg
以前の結果
Tda_roku_normal.jpg
今回の結果

その他モンテコア様のヲ級[7]で試してみました。こちらのモデルはノーマルマップ付属でしたが、自前の方でテストしています。マントの凹凸などはやはり色情報からでは辛いので元のノーマルマップの方が良いと思います。

anttweakbar_wo_no_normal.jpg
ノーマルマップなし
anttweakbar_wo_normal1.jpg
付属ノーマルマップ
anttweakbar_wo_normal2.jpg
今回の結果

テストということで勾配のスケール値を結構大きくしたのでところどころ黒くなってしまっています。そろそろステージとか床を配置したりしないと浮いてて駄目ですね。

[1] GIMP normalmap plugin
[2] NormalMap-Online
[3] Knald
[4] AntTweakBar
[5] TwCopyStdStringToClientFunc (function)
[6] TwAddVarCB (function)
[7] 深海棲艦 空母ヲ級
web拍手 by FC2
posted by シンドラー at 21:51 | Comment(0) | TrackBack(0) | Rendering | このブログの読者になる | 更新情報をチェックする