2015年02月26日

vidroで表面下散乱のテスト その2

前回の続きです。やらないと書きましたが一応反射も少し試してみました。

今回の設定
vidro_sss_003.png

前回の結果
ab5_29_s4.png
今回の結果
ab5_29_s6_emit.png

加えすぎるとプラスチックっぽくなりますし難しいですね。
web拍手 by FC2
posted by シンドラー at 21:28 | Comment(0) | TrackBack(0) | MMD | このブログの読者になる | 更新情報をチェックする

2015年02月25日

vidroで表面下散乱のテスト

気が付けば2月が終わろうとしていて困ったものです。

vidroのsample3が表面下散乱のサンプルになっているようです。
sample3_scattering.png

内部の屈折率1.33、透過100%で、ボリュームの設定は以下のような設定になっていました。
  HomogeneousExtinction	0.03 0.03 0.03
  HomogeneousAlbedo 0.80 0.40 0.20
  Anisotropy 0.5

今回は、vidroで人肌を表面下散乱でそれっぽくできないかのテストです。

肌の多いリアル系のモデルということで、かこみき様のABちゃん5モデルを使用させていただきました。結果画像を貼るだけならMMD外でも大丈夫なはずですが、問題がありましたらお知らせください。また、今回もMMDBridgeを使用しています。

肌は大体屈折率1.4で、入射光100%のうち、反射5%で透過が95%、透過の内訳は、表面下散乱で外に出るのが55%、そのまま吸収されるのが40%ぐらいだそうです[1][2]。表面だけでなく多層のモデルを作ればこの割合で行けるのかもしれませんが、今回は透過40%の設定でやってみました。

肌の設定
vidro_sss_001.png

面倒だったので反射0にしてますので、ハイライトとか出てないです。透過40%で反射0にしたとき残りの60%は全部Diffuseになるんでしょうかね。

内部ボリュームの設定
vidro_sss_002.png

血管が多いので肌色より赤っぽくなるらしいので、こんな感じにしてみました。前方散乱か後方散乱かはどちらが多いのかわからなかったので等方にしています。

実行結果

首の白いのは顔のポリゴンの首の部分と、体のポリゴンの首の部分が重なっているために出てきている何かです。vidroのドキュメントにも、重なった面は駄目だと書いていたので、そのためだと思います。

透過なし、Diffuseのみの結果
ab5_29_s_no_emit.png
完全な白色光のせいもあるかもしれませんが白っぽいです。

今回の設定の結果
ab5_29_s4.png
何となく赤っぽくなったような。クリックして原寸サイズならわかりますが、ブログ上のサイズだと殆どわからないぐらいの微妙な違いですね。

より良いパラメータを探したり、反射をちゃんと入れたり、肌の細かいノーマルマップなどを加えればよりそれっぽくなるとは思いますが、多分やらないと思います。

[1] ttp://www.netsubussei.jp/group/takada.pdf
[2] http://news.mynavi.jp/column/graphics/059/

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

2015年01月27日

vidroのVolumeのテスト

vidroのボリュームレンダリングも中々お手軽で良さそうなのですが、情報が見当たらないのでメモしておきます。とりあえずSample4のvolume_caustic.vdrにコメントを入れてみました。後、たまに黒い点が入ってしまうので、メディアンフィルタで取り除いています。

実行結果

vidro_volume_003.png

vidro090517

# "CRYSTAL"という名前のマテリアルを定義
new Material "CRYSTAL"
  # 透明度すべて1.0で完全透過
  Transparency    1.0 1.0 1.0
  # ボリューム"a"とボリューム"b"の屈折率は1.0と1.5
  IOR      1.0 1.5
  # 表面がボリューム"a"で、裏面がボリューム"b"
  Volume      "a" "b"

