DATE: CATEGORY:三国志軍記開発
城24
開発中のメイン画面
城が簡易モデルに置き換わり、傾きの問題は解消された。見た目やパフォーマンスも悪くないようだ。



◎画像の貼り付け

城の簡易モデルを作成します。まず手始めに、城画像を基本図形に張り付けてみましょう。

城画像を正方形に張り付けた   城画像を円柱に張り付けた

城画像を正方形(天井を下げてます)に貼り付けたら、左図のようになりました。さすがにこれではダメなので、円柱に貼り付けたら右図のようになりました。

十二角の城モデルを八角の円柱に張り付けたので画像が少しズレてますが、角度を合わせれば、ベースはいけそうですね。

しかし、円形や多角形はポリゴン数が増えます。円形にこだわるつもりは無いので、城モデルは四角形にしましょう。



◎前方後円城?

というわけで、簡易モデルを作る前に、ベースの城モデルを四角形に作り直します。

Castle02

作り直しの途中でこのようになりました。
円や四角形よりちょっとカッコいいと思いませんか?

ポリゴン数や画像数は増えますが、この形で進めましょう。



◎基本図形の作成

城壁の形に合わせた基本図形を作成し、画像を貼り付けました。

城簡易モデル01

ベースとしては悪くないようですが、課題が幾つかありますね。気になる所から潰していきましょう。



◎櫓の立体化

まず、櫓がペラペラの平面だと見た目が非常に悪いので、これを立体化します。

櫓の前面は城壁と同面のポリゴンで兼用できそうなので、左右と背面、上面の4枚の板ポリを追加して箱形を形成し、画像をUVでマッピングしました。

城簡易モデル02

屋根は立体的に三角にしないとダメですね。こういう時はポリゴン追加も止むを得ないと思いますが、判断に悩む箇所もあります。

例えば、櫓の1階と2階は大きさが少し違うので、1階に合わせて調節すると2階がおかしくなります。ポリゴンを追加すべきかUVマッピングで誤魔化すべきか悩んでしまいます。

作業を進めていたら、画像が微妙に傾いてることに気付きました。…そういえば、簡易モデル用の画像は正射影で取得すべきですね。他に、影の付き方も少し気になっていたので、UVマッピングの前に、画像を再取得します。



◎正射影画像とマッピング

思わしくない所に影が付いてますが、頂点をくっつけたり座標を揃えても、影が消えません。仕方がないので、XNAの画像取得プログラムでライトの方向を変えて調整しました。

正射影画像を取得して作業を再開すると、UVマッピングをしなくても平面マッピングで画像がピタリ一致します。楽で正確なのがいいですね。

あ、でもこのままだと画像ファイルが前後左右上の5枚になりますね。テクスチャアトラスで1枚にまとめるとXNA上のパフォーマンスが向上しそうですが、そのためにはUVマッピングを手動で行う必要があります。うむむ…。

とりあえずこのまま進めましょう。どうしてもパフォーマンスが出ない時は、1枚にまとめます。



◎前方後円城完成

城簡易モデルが無事完成しました。ちょっとポリゴン増えましたが、自分では納得出来るレベルになりました。

城簡易モデル03

今回は城壁内側を無視してます。いずれ内側に建築物を追加するので、その時に作ります。

通常モデルと簡易モデルのスペックは以下の通り。

○城通常モデル
マテリアル数:12
総頂点数:10009
三角形面総数:1640
四角形面総数:6832

○城簡易モデル
マテリアル数:5
総頂点数:201
三角形面総数:24
四角形面総数:56

頂点数やポリゴン数が1/50になりました。と言うか、通常モデルは無駄にポリゴン多すぎ(爆)



◎実装

いよいよ実装です。さて、どんな感じでしょうか?

城18

あれ?
こうして見るとカッコ悪いと言うか、城に見えませんね(汗)
四角形で作り直さないとダメだなぁ…。

パフォーマンスは劣化しませんでした。
柵200個より城40個の方が軽いのか…。



◎調整

城モデルと簡易モデルを四角形に作り直しました。

城19

城20   城21

