空間が同じであれば、内積で面の明るさが計算できる。�Bの場合、共通空間はローカル空間です。空間はワールドでもビューでも実は構いません。なると、法線マップの法線の値が定義されているUVZ空間(接空間)にライトを持っていっても計算は出来るわけです。して接空間なのか?こうするとピクセルシェーダ内で�Bの計算をしなくて良いからです。ピクセルの値がそのまんま使えるんです。ライトの向きはテクスチャではありませんから、頂点シェーダでUVZ空間に移動可能です。計算した値をピクセルシェーダにそのまま持っていけば、両方とも同じ空間にいるため、法線マップの法線の値と直ぐに内積を取れるわけです。ピクセルシェーダでの1ポリゴン数百〜数千回のベクトル計算が、頂点シェーダでのライトのたった3回(三角形なので)の計算で済んでしまう。結果として全体の計算量はべらぼうに下がるわけです。説明が入りましたが、要はローカル空間(もしくはワールド空間)にあるライトを接空間に変換できると、おいしいわけです。その方法を次の節で説明します。法線マップの法線の時と同様に、この向きに接空間の軸のローカル座標向きを掛けて足し算すると、ライトの向きがローカル座標に変換されます。この右辺ですが、ちょっと行列で書き直してみます:左辺にライトのローカルでの方向(LLocal)、右辺にはライトの接空間での方向(L)があります。この式は「接空間にあるライトをローカルへ」です。今私たちが欲しいのは「ローカルにあるライトの向きを接空間へ」です。言う事は、下の行列の逆行列を右から掛けてあげると、欲しい式が出てきます。結局、行列の逆行列が求められればライトを接空間に持っていけます。実はここでこの行列には嬉しい性質があるんです。上の接空間の各軸のローカル座標向きを並べた行列。横方向に見ていくとUL、VL、ZLはそれぞれ標準化されて、しかもお互いに直行しています。いう行列の事を「正規直交系」と言います。実は、正規直交系の行列の逆行列は転置行列になります。省略します(計算するとちゃんと出てきます)。よって、頂点シェーダ内で上の行列が与えられたら、それをくるっと転置しちゃえば逆行列に生まれ変わります。この座標変換は目線(カメラの向き)に関しても言えます。目線が重要なのは「スペキュラ」です。スペキュラの計算をするには法線と、ライトと、そして目線の向きが必要になります(後の章で紹介します)。この3つの方向をやはり接空間に持っていけば、同様にスペキュラの光具合が計算できるわけです。法線マップを使うときには、ライトや目線を接空間に持っていこう。これが、この節のまとめです。実装:メッシュにTangentとBinormalを追加する理屈の話はここまでで十分です。ここからは実装の話に移ります。DirectX9の場合、一番ポピュラーなメッシュフォーマットは「Xファイル」です。Y軸)を出力しないものがあります。この場合、DirectX側でメッシュを作り直す必要があります。ppCloneMesh);Optionsにはメッシュ作成時のオプションを指定します。あるのですが、今回は元のメッシュの情報を流用します(後述)。pDeclarationには作成するメッシュに含める頂点情報をD3DVERTEXELEMENT9構造体の配列で指定します。pDeviceは描画デバイスです。ppCloneMeshには作成した新しいメッシュが返ります。D3D_OK;);引数に必要な情報を入れれば、内部でクローンメッシュを作ってくれます。SDKのParallaxOcclusionMappingサンプルを参考にしています)このメッシュを描画すれば、頂点シェーダにNormal、Tangent、Binormalの3軸情報が入るはずです。実装:頂点シェーダでは頂点シェーダの仕事に移りましょう。色々なものが入り組んでいるので、分かりやすく関数にわけてみます。vertex;}特に問題ありません。転置}正規直交系なので転置するだけでOKです。この関数が返す逆行列をローカル空間にあるライトが向く方向ベクトルに対して掛け算すると、ライトは接空間に移ります。通常ライトはワールド空間に置かれるもんですが、このシェーダに入力する前にローカルに変換しておきます(オブジェクトのワールド変換行列の逆行列を掛ければ良いだけです)。);これで頂点シェーダでの作業は終了です。ディフューズの色を明度で調節して点を打つ法線マップの色は0〜1.0です。これを-1.0〜1.0のベクトル範囲にするのがポイントですね。);}これで法線マップをモデルに貼り付けられます。ライトが当たっていないと判断される部分は黒くなり、その逆はより白色に近くなるので、凹凸間が出てきます。シェーダについての完全な実装はサンプルプログラムの中のNormal.fxにあります。同じ事を書いていますが、並行してご覧頂くと参考になると思います。法線マップの作り方さて、ここまでは法線マップありきのお話でした。実際に法線マップを作成するにはどうしたら良いのでしょうか?プロの現場では色々なツールで法線マップを作っています。Maya等の3Dモデリングツールに付属している高機能の法線マップ作成機能がメジャーのようです。私が教えてもらったのはMayaにある法線マップをベイクする機能で、「こりゃすごい」といたく感動したもんです。Inc.)という法線マップを作るため(≒高解像度メッシュを作るため)の専門ツールです。ポリゴンの表面を直に削ったり盛り上げたり、スタンプを押すような感覚で表面をでこぼこにしたりと、粘土細工でも扱っているかのごとく高解像度ポリゴンを作成できます。3で9万円くらいなので、気合を入れれば買えます。他にもSOFTIMAGE|XSI(ver5以降)のUltimapperでも作成できるようです。これらのツールはいずれも「超高解像度のポリゴンメッシュで凹凸の詳細を作り、それを低解像度のメッシュに投影すれば法線マップができる」という方式を取っています。考え方はとてもシンプルですが、実用できるソフトがあるのはすばらしい事です。高さマップ(バンプマップ、ハイトマップ)から高品質の法線マップを作ってくれるソフトとしてはCrazyBumpがあるようです。法線マップだけでなくオクルージョンマップなども出力できるようです。お値段も300ドルくらいで手ごろなのも良いですね。Tools」の「NormalMapFilter」プラグインです。した凹凸であればこれでも十分な品質が出ます。法線マップについてこれ以上無いくらいじっくりと説明してきました。理屈は面倒だったのですが、わかってしまうと実装はそれ程難しくはありません。サンプルプログラムも用意しましたのでご参照下さい。