プロフィール

Na-7

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


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
ShadowMappingサンプル
シャドウマッピングサンプル
深度テクスチャを作成する公式サンプル。ライトを動かしながら、深度テクスチャの様子を確認することができる。



◎ネームプレートを表示すべきか?

山の反対側の部隊は表示しないようにしましたが、ネームプレートは表示されてしまいます。

ユニットの深度判定01

赤矢印のネームプレートは、部隊が山の反対側にいるケースです。

部隊はDepthBufferEnableやDepthBufferWriteEnableの制御で山の向こう側に隠れたのですが、ネームプレートは2Dスプライト画像なので、同じ方法では対処できません。個々に深度値を設定すれば上手くいくかもしれませんが、適切な深度値はどのように算出すべきものなんでしょうか?

…いや、ちょっと待ってください。黄矢印のように『部隊は山に隠れるがネームプレートは山の上になるケース』や、『部隊は森の中でネームプレートは森の上になるケース』はどうでしょうか?

その場合、ネームプレートの深度を適切に設定したとしても、伏兵した部隊の頭上にネームプレートが表示されてしまいます。これでは伏兵の意味がありません。

というわけで、『ネームプレートの深度を適切に設定する』ではなく、『部隊が描画されているか(部隊の深度は最前面か)を判定する』を命題とし、その判定結果に基づいてネームプレートを描画するようにします。



◎深度バッファの値を取得する方法

深度バッファには、‘最前面の物体からカメラまでの距離’が0~1の相対的な値で格納されています。この値を取得してユニットの深度と比較したいのですが、深度バッファの値はどのように取得すれば良いのでしょうか?

こちらによると、深度バッファの内容を直接取得することはできないとのこと。えっ!?!そうなの!?

…ヘルプを確認すると、その通りでした。深度テクスチャを作成するしかなさそうです。

