2ntブログ

ぷりみてぃぶろぐ

3Dイリュ毛の改造記事と、個人的な記録。

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
  1. --/--/--(--) --:--:--|
  2. スポンサー広告

ひさしぶりに!改造(お勉強)めも

イリュゲーのみならず、エロゲはDirectXを使ったプログラムがほとんどです(なんと、2Dでも!)
ということで、DirectXな3Dについてのおさらいなど、つらつら~とメモっていきます。
なんでここでやるのかって?・・・そりゃ、こういうのやるとウケが悪いでしょw


PNG
汎用画像形式。Zipと同じ圧縮形式で、ライセンスフリー!
IENDチャンク以降は独自データを追加することができる。
イリュゲーではPNG形式でポーズやシーンのセーブをすることがある。
<画像PNG~IEND>+<イリュ独自データ>+<独自データのサイズ:4ByteUInt>
きゃらコレの場合、簡単に構造を書くとこんなかんじになる。
独自データの中身はゲームによりけりだが、PNGっぽい書き方の箇所もある。
PNG部分はBigEndianだけど、イリュはいつも通りLittleEndianです。
PNGの中のブロックをチャンクといい、形式が決まってるんだけども、
<サイズ>+<4文字の識別子>+<データ>+<CRC/チェックサム>
仕様書に従って作るチャンクはこんな感じの構造なのです。
イリュの独自データはちょっと違うんだなぁ。
<UInt/チャンク先頭のチェック用固定値>+<2文字の識別子>+<データ>
ということなので、IENDなCRCの次に来る固定値+識別子を検索すれば解析しやすいってことね。
イリュはもっと圧縮画像を使うべきだと思うんだ・・・なんでBMPなんすかー!?


UnknownHexってなによ?
わけわからんデータ、ではあるんやけども、それが何に影響してるのか分からんだけで、
そのバイナリがどういうデータなのか?というのは
(暗号化でもされてない限り)だいたい分かるので、TSXBINなんかに打ち込んで見てみよう!
・・・でも、めんどくさいよね。
ということで、それがどんなデータなのか?というのを解析するツールがあればいいと思うのです。
例えば、法線データはFloat*3(長さ=1)だから、(-1,0,0)みたいな並びになる。
uvデータは0~1(?±0.5)になるし、頂点位置でほとんど+だけなのはY座標だし。
こういうのが重なると、解析しやすくなってくるわけですね。
色がRGBAだと1,1,1,0みたいな並び多いしね。
分かり易いのはええんやけど、ラジアン角とかの謎の1~3になる数値とかどうすんべ?と。
アドレス→データ長→数値変換 みたいなバイナリ表示&書き込みができたらええなと。
で、とりあえず「俺主」とかの移植キャラに輪郭線を好き勝手につけるためのHexエディタ。
シェーダー用のパラメータで、輪郭線の色とか太さとか自由に入力できるかな?
できたらええなあ・・・そんな感じのエディタをXXMiniConverterに付けたいね。


法線・・・?なんやねん、それは(困惑)
頂点はわかるけど法線がわからん人が多いね。
3つの頂点で作る△の面から生える垂線のベクトルを考えるとしようか。
これは面の法線、向き、わかりやすいわな。
頂点1つに法線1つを割り当てたらどうなるか?
つまり、3つの法線の向きが揃った△は見掛け上も実際も平面やな。
でも、もし3つの法線の向きがバラバラだったら・・・見掛けはどうなるか?
近接する頂点の法線がバラバラの場合は別の面に見える。
近接する頂点の法線が揃っている場合は連続した面に見える。
ローポリをハイポリっぽく見せるのが頂点ごとに法線を割り当てた利点やね。
法線を使って輪郭線(トゥーンシェーディング)を描画してる場合はその影響も顕著です。
法線(Normal)マッピングといって、画像から見掛けの法線を貼りつける手法がPPDで使われているように、結構面白いことができる法線。
じっくり考えつつ、パーツを分割するといいですよ!


