プロフィール

Na-7

Author:Na-7
SE(システムエンジニア)として約15年間システム系ソフト会社を勤めあげ、2008年3月退社。現在、ゲーム制作会社設立を目指して活動中。


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
DATE: CATEGORY:三国志軍記開発
ゲームパフォーマンスの実践的な改善方法
XNA Game Studioゲームパフォーマンスの実践的な改善方法
「Gamefest Japan 2008」で使用された資料。音声付き。
ゲーム速度を向上させるヒントが多数記述されている。



◎ピンポイント!

遅延対策を実施すべく、前回A案の「DrawIndexedPrimitivesの描画速度が向上するよう調査」を開始したら、いきなりヒットしました。

ひにけにXNAの「GPUはいつ描画するのか?

いや~、私の疑問がピンポイントで解説されているなんて…しかも、この記事は今月書かれたばかりじゃないですか!
ちょっとタイミングがずれていれば、A案は速攻で諦めていたかもしれません。あまりのタイミングの良さにビックリです。
Itoさん、ありがと~!!

しかも、この記事によると、前回書いた「もしかしたら垂直同期などの同期待ちかもしれません」という推測が、意外と(?)当たってたみたいです。
この推測は、追加計測をまとめた際に初めて気付いたことなので、時間を惜しまずやった甲斐がありました!(^^)



◎skinning sampleの高速化について

前述の記事によると「マテリアルバッチ」が現状を打開するキーワードになりそうです。

このキーワードからこちらのQ&Aを探し当てましたが、このQ&Aには「skinning sample」の高速化のポイントが書かれているので、「skinning sample」ベースのアニメーションを実装しているXNAユーザは、かなり参考になるのではないでしょうか?

それにしても…Itoさんが測定もせずにボトルネックを指摘できるプログラムを、公式サンプルとしないでほしいですね。
大勢のXNAユーザが「skinning sample」ベースのアニメーションを実装している現状を思うと、ちょっと悲しくなります。



◎モデルインスタンス

Q&A内のURLから、冒頭の「XNA Game Studioゲームパフォーマンスの実践的な改善方法」という資料の「モデルインスタンス」に辿り付くと、ポリゴン数の少ないモデルを沢山描画する手法が3つ挙げられていました。

・マテリアルバッチ
・シェーダーインスタンス
・HW インスタンス

ひにけにXNAではマテリアルバッチが紹介されていたので、まずこれからやってみて、効果が無ければ他の手法も試すつもりです。

ちなみに、モデルインスタンスについては、こちらの記事の「Mesh Instancing」の説明が参考になると思います。
このサンプルの存在も、ちょっと気になりますね。キリが無いので今はやりませんが、いずれ解析することになるかも。



◎ループの改善

というわけで、前述の資料のマテリアルバッチのコードと現状コードを比較したら…あれ?殆ど一緒??
いや待て、よく見ると、ループのネスティング(入れ子)が違いますね。

現状コードは、(パターンテクスチャ用の)forループの中で、エフェクトパスを開始~終了してました。これだと、ループの中でpass.Endを何度も呼び出すことになります。だから、同期待ちが発生していたのですね。

逆に、エフェクトパスを開始してから、(パターンテクスチャ用の)forループを記述し、DrawIndexedPrimitivesの発行処理が全て終了してから、最後にpass.Endするように変更しました。テクスチャ変更を反映させるために、basicEffect.CommitChangesも挿入しました。

ループ改善のポイントは以下の通り。
改修前:pass.Endが複数回呼び出されていた
改修後:pass.End呼び出し回数を1回とした

改修前と改修後の計測結果は以下の通り。
・地表モデル:30~38fps → 48~60fps
・地形種別モデル:1fps → 1fps

地表モデルは、DrawIndexedPrimitives呼び出し回数が1回であるため、描画速度が向上しました。
地形種別モデルは、DrawIndexedPrimitives呼び出し回数が多いので、そちらがボトルネックとなり、描画速度は変わりませんでした。



◎マテリアルバッチの補足説明

地形モデルに対するマテリアルバッチ改修は以上ですが、これだけだと「マテリアルバッチ=ループ改善??」と誤解されそうなので補足します。

通常のXNAプログラムでは、複数の3Dモデルを描画する際に、mesh.Drawを複数回呼び出します。これはGPU側ではpass.Endを複数回呼び出すのと同様の動きになるので、同期待ちが発生します。

これを回避するために、mesh.DrawからDrawIndexedPrimitivesに変更したり、ループを変えたりして、pass.Endの呼び出し回数を1回にするのがマテリアルバッチの目的です。たぶん…。

pass.Endの同期待ち要素は影響力が大きいので、通常の描画方式と比べれば、これだけでもかなり描画速度が向上する可能性があります。地表モデルの描画速度は1.5~2倍ほど向上しましたが、資料によると、3~5倍くらい速くなることもあるそうです。

但し、同期待ち要素は他にもあるので、他の要素がボトルネックとなっている場合、そちらを解消しないと効果は現れません。

資料では、マテリアルバッチの短所の1つに「DrawIndexPrimitive の呼び出し回数は多いまま」を挙げています。つまり、マテリアルバッチだけでは、地形種別モデルの描画速度は向上しない、ということですね。



◎次回予告

資料の内容は3割程度しか理解できませんでした。
でもまぁ、3割でも理解できるようになっただけマシかも?

これを足掛かりに、さらなる技術力向上に励みます。
頑張るぞ~!

次回は「シェーダーインスタンス」にチャレンジします。

スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント

コメントの投稿


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

トラックバック


この記事にトラックバックする(FC2ブログユーザー)



copyright © ゲーム制作の舞台裏 all rights reserved.Powered by FC2ブログ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。