法線マップをNormal/Tangentで読み、一度だけ展開します。YZ断面の矢印は、緑チャンネル反転でYの符号だけが変わる例です。平坦なRGBの例は圧縮前の説明用です。
図:法線マップをNormal/Tangentで読み、一度だけ展開します。YZ断面の矢印は、緑チャンネル反転でYの符号だけが変わる例です。平坦なRGBの例は圧縮前の説明用です。(クリックで拡大)

凹凸の逆転と、陰影全体の異常を分ける

溝が盛り上がって見える、ライトを動かすと模様の向きが不自然になる場合は、法線マップの読み方・座標空間・モデルの接線を順番に確認します。法線マップは高さそのものではなく、表面が向いているように見せる方向を記録した画像です。この記事はUnity 2022.3 LTS・URP 14・Shader Graph 14の3D Litを基準にしています。

1. インポート設定を確認する

Projectで画像を選び、Texture TypeをNormal mapにしてApplyします。すでにRGBの法線マップとして書き出された画像では、Create From Grayscaleを無効にします。白黒の高さ画像から法線を生成する場合とは処理が異なります。法線の値を通常の色テクスチャとしてsRGB変換する経路にしないよう、専用のインポート設定を使います。

非圧縮のRGB表現では、おおむね(0.5, 0.5, 1)が接空間の(0, 0, 1)、つまり元の表面法線に沿う方向です。実際のインポート後は圧縮形式などによって格納方法が変わるため、この式で読み出し用シェーダーを自作する必要はありません。

2. Shader Graphでは一度だけ展開する

一般的なTangent Spaceの法線マップなら、Sample Texture 2DのTypeをNormal、SpaceをTangentにします。RGB出力をFragmentのNormal (Tangent Space)ブロックへ接続し、入力側も接空間になっているか確認します。ここでNormal Unpackを追加したり、さらに「×2−1」を適用したりすると二重変換になります。

World SpaceやObject Spaceの値を混ぜる場合は、最終的な入力の座標空間に合わせる変換が必要です。まず追加の混合・変形を外した最小の接続で比較してください。この手順は、Object Spaceで書き出した法線画像や2D Rendererの法線処理に、そのまま当てはめるものではありません。

3. 緑チャンネルの反転は、Y方向の規約が違うときに試す

作成元とUnityで法線マップのY方向の規約が異なる場合、Import SettingsのFlip Green Channelが候補になります。これは緑のY成分だけを反転する設定で、すべての陰影不良を直すスイッチではありません。元画像を保存したまま設定だけを切り替え、分かりやすい溝や突起にライトを複数方向から当て、書き出し元の見た目と比較します。

書き出し側ですでに反転した画像を、ImportやShaderでも重ねて反転しないようにします。使用するGraphics APIの名前だけを根拠に、常に反転が必要だと判断しないでください。

4. 一部のメッシュだけおかしければ、接線とUVを調べる

  1. 同じ画像をURP/LitのNormal Mapスロットで試します。単純な平面では正常でも元モデルで異常なら、モデル側の条件を絞れます。
  2. モデルのNormalsとTangentsが存在するか確認します。法線マップをベイクしたときのメッシュ・UV・頂点法線と、Unityへ取り込んだものが一致しているか比較します。
  3. 接線が欠けていれば、モデルのImport設定で適切なImportまたはCalculateを選びます。再計算すれば必ず改善するわけではなく、ベイク時の接空間と合わせることが大切です。
  4. UVの継ぎ目・反転部分、負のScaleや独自の頂点変形がある箇所を確認します。頂点を変形した場合は法線・接線も対応しているか調べます。

修正後の確認

  • 法線の強さを0にした状態と比較し、問題が法線の経路にあるか確認する。
  • ライトを上下・左右から動かし、溝・突起・UV境界が意図した陰影になるか確認する。
  • 対象端末の圧縮設定でも確認する。Editorだけの表示で完了としない。

法線の強さを0にしても異常が残る場合は、モデルの頂点法線やライト、Smoothnessなど別の条件も調べます。無理に緑チャンネルを反転して合わせると、別の角度で陰影が崩れる原因になります。

参考資料