プロフィール

Na-7

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


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
シェーダーインスタンス4000枚
UVアニメサンプル改
UVアニメのサンプルをシェーダーインスタンスに改修中。現時点でのパフォーマンスは上々らしい。



◎訂正

前回の本文に間違いがあり、yohさんからご指摘を頂いたのですが、コメントでもちょっと怪しいことを書いてしまったので、改めて整理します。

HLSLの配列宣言と消費レジスタ数は以下の通りです。

float Params[1000]; // 定数レジスタ1000消費相当
float4 Params[1000]; // 定数レジスタ1000消費相当
float4x4 Params[1000]; // 定数レジスタ4000消費相当

私のメインPCはイレギュラーなシロモノなので、これでも正常に動作します。Intel系チップセット内蔵グラフィックスでは、頂点シェーダーをソフトウェアで対応しているそうですので、定数レジスタも仮想で4000以上実装していると考えれば納得できます。

しかし私のサブPCをはじめ、一般的なシェーダ2.0環境の定数レジスタは256個なので、(コンパイルは通りますが)DrawPrimitives実行時にエラーになります。

描画操作を実行する前に、有効な頂点シェーダーとピクセル シェーダーの両方 (または有効なエフェクト) がデバイスで設定されている必要があります。

以下のように宣言すると、エラーを回避できます。

float4x4 Params[60]; // 定数レジスタ240消費相当

上限が63ではなく60である理由は、World、View、Projection行列の受け渡しに定数レジスタを3×4個消費したため、と考えています。



◎一度に描画するモデル数

yohさんに定数レジスタ数の取得方法を教えて頂いたので、メインPCで実行したら「8192」でした。それなら2000モデルぐらい描画できそうですが、実際には1024以上のモデルを描画するとおかしくなります(前回参照)。原因は不明ですが、ドライバの仕様かバグかもしれません。

で、気になるのはMaxVertexShaderConstantsの返却値をどこまで信用して良いのか?ということです。この返却値を参照して‘一度に描画するモデル数’を決定すれば、グラフィック性能を最大限に引き出せるのですが、メインPCを見る限り、いまいち信用しきれません。今のところ「256固定で組むのが無難かな~」などと考えています。



◎イレギュラーPC

メインPCの他のプロパティも調べてみました。

DeviceType = Hardware
MaxPixelShader30InstructionSlots = 0
MaxPixelShaderProfile = PS_2_0
MaxPrimitiveCount = 65535
MaxSimultaneousRenderTargets = 1
MaxSimultaneousTextures = 8
MaxStreams = 16
MaxTextureWidth = 2048
MaxVertexIndex = 65534
MaxVertexShader30InstructionSlots = 32768
MaxVertexShaderConstants = 8192
MaxVertexShaderProfile = VS_3_0
PixelShaderVersion = 2.0
VertexShaderVersion = 3.0

ちょっと驚きなのが、頂点シェーダとピクセルシェーダのバージョンが違うということです。こういう場合、シェーダモデル2.0扱いなんですかね?

定数レジスタ数だけでなく、命令スロット数も異常ですね。
頂点シェーダ側は32768(VS_3_0規格は512以上)と桁違いに多いのに、ピクセルシェーダ側は0(PS_2_0規格は32 + 64)。
いくらなんでも0はおかしいと思いますが…ますます信用できなくなりました(笑)

PCゲームを開発する人は、こんなPCもあることを頭の片隅にでも入れておいてください。「落ちた」と言われて調べたら、環境の問題だった、なんてことがあるかも。



◎カスタムモデルクラスについて

本題に入る前に、もう1つ余談があります。

ネット上のDrawPrimitives系のサンプルは、どれも頂点データをコード内で自作しています。DrawPrimitivesの使い方に関してはわかりやすいのですが、外部ツールで作成したモデルデータをDrawPrimitivesで表示する方法はわかりません。

結論から言うと、これをやるには予めコンテントパイプラインでカスタムモデルクラスに読み込むのが理想的です。ただ、この方法は標準Modelクラスに読み込んで表示する方法と比べると、複雑で面倒でわかりにくいです。

そこで、先日のUVアニメサンプルは、標準Modelクラスに読み込んだデータをDrawPrimitives系で動かすようにしました。ちょっと実験する程度ならこれでも動くし、初心者にはこの方がわかりやすいと思います。


ですが、今回UVアニメサンプルにシェーダーインスタンスを適用しようとして、そろそろ無理が出てきました。

・メタセコイアモデルを読み込むために、
 カスタム頂点フォーマットAが必要

・シェーダーインスタンスのために、
 フォーマットAに番号を付与したフォーマットBが必要

1つのモデルにカスタム頂点フォーマットが2つ存在したら、わかりやすいプログラムとは言えないですね。

しかし、私の予定ではカスタムモデルに移行するのは公式サンプル解析後ですので、今回は標準Modelクラスを使用する方法で押し通します。



◎Matrixと定数レジスタ

ところで、前回のサンプルでは各インスタンスに(Vector3ではなく)Matrixで移動情報を渡していましたが、何か深い意図があったのでしょうか?

Matrixは定数レジスタを4つ消費するので、頂点座標とテクスチャ座標をMatrixで渡す場合は8つも消費してしまいます。定数レジスタ数が256個のPCでは、一度に30モデル程度しか描画できません。

そこで今回はVector3とVector2を渡すことにします。これで一度に120モデル程度描画できますね。



◎インデックスデータの増分値

で、実際に改修を始めると…やはりちょっと難しいですね。何とかモデルを1つ描画する所まではいきましたが、なかなか複数描画できません。

試行錯誤の末に気付いたのは、インデックスデータの増分値。複製する際に増分値を加算する必要があります(加算しないと頂点データを複製する意味が無い)が、インデックスデータの要素数ではなく、頂点データの要素数を加算する必要があったのですね。

というわけで、ようやく複数描画できるようになりました。

シェーダーインスタンス01



◎Matrixとクォータニオン

お次は板ポリの回転です。

この段階でようやく気付いたのですが、回転データも個別に渡す必要がありますね。前回サンプルがMatrixを使用していた意味がやっと分かりました。Matrixなら移動、回転、スケールをまとめて渡せるからですね。

