プロフィール

Na-7

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


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
武将情報画面
開発中の武将情報画面
武将一覧から武将を選択すると、武将の詳細情報が表示されるようになった。



◎志向属性

武将データの志向属性が企画当初の古いものだったので、作り直しました。

旧:覇/忠義/仁徳/欲/保身/漢の6種類

新:使命感/道義/礼法/情愛/名誉/保身/野心/利得の8種類

使命感 上司から与えられた任務の遂行を優先する。
道義  義理や宗教など、人道を優先する。
礼法  礼儀や法律など、社会的秩序を優先する。
情愛  人(兵、民)に対する愛情、情け、慈悲を優先する。
名誉  自身の名声を優先する。
保身  自身の安全を優先する。
野心  自身の願望を優先する。
利得  自身の利益を優先する。

※武将間の相性や国家に対する忠誠だけでなく、指示命令に対する反応(遂行/無視/出奔/反逆など)にも影響する重要な属性です。

「この武将の志向性は…」などと考えていたら、いつの間にか「えっ?もうこんな時間!?」という状態にw



◎文字の大きさ

ひにけにXNAの日本語フォント用コンテントプロセッサを利用させて頂いているのですが、半角文字列の大きさを取得すると不正確な値が返却されます。

バグかな?…いや、多分使い方を間違えたのでしょう(爆)

数値文字列の右揃えのために使いたいだけなので、半角文字用のスプライトフォントを別途定義し、大きさの取得だけそちらを参照して回避しました。



◎実装

一覧画面で武将を選択すると武将情報画面を表示するようにしました。テキスト枠とラベルのCGも追加しました。

武将一覧04    武将情報画面

ちょっと味気ないですが、スキルや所属情報など未定のため、今回はここまで。(項目数は2~3倍に増える見込み)

ちなみに、諸葛亮先生は本編に登場しません。多分(笑)



◎次回予告

先に一覧画面作ったので今回のプログラムは楽でした。

次回は部隊一覧を作成します。

スポンサーサイト

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
武将一覧03
開発中のメイン画面
武将一覧にスクロール機能やソート機能が追加された。
マウスホイールのスクロールにも対応。



◎ボタンの種類

普段あまり意識しませんが、ボタンの動作パターンは複数あります。

・押した瞬間に処理を開始するもの
 →リピート入力に配慮が必要
 →上部切り替えボタン及びスクロール上下ボタンが該当

・引いた(離した)瞬間に処理を開始するもの
 →WindowsOSではこれが標準
 →列ボタンが該当

・ドラッグするもの(非ボタン?)
 →スクロールバーが該当

今回は上記3種類を実装する必要があります。



◎入力リピート

キーボードのキーを押したり、スクロールの上下ボタンを押した場合など、入力のリピート処理は3段階あります。

例:
・第一入力は即時
・第二入力は0.2秒後
・第三入力以降は0.1秒間隔

上記の仕様を理解すれば、実装は簡単です。ただ、日常的な機能をソースレベルで実装すると、デバッグやメンテの際に若干ウザい気もします。



◎実装

スクロールバーのCGを追加して、コードを実装しました。

武将一覧03

動作テストはサクサク動いて気持ちいいですw

・上部ボタンで表示パラメータ切り替え

・列ボタンを押すと降順ソート、
 続けて同じボタンを押すと昇順ソート
 (以後繰り返し)

・スクロール上下ボタンは入力リピート処理済

・マウスホイールのスクロールにも対応


そういえば、武将選択機能がありませんね。
後日追加します。



◎次回予告

開発が順調だと、あまり書くことが無いなぁ(笑)


武将一覧は一段落したので、次回は武将の詳細画面を作成します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
武将一覧01
開発中のメイン画面
武将一覧画面を作成中。上部のボタンを押すと表示パラメータの切り替えが可能。



◎自分に対する愚痴

今回は一覧画面を作成します。

ですが、その前にちょっと愚痴らせてください。
今回はモチベーション下がりまくりだったもので…。

SEの場合は、いかに製造(プログラミング)を避けてコストを下げるかが最大の課題です。そんな世界で長年凌ぎを削ってきたので、標準的な機能を1から自作することに抵抗がありました。

また、枠やボタンの画像を準備するのは苦手で嫌いな作業です。ネットで素材を探しても、イメージ通りのものは見付からないことが多く、自作すると、ボタン1つに何時間もかかった挙句、満足できなかったりします。

