26 March 2010 0 Comments

消えたRenderState

カテゴリ分けされたレンダーステート XNA Game Studio 3.1では描画するときに欠かせないレンダーステート情報を変更するには、GraphicsDevice.RenderStateプロパティを介する必要がありました。プロパティ化したことにより、デバッガ上で即座にレンダーステートを確認できるというのはC++でDirectXを使っていた時よりも格段に使いやすくなっていました。 ですが、RenderStateクラスには実に70近いプロパティがあり、中には複数のプロパティを正しく設定しないと思い通りに描画できないといった問題があったり、Visual Studio上で編集しているときでもインテリセンスに表示される候補が多すぎるという問題がありました。また、パフォーマンス的にも複数のレンダーステートを設定するのは時間が掛かってしまいます。さらにコードのメンテナンスしやすさの面から見ても、これだけの量のレンダーステートを人力で管理するのは難しく、かといって安易にStateBlockを使用すると更なるパフォーマンス低下の原因になってしまうという問題がありました。 そこで、XNA Framework 4.0ではこれらの問題を解決する為に、レンダーステートを以下の4つのステートにカテゴリ分けしています。 BlendState 半透明処理など、カラーブレンディングに関するステート DepthStencilState 深度バッファやステンシルバッファに関するステート RasterizerState ポリゴンのフィルモード、マルチサンプル設定などラスタライズ時に関するステート SamplerState テクスチャのサンプリングフィルターやアドレスモードなどのステート また、GraphicsDeviceにはBlendFactorプロパティがあり、BlendState.BlendFactorと同じものです。これはBlendFactorを使用するBlendStateを設定した後にBlendFactorの値だけを変えたい時の為に用意されています。GraphicsDevice.ReferenceStencilとDepthStencilState.ReferenceStecilの関係も同じものです。 各ステートの初期化と設定方法 それぞれのレンダーステートはあらかじめオブジェクトとして生成する必要があります。例えばBlendStateの場合は以下のように生成します。 // 一般的な半透明ステートオブジェクトを生成する BlendState myState1 = new BlendState (); myState1.ColorSourceBlend = Blend .SourceAlpha; myState1.AlphaSourceBlend = Blend .SourceAlpha; myState1.ColorDestinationBlend = Blend .InverseSourceAlpha; myState1.AlphaDestinationBlend = Blend .InverseSourceAlpha; もしくは、C# 3.0から使えるようになった オブジェクト初期化子 を使用して BlendState myState2 = new BlendState { ColorSourceBlend = Blend .SourceAlpha, AlphaSourceBlend = Blend .SourceAlpha, ColorDestinationBlend = Blend .InverseSourceAlpha, AlphaDestinationBlend = Blend .InverseSourceAlpha, }; のように書くこともできます。この書き方のが一行ごとにオブジェクト名を書かなくて良いのですっきりとした感じになります。 こうしてできたステートオブジェクトはGraphicsDeviceクラスのプロパティに設定することでレンダーステートを変更することができます。 GraphicsDevice.BlendState = myState1; あらかじめ宣言されたステート このままだと、レンダーステートを設定する時にあらかじめ使用するステートオブジェクト作らないといけないので、それらを管理する手間が増えてしまいます。確かに、その方がパフォーマンス的には有利なのですが、良く使われるレンダーステートくらいは直ぐに使いたいと思う人が多いでしょう。 そこで、それぞれのレンダーステートクラスには良く使われるステートの組み合わせが静的プロパティとしてあらかじめ用意されています。 BlendStateであらかじめ宣言されているBlendStateプロパティ プロパティ名 意味 設定値 Addtive 加算半透明用ブレンドステート ColorSourceBlend = Blend.SourceAlpha, AlphaSourceBlend = Blend.Blend.SourceAlpha, ColorDestinationBlend = Blend.One, AlphaDestinationBlend = Blend.One, AlphaBlend 半透明用ブレンドステート (アルファ値乗算済み) ColorSourceBlend = Blend.One, AlphaSourceBlend = Blend.One, ColorDestinationBlend = Blend.InverseSourceAlpha, AlphaDestinationBlend = Blend.InverseSourceAlpha, NonPremultiplied 半透明用ブレンドステート (一般的な半透明) ColorSourceBlend = Blend.SourceAlpha, AlphaSourceBlend = Blend.SourceAlpha, ColorDestinationBlend = Blend.InverseSourceAlpha, AlphaDestinationBlend = Blend.InverseSourceAlpha, Opaque 不透明用ブレンドステート(規定値) ColorSourceBlend = Blend.One, AlphaSourceBlend = Blend.One, ColorDestinationBlend = Blend.Zero, AlphaDestinationBlend = Blend.Zero, DepthStencilStateであらかじめ宣言されているDepthStencilStateプロパティ プロパティ名 意味 設定値 Default 規定値、深度バッファの読み込み、更新あり DepthBufferEnable = true, DepthBufferWriteEnable = true, DepthRead 読み込みのみ 深度バッファとの比較はするが、深度バッファの更新はしない。パーティクル等の半透明描画時に使用する DepthBufferEnable = true, DepthBufferWriteEnable = false, None 深度バッファを使用しない DepthBufferEnable = false, DepthBufferWriteEnable = false, RasterizerStateであらかじめ宣言されているRasterizerStateプロパティ プロパティ名 意味 設定値 CullClockwise 時計方向回りのプリミティブをカリングする CullMode = CullMode.CullClockwiseFace, CullCounterClockwise 反時計方向回りのプリミティブをカリングする(規定値) CullMode = CullMode.CullCounterClockwiseFace, CullNoneNone カリングなし CullMode = CullMode.None, SamplerStateであらかじめ宣言されているSamplerStateプロパティ プロパティ名 意味 設定値 AnisotropicClamp アニソトロピックフィルタリング(異方向性フィルタリング)、クランプ Filter = TextureFilter.Anisotropic, AddressU = TextureAddressMode.Clamp, AddressV = TextureAddressMode.Clamp, AddressW = TextureAddressMode.Clamp, AnisotropicWrap アニソトロピックフィルタリング(異方向性フィルタリング)、ラッピングあり Filter = TextureFilter.Anisotropic, AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap, LinearClamp リニアフィルタリング、クランプ Filter = TextureFilter.Linear, AddressU = TextureAddressMode.Clamp, AddressV = TextureAddressMode.Clamp, AddressW = TextureAddressMode.Clamp, LinearWrap リニアフィルタリング、ラッピングあり(規定値) Filter = TextureFilter.Linear, AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap, PointClamp ポイントフィルタリング、クランプ Filter = TextureFilter.Point, AddressU = TextureAddressMode.Clamp, AddressV = TextureAddressMode.Clamp, AddressW = TextureAddressMode.Clamp, PointWrap ポイントフィルタリング、ラッピングあり Filter = TextureFilter.Point, AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap, レンダーステートの管理が簡単になった これら四種類のレンダーステートオブジェクトにカテゴリ分けと、あらかじめ用意されているステートの組み合わせを使用することでレンダーステートの管理がしやすくなりました。どれぐらい簡単になったかというと、例えば全てのレンダーステートを初期値に戻したいという場合があったとします(普段はあまりないけれど)。このケースの場合は以下の数行を書き加えるだけで実現することができます。 // レンダーステートを初期値に戻す GraphicsDevice.BlendState = BlendState .Opaque; GraphicsDevice.DepthStencilState = DepthStencilState .Default; GraphicsDevice.RasterizerState = RasterizerState .CullCounterClockwise; // サンプラーステート数はReach、HiDefともに16個 for ( int i = 0; i < 16; ++i) GraphicsDevice.SamplerStates[i] = SamplerState .LinearWrap;