# "0"という名前の空間を定義
new Space "0"

  # ボリューム"a"の定義
  new Volume "a"
    # ボリューム"a"の空間内での光の減衰を設定(0以上、50とかも設定できる)
    HomogeneousExtinction  0.2 0.2 0.2
    # ボリューム"a"の空間内での光の散乱を設定(0から1まで)
    HomogeneousAlbedo  0.3 0.3 0.3
    # ボリューム"a"の空間内での前方散乱/後方散乱の割合を設定(-1から1まで)
    Anisotropy    0.8

    # 点光源の定義
    new PointLight
      # 点光源の明るさ。テクスチャを用いることでスポットライトの効果
      Intensity  96.0 48.0 24.0 "spot.bmp"
      # 点光源の位置座標
      Position  0.2 0.75 -0.3
      # スポットライトの方向を変えるための回転行列
      X    0.95782626 -0.22987832 0.17240873
      Y    0.28734788 0.76626104 -0.57469577
      Z    0.00000000 0.60000000 0.80000000

    # 視点位置の設定
    new Eye
      Position  0.0 0.25 1.5
      Focus    0.0 0.25 0.0
      FocalLength  0.035

  # ボリューム"b"の定義(デフォルト)
  new Volume "b"

  # オブジェクト"0"の定義
  new Object "0"
    # 球のモデルデータを読込む
    File    "sphere.obj"
    # 位置の設定
    Position  0.05 0.35 0.0

HomogeneousExtinctionで減衰、HomogeneousAlbedoで散乱を設定できます。こちらは均一なので、ボリューム"a"全体にかかっています。実行結果ではスポットライトの部分だけのように見えますが、明るいのでわかりやすいだけで、よく見るとスポットライト以外のところも減衰や散乱しています。

続いて、局所的で不均一な場合のサンプルを作ってみました。Sample1のSample1.vdrを改変しました。

実行結果

vidro_volume_000.png

vidro090530

# 球のマテリアルの定義
new Material "SPHERE1"
  # 外側と内側のボリュームの設定
  Volume      "OUTER" "INNER"
  # 外側と内側の屈折率
  IOR      1.0 1.33
  # 完全透過
  Transparency    1.0 1.0 1.0

# 床のマテリアルの定義
new Material "FLOOR"
  # チェック柄のテクスチャ
  Diffuse      1.0 1.0 1.0 "check.png"

# 空間の定義
new Space "0"
  # 外側のボリュームの定義
  new Volume "OUTER"
    # 局所的な減衰の定義。starディレクトリの画像を使用する
    Extinction  25.0 25.0 0.0 "C:\vidro100630x64en\sample1\star"
    # 局所的な散乱の定義。starディレクトリの画像を使用する
    Albedo    0.5 0.5 0.0 "C:\vidro100630x64en\sample1\star"
    # 局所空間のAABBの最小座標を設定
    Origin -0.25 0 -0.25
    # 局所空間のサイズを設定。(-0.25, 0.0, -0.25)〜(0.25, 0.5, 0.25)の空間
    Size 0.5 0.5 0.5
    # 天空光源
    SkyLight  0.5 0.5 0.75 "sky.hdr"

    # 平行光源
    new ParallelLight "LIGHT0"
      Emission  0.5 0.5 0.25
      Direction  -1.0 1.0 -1.0

    # 視点座標
    new Eye
      Position  0.0 0.5 1.0
      Focus    0.0 0.1 0.0

  # 内側のボリュームの定義(デフォルト)
  new Volume "INNER"

  # 球の定義
  new Object
    File    "sphere.obj"
    Material  "SPHERE1"
    Position  0.0 0.1 0.0
  
  # 床の定義
  new Object
    File    "floor.obj"
    Material  "FLOOR"

局所的な場合は、Homogeneousを取り除いてExtinctionとAlbedoとします。ここで注意点として、OriginとSizeでちゃんと領域を指定してあげないと画面上に反映されません。

starディレクトリに画像を入れます。今回は下記の適当に作った画像1枚を入れています。

volume001.png

ディレクトリ名を空欄にすれば、下記のように局所空間全体が減衰/散乱します。

vidro_volume_001.png

結果からもわかるように、下図のような関係のようです。

vidro_volume_004.png

確認のため、もう一枚starディレクトリに画像を入れます。

volume000.png

vidro_volume_002.png

○を000.png、☆を001.pngとしていますので、○が奥になっています(視点(0,0.5,1.5)、注視点(0,0.1,0)より)。
ちゃんとした3次元テクスチャがあれば、もう少し色々できそうです。

参考サイト
[1] vidroホームページ: http://vidro-renderer.sakura.ne.jp/
web拍手 by FC2
posted by シンドラー at 22:42 | Comment(0) | TrackBack(0) | MMD | このブログの読者になる | 更新情報をチェックする

2015年01月19日

MMDBridgeとvidroのテスト

今更ですが明けましておめでとうございます。もう1月下旬とか困ったものですね。今回は楽にきれいな画像を作ろうということで既存のレンダラを使ってみることにしました。レンダラにも色々ありますが、せっかくなのでMMDBridge[1]に挙がっているvidro[2]〜[4]を使ってみることにしました。2010年が最終更新になっていますので、もう更新されないんですかね。

