データ解析一覧

MMDのデータをロードする(メモ)

MMDのデータ(PMDとVMD)をロードするということをやっていて、
今現在苦労中です。ここまでくるにも色々と気をつけなくてはいけない点がありました。防備録というかメモというか記しておきたいと思います。すごく今更ですが・・・。

座標系
データは左手座標系で格納されている。
右手座標系で処理している場合には、Z値の反転とポリゴン面の表裏が反転するので
その補正を行うこと。

親子構造に関して。
ボーンの親子構造においてローカル座標ではなくグローバル座標で位置が記録されている。よくあるモデルデータにおいてのローカルマトリクスは存在しないので、この位置と親の情報を使ってローカルマトリクスを生成する必要がある。
(親のワールドマトリクスと今求めたローカルマトリクスでの計算結果が、元々記録されていたグローバルでの位置と一致しないことがあるので注意が必要)
(スキニングメッシュの描画がおかしくなってこのことが発覚した。)

スキニングメッシュでの定番のバインド行列は回転が空のため、またボーン位置をグローバル座標で保持しているため簡単に求まる。

PMDデータは上記の性質により、頂点データをロードして単一のワールドマトリクスで描画させるとAスタンスのモデル形状として描画することが出来る。すごく簡単。

アニメーションについて。

アニメーションのデータはボーンの位置データと回転データを保持している。
ここまでは多くのデータと変わらないが、位置データは実はローカル座標でもグローバル座標でもなく、ローカルでのオフセット値が格納されている。
ネットで調べると親からの相対オフセットが格納されているということなので、これはすなわちローカル座標系でのオフセット値となるので、その情報と一致している。

足はIK(Inverse Kinematics)によって制御されるのでアニメーションのデータとしては
記録されていない。うまく動かすためには相当大変なようだ。


ATCテクスチャのデコード

先日のPVRTCに引き続き、ATCテクスチャのデコードにチャレンジしてみました。
ATCでは、AMD_compressed_ATC_texture.txt にあるように3つの種類の方式があるようです。

  • 不透明: ATC_RGB_AMD
  • アルファあり: ATC_RGBA_EXPLICIT_ALPHA_AMD
  • アルファあり: ATC_RGBA_INTERPOLATED_ALPHA_AMD

これらはそれぞれFourCCが割り当てられているようで次のようになっています。
圧縮後をDDSに出力するツール(Compressonator:AMD製)で確認してみました。

  • ‘ATC’: 4bpp: ATC_RGB_AMD
  • ‘ATCA’: 8bpp: ATC_RGBA_EXPLICIT_ALPHA_AMD
  • ‘ATCI’: 8bpp: ATC_RGBA_INTERPOLATED_ALPHA_AMD

ATCはQualcommのSnapdragonでサポートされている形式でもあり、AdrenoSDK 3.0で提供されるツールでも出力が可能となっています。しかしながら EXPLICIT_ALPHA と INTERPOLATED_ALPHA のFourCCが逆に出力されるようです。
テクスチャツールが割と扱いやすいだけにこのバグは修正されて欲しいなと思います。
それともこれらの圧縮形式を使う場合にはKTXフォーマットの方がいいのかも。

とりあえずわかっている情報からATC圧縮形式をデコードしてRGBA8にして、DDSとして出力してみました。次のような感じに変換できており無事に処理できていそうです。


右側には対等な関係にあるDXT圧縮の物を比較のために並べてみました。
だいたい同様のアルファ変化となっていますし、正しそうな気配です。


PVRTCテクスチャの解析 その5

以下は2BPPの補間モード適用状況においての話。自分用のメモですがちょっと残しておきます。

Modulation BitのLSBに 補間モードのフラグが格納される.

  • LSB = 0 なら 水平垂直の補間モード(仮にモードA)
  • LSB = 1 なら 1方向の補間モード(仮にモードB)

モードBの場合、ブロックの中心となる位置のModulation Bitの値を見る.
中心となる位置は 8×4ブロックなので LSBから数えて21番目のビット位置が見るべき値となる

  • このビットが 0 なら 水平方向のみ補間モード(仮にモードB1)
  • このビットが 1 なら 垂直方向のみ補間モード(仮にモードB2)

となる。

このようにモード振り分けに2bit使ってしまっている。
各ピクセルは2bitという点で、どのように補填するかというと、
LSBのフラグ部分に関しては、LSBから2bit目の値をコピー、同様に21番目のビットは22番目のビットの値をコピーしてくる。この状態のModulationDataは各ピクセルごとに2bitずつ割り当てられ、色の計算に使用される。

以上の処理によって、補間モード3つと各ピクセルのModulation値が求まる。

補間モードにおいて、ちょうどチェックパターンの箇所に該当する=Modulation値がちょうど存在する場所のピクセルの計算においては、2bitのModulation値がそのまま使われる。
補間モードの補間とはチェックパターンの隙間に関しての補間方法ということになるようだ。


PVRTCテクスチャの解析 その4

ようやくデコード(仮)が出来ました。
6種類くらいの並び替え方式を試していたらピタリと当てはまる物があったのです。
これで一段落かと思いきや、2BPPタイプのほうがとても難しい。
今までは割と素直な4BPPタイプの物を扱っていました。
4BPPだと処理単位が正方ブロックでModulation Dataと呼ばれる部分の並びもwhite paperにあったりして、情報が結構そろっている&解説されているためこちらを選んでいました。