9 March 2010 0 Comments

XNA Game Studio 4.0の新機能

  最近、私の忙しさの尺度はこのブログの更新頻度に反比例しているということに気づきました。去年の秋あたりから忙しくなり、今年に入ってGamefest、GDC、そしてMIXへ向けての作業に追われる毎日でした。で、ちょっとだけひと段落したので、またいろいろと記事を書いていこう思っています。 まず最初のニュースはXNA Game Studio 4.0についてです。XNA Game StudioはWindows、Xbox 360、そしてZuneと対応プラットフォームを増やしてきましたが、4.0では Windows Phone 7シリーズ への対応が決まりました。 Windows Phone 7シリーズでは要望の多かった3D APIが追加されています。ただし、Xbox 360やWindowsなどと比べると非力な携帯デバイスなので、複数のプラットフォームでゲームを作る場合にはプラットフォーム間のパフォーマンス差を考慮する必要があります。 この労力を軽減するために4.0では、”Reach(リーチ)”と”HiDef(ハイデフ)”の二つのCapsを設けました。ReachはWindows Phone 7シリーズを含めたどのプラットフォームでも動作させることのできるAPI群からなり、HiDefはXbox 360やハイエンドWindowsマシン上で動作することを前提にしたAPI群からなります。HiDefではReachの全APIが使えるようになっています。 以下はXNA Game Studio 4.0の主な新機能です。 XNA Game Studio 4.0の新機能 Visual Studio 2010に対応 グラフィクスAPIを機能的に”Reach(リーチ)”と”HiDef(ハイデフ)”にカテゴリ分け ダイナミックオーディオ マイク BasicEffectに加えて以下の基本的エフェクトクラスの追加 SkinnedEffect (スキンモデル用のエフェクト) EnvironmentMapEffect (環境マップ用のエフェクト) DualTextureEffect (デュアルテクスチャ用のエフェクト) AlphaTestEffect (アルファテスト用のエフェクト) これらの詳細は今週開催されているGDC、そして来週開催される MIX で公開される予定です。 http://blogs.technet.com/microsoft_blog/archive/2010/03/09/game-developers-have-a-great-opportunity-with-windows-phone-7-series.aspx http://blogs.msdn.com/shawnhar/archive/2010/03/09/in-which-hints-become-facts-xna-game-studio-4-0.aspx#comments http://klucher.com/blog/achievement-unlocked-xna-game-studio-4-0-for-windows-phone/