MMDBridgeのvirdoサンプルは、日本語の混じった名前のテクスチャを使っているようなPMXモデルでutf-8 decode errorみたいなのがでたのと、Diffuseなどがなぜか全部0になっている?ようなのと、エッジ色等の情報が取得できないようでしたので、Objと簡単なvdrファイルを出力するだけのものに変更しました。後、vidroのsample2のboxとwaterを使用するようなものにしています。

pythonスクリプト

後は、自前のPMXローダからobjのmtlファイルと、半角英数にリネームしたテクスチャ画像、色やエッジ情報などのマテリアルに関するvdrファイルを出力するようにしました。mtlはマテリアル名ぐらいで、それ以外の色やテクスチャの情報はvdrに出力してしまいます。

注意点としては、透明度を含むpngやtgaを指定していても、objの場合はそれを認識してくれないようですので、map_dというアルファマップ用の画像をpngやtgaから抽出する必要があります。また、vidroでは、基本的にRGB指定×テクスチャ画像の乗算で計算されるため、透明度に関しても同様に処理されます。つまり、透明度は1が完全な透明、0が不透明でそれにアルファマップの画像を乗算することになりますので、透明にしたいところを白色、不透明にしたいところを黒色と、一般的なアルファマップ画像を反転させる必要があります。(rgb = 1.0-aとした画像を新たに作成します)

実行結果

とりあえずデフォルト設定+SkyLightにHDR画像を指定してレンダリングした結果です。スカイドームに[5]を、歩きモーションに[6]を、PMXモデルに[7]を使用させていただいております。GIはやっぱりいい感じですね。

vidro_008.png

フォトリアリスティックとノンフォトリアリスティックを選択でき、ノンフォトの場合にはエッジが描画されます。デフォルトでは黒い線がすべての境界に引かれてしまうので微妙です。

vidro_010.png

そこで、エッジ色に関してはPMXファイルから取得して、エッジが無効になっているものはContourGroupでビット調整して非表示にしました。また、濃さに関してはBoundary?で、内部のしわのエッジの濃さ?はCreaseで設定する必要がありますので、PMXEditorを参照しながら多少は修正しました。

vidro_009.png

サンプルvdrファイル

全身だとこんな感じです。

vidro_006.png vidro_007.png

後はvidro付属のsample2のデータと[8]の立ちポーズを使ったらこんな感じになりました。

vidro_012.png

トーンマップの設定やVolumeの設定など、まだまだ色々できることはあるので、時間があれば試してみたいです。

参考サイト
[1] MMDBridgeホームページ: http://mmdbridge.render.jp/
[2] vidroホームページ: http://vidro-renderer.sakura.ne.jp/
[3] vidro参考サイト1: http://aether5th.blog40.fc2.com/category35.html
[4] vidro参考サイト2: http://kmurai.blog52.fc2.com/blog-category-12.html
[5] スカイドーム: http://www.nicovideo.jp/watch/sm10968092
[6] 歩きモーション: http://www.nicovideo.jp/watch/sm9554606
[7] 磯風モデル: http://www.nicovideo.jp/watch/sm24596846
[8] 立ちポーズ:http://seiga.nicovideo.jp/seiga/im4373054
web拍手 by FC2
posted by シンドラー at 21:20 | Comment(0) | TrackBack(0) | MMD | このブログの読者になる | 更新情報をチェックする

2014年07月07日

libnoiseの使い方について その5

次回○○やります、と書いて実際やったことの方が少ない気がしますね。先月更新できなかったので反動で頑張りましたが、そろそろ落ち着きますかね。

というわけで、木の3次元テクスチャをMMEで使ってみることにしました。木目調の3次元テクスチャは、[1]のexampleを参考にさせていただきました。GPLなのでGPLですね。

3次元座標でノイズを取得できますので、それを3次元テクスチャとして保存します。以前作成したDevILライブラリを扱うクラスを使って、.ddsファイルとして3次元テクスチャをそのまま出力します。DirectX Texture Toolで512x512x512で非圧縮でミップマップ付きに変換して保存したらunsigned byte: Lのみの8bitなのに150MBになりました・・・。

続いて、MMDで使用するモデルで木目が使えそうなものということで、しらす様の油絵用パレット[2]を使用させていただきました。