しかし、2BPPの物については説明があまりないです。
2種類くらいのpdfを読んで、両者から情報をかき集めてデコードしてみたのですが、それでもまだエラーが残る状態です。

デコード後にエラーが残っている図

2BPPにおいては、Modulation Dataの部分がいろいろと複雑なようです。
まずmodeにより2種類の並びに分岐します。1つは1bitで各ピクセルをColorA or Bを選択する方式、もう一つが並びがチェックパターンとなり、white paperによると補間モードとしてさらに分岐されるとなっています。
問題はこの補間モードにあるのかと考えています。

エラーの部分を抽出

エラーがどの程度発生しているのかを調べるために、2枚の画像を引き算してみました。
その結果下記のように、エラー発生具合にもばらつきがあることがわかりました。
見ているとどうも2種類のケースがあるようで、ブロック範囲全体にエラーが散るケース、規則的にエラーが発生するケースとなっているようにもみえます。
これを2BPPの8×4ブロックで区切ってみるとそれがわかりやすい気がします。

画像の差分と、グリッド表示

このことからブロック最初のピクセル情報として取り出しているデータに関しては別の情報が格納されている可能性がありそうです。


PVRTCテクスチャの解析 その3

引き続PVRTCテクスチャのデコードをやっていました。
カラーデータの読み込みと RGBA8 への展開処理を再度チェックして修正した状態の物が下記の状態です。

とりあえず仮想イメージA,Bは使用されている色情報としては正しそうな感じになってきました。

ポイント

前回から見直した(修正した)部分は、カラーA,Bそれぞれを単に出力するのではなく、隣接するピクセルからの線形補間の処理を入れたことです。またこのときに元のRGB値を 各8bitとなるように展開処理も含めてみました。

色情報が正しそうな感じになってきたので、やはり気になるのは画素の並びです。今は普通に順番に並べていますが何か他の方法で並び替えたりするとうまくいくのでしょうか。
論文には並びについて記載しているようには見えないし、いくつかの方法でうまくいかないかチャレンジしてみようかと思います。


PVRテクスチャ形式の解析 その2

以前調べてみたときから9ヶ月くらいたっていますが、最近また調べてみてわかったことを書いておこうと思います。ここでPVR形式と言っていますが、ファイルフォーマットとしての形式のことと、PowerVRのテクスチャ圧縮 PVRTC とごっちゃになっていました。調べてみた対象としては両方とも含むのですが、どちらかといえばPVRTCについて興味があるといった感じです。

PVRTexTool v3.33を使用してみてわかったのですが、PVR形式のヘッダが昔と比べて変わっています。ざっと見たところ格納できる情報が増えていました。メタ情報が格納されるようです。
これにより先頭から52バイト目からデータがあるというプログラムコードだと正しく動作しません。PVRTexToolを使っているならぼちぼち対応しておかないといけなさそうです。
その一方で、PVRTexToolのよかった点として、旧フォーマットでも保存が出来ることです。現在のような移行期においてはこの機能にお世話になりそうです。

PVRTCのデコードにチャレンジ

仮想イメージA, Bをまず取り出してみようとコードを書いてみました。
うまくいけば、元の形状が予想できるような物が出てくるはずです (と思っています)。

その結果、次に示すような2つの画像が得られました。非常に暗いですが何か色は出ているようです。

仮想イメージA仮想イメージB

ちなみに元の画像は次のものでした。

全く正しそうな感じがしません…。うまく出てくるようならば白黒の合成用画像も出してみようと思ったのですが、これは難航しそうです。


PVRテクスチャ形式の解析 その1

解析というほどでもないですが…調べてみた&わかったことをしばらく書いてみたいと思います。
PowerVR-SDKをダウンロードすると中に文章が入っています。
これが全てなのですが、防備録も兼ねてメモしていきます。必要な物は PVTRC Texture Compression.Usage.Guide(PVRTexLibの中のドキュメント)です。ここにファイルの中の画像データに関する情報が詰まっています。
ほか、PVRTCアルゴリズムの元であるSimon Fenny氏の論文”Texture Compression using Low-Frequency Signal Modulation”です。

PVRTC圧縮の特徴

  • 2BPP/4BPPから選択
    • RGBA8の画像に比べると 1/16, 1/8の圧縮率
  • 2べきサイズの正方形な画像である必要がある
  • アニメ調は不向きで写真のほうが向いている
  • スマートフォン用GPUではこの形式を直接扱える
    • PowerVR系ならば.
    • Tegra2とかでは使えない。

処理概要

PVRTCのデータから圧縮を解除してみることを考える。
PVRTCデータを伸張すると仮想的な3つのイメージデータが出てくる。
この3つのデータを合成し、最終的な画像を生成する。
ざっくり説明してしまうとこんな感じ。

3つの画像データのうち、1つはその他2つの画像をどのように合成するかのパラメータが格納された物である。
そして、2つの画像データ(画像A, 画像Bとしておく)は、元の画像データと比較して1/4のサイズになっている模様。