0から学ぶ法線マップポリゴンの表面にはテクスチャが貼られる。これは3Dのゲームを作ろうと思う方はもちろんどなたでもご存知の事です。貼るという語意から、テクスチャには色が付いているんだろうなともイメージできます。DirectXの中では「色」というのは単なる数字です。シェーダの中に入ると、それは0.0〜1.0の小数点になってしまいます。テクスチャは何とも便利な物で、ポリゴン表面のある部分の色を示す事ができます。テクスチャの色は結局数値なのですから、これを別のもっと一般化すると「テクスチャはポリゴン表面のある部分の『値』を示す事ができる」となります。ポリゴン表面の性質にも色々とありますが、色味以外の代表格と言うと「法線」です。ポリゴンの向きですね。これまで、法線は頂点単位でしか定義されませんでした。ところがシェーダが公開された時、先の偉い人は「テクスチャがポリゴン表面のある部分の『値』を示せるなら、ポリゴンの内側の細かい起伏の向きをテクスチャで表現できるんじゃないかな?」と考えてくれました。それが「法線マップ(法線テクスチャ)」です。法線マップを用いると、一枚の板ポリゴンでさえ表面にでこぼこがあるように見せる事ができます。この技術が確立したお陰で、昨今のゲームの表現力は恐ろしいほどに向上しました。幸いな事に、それ程難しい事を考えなくても、法線マップはポリゴンに貼れるんです。この章では、そんな魅力的な法線マップについて0から見ていこうと思います。最初に法線マップ自体について解説します。次にそれをポリゴンに貼り付ける方法をじっくり検討し、そして最後に法線マップを実際に作る方法について簡単に触れます。法線マップの貼り付けイメージ法線マップとは1つのピクセルが「ベクトル」を表すテクスチャです。法線を表すベクトルです。法線マップをポリゴンに貼るとどうなるのか模式図で示すとこうなります:これは4×4の法線マップを1枚の三角ポリゴンに単純に貼り付けた場合を見ています(あくまでもイメージです)。左側は貼り付ける前です。1枚のポリゴンに1つの法線が定義されています。右側は法線マップを貼り付けた場合です。先ほどの1枚のポリゴンの表面に、テクスチャのピクセルが覆う範囲ごとに法線が定義されています。それは1枚のポリゴンがピクセルの大きさに分割されているような状態です。テクスチャのサイズをもっと大きく(解像度を上げる)すれば、この分割がもっともっと細かくなってより詳細にポリゴン表面を演出できるのが良く分かると思います。ポリゴンが実際に分割される事は無いので、頂点数は増えません。粗いポリゴンでも美しい凹凸表現が可能になるのが、法線マップ最大の魅力です。法線マップのフォーマット法線マップの1ピクセルが1つの法線になる事がわかりました。実際にどういう値が格納されているのでしょうか?法線はベクトルです。XYZの3つの成分が必要になります。テクスチャで3成分と言うと「RGB」ですよね。法線マップではX成分をR、Y成分をGそしてZ成分をBで表現するのが一般的です。ところで、法線マップのXYZ軸とはどの空間の座標なのか?これ、凄く大切です。これは「ポリゴンのUV座標空間」を基準とするのが一般的です。ポリゴンを鯵の開き状態にすると次のようにUV空間に展開できます:これは円錐の展開図です。各ポリゴンの頂点には1つ1つUV座標が定義されていて、それをプロットして結ぶと上の図のように描かれるわけです。各ポリゴンが囲っているテクスチャがそのままポリゴンに貼り付けられます。テクスチャが法線マップの場合もそれは同様です。ポリゴンが鯵の開きになっているので、ポリゴン自体の法線は全部こちら側を真っ直ぐ向いています。法線マップの各ピクセルは、この座標空間で法線の向きを表現します。0.90)くらいでしょうか。法線は実質XYZのあらゆる方向に向けます。法線マップはあくまでもテクスチャなので、RGBの色にする必要があります。RGBの各成分は0〜1(0〜255の整数)なので、このままだとマイナスが表現できません。そこで、0.5を中心として0〜0.5までをマイナス、それ以上をプラスとして扱います。試しに-1.0から+1.0まで法線のX軸を変化させた時の色の変化を見てみましょう:下図は法線マップを真横から見た様子で、上はそのカラーです。こんな感じの色合いになるわけです。シェーダに入ってくる時にはRGB成分は0〜1.0に変換されています。それをXYZの値に変換すれば法線の向きになります。その辺りは後述します。法線マップは鯵の開きになったポリゴンに対してRGBの色成分でその法線の向きを表している。これがこの節のまとめです。法線マップの法線をローカル座標で表すにはさて、法線マップの点がUV座標を基準とした鯵の開きポリゴンの法線の向きを表しているのはわかりました。1)のような値になっているわけです。ポリゴンに定義されている法線はローカル座標で定義されていますよね。法線マップの法線も是非そうなって欲しいわけです。UV座標にある1枚の三角ポリゴン。それを抜き出します:Z軸はこちらを真っ直ぐ向いています。このポリゴンが実際にローカルにある様子がこちら:2つの座標があります。1つは貼り付けられたポリゴンのUV座標です。先の真上から見たのをそのままぺタっと貼り付けたと思って下さい。法線マップの法線はこのUV座標で定義されています。ここで極めて重要な言葉を紹介します。上のローカル座標にあるUVZ座標(空間)。Space)」と言います。接空間と出てきたら「ローカル座標にあるUVZ座標の事なんだな」と思い返して下さい。以後混乱を避けるために接空間で統一します。ローカル座標とポリゴンの接空間。これらを結びつける鍵は「ポリゴンの法線」です。ポリゴンは(正しくは頂点は)ローカル座標で表された法線ベクトルを1つ持っています。上の図で言うとそれは接空間のZ軸とぴったり一致します。このポリゴンのローカル法線ベクトルは頂点シェーダで「NORMAL」というセマンティクスを指定すると取得できます。NORMALで得たベクトルは上のZ軸の方向というわけです。接空間を規定する他の2つの軸、UとVのローカル座標での方向はどうか?実はこれも頂点シェーダで「TANGENT」及び「BINORMAL」と指定すると取得できます。いう所をちゃんと考慮してくれているわけです。ローカル座標にある接空間の各軸の向きは既知なんです。法線マップの法線ベクトルの向きはUVZ座標で定義されていますが、3軸のローカル座標での方向がわかっているのですから、その向きも計算できてしまうわけです。Normalの頭文字)。n)という各軸に沿っている3つのベクトルの合成です。ちなみに各軸のベクトルは標準化されているとします。