MME使用前
wood_mme_001.png

ここで問題になるのが、3次元テクスチャの座標をどうすればいいかということです。UV展開して・・・といったことは面倒ですので、MME側で頂点座標を無理やり0〜1の範囲に線形変換して、それを3次元テクスチャのUV座標として使用することにしました。

また、元のモデル?ではSpecularColorが黒色でしたので、適当に色を設定して、3次元テクスチャの明るさをSpecularのマスクとして使用しています。テクスチャをマスクとして使用するのもよく使われる方法だとは思いますが、多少は効果があるのではないかと思います。

MME使用後
wood_mme_002.png

パレットというか磨いた机みたいな感じですが…。

おまけ


3Dテクスチャつけてない上に多分今回のモデル以外ではまともに使えないと思いますが一応参考までに。
Texture3DTest.fx

[1] http://libnoise.sourceforge.net/examples/textures/index.html
[2] 【MMD-OMF4】油絵用パレットっぽいもの
web拍手 by FC2
posted by シンドラー at 01:05 | Comment(0) | TrackBack(0) | MMD | このブログの読者になる | 更新情報をチェックする

2014年04月25日

Worleyノイズについて

使い道はわかりません。で済ましてしまうのもどうかと思いましたので、一応Worleyノイズの使い道について調べてみました。人の肌のテクスチャ[1]や、ステンドグラス風のテクスチャ[2]等に使うことができるようでした。

今回、ステンドグラス風のテクスチャを作ってみようとしたのですが、IDの取得方法が良くわからなかったので適当に書き換えました。もっと良い取得方法がありそうです。

後は、隣り合う領域は同じ色にならないようなアルゴリズムもあった気がするのですが、今回はただ単にIDの剰余を取って7色に分けているだけです。

実行結果
今回もあぴミクさんを使用させていただいております。今回のエフェクトと元絵を黒縁以外50%で合成した結果になります。屈折を入れればもう少しましに見えますかね。

cellular_003.png

fxファイル等
CellularNoise_v002.zip

[1] Independant Research Skin Shader
[2] Drilian’s House of Game Development
web拍手 by FC2
posted by シンドラー at 20:10 | Comment(0) | TrackBack(0) | MMD | このブログの読者になる | 更新情報をチェックする

2014年04月24日

MMEのテスト その5

OpenGL Insights[1]を眺めていたら、Worley noise[2]というものがありましたのでMMEで試してみました。細胞みたいなノイズですね。GLSLのソースをHLSLに書き換えただけです。ライセンスはMITライセンスになると思います。

実行結果
cellular_001.png

fxファイル等
CellularNoise_v001.zip

[1] http://www.borndigital.co.jp/book/2783.html
[2] http://webstaff.itn.liu.se/~stegu/GLSL-cellular/
web拍手 by FC2
posted by シンドラー at 23:30 | Comment(0) | TrackBack(0) | MMD | このブログの読者になる | 更新情報をチェックする

MMEのテスト その4

擬似乱数を生成するよりはやっぱりテクスチャを使用した方が良いかな、ということで、どうせなら?3Dテクスチャを使用できた方が便利だろうということでddsファイルを使用することにしました。
ddsファイルは、DirectDraw Surfaceというファイル形式のようです。で、乱数を生成して画像にしてddsファイルとして出力する必要があります。自分で実装するのは面倒ですので、既存のライブラリであるDevIL[1]を使用することにします。

DevILの使い方

使い方は[2]等を参考にさせていただきました。
[1]のDownloadから、DevIL 1.7.8 SDK 64-bit Windowsなど、最新のSDKをダウンロード・展開します。
includeフォルダと、.lib, .dllがありますので、普通のライブラリと同様の準備をするだけです。(省略)

1.使用準備
init関数を呼び出します。
    ilInit();
iluInit();
ilutInit();

2. 画像の生成
OpenGLのテクスチャに似た扱いですので、慣れているとわかりやすいかもしれません。
  // IDの生成
iluint id = ilGenImage();
// バインド
ilBindImage(id);
// 画像の領域を生成(画像の幅、高さ、奥行き(2次元画像であれば1)、
// 1ピクセルあたりのバイト数(通常1,3,4のどれか)、フォーマット(IL_RGB等)、
// タイプ(IL_UNSIGNED_BYTE等)、コピーするメモリ(ピクセルデータ、
// 初期データがない場合はNULLでもよかったり?))
ilTexImage(width, height, depth, bpp, format, type, local);
// バインド解除
ilBindImage(0);

