2013/02/03

XNA 開発終了だそうで

XNA の開発が 2014/4/1 で終了との記事を見ました。
XNA Today: XNAの開発が2014年4月1日で終了
http://www.xna-today.jpn.org/archives/5359
ここ数ヶ月、XNA の利用に疑問を抱いていたので、終了報告は良いタイミングかもしれないなどと考えている所があります。

自分が XNA を利用し始めた理由は、概ね以下のような感じです。
  • 偶然 XNA の記事を目にした。
  • Java 以外の言語で存分に実装してみたかった。
  • XNA は機能が充実していない (より深く学ぶためのキッカケに適している)。

しかし、最後の「機能が充実していない」という点が、「ゲームを作りたい!」という人には大きなデメリットであっただろうと思います。僕は、これをキッカケに色々とネットで調べ、解釈し、実装するという学習の過程を楽しめていますが、ゲームの完成を目的とする人には、この過程の大半がストレスであると想像します。

まぁ、日本では、PC ゲームも Xbox 360 ゲームも盛んではなく、その時点で厳しかったでしょう。現状、Windows Phone は論外ですし。

当面、XNA で今の実装を続けるのですが、並行して次のプラットフォームを考えています。久しぶりに C++ にしてみる、あるいは、細かい事に頭を使わずに実装できる Java にしてみる、などなど。

2013/01/28

ブロック地形進捗 #2

最大頂点数をとるチャンクを空間全体に敷き詰める前提を立てていましたが、「それは流石にハードルが高すぎる」と考えるに至り、頂点数がそこまで膨大とならないようにノイズを調整し、その他実装を修正していました。

16^3 チャンクで可視範囲を 20 チャンク (20 * 16 = 320 ブロック) としたキャプチャが下図です。

他のオブジェクトの配置を考えると、16 チャンク程度で済ませる気がしないでもありません。

なお、地形の背面に存在する洞窟の状態をキャプチャしたものは下図となります。

視点から見えるチャンクの状態に依存しますが、概ね、描画の負荷が多大な状態です。原因の一つは、描画対象とするチャンクの探索にかかる負荷です。チャンクを含め、シーンに描画するオブジェクトは八分木を用いて管理していますが、満足できる結果ではないと感じています。

これから、地形だけではなく、木を表現するブロックをチャンクへ配置しようと思います。木の配置まで終えたら、節目として動画を上げてみようと思います・・・たぶん。まぁそろそろ、積んだまま放置している Borderlands 2 をやりたいな、と。

2013/01/17

ブロック地形実装進捗

「心が折れそうだ」

煮詰まってきたため、ブログを書いて気持ちを誤魔化すことにしました。納得できるパフォーマンスを出せていないので、まだ動画公開はしませんが、下図が現時点のスクリーン ショットです。

 

僕の GitHub ページでコードは公開されていますが、動画公開まではタグを貼りません。そもそも、自分の環境でもメモリ不足によりアプリケーションが落ちる状態です。

今は、チャンク サイズ 16x16x16 で作成しています。チャンクは、上下左右に int とディスク スペースが許す限り無限に配置できる設計です。
チャンク
立方体ブロックを一塊としてメッシュとする単位。Minecraft では 16x256x16 や 16x128x16 なども用いる模様。
追記
今はチャンク サイズ 32x32x32 としています(チャンクのメッシュは 16x16x16 へ分割した状態)。チャンクの粒度を細かくするとチャンク総数が増えることから、チャンク探索処理に大きな負荷がかかるため、大きなサイズとしました。メッシュはインデックス バッファの制約から 16x16x16 (ushort で収まる範囲) が妥当かと思います。Minecraft 形式の場合ならば、高さ固定から二次元でのチャンク探索となり、比較すると遥かに高速かと思います。
地形は、ノイズを用いて自動生成しています。過去の一般的な地形生成ではノイズをハイトマップ生成に利用しましたが、今回はハイトマップを更に密度へ変換して利用しています。
密度を用いる利点は、密度生成を工夫することで、内部に洞窟を自動生成させたり、ハングしている崖などの、ハイトマップのみでは表現できない地形データを表現できる事。Minecraft でも密度を利用しているとの話。スクリーン ショット上で見える地形の内部には洞窟が存在。
で、満足できていない点ですが、チャンクをあまり多くロードするとメモリ不足に陥る所です (頂点バッファを確保できなくなる)。特に、洞窟を含むチャンクでは頂点数が一気に跳ね上がり、それに応じてロードできるチャンク数が減ります。

