XNA Game Studio 4.0 Refreshに更新しよう

XNA Game Studio 4.0 Refreshに更新しよう 去年の10月にXNA Game Studio 4.0 Refreshが公開されました。これは、Windows Phone SDK 7.1の中に含まれる形でリリースされ、内容もWindows Phone 7.1の新機能追加が主だったので私もツイッターの方でつぶやく程度で済ませてました。 ですが、Windows Phone向けの新機能以外にもVisual Basic対応やバグフィクスが含まれているので、WindowsやXbox 360で開発している人でも更新する価値は十分にあると思うのでここでも紹介します。 まず、新機能としてVisual Basicに正式に対応したこと、これはWindows Phoneはもちろん、Xbox 360やWindowsでもXNA Game StudioをVisual Basicを使って開発できるようになりました。 そして、バグフィクスの中で比較的重要だと思われるのが「固定更新時、速いPCやフレーム内の処理量が少ない時に更新時間計算の誤差が大きくなり、見かけのフレームレートが下がってしまう」という問題が修正されていることです。 また、Refreshという名前の通り、既存APIからの変更は無くバイナリ互換となっているので3.1から4.0へ更新の時とは違って既存のプロジェクトやコードはそのままコンパイル、実行することができるので現在4.0で開発中の人でも安心して更新することができます。   XNA Game Studio 4.0 Refreshへ更新する 幾つかのケースがあると思うので、それぞれのケースでXNA Game Studio 4.0 Refreshをインストールする方法を紹介します。   Windows Phone SDK 7.1をインストールしている なにもする必要はありません。前述のようにXNA Game Studio 4.0 RefreshはWindows Phone SDK 7.1に含まれています。 Windows Phone Developer…

0

動的テクスチャとその注意点

パーティクルシステムなどで動的に頂点データを変更する場合、GPUとCPUが競合しないように、DynamicVertexBuffer(動的頂点バッファ)、そしてNoOverwriteとDiscardオプションを使う方法を以前紹介しました。 では、テクスチャを動的頂点バッファのように扱うにはどうしたら良いでしょうか?そもそもDynamicTexture2Dというクラスもないし、Texture2D.SetDataにSetDataOptionsを受け取るメソッドもない……。 その答えは XNA Game Studio 4.0でのTexture.SetDataメソッドはSetDataOptions.Discardを指定した時と同じ振る舞いをする(但し注意点あり) となります。 振る舞い的にはTexture2D/Texture3D/TextureCube、それぞれDiscardオプションを指定した時と同じように、指定したテクスチャがGPUで使われていた場合、内部で自動的に同じサイズ、フォーマットのテクスチャを生成し、その新しいテクスチャへデータを書き込むようになっています。 但し、この時にSetDataに渡されるパラメーターがテクスチャの一部分を書き換える設定になっていると、以前のテクスチャからデータを新しいテクスチャへコピーするようになっています。コピーだけならそれ程時間が掛からないのですが、このコピーする際に以前のテクスチャをGPUが使い終わるまで待ってからコピーするようになっているので、結局はDiscardオプションをつけていない時と同じ状態になってしまいます。 私のところでテストしたところ、256x256のテクスチャの一部分を書き換えた時、以下のような結果になりました。 方法 SetDataに掛かった時間 同じテクスチャでSetData 6.8ミリ秒 テクスチャを切り替えてSetData 0.3ミリ秒   まとめると、 テクスチャ全体を書き換える場合は、パフォーマンス問題は発生しない テクスチャの一部分を書き換える場合、複数のテクスチャを切り替えながら書き込むようにしないと遅くなる となります。 テクスチャを切り替えながらSetDataを呼ぶ方法としては「頂点テクスチャでスキンアニメーション」の記事のサンプルコード内にあるFlipTexture2D.csが参考になるでしょう。

0

乗算済みアルファとは? その2: コンポジション