裏面・・・!?
法線の続きになるけど、全く同じ位置に頂点がある△の表と裏を区別するのは何やろか。
それが面の向き。頂点を繋ぐ面は頂点番号3つの順番で表がどっちか区別しております。
面に材質(Material)が適応され、テクスチャが貼られるわけやな。
裏はどうなってるかというと、なにもない!ふしぎ!!
裏面を描画するシェーダーを使うと裏も自動で表示されるけど・・・
スカートの裏地を表現するには別の面を使ったほうがいいよね。
この両面をひとつのMeshにしたとき、困るのは法線のベクトルです。
裏と表のベクトルは普通に計算したら全く逆方向になるから・・・
もし、近接頂点の法線を平均化してしまうと、法線ベクトルが0になってしまう!?
無理やり法線の長さを1に戻すともっと悲惨なことになります。
めんどくさいけど、近くて別のMeshは分けて入れないとアカンのよね。


顔モーフを作るには?
全頂点をモーフすると某大なデータが必要なので、なんとか最適化したい。
標準顔と頂点を動かした顔のメッシュを比較して、位置が違う頂点のIDを記録すればエエねん!
でもって、次はモーフした頂点位置+法線ベクトルの情報が必要になるね。
最後は、それらの組み合わせを仕様にあわせて構築する。
表情パーツID、表情番号、Open/Closeの数値とモーフ名、頂点IDのパーツ名を綺麗に並べたらOK!
でもまあ、現状やとメッシュの出し入れにはXXが無いとダメだし、表情みながら作業したいし。
3Dなツール、または代用品が必要やね。それは・・・つまり・・・w


モーションって何なのさ?
ダンスとか、反復運動(アレ)とか、3Dのキャラクターをどうやって動かしているか?
・・・というと、ほとんどは「骨格」を動かしているんだよね。
中の人がモーションキャプチャで動かした頂点座標を取りこんで、骨格の動きにする。
なめらかな補間(球形線形補間)ができるのが、コマアニメとの差ですなぁ。
モーフは頂点や法線といった皮膚(Skin-Mesh)を動かしているんだけども、
こっちは骨格(Skeletal-Frame)を動かす。
4×4の姿勢行列(Matrix)を4元数(Quaternion)という形式と変えて
中間姿勢を綺麗につなぐ、これは数値を見ただけでは全くわからんな。
大事なのは「骨格(Frame)」を識別しているのは名前であること。
骨の名前を書き換えれば、別のゲームからモーションを移植できる!って奴やな。
そして、キャラクターによって骨格が違うこと。
関節の位置(Translate)を差分計算して位置合わせするツールは作ったやろ?
でも、関節の数が違う場合、二重関節になってる場合と互換するにはどうするか?
関節の親子関係から、回転の合成(積)または回転の分割をせにゃならん!難問よ。
ツール開発で避けて通れないところ(数学!)がんばりましょう。


ウエイトってなんなのよ・・・うまくいかへん。
Meshと骨(Bone)の関連付けが<頂点ウエイト>Weightやな。
どの骨にどれだけ乗っかってるか?という情報のことです。
1.0の荷重を骨3本に分けたり、2本だったり、4本だったり色々ですな。
で、この骨は骨格と対応してるんやけども・・・全く同じなのは名前だけ!やねん。
SkeletalFrameのMatrixをいじるのと、BoneのMatrixをいじるのは同じように見えて違うということやな。
Skeletalはアニメで動かす部分。XAやKYSやBPSやTTYで書き変わる。
Boneを動かすのはMeshを変形させたい時やねんな。
MeshごとにBoneがあるということは、別の数値を入れて部分変形もできるんや。
ウエイトが均等に乗ったMeshはだいたいの形を保つように見える。
Bone1本にWeight1全部乗せればカチーンと硬化したまま動く。
逆に、肘みたいな関節に上手くウエイト載せないと、ゴム人間みたいになるw
SB3Uでウエイト表示させながらSkeletalの変形をすると分かり易いかな?
SB3Uは元々のMeshにあったウエイト情報から数値をコピペしてるだけなのよね。
だから、ハイポリ化しただけじゃ滑らかに追従しない。
このへんの計算を綺麗にやれればハイポリ化に対応できそうなのになぁと考え中。


右手座標系と左手座標系
うん、突然コアな話題wOpenGL系(右手)とDirectX系(左手)やね。
最古の3Dイリュゲーが何かはわかりませんが、人工2まで(BR2まで)のイリュと、
レイレイ以降のイリュでは大きな違いがあります。
TBLを使ったXファイルがLSTを使ったXXになったりといった形式もそうですが、
開発ツールの変更による座標系の変更が過渡期のBR2を見るとよくわかります。
簡単にいえば、親指=X、人差し指=Y、中指=Z軸とすると、
右手と左手はひとつの軸が対称になります。
これは、平面(X,Y)を固定すると必然的に奥行きのZ軸で向き(±)が逆になるということです。
Z軸の向きが逆のデータでは、面の向きも、法線の方向も、なにもかもあべこべです。
ですが!
変換の法則さえ掴めば、MeshでもMatrixでもQuaternionでも計算できるんですねえ。
いやあ、計算機っていいものですね。


