スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

キューブマップとの格闘

毎度(というか毎日)知らない言葉がでてきて勉強しては実装しているのですが、キューブマップは思ったより大変でした。

キューブマップのサンプルはMicrosoftから出ているSkyなんちゃらってのがあるので実行してみてください。
Xboxのコントローラーで動くようにできてるので
this.keystate = Keyboard.GetState();

if (keystate.IsKeyDown(Keys.D1))
{
myCamera.Target = new Vector3(0, 0, 0);
myCamera.Distance = -50f;

}
if (keystate.IsKeyDown(Keys.D2))
{
myCamera.OrbitUp(0.01f);
}
if (keystate.IsKeyDown(Keys.D3))
{
myCamera.OrbitRight(0.01f);
}

を加えたら動きました。
ほほ~全6方向を画像で覆ってやりどこを見ても綺麗に繋がって見えるわけですね。

んでこの辺まで進むと、いざ自分のプログラムに付け加えるぞ~ってところで止まりました。
というのも他のサンプルが少ないんです。
死活問題です。

では説明。ちなみに長いので、時間の無い方は遠慮したほうがいいかもです。(汗)

まずDirectXのHELPでやられました。
あやつ「左手系座標」で説明してやがります。
こっち(XNA)は右手です。

ってことで仕様から。方向とかも
資料が無い。
た、た、試すか・・・・・・・・・(泣)

まっず絶対わすれちゃいけないのがこれ
cube6.jpg

まず方向を見るためにエフェクトにDirectXViewerで作成した6方向の名前とテクスチャ方向をいれた図をぶち込みまして表示
cube.jpg
こんな感じででてきます。
cube3.jpg
DirectXの説明からこのようなイメージで頭に焼き付いている人もいるとおもいますが
こうのほうがいいです
cube4.jpg
んでもってこうなります
cube5.jpg
うわ。下手な絵ですいません。
伝わればいいんです。

PX=ぽじてぃぶえっくす
NX=ねがてぃぶえっくす

ですね。

次にこの貼り付けた画像の取り出す方法です。
結論からいうと「中心からのベクトル(ノーマライズいらない)を与えるとその先にある色を取得してくれる命令を利用する」です。
結構重要なのに詳しい説明はどこもしてくれていないです。常識でわかれ!っていうかもしれませんが初心者にはつらいところ。

texCUBE(s, t)
3D のキューブ テクスチャ参照。s はサンプラまたは samplerCUBE オブジェクト。t は 3D テクスチャ座標。

texCUBE(s, t, ddx, ddy)
微分を指定した、3D のキューブ テクスチャ参照。s はサンプラまたは samplerCUBE オブジェクト。t、ddx、ddy は 3D ベクトル。

texCUBEproj(s, t)
3D 射影のキューブ テクスチャ参照。s はサンプラまたは samplerCUBE オブジェクト。t は 4D ベクトル。t は、参照が実行される直前の成分で除算されます。

texCUBEbias(s, t)
3D のバイアス キューブ テクスチャ参照。s はサンプラまたは samplerCUBE オブジェクト。t は 4D ベクトル。参照を実行する前に、ミップ レベルに t.w のバイアスがかけられます。


てな感じの命令が用意されています。もちろんこれはシェーダでのお話。


んでんで最初の貼り付けた絵は球の法線をtexCUBEに渡しています
そうなるとベクトルっていっても角っこを指定したらどうなるの?って思う人がいそうですね。
実験しました。
例えばXYZすべてが-1~1の立方体があるとして
(1,1,0)とかだと丁度キューブの角を向いたベクトルになりますね?
このベクトルで色を欲しがるとどっちの面の色を持ってくるか?って問題です。
答えはCubeMapFaceのナンバーが若い方が強いみたいです。
PX、NX、PY、NY、PZ、NZの順ですね。
全箇所試したわけではないのであしからず!