今は、可視範囲で 10 チャンク距離 (10 * 16 = 160 ブロック距離)、予備範囲で 12 チャンク距離 (12 * 16 = 192 ブロック距離) をロードしています。やはり、より遠方まで地形を表示したいわけで、せめて可視範囲で 12 チャンク距離程度はロードしたい所です。
Minecraft では 200 ブロック距離までも描画可能との話 (これを知ると、まだまだやれる事があると考えざるを得ません)。
理屈としては、恐らく、チャンク内で交互にブロックが配置 (立方体の角のみ隣接する配置) される構成が、チャンク頂点数を最大とする構成であろうと思います。そこで、この最大頂点数のチャンクのみをロードする前提で考えている所です。
最大頂点数のチャンクは、サイズ 16x16x16 において、頂点数 36864、インデックス数 36864。
チャンクの外部から不可視となる閉塞空間を検出し、閉塞空間に隣接する面を刈り取るなどしてみましたが、最大頂点構成では閉塞空間がなく、あえなく敗れ去った所です。とは言え、閉塞空間を含むチャンクでは大幅に頂点を削減できています。

そこで、今は、カメラとチャンクの位置関係から背面を除去しようとしている所です。チャンクのメッシュは実行中に非同期に更新しているため、カメラとチャンクの位置関係が変化した場合にメッシュ再構築を要求し、背面を刈り取るだけですが、現実装では即座にメッシュ再構築が完了するわけではないため、どうアプローチしようかと悩んでいる所です。

2012/11/28

近況

先週より、ようやく実装中心の生活に戻った所です。『とびだせ どうぶつの森』をわずかにプレイしながら。どうぶつの森は、自分でプレイ方針を決めるスタイルのゲームであるため、本当に面白いですね。

DQX については、先の近況報告の時点で利用券購入を止めていましたが、その後、『デモンズソウル』のトロコン、および、『ダークソウル』のトロコンと DLC 攻略に狂っていました。デモンズソウルでは、トロコン以外にも縛りプレイなどを続けていました。
僕は、デモンズソウルやダークソウルの動画と生放送をニコニコ動画で頻繁に視聴しているのですが、観ているとどうしても自分でやりたいという衝動にかられ、その欲望のままに再プレイを始めていました。

最近は、ほぼ毎日のように、夜はダークソウル RTA に挑戦する某氏二人 (落ち着いた口調の方と煽り口調の方) の生放送を視聴しています。正直、僕は、ダークソウルはデモンズソウルと比べると、その面白さがはるかに劣る (比較にすらならない) と感じていますが、RTA の視聴となると、タイムを縮めるための実況者の試行錯誤を垣間見ることができ、非常に面白いです。

実装の近況ですが、色々と悩んだ挙句、今は Minecraft クローンに近いものを実装しています。

僕は、Minecraft のようなゲームを作りたいわけではないですが (そもそもゲームを作りたいわけでもないですが)、ブロックで表現される世界のエディットを考えると、それは Minecraft でブロックを生成および消滅させることと同じであり、ならば Minecraft のような設計がベストであろうと考えるに至りました。

今月中にデータ定義と描画までは終わらせたかったのですが、エディタを考慮したオブジェクトの扱いや、Web 上でのデータの公開を同時に検討していると、一筋縄ではいかず、年内に終われば良いかなと考えている所です。できれば、数年前に上げた動画のように、物理エンジンへの統合とエフェクトの実装までは行いたいですが、あわてず進めていこうと思っています。

2012/08/22

DQX 廃人中から軌道修正中

DQX を、メインにエルフ♂、セカンドにドワーフ♀でプレイしています。

昨日の時点で、メインが僧侶 40、木工 30、セカンドが僧侶 24、ランプ錬金 24 です。シナリオは先輩と 2 人で進行し、人の姿を取り戻した所で長らく止まっています。

発売日から 3 日後位から木工を始め、僧侶上げよりも木工でバザー販売している方が楽しいと感じ、延々と木工をやり続けていました。僧侶レベルは、出品した物が捌けるのを待つ間、敵を適当に狩っていたら上がっていたという感じです。

それで楽しんでいたのに、まさかの 30 キャップで一気に白けました。そこで、次の楽しみを探し、木工での稼ぎの一部を資金として、セカンドでランプ錬金を地味に上げていた所です。

ですが、総じて飽きてきました。徐々にプログラミングのペースを取り戻し、DQX からフェードアウトしようと思います。

2012/08/01

Hydraulic erosion 調査

Hydraulic erosion について色々と調べていました・・・と言うか、幾つかの実装を終えました。その内の 1 つが、F.Kenton Musgrave、Craig E. Kolb、Robert S. Mace による『The Synthesis and Rendering of Eroded Fractal Terrains』で述べられているアルゴリズムによるものです。

で、そのうち調べたことを忘れ、その時に再度英語で論文を読み返すのも疲れると考え、備忘のために自分の解釈でまとめてみることにしました。なお、図解はしませんし、専門家ではないので言い回しの問題はご容赦ください。また、原文の訳を載せているわけではないので注意してください。

Musgrave らの論文の PDF は以下から得られますが・・・これは大丈夫なんでしょうか?
ebookbrowse.com: The Synthesis and Rendering of Eroded Fractal Terrains pdf
日本語で hydraulic erosion を何と言えば良いのか分かりませんが、大雑把には、
  1. 雨が降り、
  2. 雨により土が削られて土砂が生まれ、
  3. 土砂が水に混じり、
  4. 水の流れと共に土砂が移動し、
  5. 時に土砂が堆積する、
