ドリクラエミュ再高速化

 あっはい、先月あの後立て続けに投稿する筈だったんですが、無事延長戦に入っておりました(笑)。

 大枠では既に形になっていたものの、細かい所で個別の問題が発生しておりまして。終わったかと思えばまた、の繰り返しで。
 それも言われなければ気付かないような細かい不具合ばかりなんですが、気付いてしまった以上はしょうがないよねと。これが仕事ならばいつ崩されるとも分からないTODOの山に追加して優先度を下げるという判断にもなりますが、これは仕事じゃないからねしょうがないよねと(笑)。納得が優先するジャイロ理論。
 というか実際問題、(横槍で手を入れていて全てを把握しているのとは違うという事情も含め)、割と突き詰めると根本的な問題に行き当たることもあるし、そうでなくともその解析情報が後に活きるという事は往々にしてあるので。調べるだけ調べてそのまま対策が思い付いて手が動いてしまうという事の繰り返し。
 課題を潰して突破していくという達成感はゲームでもコーディングでも変わりませんですね、はい。

 それに何よりここを突破しておくと後顧の憂いを断ちまくりなので、何としても片付けてしまいたかったと。

 そんな訳でドリクラ改造の小話。(小話?)
 以前にある程度の高速化を掛けた件、要点としては「モデルデータ内で分かれているパーツをまとめて効率化する」というものですが、ここで個別にデータファイルを手直ししていくという七面倒臭い作業が待っていてどうにも億劫だったので、何とか作業を効率化できないものかと。

 当初は改造スクリプト側で定義データを用意して動的に処理するくらいにも考えていたんですが、突き詰めたら自動化出来ました(笑)。ファイルデータから一定ルールに則って自動的に区分け処理。

 ざっくり言って、
  • 実ポリゴン描画をテクスチャごと*片面・両面で区分け(※追記:テクスチャは場合によってはまとまりそう)
  • セルシェーディング(トゥーンレンダリング)の輪郭描画は色単位で区分け
 これで45パーツあったアイリ制服が、実ポリゴン描画で僅か7パーツ、輪郭描画は11パーツにと、それぞれの処理毎に大幅減量。前回は23パーツと半分程度でしかなかった所からの大躍進。
 お陰でもうご覧の有様ってなものですよ。
img
 左からオリジナル、前回分、今回。画像の数字はそれぞれ1フレームごとの所要時間(ms)(fps換算としては1000から割って考えて下さい)。とうとう重かった制服ですら100fps越えの世界に。

 なので制服+バックダンサーHGという最も重い構成では、
img
 20fps近くにまで落ち込んでしまっていたものが、50fps強に大幅改善。

 元々軽い方だった競泳水着に至っては、