うーん…わざわざ作り直したのに、簡易モデルは見た目がイマイチですね。アップで確認すると、外壁や櫓は悪くないので、城壁の内側に立体感が無いのが悪そうです。

というわけで、ポリゴン使って簡易モデルの内壁を作りました。

城22   城23

ようやくまともになりましたね。
最終的なスペックとパフォーマンスは以下の通りです。

○城(四角形)通常モデル
マテリアル数:12
総頂点数:10574
三角形面総数:1640
四角形面総数:7231

○城(四角形)簡易モデル
マテリアル数:5(画像数:2)
総頂点数:196
三角形面総数:16
四角形面総数:61

○城(四角形)簡易モデルのパフォーマンス
城約40、兵士無し:54〜58
城約40、兵士あり:27〜30

板ポリゴン方式に比べると、パフォーマンスが若干落ちたようですが、許容範囲内です。板ポリゴンの頃の問題点は完全に解消され、見た目もさほど悪くないと思うので、城モデルに関しては一段落ですね。

前回の柵モデルに続き、新しい城モデルもHPのダウンロードコーナーにUPしておきました。



◎次回予告

今回の手順(ベースモデルの作成→画像取得→簡易モデル作成)は、画質(解像度や立体感など)やパフォーマンスが良い反面、製作コストがかさみます。

自力でテクスチャを描ける人なら、簡易モデルを作るだけで済むかもしれません。でも、手描きで立体感が出せるのか疑問です。慣れた人ならできるのかな?

もう少し簡易モデル作成のコツを掴みたいので、次回は森モデルにチャレンジします。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
柵06
開発中のメイン画面
柵は簡易モデル方式で実装された。静止モデルの傾きの問題は解決したが、パフォーマンスは低下したようだ。



◎柵の作成

前回コメントで、yohさんから「(ビルボードは)奥行き感の重要な物体を表現するには向いていない」と教えて頂きましたので、城は今後別の方式を模索します。恐らく簡易モデルを作成することになるかと思いますが、他の静止モデルはどうでしょうか?

というわけで、メタセコイアでシンプルな柵を作りました。

柵01

この程度ならモデルを直接置いてもパフォーマンス的に問題無さそうな気がしますが、これは奥行き感の無い物体なので、まずはビルボードで試してみましょう。



◎柵の表示

というわけで、柵の画像を取得して配置しました。

柵02   柵03

やはり、画面の左下や右下に位置すると、回転したような傾きになります。これはビルボードの傾きによるものなので、ビルボードを無くしてただの板ポリにしてみました。

柵04   柵05

画面の左下や右下に位置しても下手に傾いたりしません。



◎柵簡易モデルの作成

柵は奥行きが無いので、両面板ポリで十分かと思ったのですが、真上や真横から見ると消えてしまいました。消えるとプレイヤーに誤解されてしまう恐れがあるので、直方体に画像を張り付けた簡易モデルを作成します。

柵画像を直方体に貼り付け01

直方体に単純に張り付けると、こんな感じになるのですね。これだとよろしくないので、上面と側面の位置をずらしました。

柵画像を直方体に貼り付け02

上面については問題無さそうですが、側面がおかしいです。これは、横棒が縦棒の奥に存在しているからです。

柵の横棒は縦棒の奥に存在している

このままだと側面がおかしくなるので、結局横棒と縦棒の位置を合わせて簡易モデル用画像を再取得しました。


大したものではありませんが、一応HPのダウンロードコーナーに3種類の柵モデルをUPしておきました。



◎パフォーマンス

柵簡易モデルをXNAに実装しました。

柵06

真上や真横から見ても消えません。絵的には問題無いのですが、パフォーマンスが気になります。

板ポリ5枚16頂点の柵簡易モデルをマップ上に200個配置したら、30→20FPSに低下しました。ガーン!この程度でそんなに落ちるとは…。

いざとなったら両面板ポリに変更可能ですが、それはなるべく避けたいので、後日モデルインスタンシング技術によりパフォーマンス向上を図ります。



◎次回予告

見た目の問題は解決しましたが、パフォーマンスが予想以上に低下したのはショックでした。この程度のローポリぐらい、パフォーマンスを気にせずガンガン表示したいものです。