という現象のシミュレートと言えば良いでしょうか。 なお、水の流れと言っても、河川のような複雑な水の流れを考えるのではありません。


アルゴリズム

※原文は時間 $t$ から $t + 1$ への変化で説明していますが、なんだか式が見づらくなるので表記を省き、数式をプログラミング言語としての式へ変えています。

Height map 上のセルについて、$a$ (altitude: 地形の高さ)、$w$ (water: 雨による水の量)、$s$ (sediment: 水に混じっている土砂の量) を考えます。

このアルゴリズムの上では、雨による $w$ の定め方については触れません。シンプルな雨の実装としては、各ループの最初に一律で $w$ へ値を加える方法がありますし、少しランダムな状態としたければノイズ関数で値を加えるなどの方法もあります。いずれにせよ、何らかの形で $w$ を与える必要はあります。

なお、シミュレーションの最初のループでは $s = 0$ であり、処理の過程において水が土を削ることで土砂が生まれる点に注意が必要です (最初から土砂があると考えてアルゴリズムを見ると混乱します)。
また、実装では height map 上の全セルについて水の移動を処理する必要がありますが、ここではセル $v$ について、隣接するセル $u$ への移動を説明している点に注意が必要です。

セル $v$ から $u$ へ流れ出る水の量 $\Delta w$ は次式となります。
\[ \Delta w = min(w_{v}, (w_{v} + a_{v}) - (w_{u} + a_{u})) \]
まず、$\Delta w \leq 0$ は、「$v$ には水がない」あるいは「$v$ から $u$ へは水は流れ出ることができない」ことを表しているため、水の移動を考えず、土砂の堆積のみを考えます。 ここで、堆積の割合を定数 $K_{d}$ (deposition constant) で定義し、堆積する量を $K_{d} s_{v}$ として堆積を処理します。
\begin{eqnarray} a_{v} &=& a_{v} + K_{d} s_{v} \\ s_{v} &=& s_{v} - K_{d} s_{v} = (1 - K_{d}) s_{v} \end{eqnarray}
一方、$0 < \Delta w$ では水が移動できるため、土砂の移動についても考えます。まず、水の移動は単純に次式で表せます。
\begin{eqnarray} w_{v} &=& w_{v} - \Delta w \\ w_{u} &=& w_{u} + \Delta w \end{eqnarray}
次に、水と共に移動する土砂の量ですが、水が全ての土砂を運べるとは限らず、その能力には限界があります。そこで、水が運べる土砂の割合を定数 $K_{c}$ (sediment capacity constant) で定義し、$\Delta w$ について共に移動する土砂の量 $c$ (sediment capacity) を次式で定めます。
\[ c = K_{c} \Delta w \]
ここで、$c$ と $s_{v}$ の比較で処理が分岐します。 まず、$s_{v} \geq c$ では $c$ 分を移動させるだけの $s_{v}$ があるため、そのまま移動させます。そして、移動後の残りの分 $s_{v} - c$ について堆積を考えます。
\begin{eqnarray} s_{u} &=& s_{u} + c \\ a_{v} &=& a_{v} + K_{d} (s_{v} - c) \\ s_{v} &=& s_{v} - c - K_{d}(s_{v} - c) = (1 - K_{d})(s_{v} - c) \end{eqnarray}
一方、$s_{v} < c$ では、$c$ 分の移動には $s_{v}$ が不足していますが、この状態は、「更に土が水に混じる余地のある状態」と考えることができるため、土を削って土砂を生み出すこととします。

なお、シミュレーションの最初の段階では $s = 0$ であり、必ずこの処理に入ります。そして、この処理で土砂が生まれ、$s$ が増加するということになります。

ここで、土砂として水に混じることのできる量に対して、実際に土砂として削る割合を定数 $K_{s}$ (soil softness constant) で定義し、$K_{s} (c - s_{v})$ だけ地形を削り新たな土砂とし、次式で水と土砂の移動と堆積を考えます。
\begin{eqnarray} s_{u} &=& s_{u} + s_{v} + K_{s} (c - s_{v}) \\ a_{v} &=& a_{v} - K_{s} (c - s_{v}) \\ s_{v} &=& 0 \end{eqnarray}
・・・と、以上のようなアルゴリズムを考えるそうです。そして、ここまでの処理を $n$ 回繰り返してシミュレーションとします。

MathJax 導入

数式を書くために、試しに MathJax を導入しました。

$ e^{i\pi}=-1 \tag{1} $
下記サイトの手順に従って導入しました。
Ichiro Maruta Homepage: BloggerでMathJaxを使ってTeXっぽく数式を入れる方法
TeX を使う日が再び訪れるとは・・・流石に構文を思い出せません。

libgdx いじり

Google が提供している Java 版の Tango Examples は Rajawali をベースにしているため、自分が仕事で開発する Tango アプリも Rajawali ベースとしていましたが、最近は libGDX への移行を進めています。一応、要点については移行が...