反転の公式
ここから本題w忘れないうちにメモっておこうと思いましたので、めも~る。
軸の方向を反転させたMatrixは、タテヨコ両軸について符号を反転し、重なった部分はそのままの符号になる。
( -1 × -1 = +1 )

matrix0;
rot-X' rot-Y' rot-Z'  W
X m00 , m01 , m02 , m03
Y m10 , m11 , m12 , m13
Z m20 , m21 , m22 , m23
T m30 , m31 , m32 , m33

左右反転(X軸/YZ平面)
matrixX;
rot-X' rot-Y' rot-Z'  W
X m00 , -m01 , -m02 , m03
Y -m10 , m11 , m12 , m13
Z -m20 , m21 , m22 , m23
T -m30 , m31 , m32 , m33


座標系の反転(Z軸/XY平面)
matrixZ;
rot-X' rot-Y' rot-Z'  W
X m00 , m01 , -m02 , m03
Y m10 , m11 , -m12 , m13
Z -m20 , -m21 , m22 , m23
T m30 , m31 , -m32 , m33


4元数による回転 + スケール + 移動
Q0( w, x, y, z) Scale-0( X, Y, Z) Translate-0( X, Y, Z)

左右反転(X軸/YZ平面)
Qz( w, x,-y,-z) Scale-Z( X, Y, Z) Translate-Z(-X, Y, Z)


座標系の反転(Z軸/XY平面)
Qz( w,-x,-y, z) Scale-Z( X, Y, Z) Translate-Z( X, Y,-Z)


どや?手首がクルクルーやろ?w
最近のイリュゲーは左手系、昔のイリュゲーは右手系、そういうかんじやでー。


4元数回転行列相互変換
4元数では姿勢がわかりにくいが、補間の計算がしやすい。
回転行列はその逆で、姿勢はわかるが、補間は難しい。
この両者のいいとこどりをするためには、相互変換をする必要がある。
四元数 → 回転行列(3×3) または 回転行列(3×3)→四元数
の公式で、OpenGL系(右手)とDirectX系(左手)を変換する行列を転置すればいい。
転置とは、つまり、回転軸の配列とベクトルの配置を逆にするということ。
もっというと、回転Matrixの行と列を入れ変えるということ。
式が複雑なため、それぞれのリンクを貼って〆にします。

DirectX/左手系 (行方向が軸の向き)

その58 やっぱり欲しい回転行列⇔クォータニオン相互変換

見比べると、途中に出てくる回転行列の内容が・・・!?

OpenGL/右手系(列方向が軸の向き)

回転行列からクォータニオン(四元数)に戻す

そこで気になるのが、スケールと移動と回転のタイミングなんよね・・・
数学オンチの私にとって道は険しい^^;まだまだ試行錯誤はつづいております。


で、きゃらコレのセーブいじってて「もしや?」と思ったことが幾つかあるので、実験しつつツールを完成させていきたいと思います。
・どこのフォルダに入れても、ロードすると部分セーブはちゃんと適応される
 ならば → アイテムセーブは本当に部分セーブをロードできないのか?
・セーブの内容は回転だけのMatrixと初期姿勢(移動アリ)のMatrixと整数値のフラグ
 回転Matrixしか読んでないならば → 回転部分を拡大したセーブデータを使うと・・・?
 もしかすると、きゃらめいくが出来るのかも!?
なんにせよ、4元数→回転行列への変換も実装しなくちゃいけませんね。
今まで避け続けていた禁断の領域に足を踏み入れたその後は一体どうなってしまうのか。
もしかしてアタシ、消されちゃうカモ!?w
使い方によってはかな~り危険なツールばかりのため、コソコソしておりましたが、はてさて。
  1. 2013/04/26(金) 21:18:10|
  2. 改造
  3. | トラックバック:0
  4. | コメント:0

コメント

<%template_post\comment>


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://ganou.blog.2nt.com/tb.php/75-995034c0
この記事にトラックバックする(FC2ブログユーザー)