モデルインスタンシングをやる前に、サンプルモデルを複数用意した方が良いと思うので、次回は城の簡易モデルを作成します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
城17
開発中のメイン画面
城の傾きや方向画像のカクカクを改善したが、スクロールするとまだ微妙な違和感があるようだ。



◎城の傾き

カメラを前後や高低に移動すると、城が逆に傾いてしまいます。

城08   城09
カメラを手前(左図)から奥に移動した(右図)

カメラを前方(奥)に移動したら、城の手前が浮き上がってしまいました。ビルボードで板ポリゴンを表示するとこうなるわけですが、映像的には、城の手前が沈んで城の上面が多く見えるようになるべきです。

傾きが逆であれば、ビルボードの回転軸の指定を変えれば上手くいくかも?

試しに Vector3(0, 0, -1) と指定すると、カメラのZ軸方向の移動に対してはいい感じで傾くようになりました。しかしカメラをX軸方向に移動すると、あらぬ方向に傾いてしまいます。

城10   城11

そこで今度は Vector3(0, 1, -1) と指定すると、カメラZ軸移動に対して傾きが固定され、X軸移動に対して傾きが自然になりました。しかし注視点を変更すると、あらぬ方向に傾くケースがあります。

出来そうで出来ないのは、もどかしいですね(−_−;



◎城画像の再取得

それにしても、同じビルボードのプログラムなのに、兵士は自然に見えて城が自然に見えないのは何故でしょうか?
私が気になるのは下記の2点です。

・兵士の画像は前面8割、上面2割なのに対し、城の画像は前面と上面の比率が逆転している

・兵士は前面、城は上面に注視している

試しに城画像を前面8割、上面2割で再取得しました。

城12   城13

一人称視点はマシになったようですが、上空視点は相変わらずですね。うむむ…。



◎カクカクの原因判明

試行錯誤を繰り返す過程で、別件の「カメラを移動して画面をスクロールさせるとカクカクする」原因が判明しました。

それは「(方向転換に伴う画像の)変化量が大きくて目立つから」でした。
…同じことを以前書いた気がします(爆)

すぐに気付けなかったのは、兵士をズームアップして画面に大きく表示された状態でスクロールしても、カクカクした印象を受けないからです。しかし、兵士のスケールを拡大するとカクカクします。

見た目の大きさは同じでも、画像が粗いと気付きにくいのかもしれません。



◎カクカクの解消

方向転換に伴う画像の変化量が大きくて目立つなら、方向画像数を増やしましょう。

まずは32枚から64枚に増やしてみましたが、まだカクカクします。そこで128枚に増やしたら、かなりスムーズになりました。

しかしこのまま単純に増やすと128×5=640枚になってしまいます。城門の数と向きはゲームに影響するのですが、映像的に表現するのは諦めた方が良さそうですね。

というわけで、映像的には4方向の城門で統一することとし、90度分の32枚だけ残して使い回すことにしました。



◎対策方針の検討

カクカクが解消されて大分マシになったものの、傾きの問題は未解決のままです。どうしたものやら…。

A案:この状態のまましばらく様子見

B案:ビルボードの角度改善を目指す

C案:上面中心の画像に変更する

D案:板ポリゴンを増やす

E案:簡易3Dモデルを作成して置き換える

F案:元の3Dモデルに置き換える

A案にしようかと思ったのですが、柵や森を追加する際に同じ問題で詰まってしまいそうです。簡単にできる案だけでも試してみましょう。



◎パフォーマンス確認

まずはF案。多分ダメだと思いますが、3Dモデルとビルボードのパフォーマンス比較ってことで。

城14

・ビルボード方式
 兵士無し:58〜60fps
 兵士あり:28〜30fps

・元の3Dモデルに置き換え
 兵士無し:10〜12fps
 兵士あり:8〜10fps

兵士ありでもさほど低下しないのは意外でしたが、城だけでこれほど遅くてはこの先ゲームになりません。映像的にはバッチリなんですけどね〜…って当たり前か(爆)

モデルインスタンシングなどのテクニックで改善は可能ですが、それをやるなら先にモデルを簡略化すべきでしょうから、今回はやりません。



◎画像の変更

お次はC案。上面中心の画像に変更しました。

城15   城16

上空視点は改善されたようですが、一人称視点だと城の後部が浮き上がってしまいます。円柱型ビルボードでは、上面と前面の両方を同時にサポートするのは難しいようです。

ゲーム難易度‘強’の場合、一人称視点固定にしようと考えていたので、逆に難易度‘中’‘弱’の場合、上空視点固定として、画像を使い分けるという方法はアリかも。若しくは、ボタンやキーを押すと視点が切り替わるとか?

画像枚数は増えますが、難易度で制限する場合は読み込み数を抑えられますね。アイデアとしては悪くないかも。



◎回転軸の修正

画像を使い分けると改善はされますが、傾きが逆であるという現象は変わりません。というわけで、B案にチャレンジ。

やはりビルボードの回転軸が気になるので、こんな感じで指定してみました。

Vector3.Normalize(new Vector3(0, 1, -1))

すると、カメラのZ軸方向の移動に対しては良くなりました。しかし、カメラを左右に回り込ませて注視点を変えると、あらぬ方向に傾いてしまいました。これはつまり、オブジェクトとカメラを結ぶ線に直角な上方向を指定しろってことですね?

Vector3 rotateAxis = Vector3.Normalize(billPos - mainMap.MapViewPos);
rotateAxis.Y = 1.0f - rotateAxis.Y;
rotateAxis = Vector3.Normalize(rotateAxis);


※Matrix.CreateConstrainedBillboard()の引数に上記rotateAxisをセットする



◎調整

城の内側の地面が透けていると城が浮いて見えるので、城モデルを修正して地面を追加しました。城やマップのスケールを考慮して、ユニットのスケールを小さくしました。仕上げに、ネームプレートの位置を修正しました。



う〜ん…ビミョ〜だなぁ(汗)
これでも大分マシになったんですけどね。

城が画面の右下や左下に位置すると、円盤が回転したような傾きになります。ビルボードや板ポリゴンを使用してる以上、これは仕方がないようです。ビルボードは大きなモデルに向かないそうですが、この城も大きくて向かない部類に入るのでしょうか?



◎次回予告

別の方式を模索するか、保留して次のテーマに移るか悩みましたが、城だけの問題であれば簡易モデルを作成した方が良さそうですし、静止モデル全般の問題であれば別の方式を模索すべきでしょう。

というわけで、次回は他の静止モデルを作成して、同じ現象になるか確認することにします。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
城07
開発中のメイン画面
ビルボードの城とネームプレートが実装され、ゲーム画面らしくなってきた。ネームプレートは城の前後関係を考慮して重ね合わされ、以前より読みやすくなった。



◎城モデルの画像取得

今回は城モデルの画像取得/表示です。

まず、画像取得プログラムを改修して、ACLモデル以外に通常モデルのスクリーンショットも取得できるようにしました。他にも、画像出力前に既存ファイルを一旦削除するとか、各種パラメータを一箇所にまとめるとか、細かい改修を併せて実施しました。


城モデルは城門の数によって5種類あるので、全ての画像を取得すると32×5=160枚になります。城門4つの城を使い回すことにする場合、90度分の画像で足りるので、たった8枚に減らせます。

パフォーマンス的にはその方が良さそうな気がしますが、調整は後で行うこととして、とりあえず160枚取得しました。



◎城データの読み込み

城を配置する前に、城データ(名称や座標を記述したテキストデータ)を読み込む必要があります。

データ読み込み機能は漢字表示機能と連動したものを過去に実装済ですが、漢字表示機能はひにけにXNAの改造版です。XNA3.1化に伴い、ひにけに版がアップデートされたので、こちらもアップデートすべきでしょうか?

ちょっと悩みましたが、既存プログラムが複雑なので今回は単純にコンバートしたプロジェクトを取り込みました。
とりあえず今は動けばいいや(笑)

しかし単純コンバート版を組み込んで実行すると「ファイルが無い」とエラーになりました。テキストファイルはC#で読み込むため、「出力ディレクトリにコピー」を「常にコピーする」に設定しておかないと、デバッグフォルダにファイルが存在せず、エラーになってしまうのです。

漢字表示機能に関係してるのかと思って原因調査に手間取りましたが、結局以前決めた仕様を忘れていたことが原因でした(爆)



◎城とネームプレートの表示

データ読み込み機能、漢字表示機能などを再実装し、城の位置の高さを取得して配置しました。

城01

高さはちゃんと取得できてますね。しかし静止画だとわかりませんが、スクロールするとカクカクします。アニメしないモデルだと目立つなぁ…。


城02   城03

ネームプレートを表示しました。城の位置は大体合ってるようですね。

しかし困ったことに、SpriteSortMode.Immediateを設定すると、スプライトバッチのDrawString()やEnd()でエラーになってしまい、他のソートモードを指定すると、非透過状態となってしまいます。

これは以前から悩んでいた問題ですが、どうしても原因がわからないのでスプライトを避けてました。しかしいよいよ実害が出てきたことですし、何としても解決しないといけません。



◎スプライトバッチ開始オプション

ヘルプを参照すると、
Immediate モードでは、グラフィック デバイス設定の衝突を発生させることなく存在させられるのは、1 つのアクティブな SpriteBatch インスタンスのみです。
とあります。グラフィックデバイスやスプライトバッチのインスタンスが複数混在してるのではないかとか、コンテントマネージャをオーバーライドしたことが影響してないかとか、いろいろ調べたのですが、結局はスプライトバッチ開始オプションの問題でした。

改修前:
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);