3. ランダムノイズの設定
  // バインド
ilBindImage(id);
// ピクセルのポインタの取得
ilubyte *data = ilGetData();
// 乱数の設定
for (int i=0; i<width*height*depth*bpp; i++)
{
data[i] = 255.0*randomfunction();
}
// バインドの解除
ilBindImage(0);

4. 画像の保存
  // バインド
ilBindImage(id);
// 上書き
ilEnable(IL_FILE_OVERWRITE);
ILboolean ret = ilSaveImage("random.dds");
// バインドの解除
ilBindImage(0);

保存したデータをDirectX Texture Toolで開いてみたところ、DXT1形式になっていたので、メニューのFormat→Change Surface Format→Unsigned 8-bit: L8に変更して上書き保存しました。DevILのパラメータ設定をちゃんとすればうまくいくのかもしれません。

HLSLでの3Dテクスチャの使用方法

3Dテクスチャの使用方法は、舞力介入PのOldTV[3]を参考にさせていただきました。
  texture3D Rand_Tex
<
string ResourceName = "random.dds";
>;
sampler Rand = sampler_state
{
Texture = (Rand_Tex);
ADDRESSU = WRAP;
ADDRESSV = WRAP;
ADDRESSW = WRAP;
MAGFILTER = POINT;
MINFILTER = POINT;
MIPFILTER = NONE;
};
...
float rand = tex3D(Rand, float3(px, py, pz)).r;


実行結果

ランダムノイズをテクスチャに置き換えました。無駄に3Dテクスチャにしていますが奥行きは2枚しか作っていません。
その他バグ?を修正したので、やっとそれっぽくなってきた気がします。

LIC_003.png

fxファイル等
LIC_v003.zip

[1] http://openil.sourceforge.net/
[2] 続・OpenGL+DevILで画像読み込み
[3] http://www.nicovideo.jp/watch/sm12149815

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

2014年04月22日

MMEのテスト その3

色々なエフェクトを参考にさせていただき、遅延レンダリングの方法が分かったのでLICを作り直してみました。といってもデータPのCroquisエフェクト[1]を改変させていただいただけです。

遅延レンダリングのやり方として、オフスクリーンに描画して、それをテクスチャとして参照する方法があるようです。

  // 法線マップ
texture CM_NormalMap : OFFSCREENRENDERTARGET <
string Description = "NormalMap";
string Format = "D3DFMT_A32B32G32R32F";
float2 ViewPortRatio = {MapTimes,MapTimes};
float4 ClearColor = {0,0,1,0};
float ClearDepth = 1.0;
bool AntiAlias = false;
int Miplevels = 1;
string DefaultEffect =
"self=hide;"
"*=NormalDraw.fx;"; // オフスクリーンレンダリングに使うfxファイル
>;
// サンプラ
sampler NormalMapSampler = sampler_state {
texture = <CM_NormalMap>;
MinFilter = POINT;
MagFilter = POINT;
AddressU = CLAMP;
AddressV = CLAMP;
};

この方法を使えば、メモリと性能の許す限り法線情報や深度情報などのG-Bufferをテクスチャとして参照することができますので、大体やりたいことはできるようになるかなと思います。

その他の方法として、sharedキーワードでエフェクトファイル間でパラメータ共有ができるようで、Excellent Shadowでもshared texture ...としてテクスチャの共有をしているようでしたので、こういうやり方でも実現できるような気はします。

また、肌のところだけ処理を外すといった処理は、techniqueのところでSubsetを指定してあげれば、指定した材質番号だけにエフェクトが適用されるようになるようです。

後は、擬似乱数がかなり適当なのでもうちょっとまともなものにしたいのですが、メルセンヌ・ツイスタやXorShiftなどをMMEで作っている人はいらっしゃらないんですかね。3次元テクスチャを使う方が楽で速いのでいいんでしょうけれど。

実行結果

あぴミクさんとぽっぴっぽーモーション[2]を使用させていただいております。



シフト演算の問題とかDirectX11であれば対応できると思うのですが、MMEのDirectX11版は公開されてないのでしょうか。MikuMikuFlex[3]とか使えばいいんですかね。

fxファイル等(素材画像は入れていません)
LIC_v002.zip