前回の投稿からものすごーく間があきましたが、乗算済みアルファの話がTwitterの方で盛り上がったので、思い出したように続きを書いてみます。 前回は今まで多く使われてきた補間アルファの問題とそれを解決するための乗算アルファの紹介をしました。今回は乗算済みアルファの真骨頂である半透明を使ったコンポジションを紹介します。 コンポジションの使い道 レースゲームでは、ゲーム内で複数の車を購入でき、さらに購入した車の各パーツを変更することができるという機能は一般的なものです。中には自分で描いた絵を車に張るなんて言うこともできるものもあります。こういったレースゲームでは、購入した車の一覧はガレージメニュー内でサムネイル表示され、車を選択すると3Dモデルが読み込まれ、自分がチューンナップした車のモデルを見ることができます。 では、このサムネイル画面はどうやって表示するのでしょうか? こういった3Dモデルをカスタマイズできるゲームでは、あらかじめサムネイル画像を用意するということはできません。なぜなら、その組み合わせは膨大な数になってしまうのと、ユーザーが描いた絵までは用意することはできないからです。そこで良く用いられるのが、3Dモデルを変更した時にセーブデータ領域などに3Dモデルをレンダリングした結果をサムネイル画像として保存し、それをメニュー画面で使用するという手法です。 単に矩形型のサムネイルを用意するだけだったら問題は無いのですが、このサムネイル画像をビルボードとして使い、メニュー画面の背景の上に重ね合わせて描画したい場合、例えば車のボディ部分のような不透明部分は不透明に、車のウィンドウ部分のような半透明部分はメニュー画面が透けて見えたりするといった重ね合わせ処理をコンポジション(Composition、日本語で「合成」)と呼びます。 コンポジションの基本 コンポジョン処理をする場合の基本として、描画するオブジェクトA,B,Cがあった場合、以下の式が成り立たないといけません。 A + B + C = (A + B) + C = A + (B + C) この式のA+B+Cという部分はオブジェクトA,B,Cの順に描画するという意味で、(A+B)+CはAとBをまとめて描画した結果を描画した後にCを描画、A+(B+C)はAを描画した後にBとCをまとめて描画した結果を描画するという意味になります。言い換えると()で囲まれたオブジェクトは別のレンダーターゲットに描画し、そのレンダーターゲットの描画結果を他のオブジェクトの描画と合成(コンポジット)できるということです。もしくは前述のレースゲームの中のサムネイル画像がカッコ内の部分に相当します。 結論から言うと、上記の式は補間アルファでは成り立たず、乗算済みアルファでは成り立ちます。つまり、補間アルファではできなかったコンポジションが乗算済みアルファではできるということです。 実際に上の式に補間アルファと乗算済みアルファのブレンディング計算式を当てはめると証明できるのですが、長くなるし、読んでもつまらないし、本題から外れるので、ここでは割愛します。 コンポジション比較 では、実際に乗算済みアルファと補間アルファでコンポジションした場合の結果を見比べてみましょう。まずは、レンダーターゲットを使わずに背景を描画した後に赤い不透明の四角形、半透明の緑色の四角の順に描画してみましょう。 乗算済みアルファ、補間アルファ、どちらも同じ結果になっていますね。 では、次に赤と緑の四角形をレンダーターゲットへ描画し、その結果をテクスチャとして使って背景を描画した後に描画してみましょう。 補間アルファを使った方は緑の半透明部分がより薄くなっており、不透明であるはずの赤い部分も半透明になってしまっています。対照的に乗算済みアルファの方は全く同じ描画結果となっています。つまり、補間アルファではコンポジッションが上手くいかなかったのが、乗算済みアルファではコンポジションができるということです。   XNA 4.0でコンポジション処理 では、実際にXNA 4.0でコンポジション処理をする時にどんなコードを書くのか見ていきましょう。 まずは、コンポジション用のレンダーターゲットの生成と、そこへ描画するコードです。通常のレンダーターゲットを使った描画と殆ど同じものですが、ここではColor.Transparentでクリアするのがポイントとなっています。このTransparent(透明色)はRGBA値が(0,0,0,0)になっています。 // コンポジション用のレンダーターゲットの生成 RenderTarget2D layer = new RenderTarget2D(GraphicsDevice, 1280, 720); // **** コンポジション用のレンダーターゲットへの描画 **** // レンダーターゲットをグラフィクスデバイスへ設定する…