img
 肌と水着の僅か2パーツにまとまるのでおそらくこれが最速級。スピードを追い求めた水着の名は伊達じゃない(笑)。
 約133fps(1000/7.5)と、120fpsすら飛び越える有様に。まぁうちは昔ながらのモニタなので60fps以上は確認しようもないですけどね(笑)。(あとストリームカメラの丸め問題もあるし >参考

 ソロは完全に余裕綽々になったので、昨年最悪の時期にあつらえてしまった新PC参考は「うるさいから黙れ」で普段パワーを抑えているんですが、もう常時それで十分だという事態に(笑)。フルパワーは録画する時くらい。

 その他は、デュエットの制服*2でぎりぎり60fps行けるかなくらい、トリオで制服*3もHGの時と同じくらいで50fps強(HGの方がデータ的に非効率で素では一番重いけど、改善後はほぼ変わらなくなる)。競泳水着ならトリオでも80fps以上出ておりました。超余裕。
 あと因みに二画面化の場合は、こちらは全体描画を二回繰り返すのでもうちょっと都合が変わってくるけれど、制服でこれまた50fps強くらい。勿論軽い衣装なら60fps余裕。

 要は重い衣装でなければ大体60fpsで遊べるようになりましたねと。
 逆に言うと惜しいなぁうん、というところまで(笑)。速度が足りてないケースでは1フレーム18-20msといったところで、16.66msまであと少しなのだけれども勿論その壁が大きい。

 元々このパーツ数問題はその数が多いほど指数関数的に負荷が掛かっていく傾向にあったので、この先はパーツ数を切り詰めても殆ど大差ない領域になった感じ。あとは実際のポリゴンデータの負荷というところかなと。
 一番テクスチャ数=パーツ数の多い制服関係とミリタリーのような細かなディテールの多い衣装とが大体横並びになっていて、ここから先は素直に本来の3D処理パフォーマンスという所になってくるのかなと思います。

 まぁもうけーぜろさん大勝利ですよね。そう言わせて下さいたまには(笑)。(割と言ってるかもだけど、疲労困憊の方が長すぎていっつも負けてる気分)
 いやもうたまに実機を起動しても「おっも」としか思えなくなりました(汗)。文句なく完全にアッパーコンパチに。

 概略としてはそんな所ですがもうちょっと込み入った話も。長いよ(汗)。

●パーツの分割問題
 前回はモデルデータのファイルを直接弄ってましたが、やっている事としてはモデルデータ内部で抱えているデータブロックを数珠繋ぎにして一つのパーツに仕立てるという物なので、一々ファイルを書き換えなくても読み込み側で細工出来るよねと。
 それもメモリ上のバイナリを同じように書き換えてもいいけれど、データ処理する部分のプログラムフロー制御をちょろまかしてしまえば同じ振る舞いを起こせるよねと。こういう小賢しい考えには長けてしまっておりまして(笑)。

 更に突き詰めると、モデルデータの描画処理は表面の実ポリゴン(テクスチャ)の描画とセルシェーディング(トゥーンレンダリング)の輪郭用の描画の二段階に分かれていて(いわゆる背面法)、テクスチャ部分と輪郭用の地色とではパーツのまとめ分類も実際には異なってくる。
 例えば、制服の黒部分と白部分とでテクスチャとしては一つなので本当ならまとめる事も可能だけれど、地色は異なるのでパーツを分けざるを得なかった。この相互関係に足を引っ張られてパーツ結合があまり効率的に出来ていなかったのがこれまでのところ。
 でもプログラム側で動的にやるなら、実ポリゴンとセルシェードで別々に処理出来るよねと。

 というかこういう事情を踏まえると、どのパーツを何処まで分けて何処までくっつければいいのかというのはモデルデータを準備する側ではとても判断しきれない。だから割と細々と分かれてたり何だか急にがっつりまとまってるデータもあったりとなるのは致し方ない。
 この先はプログラム側でその都合に合うように処理するべきだと。だからやりましたと(笑)。

 尚、もう一つパーツが分かれている理由として、一部パーツの表示・非表示の切り替え機能も介在してくる。
 制服スカートの簡略化モデルとか、あとは店内パートの着座モデル用の下半身切り替え(figmaとかの可動フィギュアで特定ポーズで造形されたパーツに差し替えるあれと同じ話)
 この為に上下半身でパーツを分ける事になっていたのが実にもどかしかったので、これもパーツグループとしては一纏めにしておいて、描画時に動的にその部位を結合するしないと切り分けるようにプログラム側で最適化。これで驚異の最小2パーツ構成(肌+衣服)に、という話です、はい(※追記:最小1パーツになるかも(笑))


●エミュ側の問題(都合)
 元々このパーツ分割数がネックになっていたのは、単純にそれだけ描画命令数が増えてしまうという点も勿論あるけれど(これは実機でも影響0という事は無かったのではないかと)、あとは描画命令の実行順も影響していたのではないかと思うところ。

 (以下、色々聞きかじった知識のごちゃ混ぜなのであくまで素人の憶測レベルだと思って欲しいですが)
 検証の過程で色々処理を外して動作の違いを見ていたところ、特に実ポリゴン側よりもセルシェードの輪郭描画側の方が負荷増加が著しかったので、その辺りの描画命令の組み立て部分で効率に大きく関わる問題を抱えてしまっているのではないかと思う。
 命令リストの途中に余計な命令が割り込んでしまうとパイプライン処理がやり直しになってストールしてしまうみたいな話を読んだこともあるし、今のGPUと当時の360のGPUでまた違う部分は往々にしてあろうかと。

 なので正直エミュの速度改善には期待できないんじゃないかなぁとは思ってまして。
 ハードパワーに大きく依存していた場合それをソフトエミュレーションで補うには限界があるだろうと。高速化の為には処理順序を最適化する他ないのだろうけれど、命令の実行順を変えてしまうというのは再現性というエミュの根幹に関わる部分。
 だから、動作させるソフト側で手直しするというのが最短の道なのだとは思います。
 8bit,16bit時代のゲーム機のエミュレーションとは訳が違うよなぁ、というのが身に染みた感じ。

 などと言っておいてこの先普通にエミュ側で改善されたら笑えますが(笑)、どうなんでしょうか。


●麻雀版・他機種版
 尚、無印・ZEROの頃は初期の独自コーディングなのでそういった問題も大きかろうと。
 実際、SONYハード展開時にマルチプラットフォームエンジンに切り替えた麻雀版については、エンジンに合わせてデータも再構成されてるからか、かなり高速に快適に動作してます。それこそ制服*3人にしても60fpsフルフレーム。もちろん一切未改造で。
 まぁデータもおそらく簡略化されている所はあるし(顕著に違うのは顔、あと東京Tシャツ)、セルフシャドウが切られていたりと全般的に負荷を軽めに調整してある筈なので一概に比較はできないところですが。

 だから続くPS移植版、Gogo.も多分軽快に動くようになっているのかとは思います。
 ただ自分はXbox版でやりたかったのだからしょうがない(笑)。

 その拘り(だってアイリのヘルメット髪許せねーもん俺は(笑)<直球)の為に数多の犠牲を払う事になったと言えばそうですが。でもその甲斐あってようやくここまで来られたとは思います。長かったなぁ、うん。
 もう俺は疲れたよ、と(笑)。


 などと何か締めが入っちゃったけど、
 前述の基本的な方針で概ね動くところは動くんですが(前回動画はその辺)、残念ながらどうしても細かい所で問題は出てくるもので。それを色々と対処していたのがここ最近の話。

 オリジナルのデータ情報を元に前述のグルーピングを走らせる訳ですが、何故か一部上手く行かない。グルーピングが上手く行かずにバラけるだけでなく、最悪は表示が乱れるケースもある。

 しかしそこを突き詰めて行くとですね、うんまぁ言ってしまうと何ですが「元々のデータがおかしいよね」(汗)。
 内部的にデータがおかしくなってるけれど見た目遜色が無かったり、あるいは上手いこと辻褄が合ってしまって動いているように見えていたりとか
(※注:すみません一部はこちらの解析ミスも残ってました、偉そうなこと書いちゃイカンですね(苦笑))

 いや別に不具合を糾弾するのが目的ではなくてですね。そりゃこんだけデータ数がずらっと並んでれば一個一個の細かい不備とか見落としてもしょうがないし、自分も「こんなんやってられるか(でもやる(笑))」みたいな心境にもなったし、それこそ見た目おかしくなければOKとなるのは無理も無いってなものでしょう。

 ただね、それを後から(勝手に)弄る身としてはそのままでは困りますと。
 結果、色々とパッチ当てリストみたいなのが出来上がってしまいました(笑)。

 以下、晒し上げる訳ではないんですが、「こういう事がありました、まだおかしかったらごめんね」という意味も含めて多少具体例も触れておきます。(流石にスクリーンショットは省略で、、と思ってたけどやっぱり文章だけでは分かりづらいので入れときました。あげつらうのが目的ではないですごめん。)


●テクスチャ問題
 衣装をざらーっと一通り確認したところ僅かに2つだけテクスチャが壊れてしまう例がありまして。具体的にはるい制服とマリンルック。
 調べてみたらパーツ毎に指定されているテクスチャ番号が間違ってました(苦笑)。だって明らかに別のファイルなんだもの。そんな物を一纏めにしたらそりゃあおかしくなりますよと。でもだったら何でオリジナルでは問題ないの、ってのはありますが。まぁ多分ここはヘッダ部分と実データ部分とで処理過程が違うみたいな話だと思う。その上で内部的に辻褄が合うように出来てしまっていたのだと思う。
 それを今回ヘッダ情報を元にグルーピングする課程では不備が出てしまうので、これを正しく読み替えるように細工。
 ※訂正:すみません、ここはこちらの解析ミス・想定外事情でした。一つのパーツブロックの中に別のテクスチャパーツが含まれているケースがあって、結果的にこちらのロジックが成り立っていただけなんですが。ただこれは、成る程そうなるかぁという、、。(パーツをテクスチャで分けなくても良いケースが出てきた模様)

 このテクスチャ問題は見た目はっきりと分かり易いので大体解決はしたとは思うけども。小さいパーツだと見落としたりするかもだからまだ要注意かなと。

 あと因みに、おそらくこの手のテクスチャ関連設定の問題で雪の髪留めの色が「元々」おかしくなっていたのが、このパーツまとめ処理の課程で必然的に解決してます。
img(以下一番右が修正後)
 デフォ髪の物のみ少し色が飛んだような状態になってました。他の髪型の物は全部色が揃ってるのでここだけの不具合なのかと思う。作業中に髪留めだけではなく髪全体のポリゴン描画色がおかしくなる現象も起きていて、最終的には収まったのでこちらが正解なのだろうとしてます。
 まぁ言わなければ気付かないよね系だと思いますので(笑)。


●ポリゴンの片面・両面、及び描画順
 ポリゴンの描画には片面のみで済ませているケース(※立体で囲われていれば裏は要らないので計算を省略する)と、板状のまま表も裏も描くようにしているケースがあって、これはそれぞれでグループを別にしないと当然おかしくなってしまう。(あるいは全部両面扱いにしてしまえば問題ないけど効率は落ちる)

 ここがまぁ割と設定がいい加減だったりしましてね(笑)。もっとも片面でいい所が両面になる分には、効率が多少落ちるだけで見た目に差は出ないし。
 ただ今回はその情報を元にグループ分けを行っているので、きちんと設定されていないと無駄なグループ分けも発生してしまうというのがまず一点。

 それと今回のグループ化の課程でパーツの処理順序=描画順序がオリジナルから変わってしまうので、そこで極僅かな問題が発生してしまう。例えばフリル等の透過パーツの縁取り部分の描画が微妙におかしくなる(※半透明ではなく、細かい形状を作る際に1枚の板にテクスチャの透過で抜きを入れて作ってる類)。めざとい話なんですが、俺は細かいよとしか(笑)。
 こういった透過パーツは後から重ねるように描画するのが正解のようなので、パーツグループが後から処理されるように細工・調整。この辺で大元の両面指定に余計な物があると処理順に影響が出やすくなっていたという所ですね。

 因みに言うとその描画不備はオリジナルでもちょっとだけ発生してしまっていたので、ついでに直るようにしておきましたと。(具体的に言うと雪制服のエプロンフリル。ほんの僅かですが。めざといので(笑))
img

 それと、逆に両面であるべきものが片面になってしまっているケースも幾つかあり。
img
 例えば遙華のカチューシャ(一部髪型で)とか、制服胸部分の裏地、エプロン等。物によってはちゃんとしているので敢えて抜いているというよりはミスの部類かと。まぁ覗き込むような角度で見ないと気付きませんが、ただ分かって見ているとそこに無の空間が出来ている事に気付いてしまいますからね。(例えば魔璃制服は着せ替え画面でも分かる)
img
 なので直せるなら直してしまいましょうと(笑)。


●セルシェードの輪郭有無
 これは元からの問題で、一部パーツでセルシェードの輪郭が誤って描画されてしまい僅かにおかしな見た目になっていた。
 先にも触れたフリルのようなテクスチャ透過パーツは、その構造上セルシェードの輪郭は無しに設定されているのが普通ですが、この指定がミスっていて描画されてしまっていたと。(具体的には遙華おだんご髪のカチューシャ)
img
 ここは単純なデータミスなので値を差し替えて終了。
 他にも気付いたら順次直しちゃいましょうというところで。


●セルフシャドウ
 キャラ自身に影を落とすセルフシャドウ、ポリゴンパーツを元に影を作る際にメガネレンズのような透明パーツは処理しないように作られているので、ここで間違ってパーツをまとめると余計な影を描画してしまうという問題があり。そこはパーツのグルーピングを適切に行うように調整。
 しかし元々これが余計に描画されてしまっているケースがあって。ここはもうデータ不備というか仕様上の問題だったんですが、、。
 例えばDLCのモノクルは対処漏れで(ノリでメガネは全部買った)、あとこれは透明パーツとは別問題だけど魔璃のカチューシャも見た目の不都合が出るのでカットされていたのが、これまたDLCの髪型は未対応。

 なんぞデータの設定忘れかと思って調べてみた訳ですが、これはモデルデータ側に情報は持っておらず、何とプログラム側のハードコード。そりゃ追加データには未対応ですよねぇ(苦笑)。(Xbox360の頃は無闇なタイトルアップデートを控えさせるとかいう名目で有料になっていたという話なので、追加パッチも滅多に無かった)
 振り返ってみるとDLCのメガネレンズ問題は無印の頃からあったようで、それをZEROでは対処した形ですが、結局またDLCは漏れてんじゃねーかと。いやそこは何とかしようよ(笑)。

 ただプログラム的には、現状でもメモリ上の除外リスト設定を見に行くという作りにはなっていて、その参照リストをセットする部分がファイルからではなくハードコードになっていたという形。
 ここまで出来てるならファイル側に持たせようよとも思う訳ですが、段取り的に間に合わなかったのか、色々協議した(あるいはしてない)中で立ち消えになってしまったのか(笑)は分かりかねますが。
 まぁこの作りだったら、そのデータを自前でねじ込んであげれば解決ですね、というところで無事に対応完了。
img

 尚このセルフシャドウ、(どうやってるかは具体的には把握してませんが)処理の性質的に、例えばスカートの下の肌に影が落ちるよう少し内側に寄る作りになっている感じで、この関係で頭部飾りの影が髪の毛に埋没しやすくなっている模様。
 帽子類の影もよく見るとそうだし、アイリの謎デバイスもイラストほど綺麗に影が落ちてはいないのはこの都合。そして前述の魔璃のカチューシャはかなり中途半端に影が出来てしまうので、いっそカットするという事になったよう(但しDLC除く(笑))
img
 ここは惜しいというか勿体ないなとは思うところですが。流石に3D処理にまで手を出せるレベルじゃあないので勿論見送り。
 PS版は少し改善してるのかな? あるいはテクスチャでそれっぽく影を置いておく戦法に変えてるだけかもですが、どうだろう。

 そんなこんなで、高速化ついでに色々細かい手直しをしておりました。
 本当はもっととっくに一区切りを付けて、今頃は違うことをやっている時期の筈だったんですが、おかしいですねぇ(笑)。
(それにまぁちょっと腹立つ事件もありましたしね。黙って没頭してましたね、、)

 お陰様で「後でゆっくり確認していこう」と思っていたものも大体まとめて処理してしまいました。
 まぁ後から都度都度と思っていても割とその場じゃあ見逃すものなんですよ。如何せん手動で高速化した時も一回ミスってるしなぁ。危うくテクスチャ模様の消えたアイリの髪をアップロードしてしまうところだった(青一色なので割と気付かず)
 なので主立ったところから、制服は全部データレベルで確認・最適化して、各キャラのお顔と髪型もまとめて全確認。「何のデバッグ仕事かな?」っていう。俺は何をやっているんだろう。そんなことは以下省略。(笑)
 何だかんだで結果的に上手く行くのは「たーのしー」なのです。

 でもってここまでやれば後は気軽に遊べるでしょうと。
 これは動画にはならない改造シリーズなんですが、毎回ランダム衣装モードとか作ってそれで暫くぼーっと垂れ流して見ておりました。意外とこの日焼けの組み合わせもいいなとか出てきたりして。
 こうやって遊びたかっただけなんですよ、元々は。ここまで(物凄く)長くなったけど(笑)。

 後まぁ(あまり自賛は趣味じゃない性格ですが)、今回の改造は本当に劇的な効果と言って差し支えないところでして。
 別にエミュ(xenia)がおかしいんじゃなくてむしろ再現度は素晴らしいレベルだし音声のデグレだけは本当に残念。まぁ何とかなるし、、)、それが更にちゃんと本領発揮出来ればこれだけ凄いんだよと(笑)。

 先に書いたように多分ソフトがエミュの足を引っ張ってるだけでエミュで解決する問題ではなかろうと思っているので、何か凄く勿体ないなぁとは思ってしまっているところ。それこそもっと普通の物だったら「高速化パッチ」などと偉そうに放流していたとは思います。
 ただまぁこれはエミュで勝手に弄るというかなり際どいラインなので。下手に助長・幇助するって話になりたくはないですし。そうでなくとも「動かすためにもそれなりに知識は要る」ので、そこはこちらでサポートする訳にも行きませんからねえ。また他人様に渡すにはもっと整理もしていかないといかんし、とか色々。そんな事よりも他にやるべき事をやろうと。(まぁ後は自分で出来るという人であれば何処かで声を掛けてみて貰えればみたいには一応思ってます、とは今は書いておきます)

 もっと日の当たる事をやれとは思い知ったこの頃ですね(笑)。
 まぁ歩く道が勝手に脇道になってるんや、が持論ですけども。