でもやっぱり定数レジスタ数は節約したいので、回転量だけ渡してシェーダー側で回転させたいものです。しかし、シェーダー側にはMatrix.CreateRotationYのような便利なメソッドが無いので、頂点変換が難しそうですね。

…そういえば、Gamefest2008の解説で、クォータニオンが便利って言ってたなぁ。再度プレゼンを聞いて、デモのエフェクトファイルを覗くと、確かに便利そうな関数がありました。

これを機に、シェーダはデモプログラムのコードをベースに置き換えます。今回は不要のもの(スペキュラとか)もありますが、今後のことを考えて、大部分を取り込みました。

シェーダーインスタンス1000枚

せっかくなので色も付けました。BasicEffectと同等ですね。回転に合わせて光が反射するのでちょっといいかもw



◎パフォーマンスは?

まだ改修中で、頂点座標と回転はインスタンス化しましたが、テクスチャ座標はまだ動的頂点バッファでやってます。
この段階での速度はどんなもんですかね?

1000枚:60fps
1500枚:60fps
2000枚:12fps

なんか以前よりも遅くなってますが…そうか!頂点バッファ書き込みをインスタンス毎にやってましたが、シェーダーインスタンス化したので1フレームに1回やれば十分ですね!



やりました!4000枚60fpsです!

動画取得中でも60fps近く出るなんてスゴイですね~!!



◎次回予告

次回はUVアニメ改修作業の続きです。

・UVアニメをインスタンシングに移行する
・動的頂点バッファを静的頂点バッファとする
・定数レジスタ256に対応する
・プログラムやコメントを整理する
・デバッグモジュールを組み込む
・メインPCとサブPCで測定する

速くなる要素と遅くなる要素があります。
最終的にどうなるか楽しみですね~w

スポンサーサイト

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
三角形2043個.JPG
シェーダーインスタンシング検証画面
サンプルを改修し、一度に幾つまで描画可能か検証した。
一定数を超えると動作が不安定になる?



◎回想

私がインスタンシングに手を出すのは2度目です。
…いや、正確に言うと普通のインスタンシングではなく、その技術を応用して6万頂点のデカい地形モデルの高速化を図りました。(気になる人は2009/3/29以降のブログを参照してください)

で、その頃気になったのは「インスタンシングの全容がよくわからなない」ということでした。

インスタンシングのテクニックは複数あるとのことですが、資料によって用語が違ったり、サンプルを実行すると「No Instancing」と書かれたものが2種類出てきたり、HWインスタンシングが表示されなかったり…(ってこれは私のPC環境固有の問題ですが)。

そこで今回はまずインスタンシングの概要を体系的にまとめてみようと思います。



◎比較一覧表

幾つか集めた資料の中では、公式サンプルの中のInstancedModel.htmが良さげな感じ。但し英文でちょっと長いので、肝心な部分がわかりにくいです。誰か訳して~(笑)

htmlの最後に比較表があったので、これとGamefest2008プレゼンテーション資料の内容を併せ、補足説明を追加しました。

XNA モデルインスタンス テクニック 比較一覧表

行見出しは(本来公式サンプルの名称とすべきでしょうが)No instancingではわかりにくいので日本語名称にしました。

わりとよさげな感じでまとまったと思いますが、自分で補足した部分は若干不安があります。もし間違いを見付けたら指摘して頂けると嬉しいです。



◎調査結果より

No instancingやらVFetchやらダイレクトマッピングやらで、インスタンシングの全容がよくわからなかったのですが、自分で1つの表にまとめることで、一通り把握することができました。

で、今後取り組むテクニックは…やはりシェーダーインスタンスですね。メモリコストは悪いですが、CPUコスト(≒パフォーマンス)はHWインスタンスと同等らしいので。

最初はマテリアルバッチを適用し、その後シェーダーインスタンスに取り組もうと考えていたのですが、併用事例は見当たらないので併用不可かもしれませんし、もし可能だとしても、マテリアルバッチを適用した段階でコードが複雑になってしまいます。そこでまずシェーダーインスタンスを導入し、マテリアルバッチはその後で考えます。


ちなみに、ダイレクトマッピングまでやればCPUコストも最速になるかと思っていたのですが、これはXbox360専用のテクニックということですので、今は無視します。



◎非公式サンプル調査

公式サンプルの解析は大変なので、手始めにこちらのサンプルコードを解析しました。XNA2.0以降で動かす場合は若干の改修が必要ですが、シンプルでわかりやすいです。

三角形10個

コード内容は一通り理解したので、モデル数を幾つまで増やせるか試してみました。ちなみに、私の予想では一度のDrawPrimitivesで描画できる最大数は60程度です。

三角形1000個

