TOP

ABOUT

PROGRAM

DIALY







変位マッピング

 1.はじめに
 変位マッピング(Displacement Mapping)やってみました。
今回は頂点シェーダでテクスチャを参照するのでSM3.0(シェーダモデル3.0)以上のグラフィックスカードが必要になるので注意してください。



 2.変位マッピング
 変位マッピングは凹凸マッピングをすこし優秀にした感じのやつです。
凹凸マッピング(Bump Mapping)や視差マッピング(Parallax Mpping)はライティングの仕方とかをいじりましたが,変位マッピングはその名の通り,頂点座標を変位させて凹凸を作り出します。そのため,凹凸マッピングや視差マッピングで横から見ると凹凸がなくて不自然という弱点がカバーされています。
 が,変位マッピングにも弱点があって,面数が少ない。すなわち,頂点数が少ない場合はきれいに凹凸がでません。なので,Nパッチという手法を使って頂点分割をして,それから変位マッピングするというやり方があるみたいです。いまどきであれば,ジオメトリシェーダ使って分割してしまうのがおそらく普通なんじゃないかなと思います。が,面倒なのでNパッチは省略。今回は使いません。Nパッチについてはimagireさんの"DirectX9シェーダプログラミングブック"に説明が載っているのでそちらを見てください。

話は戻りまして,変位マッピングのやり方です。
やり方はいたってシンプル。まず,変位マップ(高さマップ)を用意しておきます。この変位マップを基に変位させる量を決めます。
変位のさせ方ですが参照する変位マップからどのぐらい動かすかという量を求めて,法線ベクトルの方向にその量だけ移動させます。
具体的には次のようにします。

00062:  //---------------------------------------------------------------------------------------------------
00063:  // Name : Displacement()
00064:  // Desc : 変位させる
00065:  //---------------------------------------------------------------------------------------------------
00066:  float4 Displacement( float4 Position, float3 Normal, float2 TexCoord )
00067:  {
00068:  	float4 result = Position;
00069:  	result.xyz = Position.xyz 
00070:  		+ Normal	// 法線
00071:  		* (tex2Dlod( DisplacementSmp, float4(TexCoord, 0, 1) ).x )	// tex2Dだとだめなので仕方なくtex2Dlod 
00072:  		* Scale;	// 高さをスケーリング
00073:  	return result;
00074:  }
00075:  

tex2D()関数を使いたかったのですが,どうもコンパイルエラーになってしまいました。Cg言語の方ならtex2Dがそのままつかえるんですがね…。
ネットで調べてみたら,「tex2Dじゃなくて,tex2Dlodならいけるぜ!」という情報をキャッチしたので,そのまんま試してみたらうまくコンパイルに通りました。tex2Dもtex2Dlodもドキュメントを見る限りonly pixel shaderと書いてあったと思うのですが,なんでコンパイルに通るんですかね?謎です。
ちょっと気持ち悪いですが,使えるもんは使っとけ!っていうことで,とりあえず使っておきますw。
あとは普通に行列変換かけて,いつもどおりのライティングを施すだけです。
変位マッピングをやったのでこれで,一応でこぼこ三兄弟は制したことになりますね。変位マッピングはちゃんと凸凹するのですが,やっぱりきれいにみせるためにはそれなりに頂点数が多くないといけないので,あんまし使えなさそうですね。


 Download
本ソースコードおよびプログラムを使用したことによる如何なる損害も製作者は責任を負いません。
本ソースコードおよびプログラムは自己責任でご使用ください。
プログラムの作成にはMicrosoft Visual Studio 2005 SP1 Professional, XNA Game Studio 2.0を用いています。