Progress report 2017-W29 – 2017-W30: last-progress1

2017-W28-6 (Sat) から 2017-W30-5 (Fri) までの last-progress1 の進捗ログ。 ちょっと長くなった(というか画像がデカい)ので、日記から記事を分離した。

進捗: last-progress1

リポジトリを作りはしたが、個人開発だし feature ブランチは rebase しまくる思想を持っているので、 diff 等へのリンクは張らない。

より優れた三角形分割

優角 (concave, 180度以上の角)が1つ以内の多角形は、その角を共有する triangle fan を作ってやることで簡単に三角形分割できる。 今までは面倒だったため三角形分割は四角形に対してしか行っていなかった(何故なら優角の存在判定が楽だったから)が、これを任意の多角形に対しても行うことにした。

何故そんなことをしようと決めたかというと、表示テストで使っている(そしてゲーム本編でも使おうと考えている 中野シスターズという FBX モデルが、5角形を含んでいるからである。 勘弁してくれ。

優角の個数判定については、いつか別記事で書くことにしよう。 さて、アルゴリズムは(理論的には)問題ないはずであったが、一部の辺が短すぎるせいか、はたまた5頂点が同一平面上にないせいか、何故か優角の個数を誤って数えることがあった。

これを、 xyz のうち多角形が広がる幅が最も狭い軸を潰して xy, yz, zx 平面のいずれかに投影したのち平面上で法線を出すことで、諸問題を無視して正しく優角の個数を判定することができるようになった。

dots として出力されているのが、ある頂点における面の法線(隣接辺の外積)と、別の頂点における法線との内積。 当該モデルの5角形は、優角はあっても1つなので、本来は全て正か全て負か、ひとつだけ負であるかしかありえない。
5角形だけ抜き出して、(不正確な)三角形分割後の三角形ごとに表示した様子。優角が2つある5角形は見当たらない。
true, false は法線の向きである。いずれの5角形についても優角がたかだか1つと判定されているのがわかる。

マテリアル毎にメッシュをサブメッシュへと分割

FBX においては、単一のメッシュに対して、面ごとに別々のマテリアル(テクスチャも含む)を割り当てることができるようになっている。 よって、これを単純なシェーダで表示しようとすると、マテリアルは普通メッシュごとにひとつであるから、メッシュを分割してやらねばならない。

この作業は書くだけといえば書くだけだが、頂点配列、頂点インデックス配列、頂点インデックスインデックス配列、 UV 配列、 UV インデックス配列……といった多くのものを適切に分割する必要があるため、大変面倒だった。 (しかも UV 配列は、少なくとも {頂点, 頂点インデックス} が {UV, UV インデックス} に対応する場合の4通りのマッピングがあるため、大変ややこしく、よくエンバグした。) ここ2週間で一番面倒な作業だった。

テクスチャの wrap mode の設定

なかなか良さそうなモデル #中野シスターズ

@aomesan147@twitter.com, , Twitter

https://gnusocial.cardina1.red/attachment/24466 はいプロ

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147063

なぜ一部(脇の前面)だけおかしくなるんだろう……

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147518

諦めて、中野シスターズというモデルを試してみる。 http://nakasis.com/

@pball4@twitter.com, , Twitter

やはり色の違いはあれど、そこまで極端に白くなってはいない……

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147533

結論だけ言うと、テクスチャの wrap mode が正しくないからだった。 gfx-rs で FactoryExt::create_sampler_linear を使うと、 wrap mode として Clamp が選ばれてしまうが、 FBX 側では(ノード属性として) Repeat か Clamp か選べるようになっていて、当該モデルでは Repeat になっていた。

フラグメントシェーダでテクスチャ真っ青にしたのに肌色になってる部分……何なんだ??? https://gnusocial.cardina1.red/attachment/24547

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147661

uv.s < -0.1 || uv.s > 1.1 な部分を青にするとこうなる…… https://gnusocial.cardina1.red/attachment/24548

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147664

uv.s < -0.5 || uv.s > 1.5 にすると、こう https://gnusocial.cardina1.red/attachment/24549

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147666

uv.s < -0.8 || uv.s > 1.8 にすると、こう https://gnusocial.cardina1.red/attachment/24550

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147667

まじで uv の x 座標 1.95 とかになっとるやんけ https://gnusocial.cardina1.red/attachment/24551

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147672

WrapMode か…… https://gnusocial.cardina1.red/attachment/24553

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147686

FBX 2018 Developer Help: FbxTexture Class Reference https://help.autodesk.com/cloudhelp/2018/ENU/FBX-Developer-Help/cpp_ref/class_fbx_texture.html#a889640e63e2e681259ea81061b85143a

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147687

0 は eRepeat だね

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147688

はいプロ https://gnusocial.cardina1.red/attachment/24560

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147706

メッシュの描画順の制御

https://gnusocial.cardina1.red/attachment/24474 白目の部分が青くて怖いし、普通になんかバグあるなこれ

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147112

alpha が 0 の部分でクリアされてない色が見えちゃうとかそういう系かな

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147116

眼に透明テクスチャが使われてるの、予想以上に厄介だぞこれ……

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/147986

やはりどうにかして虹彩の描画順を白目部分より後にしてやるしかないか

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/148107

プロ https://gnusocial.cardina1.red/attachment/24836https://gnusocial.cardina1.red/attachment/24837

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/149141

結局、指定したメッシュを後で描画するようにしたらうまくいった

@loliconductor@gnusocial.cardina1.red, , https://gnusocial.cardina1.red/notice/149163

ファイル名 (optional) とメッシュ名を指定して、特定のメッシュの描画を後回しにするロジックを実装することで解決した。