これがプログラムであれば、時間かかったり失敗しても「この教訓が次に繋がる」と自らを励ますことができます。しかしCGデザインに関しては向上心が低いので、楽しみながら作る気になれず、徒労感だけが残ります。

「肝心なのはゲーム性で、ボタンや背景の色など2の次だ」という意識が強いので、優先順位の低いことに時間や労力を割くのが嫌なのかもしれません(苦笑)


いきなり愚痴ってすみませんでした。
気を取り直して始めましょう。



◎CGデザイン

中華風の枠やボタンを求めて、ネットでフリー素材を探したのですが、なかなかイメージ通りのものが見付かりません。結局中華風は諦めて、クール系のものを自作することにしました。

今回初めてGimpのフィルタ機能を使用。RGBチャンネルにグラデーション、アルファチャンネルにフィルタを使用して、半透明の背景を作成しました。

背景画像

透明度が高い方がカッコ良いのですが、逆に文字が読みにくくなります。それでは本末転倒なので、文字が読みやすいギリギリの透明度に調整しました。



◎実装

現在このような状態です。

武将一覧01   武将一覧02

自分では珍しくまともなデザインになったと思っているのですが、いかがでしょうか?

今の所、上部ボタンによる表示切り替えのみ可能です。ボタンやパラメータは柔軟に追加変更できます。



◎次回予告

今回は気力との戦いでしたが、フィルタのコツを掴み始めた頃から徐々に回復してきました。

次回はスクロールバーや押下ボタンを実装します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
WinFormsGraphicsDevice公式サンプル
WinFormsGraphicsDeviceサンプル
Windowsフォームアプリケーション内にXNAのアニメを描画する公式サンプル。フォーム内のポリゴンが回転する。



◎Windowsフォームの呼び出し

今回は汎用的なメッセージ表示処理を作成します。Windowsのフォーム部品を使えるなら手っ取り早いのですが、XNAでそのまま使えるのでしょうか?

試しに「プロジェクト>クラスの追加」でWindowsフォームを追加し、LoadContent()に下記を追加しました。

form1 = new Form1();
form1.Visible = true;


Windowsフォームの呼び出し01

とりあえずフォームが表示されました。このまま使って問題無いのかな?

試しにラベルやボタン等を配置すると、問題無く動作します。しかしSaveFileDialogを表示しようとしたらエラーになりました。やっぱり何か問題があるのでしょうか?



◎公式サンプル

ネットで調べると、WinFormsアプリケーション内でXNAを動かす公式サンプルがありました。

WinFormsGraphicsDevice公式サンプル

付属ドキュメントでは、XNAのGameクラスを置き換える(ユーザーフォームにGameクラスの機能を追加する)方法について解説しています。へぇ~XNAってWindowsではこんな風に実装されてるのか…。日本語版もありますので、技術的に興味がある方は一読してみてください。


ですが、これはWinFormsアプリケーション内でXNAを動かすサンプルです。逆に、XNAからWinFormsを呼び出すイメージで動かしたいのですが、その際気になることが付属ドキュメントの「GraphicsDevice の管理」に記述されてました。

どうやら、GraphicsDeviceインスタンスを単一共有化するための手法や注意事項が長々と記述されているようですが、逆に言えば、こうしないとGraphicsDeviceインスタンスが複数同時使用されて‘描画効率が落ちる’ということではないでしょうか?



◎動作テスト

メイン画面に適当なフォームを追加して、動作やパフォーマンスを確認しましょう。

Windowsフォームの呼び出し02

FPS:60 → 60 (fps)
Draw:9 → 11 (ms)

動作はあまり問題無さそうですね。フォームはモーダルでもバックの兵士は動くし、キーボード操作でスクロールさせることもできました。2msはちょっと遅い気がしますが、GraphicsDeviceインスタンスを単一にすれば早くなるかもしれません。

1つ気になるのは、フォームの背景にメイン画面を半透明で表示することができないかもしれない、という点です。

メイン画面のレンダーターゲットから毎フレームテクスチャを取得することは可能です(これは早い)が、テクスチャからビットマップ等への変換に時間がかかりそうです。半透明でないとまずいウィンドウって、あったかなぁ?



◎懸念事項