改修後:
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.None);

SpriteSortModeの中ではImmediateが一番早そうですが、この場合SaveStateMode.SaveStateとしないと、3Dモデルの描画が乱れるという不都合がありました。しかし今はビルボード方式により3Dモデルが単純化されたので、この問題は発生しません。

改修後の組み合わせにすると、無事に透過処理が行われ、負荷も若干軽減された気がします。

城04



◎ネームプレートの透明度

城やネームプレートが無事に表示されると、いろいろ気になる点が出てきます。

まずはネームプレートと文字の原点を左上から中心に変更し、上下と左右のサイズ比率や表示位置を調整しやすくしました。但し、表示位置は城の傾きやカメラ位置に連動して調整する必要があるので、城の傾きを修正してから最終調整します。

次に、ネームプレートが重なるとゴチャゴチャして読めないという問題がありますが、よく考えたら、背景が半透明では重なると読めなくて当然です。文字の左右を半透明とし、文字位置の背景は不透明としました。

ネームプレートの透明/半透明/不透明

これで幾分マシになったようですが、まだまだ読み辛いです。よく見ると、後方の城名が前方のネームプレートの手前に描かれ、文字と文字が重なっています。

これはつまり、カメラ視点で城の前後関係を把握して、後方の文字の手前に前方のネームプレートを配置(または描画)する必要があるってことですね。