0

動的頂点バッファのNoOverwriteとDiscard

今まで何度か動的頂点バッファについて触れてきましたが、実際のコードがどうなるのかは記事の中では紹介していませんでした。実は今までに紹介してきたサンプルの中でWritableVertexBuffer<T>というクラスがすでに実装されているので、このクラスを紹介します。 「GPUはいつ描画するのか?」の記事の中でSetDataOptions.NoOverwriteの説明をしました。この記事の中でNoOverwriteというのはプログラムがドライバへ伝えるヒントで、GPUが頂点バッファをアクセスしている領域にはSetDataで上書きすることはありませんよということを述べました。 では、実際にプログラムの中でこの処理をどうやったら良いでしょう?真っ先に思いつくのは以下のようなコードでしょう。 // 動的頂点バッファの生成 DynamicVertexBuffer vb = new DynamicVertexBuffer( graphicsDevice, typeof(MyVertexType), 100, BufferUsage.WriteOnly); // 書き込み先 int currentPosition = 0; int strideSize = vb.VertexDeclaration.VertexStride; // バッファの最後まで来たら、バッファの先頭へ戻る if (currentPosition + myVertices.Length > vb.VertexCount) currentPosition = 0; // 現在の書き込み先へNoOverWriteオプションを使って書き込む vb.SetData(currentPosition * strideSize, myVertices, 0, myVertices.Length, strideSize, SetDataOptions.NoOverwrite); // 書き込み先を更新する currentPosition += myVertices.Length; 考え方としては あらかじめ大きめの頂点バッファを生成する 現在の書き込み先(要素単位)を表すcurrentPosition変数を用意する データの書き込み時にはcurrentPositionから書き込み先のオフセット(バイト単位)を計算して、NoOverwriteオプションを指定して書き込む currentPositionを書き込んだ要素分だけ進める…

0

XNA 3.1から4.0への更新

英文ですが、XNA 3.0からXNA 4.0への更新についてのまとまった情報があるので紹介します。 http://www.nelxon.com/blog/xna-3-1-to-xna-4-0-cheatsheet/

0

XNA Game Studio 4.0 Language Pack(日本語)がリリースされました

日本語のXNA Game Studio 4.0Language Packがリリースされました。これでVisual Studioのメニューやプロジェクトテンプレートが日本語化されるのはもとより、日本語のヘルプドキュメントも付いているので英語を読むのが苦手という人でも安心してXNA 4.0を使えるようになりました。 注意点としてはLanguage Packとしての提供になるので一旦英語版をインストールした後にLanguage Packをインストールする必要があります。英語版のインストール方法については以前の記事が参考になると思います。また、英語版を既にインストールしている場合はLanguage Packをインストールするだけで日本語化されます。 Windows Phone Developer Toolsのダウンロード (Windows Phone開発キットに含まれている) XNA Game Studio 4.0スタンドアロン版をダウンロードする (Xbox 360/Windowsのみ開発できる) XNA Game Studio 4.0 Language Pack (日本語) のダウンロード 詳細は以下のニュースリリースを見てください。 http://create.msdn.com/ja-JP/home/news/xnags40jpnlangprel

0

XNA Game Studio 4.0がリリースされました

