質感・ライティング

法線マップ・TBN

Normal Mapping / Tangent Space

頂点を増やさず細かな凹凸の陰影を付ける。

4 / 10

インタラクティブデモ

デモを準備しています…

法線マップ・TBN

ドラッグで視点を回転、Ctrl(⌘)+ スクロールでズーム。タッチ操作は 2 本指です。

ひとことで

表面の細かな凹凸を、頂点を増やして形で作る代わりに、「その画素で表面がどちらを向いているか」を画像(法線マップ)に書き込んでおき、ライティングのときだけその向きを使う手法です。形は平らなままでも、光の当たり方が凹凸に合わせて変わるので、レンガの目地、岩のひび、服のしわ、顔のしわなどを、ほとんどコストをかけずに表現できます。

ゲームでの使いどころ

  • あらゆる 3D アセットの細部:ゲームの 3D モデルのほぼすべてに法線マップが使われています。
  • ハイポリからローポリへの焼き込み:数百万ポリゴンで彫刻した高精細モデルの凹凸を、数千ポリゴンのゲーム用モデルの法線マップに「焼き込む(ベイクする)」のが標準的な制作手順です。
  • 地形・建物:タイル状に繰り返すレンガ、石畳、木目などの素材の凹凸。
  • 水面・エフェクト:流れる法線マップで水面のさざ波を作る。

しくみ

法線マップの各画素には、法線ベクトル (x,y,z)(x, y, z)(各成分は −1-1〜11)を 0〜1 に写して RGB として保存します。

RGB=n+12\text{RGB} = \frac{\mathbf{n} + 1}{2}

平らな部分の法線は (0,0,1)(0, 0, 1) なので、法線マップは全体に青紫っぽい色になります。

接空間(TBN):法線マップに書かれた向きは、「その場所の表面を基準にした」向きです。基準となる 3 つの軸を接空間と呼びます。

  • T(接線):テクスチャの uu が増える方向
  • B(従法線):テクスチャの vv が増える方向
  • N(法線):表面の外向き
nワールド=[TBN]nマップ\mathbf{n}_{\text{ワールド}} = \begin{bmatrix} \mathbf{T} & \mathbf{B} & \mathbf{N} \end{bmatrix} \mathbf{n}_{\text{マップ}}

接空間で保存しておくと、モデルが曲がっていても、アニメーションで変形しても、同じ法線マップを使い回せます。

実装のポイント

  • 接線の計算:接線はモデルの UV から計算します(MikkTSpace が業界標準)。ベイクしたツールとゲームで計算方法が違うと、継ぎ目に陰影のずれが出ます。
  • 緑チャンネルの向き:OpenGL 系(Y が上)と DirectX 系(Y が下)で緑チャンネルの向きが逆です。凹凸が逆に見えたら、緑を反転します。
  • テクスチャの形式:法線は色ではないので、sRGB ではなく線形で読み込みます。圧縮には x,yx, y だけを保存して zz を計算で戻す BC5 などの 2 チャンネル形式がよく使われます。

つまずきやすい点

  • 輪郭と影は変わらない:法線マップは陰影を変えるだけで、形は平らなままです。真横から見ると平らなことが分かり、凹凸が自分の上に落とす影も出ません。デモの「真横から光を当てる」で確認できます。視差まで表現したい場合はパララックスマッピングを組み合わせます。
  • ミップマップでの凹凸の消失:遠くでは法線が平均されて平らになり、同時にハイライトがちらつくことがあります。粗さを補正する手法があります。
  • UV の鏡像:UV を左右反転して使い回したモデルでは、従法線の向きも反転させる必要があります(接線の w 成分で符号を持つ)。

デモで試すこと

  1. 左から「平面のみ」「平面 + 法線マップ」「実際の凹凸」です。光が動くと、法線マップの面は 2 つの三角形しかないのに、8 万三角形の実際の凹凸と同じように陰影が変わります。
  2. 「法線マップの強さ」を 0 にすると平面のみと同じに、2 にすると凹凸が強調されます。
  3. 「真横から光を当てる」をオンにすると、実際の凹凸は影を落としますが、法線マップの面は落としません。法線マップの限界です。
  4. 手前の球には、接空間の 3 軸を表示しています。場所によって軸の向きが変わるので、同じ法線マップでも球面に沿った凹凸になります。

参考資料

Filament Material System ↗

分野全体の資料で、この項目を直接扱っているとは限りません。