◎城の前後関係

カメラと各城の距離を1つ1つ計算し、それらをソートして順序を把握しようとすると、面倒な上に遅くなりそうです。XNAでサクッとできないものでしょうか?そもそも城モデルはXNAが前後位置を把握して描画してるわけだから、そこから情報を取得できても良さそうな気がします。

そこで深度バッファを確認すると、これはレンダリングされた各ピクセルの深度を記録したものでした。ピクセル単位の情報では役に立ちません。やはり自前でやらなきゃダメか。

やむなく自前での実装を検討します。カメラと各城の位置関係により距離は取得できるので、問題はソートです。

…でも待てよ?距離を0〜1の範囲に縮小して深度を指定すれば、自前ソートは不要?

float layerDepth = Vector3.Distance(モデル位置, カメラ位置) / 最大距離(=マップの対角線);

※spriteBatch.Draw()の引数に上記layerDepthをセットする

城05   城06

無事ソートできたようです。こんなに簡単に出来るとは思いませんでした(^^;

ちなみに、左図は文字背景完全不透明バージョンです。
見た目がちょっとアレなので、透明度2段階バージョンとしました(右図)。



◎次回予告

画像を取得して表示するだけと思っていたのですが、実際にやってみると課題問題が予想以上にありました。まぁ、深度指定のコツとか収穫もあったので良しとしましょう。

次回は城表示関連の残課題に対応します。
城の傾きの修正が難しくて試行錯誤中。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
川への侵入不可
開発中のメイン画面
試験的に侵入不可チェックを実装し、川には侵入不可となった。最終的には地形種別毎に移動コストを加算し、部隊の移動速度に反映させる予定。



◎地形種別の取得

今回は地形種別を取得し、データ検証を兼ねて侵入不可チェックを実装します。

カラーマップ画像の色情報(地形種別情報)を取得するコンテントパイプラインは作成済なので、これをメインプログラムに組み込み、HeightMapInfoと同様に改修します。

次に、カラーマップの解像度やスケールを252で調整し、座標を指定すると地形種別情報を返すようにします。試しに幾つかの座標を指定すると、それらしい地形種別番号が返ってきました。

これで地形種別の取得は完了です。



◎侵入不可チェック

最終的にはA地点からB地点までの最短ルートを判定できるようにしたいのですが、今回はその前段階として侵入不可チェックを行います。

一番シンプルな方法は、移動先の座標のみチェックするという方法です。但しこの方法には2つの欠点があります。

1つは、移動量が2マスを超える場合、間に侵入不可地形が存在していたとしても無視される、という問題です。しかし今回のゲームスケールでは、1ゲーム時間で2マス以上移動するユニットは存在しないので、この問題は無視します。

もう1つは、斜めに配置された侵入不可地形(川など)に対角線状に侵入すると、越えることができる、という問題です。

川を超えてしまう

この問題を解決するため、斜めに移動する場合は縦横の隣接マスも同時にチェックします。



◎フィールド散策

移動先が侵入不可の場合、向きを変えるようにして実行すると、予定外の所で向きが変更されました。うーむ。

…原因調査でしばらくハマってしまいましたが、どうやら移動プログラムがおかしかったようです。いきなり川沿いに移動させるのは無謀だったかな?

とりあえず1ユニットをパッド操作で8方向に動かすようにして、フィールドを散策し、ユニットの周囲の地形を確認しました。

フィールド散策

ユニットの周囲の地形と地形種別番号が合いません。データがおかしいのかと思ってテキストに出力しマップと比較すると、データとマップは一致しました。

では何故見た目と合わないのか調べたら、現在表示しているマップテクスチャがズレてました。メタセコイアで地形を再作成した際に、テクスチャを絶対パスで指定してしまい、昔の正射影画像が表示されていたのです。…もっと早く気付くべきですね(爆)



◎はみ出しモデル

テクスチャ画像を最新版に戻したら、テクスチャの境界線が出現してしまいました。とりあえずその問題は後回しにして、フィールド散策を続行すると、少しだけずれてる感じ。カラーマップの解像度を253で調整すると、ピタリ一致しました。


しかしまた新たな問題発生。部隊ユニットの中央の騎馬は川に侵入しなくなったのですが、その周囲の騎馬は川にはみ出してしまいます。

袋小路への侵入

最終的には、橋を渡る際は縦陣で一騎ずつしか渡れないようにするつもりですが、それ以外の陣系で袋小路に侵入した場合の処理も考える必要があります。移動処理を本格的に作る際に実装する予定です。



◎川沿いに南下

侵入不可チェックが可能となったので、再度川沿い南下プログラムにチャレンジします。

…今度はうまくいったようです。しかしこのマップは川が多すぎて必ず袋小路でつっかえてしまうので、デモとしては面白くないですね。1つ気になるのは、道沿いに斜めに突っ切ってくれないケースがあることです。何故かなぁ?

…仕様上の問題でした。川と道がクロスになる場合、川が斜めに存在するので侵入不可と判定されてしまうのです。

移動元と移動先が道の場合、優先的に移動可能としました。これで道がある場合はちゃんと通るようになりました(冒頭図参照)。



◎次回予告

地形種別の取得は無事完了し、試験的な侵入不可チェックが成功しました。地形関連は一段落ですね。

次回は城モデルの画像取得/表示です。

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

| BLOG TOP |

copyright © ゲーム制作の舞台裏 all rights reserved.Powered by FC2ブログ