XNA Game Studio 4.0がリリースされました。前述のとおり、XNA Game Studio 4.0はWindows Phone Developer Toolsに含まれる形でリリースされました。 Windows Phone Developer Toolsのダウンロード リリースノート CTP版やベータ版のWindows Phone Developer Toolsをインストールしている場合はリリース版をインストールする前に以前のバージョンをアンインストールする必要があります。 Windows Phone Developer ToolsにはVisual Studio Express for Windows Phoneが含まれるのでVisual Studioがインストールされていない状態でもWindows Phone Toolsをインストールすることができます。 Visual Studio 2010 Professional以上がインストールされている場合は、お使いのVisual Studio上で開発をすることができます。 Windows Phone Developer ToolsはWindows VistaとWindows 7のみのサポートとなっています。Windows XP向けにはXNA Game Studio 4.0のスタンドアロン版をダウンロードできます。 Windows Phone Developer Toolsには以下のものが含まれます。 Visual Studio 2010 Express for…

0

XNA Game Studio 4.0の乗算済みアルファ機能

3D対応のグラフィクスカードが登場してから、グラフィクス・プログラマー、というより、デザイナーさんの長年の悩みのひとつとして、スプライトなどの画像のエッジに意図しない色がでてしまうという、色のにじみ問題があります。 この問題に直面したデザイナーさんの多くはグラフィクス・プログラマーに相談しますが、 「バイリニア・フィルタのせいだね、絵の方を変えるようにしてね」 と、言われることが多いと思います(私も昔はそう返答してました)。デザイナーさんの中にはカラー部分とアルファチャンネル部分を分けて時間を掛けて修正したり、エッジ部分を処理するツールを使ったりしていました。ですが、プログラマーに絵を渡す前にいちいちツールを通す手間があり、こういったツールはエッジ部分を見つけて処理するという画像処理をするので、処理に時間が掛かり、ゲーム実行時に使うには向いていない手法です。ですから、レンダーターゲットを使ってリアルタイムにスプライト画像を作って使うというケースでは使えません。また、画像のを表示座標を整数値にクランプしたり、中にはバイリニア・フィルタリングを切ってしまうなどの、せっかくのバイリニア・フィルタリングの効果を消してしまっている人達もいます。 ゲーム製作初心者の多くがこの問題に直面し、フォーラムなどには定期的に同じ質問があがりますが、大抵は前述のプログラマーのような返答をもらうことが多いです。 実はこの問題の原因はバイリニア・フィルタリングのみの問題ではなく、バイリニア・フィルタリングとアルファ・ブレンディングを併用したときに起こる現象なのですが、この原因と、対処方法を簡潔に説明するのは簡単ではありません。バイリニア・フィルタリングとアルファ・ブレンディングの両方の仕組みを理解する必要があります。仕事でゲームを作っているのであれば時間を掛けて理解するのも仕事のうちなので、勉強会を開いたりして(勉強中も会社がお金払ってくれるしね)、説明することもできますが、趣味でゲームを作っている人達にこういった説明をし、更に修正してもらうというのは現実的ではありません。 乗算済みアルファで解決 2008年の8月、XNAフォーラムへの投稿があったときに、私とShawnはこの問題について話をし、その結果、解決策として乗算済みアルファ(Pre-Multiplied Alpha)を使うということになりました。おそらく聞きなれない言葉だと思いますが、海外でもゲーム開発者の間ではあまり知られていない言葉で「Premultiplied Alpha Game」で検索するとヒット数は5,000件足らず、トップはShawnのサイトで、日本に至っては「Premultiplied Alpha ゲーム」で検索すると165件で、トップは前述のフォーラムの投稿になっています。これは、現在(2010年6月)の時点での状況で、2008年当時はさらにヒット数が少なかったと記憶しています。 注:Pre-Multiplied Alphaの日本語訳が見つからなかったので、ここでは「乗算済みアルファ」という日本語に訳しています この問題の特徴として 初心者をはじめ、殆どの人が同じ問題を経験している 解決策はあるが、プログラムとコンテントの両方を変えないといけない 解決策自体があまり知られていないので、ググもとい、Bingで検索して自力(特に初心者)で解決するのが難しい 今までのゲームライブラリの多くはプログラム部分に特化しているものが多く、2番目のコンテント自体の変更をコントロールできなかったのが解決策を採用できなかった、できてもコンテントまでは面倒見てくれないので実際に使われることが少なかったのではないでしょうか? 幸い、XNAにはコンテント・パイプラインが標準でついているので乗算済みアルファを実現できる! と、Shawnと私で盛り上がったのですが、時期的に3.0の出荷時期だったので実現することができませんでした。そして、3.1の時にはマイナーバージョンアップということで採用が見送られました。 そして、Windows Phoneという新しいプラットフォームへの対応をするために大規模な変更をする必要があったXNA Game Studio 4.0で、ついに実現することができました。 乗算済みアルファをXNA Game Studio 4.0で使う まずは、乗算済みアルファの効果の程を動画で見てください。判りやすくする為に拡大画面もありますが、720pの動画だと実物大でも差があるということがわかるので、HD動画をフルスクリーンにして見ることを勧めします。 では、どうやって乗算済みアルファをXNA Game Studio 4.0で使うのでしょうか?   答え: なにもしなくて良い (ただし、4.0以前からの移行には多少の変更が必要)   XNA Game Studio 4.0では乗算済みアルファが既定となっています。スプライト用の画像をコンテントとしてプロジェクトに追加し、普通にSpriteBatchで描画するだけで乗算済みアルファを使う、つまり今まで悩みのタネだった色のにじみも、手作業で修正する必要も、ツールで処理する必要もなくなったということです。 次回は、乗算済みアルファ設定とプログラム内での使い方の仕方を紹介します。 つづく…