三国志軍記はシミュレーションゲームなので、リストやグリッド(或いはツリービューやリストビューなど)を多用します。メッセージダイアログだけならともかく、これらの複雑なウィンドウを全て自作すると面倒なので、可能であればWindowsフォームを利用したいところです。

ですが、そのために制限事項が増えたり、パフォーマンスが低下したり、余計な作業や懸念が増えるようであれば、初めから自作した方が良いのかもしれません。

どうしたもんかなぁ(悩)


ちなみに、いずれXbox360に移植することも考えてますが、その際には操作性(キーボード&マウス→パッド)や描画処理など大幅に作り直すことになると思うので、その時に考えます(^^;



◎次回予告

Xbox360の人って、皆さんどうしてるんですかね?
凝ったウィンドウはあまり見かけない(それ以前に日本語表示が少ない)気がするので、自前で用意してるのかな?

まだ結論が出ないので、次回はリストやグリッドについて調べます。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
視野角チェック
開発中のメイン画面
カメラから遠い部隊のネームプレートは表示されなくなった。FPSは安定レベルに達したらしい。



◎チェックロジック変更

今回は、ネームプレートの描画速度向上を図ります。

高さチェック専用の‘最も高い標高値のみ返却する方式’を別途作成し、Listを使わないようにします。

最も高い標高値のみ返却する方式を別途作成

8ms → 4~8ms

描画時間がバラつくようになりました。平均すると6msなので、少し速度UPしたようです。

これは多分、「視線List構築完了後に高度比較チェックする」というロジックを「高度をセル単位で毎回比較し、遮蔽物が存在する場合はチェックを中断する」に変更したので、遮蔽物が多いとチェック時間が短くなる、ということでしょう。

少し早くなりましたが、期待したほどではなかったなぁ…。



◎距離チェック

カメラから遠い部隊のネームプレートは、文字が小さく潰れてほとんど読めません。実戦においても、遠くの部隊は敵味方の識別すら困難でしょうから、ネームプレートを表示しないようにしましょう。

距離チェック

4~8ms → 1~4ms

近隣部隊数によってバラつきますが、通常は2~3ms程度です。高度チェックが重いので、高度チェック不要のものは事前に除外しておくと効果が高いようですね。



◎視野角チェック

それならば、視野角外側の部隊も高度チェックから除外しましょう。

XNA用プログラム

視野角チェック

1~4ms → 0.5~2ms

やりました!目標達成です^^

これだけ軽いと、戦場をスクロールして眺めるだけでちょっと気持ちいいですw



◎次回予告

たかがネームプレート(?)に長らく苦戦を強いられましたが、ようやく完成しました。

次回は汎用的なメッセージ表示処理を作成します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
ネームプレート表示制御02
開発中のメイン画面
チラつき現象がなくなり、描画速度も向上して以前のレベルに近付きつつあるようだ。



◎バグ調査

ネームプレートが表示されたりされなかったりでチラチラする現象を調査します。

まず、表示時と非表示時の座標をそれぞれ確認し、あらためてセルの座標リストを取得すると…あれ?件数が違う??

視覚的に並べると、こんな感じでした。

傾きが1以上の場合細切れになる

どうやら、傾きの大きさが1以上の場合細切れになるケースがあったようです。

ちゃんと作り直さないといけませんね。



◎苦戦の要因

直線の座標は、一次方程式‘y = dx + a’で簡単に求めることができます。にもかかわらず苦戦する理由は、この式をそのまま利用しただけでは理想的な座標が取得できないからです。

y=dx+aで算出したセルのイメージ(PDF)

(1,?,4)、ではなく(0,?,4)が算出される原因を理解しないまま適当に作成して失敗しました(>_<)

これは要するにint型の整数除算の影響で、セルの左下同士を結ぶ直線(図の赤矢印)を算出している状態です。



◎改修

理想的な座標を取得する方法として、セルの中央を結ぶ直線をイメージしました。

セルの中央を結ぶ直線のイメージ(PDF)

上図をイメージして作成したのが下記プログラムです。

XNA用プログラム

ただ、イメージ図とプログラムが微妙に異なる気がするのですが、テストした限りでは、プログラムが正しいような??



◎実装

ネームプレート表示制御02

チラチラ現象は解消されて、動作が安定しました。ネームプレート描画速度は40ms → 8msになりました。



◎次回予告

これで本当に正しいのか不安なところもありますが、チラつきは解消されたので、次回はパフォーマンス向上を図ります。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
ネームプレート表示制御01
開発中のメイン画面
とりあえず、山向こうの部隊のネームプレートが表示される問題は解消したようだ。



◎ネームプレート画像集約方式

ネームプレート表示制御は、前々回‘中間テクスチャ方式’で煮詰まってしまいました。しっかり勉強すれば最後まで実装できるはずですが、しかし速度は遅い(9ms以上)ので、実用的ではありません。


実はその後、別の方式を考えてました。

現状は、ネームプレート5枚(左枠/中枠/顔画像/名前/右枠)をspriteBatch.DrawとDrawFontで描画しているのですが、全ネームプレートを1枚の画像に集約し、板ポリに張り付けて、シャドウマップを参照しながらカスタムエフェクトで直接描画する、という方式です。

この方式であれば、公式サンプルと同等の速度が期待できます。少なくとも、中間テクスチャ方式よりは格段に速いでしょう。但し、シェーダーインスタンスで描画しないと、現状のスプライトバッチより遅くなる可能性があります。



◎マス目管理方式

そんなことを考えていた矢先、yohさんから前々回のコメントで‘ZX平面のマス目で管理する方式’をご提案頂きました。

今後‘企画見直し’の段階で、部隊移動(配置)をマス目管理方式とすべきか検討するつもりでしたが、ネームプレート表示制御に利用するとは考えが至りませんでした。
(目前の技術課題に執着するあまり、視界が狭まってました)

貴重なアドバイスを頂きまして、どうもありがとうございました!>yohさん



◎基準データ作成

現在、地形モデルの高さ情報は65×65、地形種別は256×256のマス目で管理しています。

部隊移動等もマス目で管理すると仮定し、先日のマップ拡大に合わせて、今後はマス目を1024×1024で統一管理しましょう。

…というわけで、高さと地形種別のデータを1024×1024の配列に格納しました。今後はこのデータを基準に計算します。



◎直線上に存在するセルの抽出

カメラからターゲットまでの間に障害物(高い山など)が存在するかチェックしたいのですが、どのセルをチェックすれば良いのでしょうか?図にまとめるとこんな感じです。

直線上に存在するセル(PDF)

人間は図を見ると直感的に判断できますが、それをプログラムにするのは意外と難しいような…?

XNA用プログラム1

コーディングだけで丸二日かかりました(爆)



◎視線高度の算出

チェック対象セルを抽出したので、チェック対象セルの位置の地形高度は取得可能になりました。

次に、同位置の視線高度(カメラとターゲットを結ぶ直線の高度)を算出します。

視線高度の算出(PDF)

最後に、地形高度と視線高度を比較して、視線を遮る山が無いかチェックします。

XNA用プログラム2



◎実装

ネームプレート表示制御01

静止画だとわかりませんが、山向こうの部隊のネームプレートが表示されなくなりました。

動作は概ねOKっぽいのですが、問題が2つあります。

・一部のネームプレートが一瞬描画されずチラつくことがある

・パフォーマンスが悪い(1ms → 40ms)

最適化前のベタコーディングとはいえ、ネームプレート表示だけで40msはビックリです。これだけ遅いと何か根本的に間違えてないか不安になりますね(ーー;



◎最適化案

今回のプログラムは‘座標リスト返却方式’です。これは(移動処理などでも使えるよう)汎用性を重視した設計ですが、List.Addを毎フレーム数万回実行すると思われるので、これがネックと予想しました。

そこで、高さチェック専用の‘最も高い標高値のみ返却する方式’を別途作成し、Listを使わないようにすれば、パフォーマンスが向上すると思います。

それでもまだパフォーマンス不足であれば、マス目の解像度を下げて256×256とします。

目標値はズバリ20倍!(40ms → 2ms)



◎次回予告

次回はチラつきバグの調査修正と最適化の予定です。

最適化よりバグ調査の方が大変かも(^^;

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
三国志牧場
三国志牧場
基本プレイ無料のブラウザゲーム。土地を耕し、武将カードを植えると土から武将が生えてくる。収獲した武将を戦闘に出して天下統一を目指したり、友達の手伝いに行かせることができる。



◎1月の目標達成度

・活動時間月152時間以上

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

 (中間目標:1/15迄に72h以上)

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

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

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


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

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


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

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


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

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


・企画見直し(24h)

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


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

実績:55hでブログ更新、HPに『地形モデルから高さを取得する』等を追加(達成率:100%)


・別件企画(32h)

実績:5h(達成率:15%)


・予定外作業

実績:13hで地形描画速度向上(達成率:100%)
実績:17hでネームプレート改善(達成率:100%)
実績:31hでマップ拡大、高さズレ修正(達成率:100%)
実績:14hでシャドウマッピング調査(達成率:50%)



1月は、時間も成果も上々でした!



◎作業時間分析

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

○良かった点
・活動時間月間目標達成
・1日の時間目標達成率も達成
・活動予定実績報告が習慣化した
・ブログ更新多数
・新規ブログ設立

○悪かった点
・企画見直し未着手
・別件企画停滞


特に前半が絶好調で、難しそうな課題を短期間で次々とクリアしたのは我ながら上出来でした^^

後半は頭の冴えに陰りが出てきたようで、課題クリアまで多少時間がかかるようになりましたが、これは仕方が無いというか、普通ですね。

それでもやる気/集中力/活動時間は維持したので、後半も満足できるレベルだったと思います。

1年中この調子だといいなぁw



◎進捗状況チェック

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



◎2月の目標

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

・ネームプレート表示制御(24h)

・メッセージ表示制御(8h)

・履歴フロー検証(32h)

・企画見直し(24h)

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

・別件企画(24h)

履歴フロー検証は企画見直しの一環です。
(ボリュームが大きいので項目を分けました)



◎次回予告

次回はマス目方式によるネームプレート表示制御を検討します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
近クリップ平面=50
地形モデルのシャドウマップ
シャドウマップを1色8ビットのテクスチャで取得する場合、精度が低いので注意する必要があるようだ。



◎シャドウマップ書き換えテスト

前回のテストで、シャドウマップ(深度テクスチャ)から深度値を取得するのは速度的に無理っぽいことがわかりました。

その後あれこれ考えたのですが、シャドウマップのユニット座標のカラー(深度値)を、ネームプレートの範囲にコピーするのはどうでしょうか?

というわけで、(spriteBatch.Drawを使用して)シャドウマップの書き換えテストをやってみます。

シャドウマップ書き換えテスト

書き換えが反映されて、シャドウマップの一部と、メイン画像の影の形が変わりました。動作的にはOKですが、60→30FPSはちと遅いですね。

細かい計測はしてませんが、追加したコードから察するに、レンダーターゲットとして取得したテクスチャを書き換え前に再描画する(2048×1024)処理がかなり重そうです。

…待てよ?
わざわざシャドウマップを再描画/修正/反映しなくても、深度バッファに直接描画すれば良いのでは?



◎レンダーターゲットの解像度

しかしメインプログラムでやろうとすると、RenderTarget2Dを作成しただけで60→8fpsまで低下しました。
…えっ?まだレンダーターゲット切り替えてないのに、作成しただけで遅くなるものなんですか?

試しにRenderTarget2Dの解像度を変更すると、1024×720以下で60fps、1280×720以上で8fpsになるようです。何かGDCメモリ不足っぽいなぁ…仕方が無いので、当面1024×720とします。(4対3に逆戻り(^^;)

で、一通り実装したつもりですが、動かしてみると…狙い通りになりません。どうやら、シャドウマップの取得に失敗したようです。原理を理解しないままサンプルコードを強引に流用したので、どこかおかしいのでしょう。



◎サンプル解析

というわけで、サンプルを(今度は丁寧に)解析します。まずは、シャドウマップの取得部分を理解しましょう。

…ははぁなるほど。頂点シェーダの

VS_SHADOW_OUTPUT Out;
Out.Position = GetPositionFromLight(vPos);
Out.Depth.x = 1-(Out.Position.z/Out.Position.w);


これで深度を算出して、頂点シェーダでカラー(赤系)に変換してるんですね。

描画時は…なるほど、シャドウマップを参照しながら描画してますね。深度バッファへの直接書き込みはしてません。
…と言うか不可能っぽいですね。まずいなぁ。

サンプルと同じ方式でやろうとしたら、シャドウマップを参照しながらネームプレートを描画するカスタムエフェクトを実装する必要がありますが、ネームプレートには漢字が含まれるので、

・スプライトフォントを描画するカスタムエフェクトを作成する

・スプライトバッチのエフェクトをカスタムエフェクトに切り替える

上記のいずれかを実現する必要があります。不可能とは思いませんが、ハードルがさらに上がっちゃったなぁ…(--;



◎他の方法を検討する

もっと簡単な方法は無いかと改めて考えたのですが、『深度テクスチャからターゲットピクセルのみ集約した中間テクスチャを作成し、そこから色情報(深度値)を取得する』という方法はどうでしょうか?

中間テクスチャの解像度を512×2ぐらいにすれば、そこそこ早く取得できるかも…??



◎シャドウマップの精度

新方式で実用的な速度が出るか試したいのですが、それ以前の問題として、シャドウマップがうまく取得できません。
何が悪いのか?う~ん…。

ここで散々悩まされたのですが、原因はシャドウマップ取得時に渡す斜影変換行列の近/遠クリップ平面にありました。

近クリップ平面=1   近クリップ平面=50

左図:近クリップ平面 = 1.0f、遠クリップ平面=1000.0f
右図:近クリップ平面 = 50.0f、遠クリップ平面=1000.0f

ちなみに、上記画像はシャドウマップ取得前に「白」でクリアしたものです(わかりやすくするため)。通常はシャドウマップ取得前に「黒」でクリアするので、左図は画像全体が真っ黒となり、何も描画されなかったように見えます(混乱しやすい)。

それと、近クリップ平面=1.0f、遠クリップ平面=900.0fとした場合、左図と同様になりました。近/遠クリップ平面間の距離を狭めたのに、右図より悪い結果になった理由は、‘テクスチャ精度が低い(256段階)から’と思われます。興味がある方は、こちらの『③ 深度の精度はNear-Far比で驚くほど落ちる』を参照してください。



◎パフォーマンスチェック

ようやくシャドウマップが取得できました。精度不足の懸念がありますが、とりあえず新案の速度を確認しましょう。

シャドウマップからターゲット座標を集約した中間テクスチャ

(ただの細い線に見えますが)上図は、地形のシャドウマップからターゲット座標のみを集約した中間テクスチャです。画像を拡大してよく見ると、左端から1ピクセル単位で色が変わっているのが確認できます。これは各部隊が描画される位置の地形の深度を表します。

Texture2D.GetData()が激遅なので、シャドウマップから必要な座標の色のみ集約して小さな中間テクスチャを作成し、そちらから色を取得することにより高速化を図ります。

○測定結果
地形モデルのシャドウマップ取得:0.7ms
ピクセル集約&中間テクスチャ作成:2.5ms
中間テクスチャから深度情報取得:6.0ms

むむぅ…深度確認だけで9msは遅すぎですね。

あまり実用的ではなさそうですが、とにかく一度最後まで実装してみましょう。



◎シェーダーインスタンスのW値

その後一通り実装したのですが、深度判定がうまくいきません。どうやら、部隊の深度が正しく取得できていないようです。

ShadowMap_FlagMan01

上図は部隊のシャドウマップです。該当位置に深度値が出力されますが、その値が0~5までしか存在しません(本来は0~255)。今回は近/遠クリップ平面の値を変えてもダメでした。

原因は、HLSL内で深度(Z/W)を計算する際の、W値にありそうです。W値は

float4 val = mul(position, WorldViewProjection);

val.wに格納されるらしいのですが、シェーダーインスタンスの都合により‘ワールド座標変換行列を直接渡すことができない状態’なので、w値を算出する方法がわかりません。

・HLSL内でSRTからワールド座標変換行列を生成する
・他の方法でw値を算出する

上記のどちらかが判明すれば、シェーダーインスタンスでシャドウマップを取得できるようになるのですが、ネットで調べてもわかりませんでした。う~ん…。



◎ベクトルと行列の乗算

仕方がないので、別の方法を考えましょう。XNA側でW値を算出してHLSLに渡すのはどうでしょうか?

…今度は、ベクトルと行列の乗算がわからずに悩みました。HLSLの乗算は数学的な乗算と異なるようなので、こちらのヘルプを読んで試作したのですが…

Vector4とMatrixの乗算(試作)
ShadowMap_FlagMan02

ダメですね。ヘルプの解読を誤った可能性が高そうです。

…というか、もっとわかりやすく書いて欲しいッス(;_;)



◎次回予告

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

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

| BLOG TOP |

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