スポンサーサイト

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

バンプマップの基礎

とある野望が芽生えまして、そのための準備をしていましたら(内容は近々載せると思います)バンプマップの処理が気になりだしてまたまた弄っていました。
あーモーションやるっていってたのに有言無実行のへなちょこめ!

メモがわりに作ったブログだったのに気づけば結構ちょこちょこ書いてるなーと思いながらも、読み返していると、本人は初心者のくせに初心者に優しくない書き方。
ぅん。反省。

バンプマップをあーだこうだ!載せる前に実装時躓いたことなどをひたひたと書き綴りたいと思います。

まず!最初に詰まるであろう場所は「座標の統一」だとおもいます。
・頂点座標系
・TangentSpace
・接空間座標

などのわけわかめな言葉達に翻弄されるのです。

ものに光を当てる!といったときに頭の中では普通ワールド座標で考えると思います。

ではここで法線MAPを取得してそれをワールド座標に計算して光の演算を行うとしましょう。
ライトなどはこんな感じ、
L = normalize( LightPosition - (float3)WorldPos );
法線(この場合はローカル→ワールド)は
N = normalize( mul( Normal, (float3x3)WorldMatrix) );
などしてやり同じ座標系にて計算します。

ところがここで気になることがでてきます。
BumpMapの法線を参照するとき、法線データは画像の中にあるわけですから、一般のシェーダ命令を使用することを考慮するとピクセルシェーダでしか演算できません
このようなものは実行回数的にも極力バーテックスシェーダで終わらせたいのが本音です。

そこで先ほどでてきた「座標を変える」作業がでてくるのです。
具体的には接空間座標(タンジェントスペース)で演算を行うのです。
なんじゃそれ?という方はモデリングのUV作業を思い出してください。
あれが接空間座標のイメージになります。(ぉぉぉ、見事にアバウト。)
画像はXとYしかないので2次元ですが真上から見ていると捕らえて自分方向にZが存在すると思ってください。
この座標系に視点やライトベクトルをもっていくということは貼り付けるテクスチャに対してどの方向からライトを当てているかを考えるということです。
もちろん1点1点その方向は違ってくるわけで混乱しがちですが、座標さえそろえてしまえば計算内容はワールドで用いたものと全く同じで構わないので、そこまで混乱せずに済むでしょう。

ということで流れ的にはこうなります。

バーテックスで使用するベクトルはすべて接空間座標にしておく。

ピクセルシェーダでBump法線を取得するがこれはもともと接空間座標で取得するのでそのままNormalベクトルとして使える。

光の演出を行う


では実際にベクトルを接空間にするときはどうしたらよいでしょうか。
変換用の逆行列を用意しそれをかけてやるだけです。
(例)ライトベクトルを変換。
TBNはそれぞれTangent、Binormal、NormalでLightDirはワールド座標上でのライトベクトル。

float3x3 mat ={N,T,B};
mat = transpose(mat);
Out.L = mul(LightDir,mat);

としてやるか、

Out.L.x = dot(LightDir, T);
Out.L.y = dot(LightDir, B);
Out.L.z = dot(LightDir, N);

とします。
良くあるサンプルにはNTBにworldが計算されていないことが多いのでその変も注意です。
mulを使う場合にはnormalizeを適所でしておいてください。

TangentとBinormalの取得方法については過去の記事を見てくださいな~
BinormalはXNAはそのままコンテントパイプでの読み込み時に持たせることが可能ですがcrossを使って出してもその辺はお好みで。

あと、忘れていけないのがテクスチャから取得した法線情報は0から1の間にあります
よって
float4 N = normalize(2 * tex2D( NormalSmp, Tex ) - 1);
として-1~1の間に拡張してやらなければなりません。


最低限の数学知識は
・normalizeってのは長さ1のベクトルにしてくれるのだな~
・ベクトルの足し算ってのはベクトル同士の矢印をくっつける感じ?
・内積で二つのベクトルの角度らしきものがでるのだな
・外積で垂直に交わるベクトルがでるぜぃ

くらいでなんとかなりそうです。

他に勝手なイメージですが、
 X = U = Tangent
 Y = V = Binormal
 Z = W = Normal
は何かに使えるかも。

また元になるMapファイルは正確につくりましょう。
UV方向が違った作成ツールなどを使うとかなり痛い目にあいます(はい。私です。)
Gimpのプラグインで優秀な作成ツールがあるみたいです。(Gimpとはフリーの強力ペイントソフト)
↑で落としてきたらフォルダのPlug-Inフォルダを探して全部ほうりいれます。
画像を出したらメニューの「フィルタ」→「マップ」→「normal map」で窓が開きます。
Filterは、「4 sample」か「Sobel 3x3」がいいと思う。
「4 sample」の場合Scaleを調整。
んでもって肝なのが「Invert Y」にチェックを入れる!!!(私の見ていたサイトがXNAのものではなかったので違いました)
私の環境ではチェックを何も入れないのが正解のようです。
ここでUV方向の切り替えができるので自分の環境にあった方向にしてやってください。

書き出したら止まらなそうなのでこの辺で。
ねよっと。

コメントの投稿

非公開コメント

プロフィール

あしゅ

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

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

この人とブロともになる

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