プロフィール

Na-7

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


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
DATE: CATEGORY:三国志軍記開発
自作地形28
開発中の自作地形
アルファ値を利用して複数の地形モデルを透過合成し、見た目や機能を損なうことなく高速化を実現した。



◎ビット演算

これまで何百種類ものパターンテクスチャを4次元配列で管理してきましたが、G案は複合テクスチャを廃止するので、今後は地形種別数×15種類になります。これに伴い、パターンテクスチャは2次元配列とビット演算で管理することにしました。

ビット演算の考え方は昔から知っていましたが、実際に経験したことは殆ど無かったので、少々苦戦しましたw
例えば、こんな感じ。

命題:iが0~15の時、iの各ビット値をi1~i4に格納する

int i1 = (i >> 3) & 0x1;
int i2 = (i >> 2) & 0x1;
int i3 = (i >> 1) & 0x1;
int i4 = i & 0x1;

目的は一応達成できましたが、これで良いのでしょうか?
もっと効率の良い方法がありそうな気がしますが…。

それと、0x1を0b1に変更するとエラーになるんですけど、C#言語は2進数表記できないんですかね?



◎インデックスバッファ不足

地形種別モデルを3個まで無事作成できましたが、4個目で落ちました。どうやらインデックスバッファ不足のようです。

調べてみると、インデックスバッファ配列(各頂点番号を格納)が冗長すぎて、インデックスバッファが不足する、という状況でした。

バッファ配列が冗長すぎなければ、当面は足りそうです。つまり、バッファ配列を最適な大きさで確保できるか?が焦点になりそうです。

これまで地形モデルは数個以内でしたし、パターン数が増えてもインデックスが分割されるだけなので、総インデックス数は不変でした。

しかしG案は、地形モデル数が増加する上に、パターンが重なる分だけ総インデックス数も増加します。どうすれば、効率的なバッファ確保ができるでしょうか?

確か XNA Creators Club に、一定の大きさのバッファを使い回すサンプルがあったと記憶してますが、今は改修中でソースがややこしい状態なので、即時導入はやめておきます。



◎安全性に対する懸念

今すぐできそうな手法としては、現在のインデックス配列をテンポラリとみなし、最終段階でインデックス配列を新たに作り直す方法です。
(テンポラリ配列の作成が完了した段階で、総インデックス数が判明します)

但し、この手法には懸念があります。

private static readonly Int16[] vertexIndices = new Int16[(数量)];

現在は、お手本に従い上記のように宣言してますが、後で作り直すためにはreadonlyキーワードを削除する必要があります。でもこれ…消すとヤバそうな気がしませんか?

試しにやってみたら、とりあえず動きました。でもかなり不安なので、この方法は安全性が確認できるまで封印します。これは推測ですが、readonlyは配列のガーベージコレクション対策かもしれません。インデックス配列はメモリ配置が変わるだけでヤバそうだし…。

結局、バッファ問題は先送りとし、当面は定数で細かく指定することにしました。先に地形モデル仕様(データ構造と描画方式)を確定させないと、バッファ事情も変わりそうなので。



◎SetPixelの謎

パターンテクスチャ自動作成ツールも改修が必要です。テクスチャにアルファ値を設定し、PNG形式で出力します。

しかしいざ作ってみると、SetPixelした座標とは無関係の座標のアルファ値まで勝手に変化したりして、かなりハマりました。その不思議な現象は、どうやら下記の初期化方法に問題があったようです。

(注:XNAではなくC#です)
for (int y = 0; y < height; y++)
 for (int x = 0; x < width; x++)
  srcB.SetPixel(x, y, Color.FromArgb(0, workB.GetPixel(x, y)));

上記の部分を下記のように修正したら直りました。

for (int y = 0; y < height; y++)
 for (int x = 0; x < width; x++)
 {
  Color color1 = work.GetPixel(x, y);
  Color color2 = Color.FromArgb(a, color1.R,color1.G, color1.B);
  work.SetPixel(x, y, color2);
 }



◎表示する順番

そんなこんなで苦戦しつつも、何とか5つの地形モデルを表示することができました。

自作地形27

うん?何か少し印象が違うような…ああ、川が干上がって途切れ途切れになってますね。川モデル表示後に河原モデルを表示したので、川の一部が河原に上書きされたようです。
モデルを表示する順番を変えたら直りました。(冒頭図参照)

洪水前後の水位の増減は、これを利用してできないかなぁ…(ぼそっ)



◎データ比較

ここで改修前後のデータを比較してみましょう。

描画プリミティブ数:38万 → 51万(1.3倍)
地形モデル数:2 → 5(2.5倍)
DrawIndexedPrimitives呼び出し回数:446 → 75(0.2倍)
1fps → 5fps(5倍)

「激重」から「ちょい重」ぐらいになりました。見栄えや機能を低下させずに早くなったのは嬉しいですね~!



◎マテリアルバッチの適用

マテリアルバッチを適用すれば、さらに早くなるかと期待してやってみましたが…結果から言うと、全然早くなりませんでした(--;

Effect取得に苦心してやっと動いたと思ったのに…。
1モデルあたりの規模が大きすぎるのかもしれません。

おかげでソースが中途半端な状態になっちゃったんだけど、元に戻した方がいいのかなぁ?う~む…。



◎次回予告

G案の改修が完了しました。
予想外の改修ボリュームでした…。
でもそこそこ早くなったので、やった甲斐はありましたね。

しばらく休みなしだったので、明日は1日お休みします。
次回は…XSIかな?

スポンサーサイト

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

コメント

コメントの投稿


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

トラックバック


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



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