0

XNA Game Studio 4.0の画像コーデック

歴史的背景 その昔、私達がXNA 1.0を設計していた時、テクスチャやモデルの読み込みをするのに単にD3DXのラッパーを作りよりも新しいものにしようと決めました。これは、後にコンテント・パイプラインと呼ばれるものでした。 しかし、1.0ベータをリリースした時にはコンテント・パイプラインは未完成でした。テクスチャ読み込み関数がなければ、せっかくのグラフィクスAPIを試すこともできません。このままではリリースできないので、急遽追加されたのがTexture2D.FromFileメソッドでした。 FromFileメソッドはWindows上でしか使えません。なぜなら、D3DXはXbox 360上ではサポートされていないからです。D3DXをXbox 360に移植することも考えましたが、既にコンテント・パイプラインで提供されているのと同じ機能を再実装するのは労力の無駄に思われました。また、FromFileメソッドを削除しようともしましたが、ベータ版との互換性を無くしてまで削除する必要はないと考えました。 XNA Game Studio 4.0ではプラットフォーム間での一貫性を保つことが目標です。Windows版のみの機能というのは、この目標に反します。また、Windows Phone対応によって、Webサービスやピクチャライブラリといった、実行時の画像の読み込みや、書き込みが必要になるシナリオへ対応することが重要になってきました。しかし、D3DXの画像処理用コードは、量が多く、不明瞭な機能も多いので、すべての対応プラットフォームへ移植するのには時間が掛かりすぎます。 そこで、私達はD3DXの画像読み込みコードの代わりに、シンプルな新しいAPIを使うことにしました。このAPIは Windows、Xbox 360、そしてWindows Phoneで同じ動作をする PNG、JPEG、そしてGIFフォーマットに対応 スケーリングや切抜き処理に対応 スクリーンショット、フォトアルバム、そしてWebサービスなどで扱うピクチャ向けに設計されている ゲームテクスチャなどの大きな画像の読み込みには最適化されていない(コンテント・パイプラインを使うべき) D3DXの画像読み込みより機能が少ない(ミップマップ、DXT圧縮や、カラーキーには対応していない) 画像読み込み用の二つのオーバーロードが追加されました。 static Texture2D FromStream(GraphicsDevice GraphicsDevice, Stream stream); static Texture2D FromStream(GraphicsDevice GraphicsDevice, Stream stream, int width, int height, bool crop); これらのメソッドはファイルからではなくストリームから画像を読み込みます。ですから、他にもFileStream、MemoryStream、NetworkStream、TitleContainer.OpenStreamなど様々なストリームから画像を読み込むことができます。ファイルから画像を読み込む場合は、以下のようにします。 using (Stream stream = File.OpenRead("cat.png")) { texture = Texture2D.FromStream(graphicsDevice, stream); } 以下は新しく追加された画像保存用のメソッドです。 void SaveAsPng(Stream…

0

XNA Game Studio 4.0のエフェクト・コンパイラーとコンテント・パイプライン・オートメーション

今までのXNAにはEffect.CompileEffectFromSourceメソッドがありました。Xbox 360上ではランタイム時にシェーダーのコンパイルは使えず、Windows上でのみ使えるメソッドでXbox 360とwindows用のシェーダーをコンパイルすることができました。しかし、この方法では以下の問題がありました。 ランタイム用のAPIのように見えるのに、すべてのプラットフォームで使えない Windows再配布コンポーネントにはXbox 360用のシェーダーコンパイラーが含まれている。これはWindows専用のゲームを作っている人達にとってはスペースの無駄遣いになる 新しいプラットフォームを追加するたびに、正規のバージョンとは別のパッケージを追加してきました。これはバージョン管理としては良い方法ではなく、無関係のプラットフォームのシェーダーコンパイラーをアップデートする度にWindows版のフレームワークDLLを更新しないといけません。 Game Studio 4.0ではシェーダーコンパイラーをWindows版 XNAフレームワークからコンテント・パイプラインへと移しました。Effect.CompilerEffectFromSourceの代わりにEffectProcessorを使うようになりました。 コンテント・パイプライン内でエフェクトをコンパイルするには幾つかの方法があります。 .fxファイルをコンテントフォルダに追加してF5でコンパイル。簡単、でも柔軟性がない .fxファイルをMSBuildプロジェクトに追加(別の機会で紹介します)し、コマンドラインからmsbuild.exeを使う。この方法はとても便利なのですが、活用している人が少なくて残念です。 MSBuild APIを使ってプログラム的にプロジェクトをメモリ内に作って実行する。これはレベルエディタなどの大きなプロジェクト向けの方法ですが、設定するのに手間が掛かります。 XNA Game Studio 4.0の新機能: MSBuildのプロセスを使わずに直接インポーターとプロセッサーをC#コードから呼び出す。これ以降は、この新しいやり方を紹介します。 ContentPipelineの機能を使うにはMicrosoft.Xna.Framework.Content.Pipeline.dllを参照する必要があります。しかし、参照追加のダイアログを開いても、このアセンブリは表示されないでしょう。どこへ行ったのでしょうか? .Net Framework 4.0にはClient Profileと呼ばれるものがあります。これは.Net フレームワーク全体ではなく、クライアント向けアプリケーション用に最適化されたサブセットとなっていて、フレームワークのダウンロードサイズが小さいなどの利点があります。XNA Game Studio 4.0ではWindows向けのゲームを作った場合、デフォルトでClient Profileを使うようになっています。コンテント・パイプラインのアセンブリを参照するには対象プラットフォームを.Net Framework 4にする必要があります。 やり方は以下のとおりです。 Visual Studio上でプロジェクトのプロパティを開く アプリケーションタブを選択 対象のフレームワークを「.Net Framework 4 Client Profile」から「.Net Framework 4」に変更する 参照の追加を選択 .Netタブを選択 Microsoft.Xna.Framework.Content.Pipelineを選択。必要に応じて他のアセンブリファイルも追加する。(ここではMicrosoft.Xna.Framework.Content.Pipeline.TextureImporterを追加しています) インポーターを呼び出す まずはテクスチャをインポートするサンプルを紹介します。まず最初にusingステートメントを記述します。 using Microsoft.Xna.Framework.Content.Pipeline; using Microsoft.Xna.Framework.Content.Pipeline.Graphics; using Microsoft.Xna.Framework.Content.Pipeline.Processors;…

4