[1] http://www.nicovideo.jp/watch/sm14263863
[2] http://www.nicovideo.jp/watch/sm5838726
[3] http://www.nicovideo.jp/watch/sm22078209

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

2014年04月16日

MMEのテスト その2

静止画にしか使えない実用性のないエフェクトですが、昔の記事で書いていたアンサンブル平均をMMEでやってみました。

正規分布に従うノイズをもつカメラモーションはVMDConverter[1]を使用させていただき、VMDConverter用のcsvファイルをプログラムで生成してvmdに変換しました。

使い方はReadme.txtに書いていますが、やっていることはカメラを微妙に動かしながらレンダリングした過去フレームの総和を保存しておいて、フレーム数で割っているだけです。

既存のエフェクトを改変させていただくことでできましたが、まだtechniqueの書き方がいまいちわからないですね。

実行結果
今回もあぴみくさんと初期ステージを使用させていただいております。ポーズを工夫する気力がなかったので初期ポーズです。

MMDで「ファイル→画像ファイルに出力」で出力した結果
mme_average_001.png
アンサンブル平均5000回とった結果
mme_average_002.png
ここで見るとまったく違いがわかりませんね。

fxファイル等
MME_average_v0.zip

[1] http://yumin3123.at.webry.info/200810/article_4.html

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

2014年04月12日

MMEのテスト その1

今更ながらMMEを試してみることにしました。とりあえず[1]を参考にさせていただいて、LIC法をMMEで作ってみました。

エッジを加えてないせいもありますが、かなり拡大しないと薄すぎますね。やっぱりGLSLとは違うので、色々やりたいことはあるのですがどう実装すればいいのかがわからないですね。ポストエフェクトは重ね掛けできるみたいですが、色々なレンダリング結果を違うfxファイルから参照したりとかできるんでしょうか。

fxファイル等(エラーがあったので差替えました。2014.4.14)
LIC.zip

実行結果

あぴみくさんを使用させていただいております。

LIC_MME_001.png

[1] MikuMikuEffectで学ぶHLSL入門
web拍手 by FC2
posted by シンドラー at 21:11 | Comment(0) | TrackBack(0) | MMD | このブログの読者になる | 更新情報をチェックする

2012年11月07日

BVH→VMDのフレームの間引きについて その4

続きです。

クォータニオンの補間曲線近似の時にたまにエラーが出ていたのですが、エラーが出ているところを見ると、線形補間中の現在のクォータニオンと、目標となるVMDファイルのクォータニオンのx,y,z,wのそれぞれの符号が逆の場合にニュートン法が収束していませんでした。

例:
現在:x,y,z,w=-0.01, -0.02, 0.4, 0.64
目標:x,y,z,w= 0.016, 0.022, -0.38, -0.66

この場合、符号が反対なだけで表している角度はかなり近いようでしたので、現在と目標の符号がすべて逆の場合、目標のクォータニオンを-1倍することでエラーが発生しなくなりました。

他のエラーとしては、オイラー角で判定していたため、方向は同じだけれど変化量が多い場合にも発生していたため、ある一定以上オイラー角が変化した場合にも区切りを入れることにしました。

また、前回は適当にニュートン法を使っていましたが、一応数式で考えて計算してみました。

bezier_002.png

ただ、振動しながらの減少というか単調減少しない場合も多かったので、何か間違っているかもしれません。

実行ファイル
BezierTest_v005.zip

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

2012年11月06日

BVH→VMDのフレームの間引きについて その3

続きです。

クォータニオンは軸も角度も細かく変わりますので、クォータニオンから一旦オイラー角に変換して、オイラー角のXYZ各軸の方向が変化した場合に、そこで区切るモードも追加しました。

その他のBVHファイルでの確認ということで、下記サイトのもので試してみました。
https://sites.google.com/a/cgspeed.com/cgspeed/motion-capture
手順としては前回同様Live Animation経由でVMDにしています。

いくつかの形式のBVHがありますが、Live Animationでそのまま読込んで問題ないのは3. MotionBuilder-friendly versionでした。

ここのBVHのデータ元はCarnegie Mellon Universityのもので、研究用などにフリーで使用可能で、BVHやその変換したものをそのまま配布してはいけない、というライセンスのようです。
http://mocap.cs.cmu.edu/

実行結果

オイラー角判定で削減した結果と全フレームの結果を重ね合わせています。
動きがゆっくりなせいもありますが、ずれは殆どないように見えます。

実行プログラム
BezierTest_v004.zip

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