あれ?(^_^;

三角形100個×10行=三角形1000個描画できました。私の認識は間違ってたみたいです(汗)



◎1度に描画可能なモデル数は?

問題は、エフェクトファイルの先頭の配列宣言です。

float4x4 InstanceTransforms[1000];

「HLSLでは、配列の数だけ定数レジスタを消費する。だから定数レジスタの数を超えることはできない」という認識だったのですが…まさか定数レジスタが1000個もあるとは思えません。

で、試しに三角形を5000個に増やしたら、エフェクトファイルのコンパイルエラーになりました。

maximum constant register index exceeded - Try reducing number of constants referenced

エラー内容を考慮すると、定数レジスタの数に依存するという認識は正しいようです。

で、実際に幾つまで可能なのか試してみました。

三角形1025個   三角形2043個
1025個を指定した画面(左図)と2043個を指定した画面(右図)

1~1023:
 正常に表示される

1024:
 1個も表示されない

1025~2043:
 1024を引いた数だけ表示される

2044~:
 エフェクトファイルのコンパイルエラーになる


上記の結果から推測すると、

・このPC環境には1024個の定数レジスタがあり、
 それを超えると動きが不安定になる。

・HLSLの規定数(約2048)を超えると、
 コンパイルエラーになる

このように考えれば筋が通ります。ただ、内蔵グラボで1024個は多すぎる気がしますが…。

…あ、そうか!
スカラ型じゃなくてベクタ型の配列だから、実際に必要な定数レジスタは4分の1ですね!

つまりこのPCの定数レジスタ数は256、だから一度に約1024個まで描画可能ってことか~!



◎まとめ

こちらの「バーテックスシェーダの比較」で定数レジスタ数を確認すると、シェーダモデル2.0は256以上となってました。つまり、シェーダモデル2.0以降では、一度に最大1023個まで描画可能というわけです。

この様子だと、ビルボードアニメ6000体を12回(両面なら24回)で描画できるかもしれませんね。マテリアルバッチを検討する必要も無さそうです。



◎次回予告

次回は、UVアニメのサンプルにシェーダインスタンシングを適用します。どれだけ速くなるか楽しみですね~!w

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
ネームプレート無しユニット多数
測定テスト画面
簡易3Dモデル236体、ビルボードアニメ6000枚をインスタンス無しで表示してみた。さすがに重い。



◎前回の続き

前回コメントでひげねこさんからアドバイスを頂き、タイムルーラーのマーカーグラフ(バー)が高負荷時に表示されない謎が解けました。

UpdateとDrawは必ず対で呼ばれるものと思っていたのですが、条件によるのですね。こちらの記事も大変参考になりました。

ちなみに、メインプログラムのIsFixedTimeStepをfalseにすると、タイムルーラーは正常に表示されますが、移動ユニットはブレて表示されます。固定更新か可変更新か決めて、それに沿ったプログラミングをする必要がありますね。



◎固定?可変?

固定更新と可変更新どちらにすべきか考えたのですが、

○固定更新
・Updateが複数回呼ばれることを考慮した
 プログラミングが必要

○可変更新
・UpdateやDrawが呼ばれるタイミングが変動する
 ことを前提としたプログラミングが必要

開発コストの差はあまり無さそうな気がしますね。それなら、Xbox360に移行しやすい固定更新にしましょう。


残る問題は、固定更新だとタイムルーラーがちらついたり空のバーが表示される現象ですが、皆さんどのように対処しているのでしょうか?

…え?60fpsをキープしてるから問題無い?
こりゃまた失礼しました(爆)

とりあえず、60fps以下の場合はバーを無視して、ログの値のみ記録します。



◎現状パフォーマンス測定

○移動ユニット無し
fps:45.67
Bar 0 Update Avg.:0.02ms
Bar 0 Draw Avg.:17.76ms
Bar 1 mainMap Avg.:4.53ms
Bar 1 mapobjectManager Avg.:12.69ms
Bar 1 unitManager Avg.:0.00ms

○移動ユニットあり
fps:29.95
Bar 0 Update Avg.:2.52ms
Bar 0 Draw Avg.:23.11ms
Bar 1 mainMap Avg.:4.36ms
Bar 1 mapobjectManager Avg.:12.48ms
Bar 1 unitManager Avg.:5.73ms

UpdateよりもDrawがかなり重いですね。その中でも、マップオブジェクトマネージャが半分を占めています。

マップオブジェクトマネージャは静止ユニットを管理するもので、城や柵などの3D簡易モデルと、木のようなビルボードアニメの両タイプを含んでいます。ちなみに、mainMapは地形で、unitManagerは移動ユニットです。

Update+Drawを16.6ms以下にすることが当面の目標ですので、一番重いマップオブジェクトマネージャを重点的に調べましょう。



◎条件変更テスト

城を36→1個にしてみました。

○移動ユニットあり
fps:29.94
Bar 0 Update Avg.:2.44ms
Bar 0 Draw Avg.:16.53ms
Bar 1 mainMap Avg.:4.46ms
Bar 1 mapobjectManager Avg.:5.21ms
Bar 1 unitManager Avg.:6.66ms

城35個で7ms以上かかってました。そんなに重いのか?
もう少し詳しく調べた方が良さそうですね。

それと、CPU側の数値の割に、fpsの数値が低いですね。GPU側にも別のネックがあるのかな?


さらに柵や木を減らして、描画処理時間を測定しました。

城35:7.2ms
柵19:0.7ms
木20×19:4.0ms
城1&柵1&木20×1:0.6ms

同じ簡易モデル方式でも、城と柵でかなり違うので、城特有の処理が重そうです。試しに、ネームプレートを外してみました。

城36、ネームプレートあり:7.85ms、30fps
城36、ネームプレートなし:2.69ms、58fps

うわ、ネームプレートだけでそんなに重かったのか~!
数値で見ると一目了然ですね。

あのネームプレートは、城から外して移動ユニットに付けるつもりだったのですが、このままじゃ使えませんね。とりあえずコメント化して、インスタンシングが終わってから考えます。



◎現状パフォーマンス再測定

ネームプレート無しで、元の条件(城36、柵20、木20×20)で再測定しました。

兵士の数はランダム(1~10人×100部隊)だったので、10人×100部隊で固定しました。木も7種類からランダム選択だったのを1種類に固定しました(数値を安定させるため)。

ネームプレート無し移動ユニットあり01   ネームプレート無し移動ユニットあり02

○移動ユニット無し(カメラ近→遠)
fps:57.07 → 58.95
Bar 0 Update Avg.:0.01 → 0.01ms
Bar 0 Draw Avg.:11.96 → 14.91ms
Bar 1 mainMap Avg.:4.35 → 6.70ms
Bar 1 mapobjectManager Avg.:7.34 → 8.02ms
Bar 1 unitManager Avg.:0.00 → 0.00ms

○移動ユニットあり(カメラ近→遠)
fps:29.94 → 29.94
Bar 0 Update Avg.:2.38 → 2.40ms
Bar 0 Draw Avg.:21.67 → 26.50ms
Bar 1 mainMap Avg.:4.32 → 6.07ms
Bar 1 mapobjectManager Avg.:6.85 → 7.79ms
Bar 1 unitManager Avg.:10.32 → 12.46ms

○マップオブジェクト内訳
城36:2.85ms
柵20:0.65ms
木20×20:5.6ms

兵士の人数がおよそ倍になったので、ユニットマネージャの数値もおよそ倍になりました。この辺はインスタンシングに期待しましょう。

マップオブジェクト内訳の合計値がマップオブジェクトマネージャの数値よりも大きい理由はよくわかりませんが、ループ処理による効率化か誤差でしょう。

現状のパフォーマンスは、こんな感じです。



◎数を増やす

最後に、できればもっと沢山出したいので、数を増やして測定しました。(城36、柵200、木20×200、兵士10×200)

ネームプレート無しユニット多数

○移動ユニット無し(カメラ近→遠)
fps:15.74 → 15.00
Bar 0 Update Avg.:0.01 → 0.01ms
Bar 0 Draw Avg.:52.92 → 63.05ms
Bar 1 mainMap Avg.:4.44 → 6.02ms
Bar 1 mapobjectManager Avg.:48.25 → 56.84ms
Bar 1 unitManager Avg.:0.00 → 0.00ms

○移動ユニットあり(カメラ近→遠)
fps:8.31 → 6.97
Bar 0 Update Avg.:5.09 → 5.01ms
Bar 0 Draw Avg.:72.69 → 88.85ms
Bar 1 mainMap Avg.:4.45 → 6.31ms
Bar 1 mapobjectManager Avg.:47.88 → 57.01ms
Bar 1 unitManager Avg.:20.10 → 25.34ms

さすがに重いですね~。
ビルボードアニメだけで6000枚だし無理もないか。

とりあえずインスタンシングでどこまでいけるか様子を見て、その範囲内でゲームデザインを見直します。



◎次回予告

移動ユニットの有無がfpsに影響するので、そちらに気を取られていたのですが、ネームプレートが予想以上に遅いのは驚きでした。GPU側のデータも取得できると良いのですが、私はVISTA以降のPCを持ってないので無理っぽいです。

とりあえず現状パフォーマンス調査が終わったので、次回はインスタンシング概要調査です。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
デバッグサンプル高負荷時
デバッグサンプル
デバッグに便利なツールが内包されている。タイムルーラーのマーカーは高負荷時に表示されないことがある??



◎はじめに

今回からXNAのモデルインスタンシングに取り組みます。

公式サンプルの機能をそのまま取り込むのが一番の近道かもしれませんが、今回は「何も考えずに強引に組み込む」というのはやりません。

ゲームの大半が出来上がっていて「あとは高速化するだけ」という段階であればそれもアリと思いますが、まだプログラムの大半が未着手ですし、この先やりたいことが沢山あります。強引に組み込んで高速化しても、また遅くなる可能性が高いので、今後に備えてインスタンシングをみっちり勉強するつもりです。



◎導入プロセス

1.既存プログラムのボトルネックを特定する

2.インスタンシングの種類と概要を把握する

3.適用するインスタンシングの種類と
  シェーダーのターゲットバージョンを決める

4.サンプルを解析し、ノウハウを吸収する

5.既存プログラムにインスタンシングを導入する



◎デバッグコマンドのエラー

既存プログラムのボトルネックの特定は、こちらのデバッグツールを利用させて頂きます。

まずサンプルを実行し、デバッグコマンドでhelp、echo、fps等を確認、問題なし。しかしposコマンドを入力すると、エラーになりました。

文字 'イ' (0x30a4) は、この SpriteFont では利用できません。可能な場合は、この文字が含まれるように、フォントの CharacterRegions の範囲を調整してください。

ビルドは通ったのに、フォント関連のエラーが発生しました。念のためConsolasフォントをインストールしたのですが、現象変わらず。

環境が悪いのか?POSコマンドの使い方が悪いのか?
エラーの原因を調べていくと、ちょっと意外なことが判明しました。

[0] = "CMD>pos"
[1] = "Unhandled Exception occured"
[2] = "インデックスが範囲を超えています。(~以下略)

spriteBatch.DrawStringで、上記[2]行目の日本語文字列を表示しようとしてエラーになってました。つまり、エラーの直接原因は「XNA3.1でエラーメッセージが日本語化されたから」でした。

日本語に対応したくても、どのエラーが発生してどの日本語コードが使用されるか予測できないので、対応は不可能です。フォント関連のエラーメッセージに惑わされないよう気を付けましょう。


ところで、デバッグコマンド内でエラー(インデックスが範囲を超えています)が発生した元の原因は、posコマンドの使い方が悪かったからでした(爆)
(誤:pos 10,10、正:pos 10 10)



◎コンポーネントの組み込み

では、メインプログラムにデバッグコンポーネントを追加しましょう。まずファイルをプロジェクトに追加…って、コピーしてnamespace変更でいいのかな?それともプロジェクト参照追加&using指定の方がスマートかな?

デバッグサンプルを確認すると前者のようでしたが、Gamefest2008のデモを確認すると後者のようでした。どっちでもいいから適当にやれってこと?w

結局、ソースモジュールを追加する度にusingを追記するのは面倒な気がするので、前者方式としました。この方式で多数のプロジェクトに組み込むと、コンポーネントのアップデートが大変かもしれませんが、まぁいいかw


それと、こちらの記事で「固定更新から可変更新に変えないと正確なFPS測定ができない」といった感じのことが書かれてますが、これは16.6msよりも細かい値、つまり60fpsを上回る領域をチェックしたい場合の話と解釈しました。
もし間違いでしたら指摘して頂けるとありがたいです。



◎再測定

コンポーネントを組み込んだので様子を見ると、fpsカウンターの値は従来のFrapsと一緒でした。

…いや待て、これまでずっとデバッグモードでビルドしてましたが、測定時はデバッグ無しでビルドしないといけませんね。

移動ユニット無:30 → 45 (fps)
移動ユニット有:20 → 30 (fps)

うわ!?過去の数値と10以上違う!デバッグの有無でFPSこんなに変わるんだったっけ?

ということは、最近の測定データはやり方が間違っていたのですね…ご、ごめんなさい~!_O_


今更かもしれませんが、UVアニメを再測定し、HPにUPしました。

UVアニメーション パフォーマンス測定データ

どの方式も数値が良くなりましたが、全体的な傾向はあまり変わってないようですね。やっぱり、シェーダー改修方式が一番早そうだなぁ…。

2000枚前後で何かがネックになってるようで気になりますが、詳しく調べて高速化を図るなら、サンプルよりもメインプログラムを対象とすべきですね。



◎タイムルーラーで測定

本題に戻って、メインプログラムの現状パフォーマンス調査再開。どの個所がネックになっているのか、タイムルーラーで測定します。

移動ユニット無現状パフォーマンス   移動ユニット有現状パフォーマンス

○移動ユニット無し
fps:45
Update Avg.:0.02ms
Draw Avg.:17.45ms

○移動ユニットあり
fps:30
Update Avg.:2.74ms
Draw Avg.:22.70ms

数値よりもバー(青色がUpdate、黄色がDraw)が気になったのですが、移動ユニット有りの方に黄色バーが見当たりません。数値が大きすぎると表示されないものなのでしょうか?


とりあえずマップ/静止ユニット/移動ユニットの3描画処理をマークすると、バーが2本表示される正しい画面と、空のバーが1本表示される正しくない画面が、瞬間的に交互に表示されて画面がチラつきました。

バーが2本表示された瞬間   バーが空白になった瞬間

どうも様子がおかしいので、Draw内の処理を全てコメント化したら、10秒に一回ぐらいの間隔でバーが空になる瞬間がありました。draw内の処理が増えると、バーが空になる瞬間が増えるようです。

コンポーネントの組み込みに失敗したのかなぁ…。



◎再現テスト

試しに、デバッグサンプルのDraw()の最後「timerRuler.EndMark("Draw");」の直前に
timerRuler.BeginMark(1, "dummy", Color.Red);
timerRuler.EndMark(1, "dummy");

と入れてバーを2行にしたら(視覚的にわかりやすくするため)、先程と同じく、バーが空になる(正確に言うと値が1になる)瞬間がありました。さらに、他のタスクを起動してデバッグサンプルを非アクティブにすると、恒常的に再現しました。

ちなみに、デバッグサンプルを改修しない場合は、黄色いバーが表示されない現象が再現します。

デバッグサンプルで再現したので、組み込みに失敗したわけではなさそうです。

コンポーネントを解析すると、前フレームのログのマークカウントが1になるタイミングがありました。この瞬間に、空のバーが1本の画面が表示されたわけです。

しかし、高負荷時にマークカウントが1になる理由が分かりません。やっぱりPC環境の特性なのかと思い、試しにサブPC(GeForceFX5200)で実行すると…再現しました。

PC環境に依存しないってことは、コンポーネントの仕様ってこと?!



◎次回予告

マーカーグラフは、高負荷時に振り切れる様子を確認して、そうならないように調整するための目安と思いますが、高負荷時に表示されないのはおかしな話です。

測定ミスが発覚したばかりなので、不安は払拭したかったのですが、仕方ないですね。マーカーグラフを無視してログの数値だけ追いかけます。

というわけで、次回はパフォーマンス測定の続き&インスタンシング概要調査です。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
GamefestJapan2008Demo
GamefestJapan2008デモ実行画面
こちらにUPされている動的頂点バッファデモ実行画面。
方式を変えてもFPSは一緒?



◎前回の続き

すみませんがまた予定を変更して前回の続きです。

前回は動的頂点バッファが意外に遅くてガッカリしましたが、こちらの記事に原因らしきことが書かれてました。

「頂点変換をはじめとするシェーダーでするべき仕事もCPUでしてしまい」「CPUで頂点変換処理をした時に比べて、単純なシェーダー処理をするだけで8.5倍」

もしかしたら、前回デモのネックはCPU側で、シェーダー処理に変えればパフォーマンスが向上する、ということかも?



◎デモ実行

まずはデモプログラムをリリースビルドし、EXEを実行して数値を確認しました。

(Particles: 3,000 → 10,000)

○Draw Method: SpriteBatch
FPS:60.02 → 24.45
Bar 0 Update Avg.:0.08 → 0.25ms
Bar 0 Draw Avg.:1.21 → 3.50ms
Bar 1 Draw Avg.:0.98 → 3.20ms

○Draw Method: TransformedVertex
FPS:60.02 → 24.16
Bar 0 Update Avg.:0.08 → 0.27ms
Bar 0 Draw Avg.:2.25 → 7.26ms
Bar 1 Draw Avg.:0.28 → 1.00ms
Bar 1 FillVertex Avg.:1.47 → m4.93s
Bar 1 SetData Avg.:0.13 → 0.39ms

○Draw Method: ParameterInVertex
FPS:60.02 → 23.94
Bar 0 Update Avg.:0.08 → 0.29ms
Bar 0 Draw Avg.:1.04 → 3.53ms
Bar 1 Draw Avg.:0.37 → 1.36ms
Bar 1 FillVertex Avg.:0.15 → 0.56ms
Bar 1 SetData Avg.:0.17 → 0.62ms

う~む…。

2番目のTransformedVertexが「CPUで頂点変換処理」方式で、3番目のParameterInVertexが「単純なシェーダー処理」方式らしいのですが、どの方式もFPSは同じですね。FillVertex Avg.は8倍以上の差がありますが、これを「速度アップ」と言っているのでしょうか?

だとすると、今までFPSを計測してパフォーマンス比較していたのは「間違い」ということになります。逆に、FPSで比較するのが正しいとすれば「私のPC環境では差が出ないケースがある」ということになります。

いずれにせよ、これまでの計測方法は(比較数値または検証環境が)間違っていた可能性が高そうです。

…どうにも、参りましたねぇ(ー_ー;



◎描画処理の時間

ちょっとヘコみましたが、気を取り直して話を進めましょう。

ソースを覗いて確認すると、FillVertexは以下の時間を示すものでした。

描画方法2(TransformedVertex):
「登録されているパーティクルから4頂点を計算してバッファに格納する時間」

描画方法3(ParameterInVertex):
「登録されているパーティクルのパラメーターを4頂点に増やしてバッファに格納する時間」

これだけだど描画処理の一部にすぎないので、比較するならBar単位(FillVertex+SetData+Draw、またはBar0)で比較すべきと思いますが、それだと差は2~3倍程度ですね。

他のPC環境だと、8倍ぐらい差が出ることもあるのかなぁ?



◎結論

描画方法2と描画方法3の数値の差は2~3倍ですが、これはCPU側のみの数値です。GPU側の数値はありません。あえて言うなら、FPSがCPU+GPUの数値に該当すると思います。

気になるのはParticles:10,000のケースで、CPU側の数値は差があるのに、FPSは差がありません。これはつまり、GPU側がネックになっていて、CPU側のパフォーマンスを改善しても効果が無い、ということではないでしょうか?

だとすると、私のPC環境では3番目の方式も「実質的な効果は無い」という結論になります。(CPU側が空くので他の処理を行う余裕は出来るが、ボトルネックは解消できない)


それとパフォーマンスの計測方法ですが、以前yohさんからアドバイスを頂いた通り、GameDebugライブラリを導入した方が良さそうです。面倒な時はせめてタスクマネージャでCPU負荷をチェックして、遅延原因がCPU側かGPU側か切り分ける習慣を付けるべきですね。



◎シェーダーモデルのターゲットバージョン

私のメインPCでは、ハードウェアインスタンシングのデモが表示されません。グラボが未対応だからでしょう。(ちなみにシェーダーインスタンシングは表示されます)

できればシェーダーモデル2.0でも遊べるようにしたいのですが、グラボが毎度ネックになるようで、いい加減切り捨てたくもあります。

シェーダーモデル2.0のPC、どれくらいあるのかなぁ?
2年前に購入した目の前のPCがその1台なので、少なくなさそうな気もしますが…ただの錯覚?w



◎次回予告

高速化できるかと期待したのですが、結局またグラボがネックでガッカリな結果に終わりました。

次はインスタンシングなので、シェーダーモデルのターゲットバージョンも決めないといけませんね。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
動的頂点バッファを使用したUVアニメ
サンプルプロジェクト実行画面
以前と同様のサンプルプロジェクトを作成して、パフォーマンスを比較した。意外と遅い?



◎動的頂点バッファ

XNAのモデルインスタンシングについて調べていたら、DynamicVertexBuffer(動的頂点バッファ)に関する記事を見付けました。頂点データの動的変更は、これを使った方が速くなるかも…?

というわけで、インスタンシングの前にこれをやります。



◎SetDataのエラーと対処

DynamicVertexBufferに関する記事はちらほら見かけるのですが、シンプルなサンプルはなかなか見当たりません。そこで、ソーサリーフォースのIndexBufferサンプルを自力でDynamicに改修することにしました。

まず、VertexBufferやIndexBufferを単純にDynamicVertexBuffer等に置き替えると…

インデックスバッファサンプル実行画面01

エラーもなく普通に動きました。(ちょっと意外w)


次に、頂点データの内容を動的に変更すると…SetDataでエラーが発生しました。

操作は中断されました。デバイスで設定されているリソースは変更できません。また、タイリング ブラケット内で使用した後に変更することもできません。

以前発生したのと同じエラーですが、今回はDynamicVertexBufferを使用しているので対処可能です(こちらの記事によると、SetDataOptions.NoOverwriteが良いらしい)。

this.vertexBuffer.SetData(vertives, 0, vertives.GetLength(0), SetDataOptions.NoOverwrite);

インデックスバッファサンプル実行画面02

時間経過と共に、頂点が上方向に移動しました。
成功ですねw

ちなみに、今回はSetDataOptions.Discardとしても結果は一緒でした。モデル数や頂点数で違いが出るのかな?



◎パフォーマンス比較

以前と同様のサンプルプロジェクトを作成して、パフォーマンスを比較しましょう。

…で、実際に作ってみると、ちょっと悩ましい点が出てきました。

・バッファ領域を全インスタンス分確保すべきか?
 →多分その方が早いので、全インスタンス分確保する

・頂点/インデックスデータを毎回取得/設定すべきか?
 →公平に比較するため、前回同様毎回取得/設定する

そもそもデモ内でインデックスデータは変更してないので、インデックスデータの取得/設定は全く無駄なんですが、実際のゲームに適用する場合を考慮して以前のデモに組み込んでしまったので、今回も同様の想定としました。

よく考えると、頂点データを変更してもインデックスデータは変更しないケースの方が多い気がしますが…まぁいいかw

動的頂点バッファを使用したUVアニメ

  シェーダー改修方式 → 今回方式
板ポリアニメ 100枚:60 → 60(fps)
板ポリアニメ1000枚:59 → 38(fps)
板ポリアニメ1500枚:40 → 30(fps)
板ポリアニメ2000枚:30 → 20(fps)
板ポリアニメ3000枚:20 → 15(fps)
板ポリアニメ5000枚:15 → 10(fps)



2/14追記
この回の計測データはデバッグ付きで実行したものです。
デバッグ無しで計測したデータはこちら



ありゃ?遅くなっちゃった?
と言うか、これまでで一番遅いですね…。



◎バッファ更新タイミングの変更

頂点データとインデックスデータを毎回バッファにセットしてるから遅いのかもしれません。アニメ画像番号が更新された時だけ、バッファ操作するように修正しましょう。

       改修前 → 改修後
板ポリアニメ 100枚:60 → 60(fps)
板ポリアニメ1000枚:38 → 59(fps)
板ポリアニメ1500枚:30 → 30(fps)
板ポリアニメ2000枚:20 → 23(fps)
板ポリアニメ3000枚:15 → 15(fps)
板ポリアニメ5000枚:10 → 9(fps)

1000枚はシェーダー改修方式と同等まで改善されましたが、1500枚以上は大差無いようです。1000枚超えたあたりを細かく測定してみました。

板ポリアニメ1050枚:58(fps)
板ポリアニメ1080枚:50(fps)
板ポリアニメ1100枚:45(fps)
板ポリアニメ1150枚:40(fps)
板ポリアニメ1200枚:30(fps)

ふむ…1000枚を超えたあたりから急に遅くなるのは間違いないようですね。もしかして、1024枚を超えるとGDCメモリを超えてスワップが発生するとか?でも、バッファメモリが足りなければ領域確保時にエラーになりそうだけどなぁ…。

以前の方式と今回の方式をPIXで細かく比較すれば、原因がわかるかもしれませんが、わかった所で以前の方式を超えることは出来ないので、この点に関してはこれ以上追及しないことにします。



◎以前の方式を超えられない理由

シェーダー改修方式のようなイレギュラー方式はともかく、DrawUserIndexedPrimitives方式よりも遅い理由は把握しておきたいですね。予想としては、頂点データの更新頻度が頻繁すぎるからじゃないでしょうか?

アニメは80ミリ秒毎に更新するので、Draw()呼び出し(約17ミリ秒毎)5回毎に、バッファを1回更新することになります。ということは、「DrawUserIndexedPrimitivesで5回表示」と「バッファ更新+DrawIndexedPrimitivesで5回表示」のどちらが早いか?を比較していたことになり、「後者がやや遅い」と仮定すれば、これまでの計測結果が納得できます。

では、この仮説が正しいか検証しましょう。アニメの更新頻度を変更して、両者のパフォーマンスを比較します。

○アニメ更新頻度:80 → 160
       DrawUser~方式:今回方式
板ポリアニメ 100枚:60 → 60:60 → 60 (fps)
板ポリアニメ1000枚:59 → 59:59 → 59 (fps)
板ポリアニメ1500枚:30 → 30:30 → 30 (fps)
板ポリアニメ2000枚:30 → 30:23 → 30 (fps)
板ポリアニメ3000枚:20 → 20:15 → 20 (fps)
板ポリアニメ5000枚:12 → 12: 9 → 10 (fps)

○アニメ更新頻度:80 → 500
       DrawUser~方式:今回方式
板ポリアニメ 100枚:60 → 60:60 → 60 (fps)
板ポリアニメ1000枚:59 → 59:59 → 59 (fps)
板ポリアニメ1500枚:30 → 30:30 → 30 (fps)
板ポリアニメ2000枚:30 → 30:23 → 30 (fps)
板ポリアニメ3000枚:20 → 20:15 → 20 (fps)
板ポリアニメ5000枚:12 → 12: 9 → 12 (fps)

DrawUser~方式は、更新頻度を下げてもパフォーマンスが変化しなかったのに対し、今回方式は、更新頻度を下げるとDrawUser~方式と同等のパフォーマンスになりました。

この結果だけで決めつけるにはデータ不足とは思いますが、先程の仮説は正しい気がします。(多分w)



◎まとめ

今回の結果だけを見ると、動的頂点バッファ方式はDrawUserIndexedPrimitives方式を超えられません。但し、別のケースであれば逆の結果になる可能性もあるはずです。

予想としては、

・頂点/インデックスデータを頻繁
 (80ミリ秒以内毎)に更新する場合
 →DrawUserIndexedPrimitives方式が良い

・頂点/インデックスデータを時々
 (160ミリ秒以上毎)更新する場合
 →動的頂点バッファ方式が良い

・頂点/インデックスデータを全く更新しない場合
 →通常のDrawIndexedPrimitives方式が良い

こうなることを期待していましたが、動的頂点バッファ方式が良いケースを実証できなかったのは残念ですね。


それと、私のPCでは1000枚を超えると急激にパフォーマンスが低下するらしく、1500枚で30fpsを超えられるのはシェーダー改修方式だけのようです。どの方式にも長所短所があるはずですが、あの方式の短所って何かなぁ?



◎サンプルプロジェクト

とりあえず今回のサンプルプロジェクトをHPにUPしました。なるべくシンプルにまとめたつもりですのでご参考まで。

XNA3.1でUVアニメーション(動的頂点バッファ方式)



◎次回予告

「動的頂点バッファ」という言葉が何となくカッコ良くて、ちょっと憧れていたのですが、今回はその効果が実感できなくてちょっとガッカリ。どうすればその効果が見えるようになるんですかねぇ?

それはともかく、次回からモデルインスタンシングです。
…って前回も言ったなぁ(汗)

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
徐晃出陣
徐晃出陣
于禁の七軍が壊滅してしまったため、宛に駐留中の徐晃に樊城救援の命が下った。重大任務を果たすべく、決意を固めて出陣する徐晃。



◎1月の目標達成度

・活動時間月120時間以上

実績:120h(達成率:100%)

 (中間目標:1/20迄に60h以上)

実績:60h(達成率:100%)


・画像ファイルの統合(10h)

実績:50hで完了(達成率:100%)


・企画見直し(24h)
・全体スケジュール見直し(12h)
・マップオブジェクト属性読込、表示(24h)

実績:未着手(達成率:0%)


・ブログ更新/HP更新(40h)

実績:54hでブログ更新、HPに「XNAのBasicEffectをカスタマイズ可能とする」「XNA3.1でUVアニメーション」など3記事を追加(達成率100%)

・その他(10h)

実績:13hでCG監修等実施(達成率100%)


・予定外の作業

実績:3hでインスタンシング調査 作業中


前半はボロボロでしたが、後半はそれなりに頑張ったと思います。でも進捗はいまいちですね~。



◎作業時間分析

作業時間集計2010年1月(PDF形式)


○良かった点
・後半頑張って、活動時間月間目標を達成した
・HP記事を8hで3件登録した

○悪かった点
・前半の活動時間が非常に少ない
・「画像ファイルの統合」が目標時間を大幅に超過した
・ブログの時間が多い(理想は30%以内)


大戦略Webの影響で前半ボロボロでしたが、引退後はペースを取り戻しつつあります。HP記事を8hで3件登録した頃は集中できていたので、集中時間帯が増えるよう頑張ります。



◎画像ファイルの統合について

1月の目標を決めた段階では、統合後の画像表示を深く考えてなかったので、画像を1枚にまとめるだけで10hと考えていました。

ところが、実際に画像を統合してみると、そのままでは全く表示できません。大戦略Webに気を取られていたとはいえ、そんなことに気付かなかったとは我ながら情けない(>_<)


元々の予定では、画像統合やインスタンシング等の高速化はゲーム全体がある程度出来あがってから実装するつもりだったのですが、画像を統合した以上、表示しないと意味無いので、そのまま表示プログラムに突入しました。

表示にはテクスチャ座標の動的変更が必要です。これは1年前からやりたくて出来なかったテーマの1つですが、これが出来るようになったのは、私のXNAスキルがそのレベルまで向上したからだと思います。

しかし、実装に伴い遅延現象が発生し、原因究明にかなり時間を要してしまいました。まだまだ精進せねばなりませんね。



◎進捗状況チェック

スケジュールは凍結中です。

画像統合までやってしまったので、インスタンシングでどこまでパフォーマンスが出るか様子を見てから、企画とスケジュールの見直しを行います。



◎2月の目標

・活動時間月144時間以上
 (中間目標:2/15迄に72h以上)

・インスタンシング調査/解析/実装前検証(48h)

・インスタンシング実装/計測/調整(40h)

・ブログ更新/HP更新(48h)

・その他(8h)

インスタンシングは手強そうですし、やりたいことも多いので、時間配分を多めに設定しました。作業時間の効率化を図るよりも、パフォーマンスを高めることに集中したいですね。



◎次回予告

というわけで、次回からいよいよモデルインスタンシングです!

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
画像解像度変更(GIMPで縮小02)
開発中のメイン画面
低解像画像に差し替えたら、遅延現象が解消された。木の画像はGIMPで縮小したものを使用している。



◎エフェクトの使い回し

前回の遅延原因調査の続きです。

特に工夫もなく何百枚ものテクスチャを差し替える旧方式が遅延せず、前回のテクスチャアトラスで遅延が発生するのはどうしても納得できません。あれこれ悩んで、ある仮説に至りました。

前回、画像の数だけモデルとエフェクトを用意したのは、Draw()内のエフェクトパラメータ変更を最小限に抑えるためです。しかしエフェクトがグラフィックデバイスのレンダーステートパラメータセットだとしたら、エフェクトを増やすとパラメータ変更が大量発生することになります。

それよりも、1つのエフェクトを使い回して、一部のパラメータ(テクスチャ指定など)をDraw()内で動的に変更した方が、パラメータ変更負荷が減るのではないでしょうか?

で、実際にやってみたら…変化なし。どうやらこれも違うみたいです。



◎ミップマップの有無

次に考えた仮説は、1枚あたりのテクスチャ解像度が増えたために、CPUメモリからGPUメモリへの転送に時間がかかる、ということです。

だとすると、ミップマップを有効にすれば画像解像度が自動選択されるので、遅延を解消できるかもしれません。

ミップマップ設定を確認すると、旧方式も前回方式も「モデル:有、テクスチャ:無」でした。前回方式のテクスチャミップマップを有効にすると

6 → 2 (fps)

さらに低下してしまいました(爆)



◎画像解像度の変更

ここでyohさんから「テクスチャやエフェクトがGPUメモリに収まりきらなくてスワップが発生してるかも」とのコメントを頂きました。

エフェクトに関しては、今回冒頭で試してダメだったので、違う気がします。また、連画取得時の解像度を下げてテクスチャの総データ量を大幅に減らしたので、テクスチャの総データ量も関係ありません。そうなると考えらるのは、やはり「1枚あたりのテクスチャ解像度が増えたから」でしょうか?

ミップマップ設定ではなく、元画像の解像度を変えないと意味が無いのかもしれません。とりあえず、木の画像解像度を落としてみましょう。

画像解像度変更(40×40)   画像解像度変更(GIMPで縮小01)

元々2048×2048用の表示パラメータなので、画像を差し替えただけだと、カメラ位置によって表示が崩れます。パラメータ修正前と修正後それぞれ試したら、どちらも移動ユニット無しで30fps、移動ユニット有りで20fpsでした(旧方式と同じ)。

やっと遅延原因が判明しましたよ~!!


ちなみに、連画出力ツールで512×512画像を出力して差し替えたのが左上図です。

元の2048×2048画像をGIMPで512×512に縮小した画像に差し替えたのが右上図です。

低解像オリジナルよりも、高解像オリジナルをGIMPで縮小した方がマシな気がするのは気のせいでしょうか?w



◎単色画像への差し替え実験

遅延原因は判明しましたが、単純に画像解像度だけの問題か気になったので、単色画像への差し替え実験を行いました。

単純画像に差し替え

2048×2048の単色画像に差し替えたら、遅延現象発生しました。つまり、ファイルサイズや模様の複雑さは関係ない、ということです。(ちなみに、元のファイルは1~2MB、単色画像は20KBです)



◎まとめ

今回分かったことを順にまとめていきましょう。

・画面に表示するテクスチャの種類が一定数を超えると
 急激に遅延する
 →一定数以下だとfpsは低下しない(「4枚」は偶然)

・画像1枚あたりの解像度が大きいと、負荷要因が高い
 →表示するのはその一部だけでも、
  全体解像度分の負荷がかかる(ポイント)
 →ファイルサイズや模様の複雑さは関係ない

ここまでは理解できますね。


1ピクセル1バイトと仮定すると、

2048×2048=4MB(画像1枚当たりのデータ量)
4MB×4枚=16MB(画像4枚当たりのデータ量)

私のPCでは、描画テクスチャ量が16MBを超えると、CPUメモリからGDCメモリへの切り替え遅延が発生する、と考えると納得できます。(地形とか他の要素は省略)


この仮定を、旧方式に当てはめるとどうでしょうか?

256×256=64KB(画像1枚当たりのデータ量)
16MB÷64KB=256枚(切り替え無しで描画できる枚数)

この計算だと、描画テクスチャが256枚以下なら遅延しないことになります。

テクスチャ総数は数千枚に及んだものの、同時に描画するのは通常256枚以下だったので、遅延が発生しなかった…と考えると納得できます。

ふーむ、こういうことだったのか…。



◎今後の方針

遅延原因は判明しましたが、こうなると旧方式に戻すべきか悩みますね。今後の方向性によって変わると思いますが、

:切り替え遅延が発生しない方向を目指す
:高速な切り替えを目指す
:両方目指す

なら旧方式、なら前回方式にすべきかと思います。


が実現できた場合、通常はよりも早そうですが、画面内のテクスチャ数が一定数を超えると急激に遅くなります。そういったことが滅多に無いよう工夫する必要がありますが、そこそこ実現できそうな気がします。

もちろん、ユニットの種類を増やすと上限256枚ではパンクしそうですが、解像度を下げれば許容枚数が増えます。既に80×80まで下げてますし、限界ギリギリの64×64まで下げると4096枚までOKということになります。

地形や簡易モデルのテクスチャ数も影響しそうなので一概には言えませんが、画面内のテクスチャ数を4096枚以下に抑えるのは、それほど困難ではないかもしれません。
(仮に超えたとしても、私のPCよりGDC性能が良ければ遅延しないかもw)


一方、が実現できた場合、テクスチャ数など気にせず無制限に追加できます。ただ、前回は30→7fpsまで低下したほどの遅延現象を、インスタンシングでどこまで回復できるか疑問です。(やってみないとわからない)


理想としてはかもしれませんが、今の私のレベルではハードルが高そうですし、開発やテストのコストも非常に高くなりそうです。(例えば、AB両実装プログラムでのテストパターンを考えたり準備するだけでも手間がかかりそうです)

進捗が非常に悪いので、これ以上進捗が遅れる要因は避けるべきでしょう。


というわけで、ABどちらかにするつもりです。まだの実現性がわからないので、インスタンシング導入の様子を見て決めたいと思います。



◎次回予告

2月になったので、次回は「1月の総括と2月の目標」です。

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

| BLOG TOP |

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