深度テクスチャの作成は難易度が高く、特定ピクセルの色をゲットするのでコスト(処理時間)もかかりそうです。メンドクサイ上に、遅くて使い物にならない恐れがあるなんて…正直やりたくないッス(--;

他に良い方法は無いかと考えたのですが…ユニット同士なら深度を自分で管理する方法もありますが、地形の起伏の深度を考慮すると、深度バッファーから取得する以外に方法は無さそうです。

こうなったら仕方がない。使い物になるかどうか試してみましょう!!



◎公式サンプル

こちらの公式サンプルで深度テクスチャーの作成方法を勉強しましょう。

ShadowMappingサンプル

中身をちらっと覗いてみると…レンダーターゲットは使用経験があるのでそこそこ理解できますが、真面目にやると面倒臭そうですね。

とりあえず、サンプルの深度テクスチャーから深度を取得できるか確認しましょう。



◎技術資料

深度テクスチャーの深度を確認するために、サンプルコードを用意しました。

テクスチャカラーを配列に格納する

技術的な価値はありませんが、デバッグ等の使い勝手は良さそうなので、HPの技術資料に追加してしまいましたw



◎深度取得テスト

サンプルの深度テクスチャーカラーを配列に格納して色を確認すると…ヘルプに記述された通り、RGBAのうちRのチャンネルのみ値が格納されました。このままだと深度値が256段階になってしまうので、精度が足りず山の奥か否か正確に判断できない可能性があります。サーフェイスフォーマットを変更して、精度を上げる必要があるかもしれません。

しかし何より問題なのは、Texture2D.GetData()の遅さです。何と60→4fpsまで落ちてしまいました!
噂には聞いてましたが、まさかここまで酷いとは…><

テクスチャの解像度は2048×1024だったので、1280×768にすれば多少早くなると思います。とは言え、焼け石に水のレベルですね(ーー;



◎次回予告

このままでは使い物にならないので、次回は別の方法を探ります。

スポンサーサイト

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
高さ修正完了
開発中のメイン画面
ユニットが地面に埋まるバグが修正されたらしい。



◎ズレの原因判明!

公式サンプルの付属ドキュメントも日本語化されたので、中身を確認しました。こういう原理だったのですね(今更何言ってんだw)

原理もプログラムも問題無さそうです。こうなったら、ズレるケースでの変数を全てトレースして確認しましょう。

…全ての変数及び計算結果と、Excelでの手計算が全て合致しました。全て正しい数値なのにズレるということは、メタセコイアの地形が違うということ?

メタセコイアで座標確認用モデルを配置した

メタセコイアで、先程算出した座標の位置に確認用モデルを配置したら、ズレました(頂点の位置ではピタリ合致しました)。

つまり、メタセコイアの地形生成ロジックとXNAの計算ロジックがズレてました!!

四角形のセルを横から見た図

地形モデルのセルは三角形ポリゴン2枚で構成されます。メタセコイア地形モデルは、各ポリゴンの面の角度がそれぞれ異なるわけですが、これはXNA計算ロジックの想定外です。



◎改修

というわけで、GetHeightの計算ロジックをメタセコイア地形モデル用に改修しました。(サンプルはこちら

高さ修正完了

やりました!完璧です!!

高さのズレに長いこと悩まされてきましたが、ついにクリアしました!^^



◎次回予告

まだネームプレートに問題があるので、次回はそちらを修正します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
マップ拡大01
開発中のメイン画面
マップが拡大されて広くなったが、幾つかの問題が発生したようだ。


◎城の位置

ネームプレートがまともになったので、ついでに城のネームプレートも復活させたのですが、そうなると城の位置が気になってきました。城の位置は最初からずれていたので、これを機に修正しましょう。

…基準点を襄陽/樊城と宛に決めて、地形テクスチャと合う位置に調整したのですが、他の城はこれで良いのでしょうか?良さそうなのと悪そうなのが混在して、判断がつきません(汗)



◎マップの拡大

そろそろマップを拡大したいと考えていたので、これを機にマップを拡大し、地形テクスチャを再作成しましょう。

というわけで、地形モデルを縦横2倍(面積4倍)に拡大しました。城と城の間の距離を考えると、これぐらいが丁度良さそうです。ただ、プレイヤーが全体を把握しようとすると、ちょっと広すぎるかもしれません。

うーん…拡大より縮小の方が簡単なので、とりあえず広めに作っておいて、後で縮小するか検討しましょう。

で、単純にスケールを倍にしただけだと地形テクスチャが荒く見えるので、地形テクスチャを1024×1024 → 2048×2048としました。

マップ画像1024   マップ画像2048
左図:1024×1024、右図:2048×2048

近くの地面をよく見ると、確かに2048×2048の方が細かいのですが、言われないと気付かないレベルです。

それよりも、2048×2048だと激重で37→6FPSとなってしまいました。多分キャッシュオーバーでしょうが、これではゲームになりません。美的効果も低いので1024×1024に戻します。



◎高さのズレ

マップ拡大に伴うXZ座標修正は一通り終えたのですが、よく見ると、城や兵士が地面にめり込むケースが増えたようです。以前から散見された現象ですが、マップ拡大でさらに目立つようになり、酷い時はユニット全体が完全に埋まってしまいます。

…で、あれこれ調べて原因らしきものが見付かりました。グレースケールマップの解像度を変更した際に、メタセコイアで地形モデルを拡大したのですが、拡大時の基準座標がXNAと異なっていた可能性があります。

メタセコイアで拡大せずにXNAで拡大し、XNAの座標系をそちらに合わせると修正できるかもしれません。しかしマップを修正する度にズレで悩むのはウンザリしてきたので、もっと柔軟に対応できるよう根本的な見直しをしましょう。



◎改善案

高さに関する情報は、現在下記の3つがあります。

・(メタセコイア上の)地形モデルの頂点の高さ
 →グレースケールマップが基準
 →拡大しない方が無難

・(XNA上の)地形モデルの頂点の高さ
 →地形モデルが基準
 →広さと高さの倍率を指定する

・(XNA上の)GetHeightの高さ(XNA)
 →グレースケールマップが基準
 →広さと高さの倍率を指定する
  (但し高さの倍率基準は上記と異なる)

地形の頂点数やスケールを変更すると、上記3点の整合性が崩れてユニットの高さがズレます。3つの関係を保とうとするからややこしくなるので、2番目と3番目の要素を合体させて要素を減らしましょう。

具体的には、GetHeightの基準値をグレースケールマップから地形モデルの頂点座標に変更します(XNAではグレースケールマップ不要とします)。



◎頂点データの数

サンプルプログラムを新規作成し、地形モデルの頂点データを取得すると、65×65=4225個ではなく4624個ありました。
(399個多い)

中身を確認すると、Positionの値が同一のデータが散見されました。テクスチャを複数マッピングした影響かもしれませんが、座標以外は不要なので、ソート後に削除します。



◎ソートの安定性

頂点データは順序不定なので、X及びZ座標でソートします。まずList型に代入し、Z座標でソートし、続けてX座標でソートすると…あれ?X座標はソートが反映されてますが、Z座標は順序不定です。中間では間違いなくソートされてるのに…?

その疑問の答えはこちらの『ちなみに、このSortメソッドは「安定していない」。』以降に書かれてました。
うわ、C#の仕様ですか!?(爆)


少し調べた限りでは.Net Frameworkに安定ソートは無さそうだったので、バブルソートを実装して対処しました。今のPCで数万件のソート速度に差は出ないから種類は何でも良いのですが、わざわざコードを記述する時点でスマートじゃない気がするなぁ(苦笑)


昔話。
8ビットPCの自作ゲームが遅くて、悩んだ末に逆写像ソートを実装したら、圧倒的な早さで衝撃を受けました。意外とシンプルなコードで、なぜこれでソートできるのか(しかも安定性あり)未だに原理が理解できませんw



◎技術資料

そんなこんなで、サンプルプログラムが完成しました。

地形モデルから高さを取得する

この方式は開発当初から望んでいたのですが、ようやく実装できるレベルに達した、というわけです^^



◎誤差

新方式に切り替えたついでに高度のズレが解消されると嬉しかったのですが、残念ながら現象は引き続き発生します。
原因を調べると…単なる誤差のようです(爆)

float a = 256.7f % 8.0f;
Console.WriteLine("a = "a.ToString());

これを実行すると

a = 0.7000122

と表示されます。floatの桁落ちによる誤差ですね。
誤差を減らすためにdouble型にキャストしたいのですが、どうも単純にはできないような…?

float a = 256.7f;
double b = (double)a;
Console.WriteLine("b = " + b.ToString());

実行結果は以下の通り。

b = 256.700012207031

double → float で誤差が生じるのは理解できますが、
float → double で誤差が生じるとは初耳です。

こんな時は…そうかdecimalを使うのですね。
よしこれで計算の誤差が減りましたよ。

…高さのズレ再発しました。
結局誤差は大した問題じゃなかったようです(><)



◎現状の再確認

フローに沿って座標値をトレースしても、他におかしな点はなさそうでした。座標値が正しいのに、なぜズレが発生するのでしょうか?

基本に戻って、ズレの状態を確認する所からやり直します。

GetHeight確認01   GetHeight確認02

確認用モデルをX=-88(左図)、X=-84(右図)で並べました。

X座標またはZ座標が頂点座標と一致する(8の倍数)と正確な高さを取得し(左図)、頂点座標から離れると高さがズレます(右図)。ちなみに、上記のdecimal方式で誤差を減らしても見た目変わりません。

ということは、

仮説A
GetHeightの計算ロジックがおかしい(または不正確)

仮説B
メタセコイアの地形生成ロジックとGetHeightの計算ロジックが合致しない

上記のどちらかと思いますが、頂点座標と一致する座標の高度は合致するので、仮説Bはありえないでしょう。ということは仮説Aってこと?でも、公式サンプルのボールは地面の上を正確に転がった気がするなぁ…うーん(ーー;



◎次回予告

地形を拡大した影響で、ズレが無視できないレベルになったので、何らかの結論を出すまで徹底的に追求します。

というわけで、次回は引き続き高さのズレを調査します。

…最悪サイズ戻すかも(ぼそっ)

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
ネームプレートの改良02
開発中のメイン画面
ネームプレートの文字が、近い部隊は大きく、遠い部隊は小さく表示されるようになった。カメラ移動に伴う不自然な表示も緩和されたようだ。



◎ネームプレートの画像修正

画面の解像度を大きくしたので、文字やネームプレートも大きくしましょう。

ネームプレートの改良01

文字が大きくなって読みやすくなりました。



◎ネームプレートの座標修正

カメラが移動すると、カメラに映ったメイン画面の地形/部隊/ネームプレート等も移動します。しかしこの時のネームプレートの移動が不自然な感じで、以前から気になってました。これを機に修正しましょう。

私が考えた案はこんな感じです。

ネームプレートの配置座標案



◎試してみる

最初はクォータニオンを試してみました。

Quaternion q = Quaternion.CreateFromYawPitchRoll(0, MathHelper.ToRadians(90), 0);
Vector3 targetPos = Vector3.Transform(unitPos, q);


しかし計算結果を確認すると、全然違いました。どうやら、CreateFromYawPitchRollとCreateRotationX/Y/Zは同じっぽいです。別物だと思ってました(爆)

クォータニオンにはCreateRotationX/Y/Zが無いので、MATRIXによる比較テストで確認しましょう。

XNAのコードと実行結果

おや?値が異なるケースがあるなぁ…ははぁ、これがいわゆるシンバルロックというヤツですね?
ちなみに、45度だと同一の値でした。



◎三角関数の応用

MatrixやQuaternionのメソッドを一通り調べたのですが、簡単に算出する方法がわかりません。仕方がないので、三角関数を地道に組み合わせて計算することにしました。

XNAのコード

この程度のプログラムなのに、作り上げるまで数日悩みまくりでした(爆)

で、いざカメラを動かしてみると、ネームプレートの位置が不自然です。スケールレート(カメラから部隊までの距離が基準)を調整すれば良くなりそうですが、それならスクリーン座標とスケールレートの調整だけで十分でしょう。

…うわー何無駄なことやってんだオレ!(連爆)

ネームプレートの改良02

最後は満足できる状態になったものの、こんなことで悩みまくった自分自身に自己嫌悪(ーー;



◎次回予告

今月前半まで開発好調だったのに、回転について考え始めたら、急に調子悪くなってきました。昔は三角関数得意だったのに…って20年前の話じゃアウトかw

次回は城の座標修正、地形テクスチャ修正などを行う予定です。

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

| BLOG TOP |
DATE: CATEGORY:雑記
ブログを新たに設立しました。

日本社会への提言

上記ブログでは、日本の社会構造から身近な問題まで、様々な懸案に対して筆者独自の分析と解決策を提言します。
(記事は全て私自身が記述したものです)

お時間があれば、是非覗いてやってください。
できればコメントなど添えて頂けると嬉しいです。

尚、上記ブログの更新頻度は月1~2件程度を目安としているので、引き続き「ゲーム制作の舞台裏」がメインブログとなります。
| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
矢印の改善08
開発中のメイン画面
矢印モデルが改良されて、以前より見やすくなった?



◎板ポリ矢印

前回の矢印モデルは先端がわかりにくかったので、今回は矢印モデルを改良します。まずは板ポリに矢印テクスチャを張り付けたシンプルな矢印で試してみましょう。

矢印の改善01

前回よりは見やすくなったようですが、廖化の奥の矢印は見辛いですね。矢印を水平に配置したので、カメラの角度が水平に近付くと見辛くなるようです。

対策として、垂直両面の矢印を追加しました。これなら真横から見ても大丈夫でしょう。

矢印の改善02   矢印の改善03

存在感がUPしたのは良いのですが、半透明だと色の濃淡が出来て違和感がありますね。半透明をやめると濃淡の違和感は無くなりますが、中央の黒いライン(影)は消えません。



◎矢印モデルの改良

矢印モデルを改良します。今回は三角ポリゴン8枚分です。

矢印モデル02

XNAで表示すると、こんな感じです。

矢印の改善04   矢印の改善05

これまでの中では一番マシですね。ただ、半透明はやはり色の濃淡が出来て違和感があるので、ステンシルバッファを利用して二重描画しないようにします。

矢印の改善06

色の濃淡は均一になりました。



◎アルファマップ

デザインが味気なさすぎなので、少し変化を付けましょう。こちらの記事を参考に、GIMPの透明グラデーションでアルファマップ(と呼ぶんですよね?)を作成しました。

矢印用アルファマップ01(ブログ用)   矢印の改善07

実際に使用するアルファマップは白ですが、それだとわかりにくいので赤く色付けしました(上左図)。そのテクスチャをモデルに張り付けてXNAで描画したのが上右図です。

ステンシルの二重描画防止機能が無効になってしまいました。理由はよくわかりませんが、併用できないのかもしれません。デザインもあまり良くないですね。

矢印用アルファマップ02(ブログ用)   矢印の改善08

先程よりはマシになったと思います。デザインにこだわるとキリが無いので、今回はここまで。



◎次回予告

履歴画面のイメージは概ね出来たので、次回は報告から履歴登録/表示までのフローを実装します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
履歴画面の検討05
開発中のメイン画面
画面左側が履歴画面で、右側は自部隊の視界。履歴画面にはこれまで報告された敵味方部隊の進軍状況が表示されている。



◎上級ルールを普通に表示した場合

三国志軍記の索敵ルールは以下を予定しています。

初級:全て表示

中級:味方部隊の索敵範囲のみ表示

上級:自部隊の索敵範囲のみ表示

中級ルールの索敵範囲表示は実装済です。では、上級ルールを普通に実装するとどうなるでしょうか?

上級ルール用の索敵範囲01

上図のように、自部隊以外は何も表示されません。つまらないですね。

そこで、今回は履歴画面を検討します。



◎画面構成の検討

従来のリアルタイムストラテジーゲームでは、索敵の概念が無いものが多く、履歴機能は無かったり、あっても文字で表示される程度です。‘現状’が判断基準なので、過去の履歴はオマケ程度の扱いというわけです。

しかし三国志軍記の上級ルールは、‘現状’で判断するのではなく、敵味方の行動を予測して判断するので、敵味方の履歴(味方部隊の行動予定含む)が判断基準となります。よって、履歴画面をグラフィカルでわかりやすく表示することが重要です。

いっそのこと画面全体を履歴表示にしても良いのですが、それでは自部隊が敵と遭遇したり戦闘した際に、戦場の臨場感が味わえません。よって、画面左側に履歴、右側に自部隊の視界を表示します。

履歴画面の検討01

最初は、画面左側をレーダー画面、右側を自分の視界と考えると理解しやすいでしょう。この後、画面左側が履歴画面となるように検討します。



◎履歴部隊の描画

ユニットマネージャクラスとは別に履歴マネージャクラスを作成し、履歴部隊を半透明で表示します。

これがなかなかうまくいかなかったのですが、原因はユニットクラスを継承した履歴ユニットクラスの中に、継承元のユニットクラスと同一名の変数を定義したためでした。この場合変数がそれぞれ作成されるので、他クラスからSet/Getすると混乱します。このミスは、一度記述してしまうと後で気付きにくいですね(^_^;

履歴画面の検討02

ちなみに、ユニットは下記のように3回描画しています。描画速度はモデル数に比例しますが、1000体を一回描画すると2.5msぐらいです。

・左側ユニット描画
・右側ユニット描画
・左側履歴ユニット描画(半透明)

履歴の部隊数は今の所無制限です。ガーベージコレクション対策や、表示時に近くの履歴をまとめるなど、何らかの工夫が必要になると思いますが、その辺の課題は後日検討します。



◎時系列の表現

同一部隊の移動履歴を日付と矢印で表現します。矢印は棒と先端のモデルに分割し、棒の部分をスケール変更し、先端はそのまま置きます。

矢印モデル   履歴画面の検討03

履歴部隊は半透明で表示しているので目立たないですね。不透明とした方がいいのかな?

VGA(800×600)では左側画面が小さくて見にくいので、1280×720(16:9)としました。それでもちょっと狭いですね。

ちなみに、ビューポートを分割しない場合はこんな感じです。

履歴画面の検討04

やはり広い方が見やすいですね。今はVキーを押すと一瞬で分割/非分割の画面を切り替え可能なので、このままユーザーに選択させるのが良いかもしれません。



◎解説

部隊を追加したので、この履歴から状況を考察してみましょう。

履歴画面の検討05   履歴画面の検討06

自部隊を魏の曹仁、現在の日時を7/18朝と仮定します。

7/14夕刻に関羽と廖化が合流し、その後廖化は曹仁の左手に廻り込んできました。ここで気になるのは、関羽のその後の足取りが把握できていないことです。廖化の反対側から挟撃してくるかもしれないので要注意です。

友軍のホウ徳が合流したので、彼と共に廖化を叩くか、片方を残して関羽に備えるか、一旦後退して体制を整えるか、廖化を無視して侵攻するか。

たった4部隊でも作戦パターンがいろいろ考えられますね。さらに50部隊や100部隊の規模になり、誤報や抜け駆けが混じると、凄いことになりそうですw



◎次回予告

今回の記事で、私がどんなゲームを作ろうとしてるのか、少しでも御理解頂けたら嬉しいのですが、いかがでしょうか?

ただ、この矢印モデルは先端が意外とわかりにくいですね。ビルボードを2枚組み合わせると、上空/地上どちらから見てもわかりやすくなるかもしれません。

というわけで、次回は細かい手直しや調整を行います。全体の雰囲気は良さげなので、上級ルールも当初案のままいけそうかな?

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
地形モデル再作成11
開発中のメイン画面
地形モデルの頂点数を減らして描画速度を向上させた。
これでビューポートを分割しても大丈夫!?



◎前回のおさらい

前回はメタセコイアの機能を使用して頂点数を減らしました。

メタセコイアで頂点数を減らす01   メタセコイアで頂点数を減らす02

左図が元のモデル、右図が頂点数を減らしたモデルです。山がくっついて山脈になったり、テクスチャや高さ情報が滅茶苦茶になったりで、使い物になりません。

そこで、なるべく原形/テクスチャ/高さ情報を保持しつつ頂点数を減らす方法を検討します。



◎要件

まずは、目的を達成するための要件を整理しましょう。

・周囲8頂点が同一の高さの頂点を削除する
 →さらに減らしたい場合は、
  高度差が一定値以内の頂点を削除する
 →地形テクスチャの4隅の頂点は削除しない

・頂点の座標は変更しない
 (テクスチャ/高さ情報の整合性を保持するため)

上記要件を満たせば、目的を達成できるでしょう。また、頂点を沢山削除するために、下記を実施します。

・予めグレースケールマップ(高さ情報)を修正して
 平地を慣らしてから地形を生成する



◎手法検討

前述の要件を実現するための手法を検討します。

A案:メタセコイアで選択/削除/面生成する(手動)

B案:Softimageモデルに変換
   →Softimageで頂点削除スクリプトを作成実行
   →メタセコイアモデルに戻す

C案:XNAでグレースケールマップから
   (頂点を削除しつつ)地形モデルを生成する


A案は、条件に合致する頂点の選択がちょっと面倒です。荊州だけで7マップ、最終的には50以上のマップを手動でやるとかなり手間かも^^;

B案は、まずSoftimageのスクリプトを勉強する必要があります。また、データ変換ツール(メタセコイア→Softimageは入手済、逆方向は未入手)の座標精度が100%維持されるか一抹の不安があります。

C案は、頂点数を減らしてから地形モデルを生成するプログラムは複雑で大変そうです。


‘周囲8頂点が同一の高さの頂点を削除する’というロジックは単純なので、なるべく自動化したかったのですが、B案C案はそれなりに大変そうなので、今回はとりあえずA案でやりましょう。



◎グレースケールマップ修正

まずは、グレースケールマップを修正して平地を慣らします。山岳地帯はそのままです。

地形モデル再作成01

修正したグレースケールマップを元に、地形を再作成しました。



◎平野部の頂点を削除する

次はいよいよ頂点数を減らします。作業をやりやすくするため、Y軸を10倍に拡大します。

地形モデル再作成02

この状態から、境界付近の頂点や、地形テクスチャの4隅の頂点を選択から除外し、残りの頂点を削除します。

ちなみに、メタセコイアの「選択部の記憶」は、ファイルを保存して再び開くと無効です。材質を割り当てておいて「現在の材質の頂点・面を選択」で選択状態を戻すことを考えたのですが、地形テクスチャの4隅の頂点だけ残すことができません。

地形モデル再作成03   地形モデル再作成04

結局、4隅の周囲面も残しておいて、後で削除して作り直すことにしました(上左図)。

選択操作や頂点残しが思い通りにならなくて何度もやり直したのですが、平地面を作成してテクスチャマッピングを始めた段階で気付きました。この作業(下左図)を先にやっていれば、地形テクスチャの4隅の頂点を残す必要なかったですね(ーー;

地形モデル再作成05   地形モデル再作成06

モデルが完成しました。(上右図)



◎実装

作ったモデルをXNAで差し替えました。

地形モデル再作成07

うわー何だこりゃ?テクスチャがおかしいのか?でもMeshViewでは正常に表示されたのに…?

結局これはテクスチャマッピングの問題でした。XNAでWrapしない設定で描画しているので、各画像に対応した位置にマッピングし直す必要があったのですね。

地形モデル再作成08

これでテクスチャはOKです。ちなみに地形描画は5.5ms→0.7msと8倍になりました。メチャ軽いッス!^^


これでOKかな?と思ったものの、よく見ると山岳地帯でユニットの高さがズレることがあります。以前はほぼカンペキだったのに、何故?



◎大嘘でした

調査の結果、地形モデル生成時に64×64で作り直したので、253×253の高さマップと不整合が生じたことが原因と判明しました。…あれ?何かヘン??

前回「頂点数を4224→528としたら、5.5ms→0.5msになった」と書きましたが、実は確認ミスによる大嘘で、頂点数は

64009 → 528

でした。グハッ!どうりで10倍も早くなったわけだ(ーー;



◎再検討

頂点数と描画速度をあらためて掲示します。

頂点数:64009、5.5ms(253×253フル方式)
頂点数:2186、0.7ms(65×65平野部削除方式)
頂点数:528、0.5ms(適当に頂点削減方式)

で、今後どうするか改めて検討します。

A案:253×253平野部削除方式(予想2.5ms)

B案:65×65フル方式(予想1.0ms)

C案:65×65平野部削除方式(0.7ms)

A案だと、ビューポート分割時は4回描画するので計10ms。地形描画だけで10msは遅すぎなので不可ですね。一番速いのはC案ですが、今の所B案でも十分なので、平野部起伏付きのB案で再作成します。



◎再実装

グレースケールマップを縮小して地形モデルを再作成しました。

地形モデル再作成09

地形描画速度は予想通り1msなのでOKです。ただ、山がちょっと低いようなので、高さを2倍にしましょう。


地形モデルの高さを2倍にしたら、高さ情報と不整合が生じてしまいました。高さ情報を取得するコンテントパイプラインのプロパティを何度も調整したのですが、どうしても合いません。単純に2倍にしただけなのに、何故?

…実はメインプログラム側のGetHeight()で、高さ情報を返却する前に修正する必要があったのでした。(原因特定に半日かかりました(^^;)

地形モデル再作成10   地形モデル再作成11

通常表示で60fps、分割表示で30fpsになりました。さらに最適化すれば分割表示で60fpsが可能かもしれませんが、現段階ではこれで十分でしょう。



◎余談

ビューポートを左右分割した状態で、スクリーン座標を取得し、その座標を基準にスプライトバッチで絵や文字を表示する場合、グラフィックデバイスのビューポートや右側のビューポートから座標を取得するとズレます。左右いずれに描画する場合も、左側ビューポートから座標を取得すると上手くいきます。

これは恐らく、グラフィックデバイスのビューポートや右側のビューポートがX座標の差分を管理し、さらにスプライトバッチも同様にX座標の差分を管理して、X座標の差分が2度加算されてしまうからだと思います。



◎次回予告

今回は結局 253×253 → 65×65 としただけですが、いざとなったら平原部削除方式が使えることが検証できたので、頑張った甲斐はあったと思います。

地形描画の高速化によりビューポート分割表示が可能となったので、次回から履歴画面の検討に入ります。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
ビューポート分割01
試行中のメイン画面
ビューポートを分割すると、描画処理の負荷が倍増するようだ。対策は可能なのか?



◎サンプル解析

ビューポート分割のサンプルを作成する予定でしたが、公式サンプル非公式サンプルがあったので、それらを解析すれば十分ですね。

ビューポートを分割設定すれば自動的に表示されると思っていたのですが、ビューポート毎にそれぞれ描画する必要があるそうです。ということは、描画負荷が2倍近くになるってこと?今でも30fps切ってるのに、とても無理っぽいなぁ…。

しかし、ビューポート分割が出来ないと、上級ルールや履歴画面の構成が思惑通りに出来ません。とりあえず、試しに実装して様子を見ましょう。重すぎて駄目なら、画面構成案を練り直さないといけません。



◎ビューポート実装テスト

試しにビューポート分割してみました。

ビューポート分割01

やはり重くなりましたね。

FPS :25~30fps → 15~20fps
Draw:16~20ms → 35~40ms

今回はDrawのコードを単純に2回実行したので、工夫すればもう少し早くできます。例えば、‘索敵範囲内のステンシル領域を塗り潰す処理’を2回行う必要はありません。

しかし最大のネックは地形描画です。1度の描画に5.5ms要しますが、これが索敵範囲の描き分けで2回、ビューポート分割で計4回になると、地形描画だけで22ms要します。つまり、地形描画が描画負荷全体の半分以上を占めているわけです。

テスト結果:
 地形描画のパフォーマンスを上げない限り、
 ビューポート分割は重すぎて実装できません。



◎地形モデル頂点削減テスト

地形モデルは、メタセコイアの地形生成機能で自動生成したものをXNAの通常機能で描画しています。パフォーマンスを改善することは可能でしょうか?

地形モデル頂点数は現在

65 × 65 - 1 = 4224

となっていますが、試しにメタセコイアの頂点削減機能で頂点数を1/8(528)に減らしたモデルに差し替えてみました。

地形モデルの頂点削減テスト01   地形モデルの頂点削減テスト02

地形描画が0.5msを切りましたよ!
まさか十倍も早くなるとは思いませんでした(^^;

ビューポート分割表示で30fps(左図)、非分割で60fps出ました!(右図)
60fps見たのは2年ぶりぐらいかも(爆)


もちろん、このままでは地形テクスチャがずれたりユニットが地面に埋もれたりで使い物になりません。山の形が山脈になってるしw

でも地形の頂点数を減らすだけでここまで効果があるなら、できる所までチャレンジしたいですね!^^



◎次回予告

というわけで、次回は地形の頂点数を減らす方法を検討します。

ビューポート分割の採否は、頂点数をどこまで減らせるかの結果次第ですね。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
中級ルール用の索敵範囲02
開発中のメイン画面
味方部隊の視界に入った部隊のみ表示されるようになった。遭遇時の演出もおまけで追加された。



◎索敵範囲

中級ルールでは、味方部隊の視界に入った敵味方部隊を表示します。つまり

・味方部隊
・味方部隊の視界
・味方部隊の近くにいる敵部隊

を表示します。敵の視界や味方部隊から遠い敵部隊は表示しません。


ここで検討課題が2つあります。

・味方部隊の近くの敵の判別方法

・特定の部隊のみ表示する方法



◎判別方法

XNAにはモデルの当たり判定(衝突判定)を処理する機能があります。使ったことがないのでよくわからないのですが、球型の当たり判定なら多分簡単でしょうから、これを利用するとスマートにできるかもしれません。

もっと原始的な方法もあります。全てのユニットの互いの距離を総当たりでチェックする手法です。
こう書くと時間がかかりそうな印象を受けるかもしれませんが、前述の方法も内部では同じようなことをしてると思います。むしろそちらの方が負荷が高かったりして??

どちらにすべきか迷ったので、ネットを参照すると、こちらに両方の手法が書かれた記事がありました。

えーと…どちらでも大差無いようですね(^^;
とりあえず後者でやります。



◎特定部隊のみ表示する方法

普通に個別表示していた場合は、当たり判定の結果をフラグに持たせて描き分ければ問題無いでしょう。しかしユニットはシェーダインスタンスで一括描画しているので、描画を個別にオン/オフできません。対処法案として下記2案を考えました。

A案:当たり判定の結果をふまえた描画ユニットリストを
   毎フレーム再構築する

B案:定数レジスタにフラグを持たせて
   シェーダ側で描き分ける
   (フラグがオフの時は透明色を描画する)

中級ルールでは表示すべき敵部隊数が少ないので、A案の方が早そうな印象を受けるかもしれません。しかしシェーダインスタンスのDraw回数が減るわけではないので、処理が増えるA案の方が不利かもしれません。でも、シェーダにifを追加すると頂点毎に判定するわけだし…ブツブツ。

正月ボケの頭でしばらく悩んでいたのですが、ようやく良い案が浮かびました。

B案改:インスタンス情報を定数レジスタに格納する際に、
    非表示ユニットの座標を地面の下にずらす

これならシンプルで負荷も増えません。



◎実装

実装しました。

中級ルール用の索敵範囲01

プレイヤーを魏としたので、関羽、糜芳、呂蒙などの部隊は表示されなくなりました。魏のユニットが近付くと表示され、離れると非表示となるので、衝突判定や非表示のプログラムはうまく機能したようです。

しかし呉の馬忠が表示されています。しかも旗手だけ表示されてないようですが…??



◎デバッグ

呉や蜀のユニットが(近くに魏がいなくても)表示されっぱなしになるものが、まれに存在します。

既存バグかも01   既存バグかも02

デバッグのため、非表示の際に上半身が残るようにしたら、上図のようなケースが存在しました。同じ部隊の中で、表示状態と非表示状態の兵士が混在しています。

表示/非表示の制御は部隊単位で行っているので、部隊編成リストか各個体の部隊参照インデックスがおかしいのかな?…中身を全て出力して照合したのですが、問題無さそうです。

あと考えられるのは、シェーダインスタンス描画時にリストを表示モーション番号順に再構築する際にリンクが切れたとか…こちらの中身も全て出力して前リストと照合したのですが、問題無さそうです。

いや、この段階で正しいなら表示がおかしくならないはずですが…おや?

…結局既存バグじゃなくて、新規追加コードの単純ミスでした(><)



◎修正

単純ミスを修正し、おまけで敵部隊遭遇時のエフェクトも付けました。



エフェクトや演出は最終段階で丁寧に作り直すつもりですが、今はこんなもんで十分かとw

ちなみに、ジャーンジャーンの文字は横山先生の漫画から拝借させて頂きました。厳密に言うと著作権違反ですが、これだけで文句言う人はいないよね?(^^;



◎次回予告

実装作業よりも、実装前の検討/実装後のデバッグ/おまけの演出の方が時間かかってしまいました。まぁプログラムなんてそんなもんですよね?w

次回はビューポート分割表示のサンプルプログラムを作成する予定です。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
三国風雲Onweb
三国風雲Onweb
中国で開発された基本プレイ無料のブラウザシミュレーションゲーム。建物建設や武将育成、個人戦/城戦/国戦など主な要素は一通り揃っている。



あけましておめでとうございます。今年もよろしく!^_^


◎12月の目標達成度

・活動時間月128時間以上

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

 (中間目標:12/15迄に80h以上)

実績:73h(達成率:91%)

 (1日の時間目標達成率70%以上)

実績:72%(達成率:100%)


・旗手モデル作成(16h)

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

・連画取得ツール改修&連画取得(24h)

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

・履歴画面イメージ作成(24h)
・企画見直し(24h)

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

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

実績:31hでブログ更新、HPに『索敵範囲を描き分ける』を追加(達成率:100%)


・予定外作業

実績:6hで部隊ラベル実装(達成率:100%)
実績:27hで索敵範囲描き分け処理の開発/実装(達成率:100%)
実績:40hで別件企画(達成率:50%)



半年ぶりにメイン画面の開発に戻りました。索敵範囲描き分け処理の問題を解決して年を越せたので嬉しいです^^



◎作業時間分析

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

○良かった点
・活動時間月間目標達成
・1日の時間目標達成率も達成
・月間ブログ更新数昨年最多

○悪かった点
・活動予定時間未定の日が多い(13日)

久々に活動時間月間目標を達成し、目に見える形で進捗が進み、新たな問題も一通り解決できました。いつもこの調子でいけたら良いのですがw



◎活動予定時間未定について

活動予定時間が未定となった理由は様々ですが、『気付くと夕方だった』というパターンが一番多かったと思います。

生活時間帯は不規則ですし、開発時以外はネットに接続しないので、用事を先に片付けると夕方だったりします。

『毎朝必ず前日の実績をまとめて当日の予定をたてる』のが理想的とは思いますが、規則正しい生活にこだわりすぎて義務感が先行すると、ストレス増大や開発意欲低下の要因になりかねません。

というわけで、活動予定時間は‘毎朝必ず’ではなく‘なるべく毎朝’という努力目標程度に考えています。未定日が2ケタだと多すぎるので、なるべく1ケタになるよう心掛けます。



◎別件企画について

3年前に企画概要だけ作って保留としたカードゲームですが、昨年12月から具体的な設計に入りました。途中でゲームデザインを大幅に変更するアイデアが浮上し、ルールやカードレイアウトの大幅改定中です。

最終的にはPCやXBox360でゲーム化するつもりですが、まずはリアルカードゲームとして試作第一版を作成し、友人達とテストプレイすることを目標としています。

まだ発表できる段階ではありませんが、制作はわりと良いペースで進んでいるので、ゆるゆるとお待ち下さいw



◎進捗状況チェック

スケジュールは凍結中です。企画見直しが完了したら、スケジュールの見直しを行います。



◎1月の目標

・活動時間月152時間以上
 (中間目標:1/15迄に72h以上)
 (1日の時間目標達成率70%以上)

・中級ルール用索敵範囲作成(8h)

・ビューポート分割表示サンプル作成(16h)

・ビューポート分割表示実装(8h)

・履歴画面イメージ作成(24h)

・企画見直し(24h)

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

・別件企画(32h)



◎次回予告

次回は中級ルール用の索敵範囲を作成します。味方の索敵範囲に入った敵だけ表示します。

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

| BLOG TOP |

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