BVH→VMDのフレームの間引きについて その2

昨日の続きです。

回転の方は、クォータニオンの線形補間になっているようでした。
自分で実装するのが大変でしたので、実例で学ぶゲーム3D数学のサンプルソースコードを参考にさせていただきました。

並進の時と同様に、削除しないフレームは、クォータニオンのx,y,z,wの値の方向がどれか一つでも変化したら削除しないことにしました。こうするとボーンによっては殆ど削除されなくなってしまいますので、工夫すればもっと減らせるかもしれません。

また、dxとクォータニオンの値x,y,z,wは既知ですので、そこからニュートン法でdyの値を探索するようにしました。dyの候補として、x,y,z,wそれぞれの誤差を減らす方向に4個の候補ができますので、4つのうちでもっとも誤差が小さいdyを次のdyとして探索していきました。探索に失敗した場合は線形補間でごまかしています。

実行結果

昨日と同様のデータを用いています。
世界進出プロモーションサイト
http://www.perfume-global.com/


あまり削減できていませんが、全フレームの場合と比べてもほぼ誤差がない感じになっていますので、自動で減らすのであればこれぐらいかなと思います。

実行プログラム
BezierTest_v003.zip

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

2012年11月05日

BVH→VMDのフレームの間引きについて

MMDでBVHファイルを使用する場合、BVH→VMDに変換すると思います。
そのために使用できるソフトウェアとしてLive Animationがあります。
http://www.drf.co.jp/liveanimation/
手順参考:http://mikudan.blog120.fc2.com/blog-entry-223.html

このソフトウェアでVMDファイルとして出力できるのですが、すべてのフレームに点が打たれていてサイズが大きいので、自動で間引くためのプログラムを作成してみました。

間引いてはいけないフレームとしては、並進(センターやIK)の場合、各XYZ軸方向の移動方向が変化した場合です。
例えば、X軸の場合、右にすすんでいて次に左にすすむ場合、つまり符号が変わるタイミングのフレームを削除してしまうと、元の動きを実現することはできなくなります。
ですので、各軸方向で、一つでも符号が変化したら、そのフレームは削除しないことと、あまりにも間が空くと、同じ方向に進んでいても補間曲線で表せなくなってしまうので、間引く最大数を指定することにしました。

また、合っているのかどうか微妙なのですが、一応補間曲線も自動で追加できるようにしました。
本当は間引くフレームの座標からベジェ曲線のパラメータを推定したかったのですが、時間がかかりそうでしたので、とりあえずMMDの(ax, ay), (bx, by)の2つの制御点から625個(ax,ay,bx,byそれぞれ0, 32, 64, 95, 127の5通りで5x5x5x5)のベジェ曲線を生成し、625個の中から一番近いベジェ曲線を選んでみました。

生成したベジェ曲線の例
line0234.png line0272.png

bezier.png

上のような理由から3次方程式を解くプログラムを作成しました。この辺MMDではどうやってるんでしょうかね。xの代わりにtをそのまま使用しているのか、何か間違っているのか。

Bezier.cpp

このプログラムは下記のサイトを参考にさせていただきました。
[1] http://ideone.com/HqTOP
[2] http://ja.wikipedia.org/wiki/%E4%B8%89%E6%AC%A1%E6%96%B9%E7%A8%8B%E5%BC%8F
[3] http://okwave.jp/qa/q2277096.html
一応カルダノの公式で還元不能になる場合はビエタの解を使うようにしましたが、計算時間を考えると結局数値計算的に解いた方がいいんでしょうね。

実行結果

PerfumeのBVHファイルをLive AnimationでVMDファイルに変換して試してみました。
世界進出プロモーションサイト
http://www.perfume-global.com/

初音ミクVer2と初音ミクメタルを重ねて表示して、片方が全フレーム、もう片方が間引いたVMDファイルを使用しています。大体1/3ぐらいしか間引けていないので、殆どずれがないかと思います。



角度の方は等間隔で1/3フレームに間引いています。角度の方も何か工夫がしたいですね。

ちゃんと動くかどうかわかりませんが実行プログラムもあげておきます。使い方についてはReadme.txtを見てください。

実行プログラム
BezierTest_v002.zip
(2012.11.05追記:ものすごく初歩的なバグがいくつかあったので修正しました)
web拍手 by FC2
posted by シンドラー at 00:26 | Comment(2) | TrackBack(0) | MMD | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。