CubeMapFaceといえばこれもやられました。
6枚もあるのでforを使って(CubeMapFace)iとしてフェイスを切り替えしていたんですが、ブレイクをかけてこいつにポイントして+を開くとNX~Z、PX~Zの順に表示されます。
これはiの表示順だと勘違いしちゃったんですね。。。違うのであしからず。
PX、NX、PY、NY、PZ、NZが正しいです。

話がそれましたが、次に思うことは「んじゃキューブマップつなげてデバッグ表示してみよう!」となりますがこれまた難儀。
ソース載せます。
注意:この方法は「重くていいからソースが短く後でサックリ消せる」ことを重視していますので、とにかく重いです。古いPCの人はまともに見れないかもしれません。
もしデバッグでも軽いものがいいという人はこの方法の次に書いた方法をお勧めします。

とりあえず関数としてどこかに
        private void DebugCubeMap(RenderTargetCube r, int CubeMapSize, int CubeMiniMapSize)
        {
            //動的キューブマップ簡易目視用
            int i, cubeX = 0, cubeY = 0;
            byte[] data = new byte[CubeMapSize * CubeMapSize * 4];
            for (i = 0; i < 6; i++)
            {
                r.GetTexture().GetData((CubeMapFace)i, data);
                Texture2D LookTex = new Texture2D(GraphicsDevice, CubeMapSize, CubeMapSize, 1, TextureUsage.None, SurfaceFormat.Single);//カラーMAPの人は最後を.Colorに。
                LookTex.SetData(data);
                this.spriteBatch.Begin(SpriteBlendMode.None);
                switch (i)
                {
                    case 0:
                        cubeX = CubeMiniMapSize * 2;
                        cubeY = CubeMiniMapSize;
                        break;
                    case 1:
                        cubeX = 0;
                        cubeY = CubeMiniMapSize;
                        break;
                    case 2:
                        cubeX = CubeMiniMapSize;
                        cubeY = 0;
                        break;
                    case 3:
                        cubeX = CubeMiniMapSize;
                        cubeY = CubeMiniMapSize * 2;
                        break;
                    case 4:
                        cubeX = CubeMiniMapSize * 3;
                        cubeY = CubeMiniMapSize;
                        break;
                    case 5:
                        cubeX = CubeMiniMapSize;
                        cubeY = CubeMiniMapSize;
                        break;
                }
                spriteBatch.Draw(LookTex,
                    new Rectangle(cubeX, cubeY, CubeMiniMapSize, CubeMiniMapSize),
                    new Rectangle(0, 0, CubeMapSize, CubeMapSize),
                    Color.White);
                this.spriteBatch.End();
            }
        }

を入れてやり
DebugCubeMap(cubeRt,1024,125);//デバッグ用キューブマップの表示
で表示します
引数は「CubeMapの元サイズ」「目視するサイズ(1辺の大きさ)」を渡して下さい。
コピペの際、タブが入らなかったので半角スペースを全角に置き換えて貼り付けました。
テキストエディタなのでCtrl+Rなどの置き換え機能を使用して全角スペースを殺してください。

↑の方法は重いので気にいらない!という人は以前紹介したMSDNのBBSの中間くらいの記事を見てください。



これでやっとキューブマップの全容が見えてきましたね。
感のいい人ならここで気になることも出てきたはずです。
「最初からテクスチャを用意するなら楽だけど動的に生成した場合、左右逆にならない?」ってことです。
キューブマップの使い方は「反射するものを綺麗に表現するためにはどうしたらよいか?」というところから開発されたものだと思います(あくまで予想)

その点からも回りに見えるものを実際の映像とリンクさせてやる作業には注意がいります。
そんなことしないから必要ないんだけど?っというのが普通の意見だと思いますが、キューブマップを利用したシャドウマップを実装したいときにこの辺が重要になるので注意しておいてください。


なんかまた無駄に長い。
ねよっと。

コメントの投稿

非公開コメント

プロフィール

あしゅ

Author:あしゅ
ぷぃぷぃ日常。
いつのまにか雑記ブログに。

カテゴリ
最新記事
検索フォーム
最新コメント
リンク
このブログをリンクに追加する
ブロとも申請フォーム

この人とブロともになる

カウンター
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。