2012年2月14日火曜日

ノーマルマップ(法線マップ)について

みなさん、こんにちは。
柳村です。

先日、modo UserGroup Tokyo 主催の勉強会へ参加させていただきました。
私は、リプリケータについて解説をさせていただいたのですが、
そのなかで、軽くふれましたノーマルマップについて補足させてただきます。

まず、ポリゴンの法線について簡単にお話しておきます。

ポリゴンというのは、基本的に”面”なのですが、
その面が3D空間の中で”どの方向を向いているのか?”という事を表しているのが、ポリゴンの法線です。
下の画像では、ポリゴンからヒゲのように生えているのが法線です。


modoは初期設定の状態ではポリゴンの法線が表示されないので、
表示したい場合は、ビューポートオプション(ビューポート上で"o"キーで開きます)で
表示属性の、選択法線の表示にチェックを入れてください。

つまり、法線の方向=ポリゴンの面が向いている方向なのですが、
この法線の方向をもとにして、ライトとの角度やカメラから見た角度などを
コンピューターが計算することで、そのポリゴンの明るさや・ハイライト・鏡面反射など、
さまざまな要素が決定するのです(シェーディング)。

余談ですが、このことから非平面ポリゴンというのは極力避けなければいけないです。
非平面ということは平面に非(あら)ずなので、面ではないのです。
ポリゴンの面の方向を示す法線ですので、3DCGでは面ではない非平面にも法線は存在します。
しかし非平面の面の方向を示しているので、変な反射や不正な影などのレンダリングエラーの原因となります。


話を戻しまして、ポリゴンの面の方向を示すのがポリゴンの法線ですから、
基本的には、1ポリゴンについて、法線は1本です。

そこで、技術屋は考えました。

たとえば、ディフューズカラーの場合、
普通は1ポリゴンのディフューズの色は、マテリアルのカラーで指定された1色ですが、
テクスチャを投影することで、1ポリゴンの中に複雑な模様を表現できます。

ということは・・・テクスチャを投影してポリゴンの法線をコントロールすれば、おもしろくなるんじゃないの?

つまり、テクスチャの各ピクセルごとに法線の情報を持たせれば、1ポリゴンに複数の法線を指定できるということです。
10ピクセルx10ピクセルの100ピクセルの画像をポリゴンに投影すれば、
1ポリゴンの中で100本の法線を持たすことができるということになります。
実際には法線が何本とかは考えないと思いますが(笑)

これがノーマルマップ(法線マップ)です。

その仕組みを簡単にお話しますと、
3次元空間はXYZという、3つの要素で成り立っています。
都合のいいことに、画像フォーマットもRGBと言う3つの要素で構成されています。
これを利用して、そのピクセルが3次元空間のどの方向を向いているのか?というのを
RGB値で表現しています。

たとえば、X軸はR Y軸はG Z軸はB と割り当てて、
Rが0のときはX軸方向は-1.0
Rが255のときはX軸方向は1.0
というように、コントロールできる仕組みです。

とは言ってもノーマルマップを自分でPhotoshopなんかで描くと言うのは、おそらくないでしょう。
上記のようなことを考えながらRGBを割り出してペイントするなんで、私には無理です(笑)

ところで、ここまでノーマルマップについてお話して来ましたが、
ノーマルマップ使うと、どうなるの?と、お思いではないでしょうか?

結論から言いますと、バンプマップよりも立体感のある、擬似的な凹凸を表現できるようになります。

バンプマップもノーマルマップも擬似的に凹凸を表現する機能です。
擬似的に凹凸に見えるということは、ポリゴン内部の法線の向きが異なることで、
ハイライトが入ったり、ライトから受ける影響が違ったりするので、1ポリゴンの中でも凹凸に見えるのですね。

では、バンプマップとノーマルマップの大きな違いは・・・

○バンプマップ
  ・画像の明度(白黒画像が多い)により、
   ピクセルの高低差のみ(高いか低いかだけ)を持っているデータ。
  ・値は相対的。
   (ここのピクセルは”高さが何ミリ”なんていう絶対的なデータではないという事。)
   なのでバンプの高さ(範囲)などを、マテリアルで指定します。
   50%グレーを基準に、白がプラス方向の高さ、黒がマイナス方向高さとなります。
  ・そして、隣り合うピクセルの明度差(高低差)からそのピクセルの法線方向が
   自動で決められます。

○ノーマルマップ
  ・法線のベクトル(方向)を持つデータ。
  ・値は絶対的。

となります。

つまり、バンプマップは高低差のデータをもとにして、そのピクセルの法線の向きを求めるのに対して、
ノーマルマップははじめから法線の向きを持っているデータということです。

下の画像は、バンプマップとノーマルマップの比較です。


バンプマップは所詮256段階の諧調しかない中で、
明度から高低差をもとに法線の方向を求めているので、
ノーマルマップと同じくらいの凹凸感を持たせると、諧調飛びが起きています。


このようにノーマルマップでは、きれいに立体感のある凹凸を表現できます。
この技術は、リアルタイムレンダリングやゲームといった分野で活用されています。
軽いデータで複雑な立体感が得られて、リアルな表現ができるからですね。

ではどのように作るのかというと、”ベイク”によって作成するのが一般的だと思います。

ハイポリゴンでディティールの細かいオブジェクトを、ローポリゴンの荒いオブジェクトに
ベイクすることで、ローポリゴンでもハイポリゴン並みの表現を可能にします。

ほかの方法としては、写真やハイトマップ(バンプマップ)からノーマルマップを作成する
アプリケーションもあるようです。(CrazyBumpなど)

ここでは、modoでベイクによる作成方法をご紹介します。


プリセットから呼んできた十字架のアイテム(Gem Set Cross 01.lxl)を
平面のPlainにベイクしてみます。
PlainオブジェクトはあらかじめUVを展開してあります。

Plainオブジェクトにマテリアルを割り当てて、
新規画像を作成・追加します。


作成した画像のエフェクトを、ディフューズの色から法線に変更します。


plainを前面表示に、Gem Set Cross 01.lxlを背面表示にします。


追加した画像を右クリックし、オブジェクトからテクスチャへベイクを選択します。


すると、距離を聞いてきます。
これは、ベイクされるPlainからどのくらいの距離までをベイクするか?という指定です。
今回は、Gem Set Cross 01.lxlの高さより少し高い、5mmを指定しました。

OKを押すとレンダリングが始まり、画像にノーマルマップがベイクされます。

Gem Set Cross 01.lxlを非表示にしてみると、
Plainオブジェクトにベイクされていて、バンプでは表せない立体的な凹凸の表現ができているのが
おわかりになると思います。
回転などしてみると、ハイライトの入り方がとてもきれいで、バンプマップとは一味違います。


このベイクという作業は、Gem Set Cross 01.lxlのポリゴンの法線を、
Plainオブジェクトに転写した、という作業です。
ハイポリゴンの情報を、1枚のポリゴンに転写した、とも言えますね。
ですが、あくまでも擬似凹凸です。

ここまでが、ノーマルマップの解説なのですが、
勉強会のリプリケータの解説で、このノーマルマップを使用していたのは何か?と言いますと、
先ほどまでの解説では、法線の情報はシェーディングに使っていましたが、
レプリカの向きは頂点やポリゴンの法線方向に向く。という事なので、
法線の方向の情報を持つ、ノーマルマップをつかえばレプリカの方向も制御できる!というわけです。

たとえば、以下のようにコーンをベイクしてノーマルマップを作成して、コーンの法線を転写します。


作成したノーマルマップをサーフェイスパーティクル法線に指定すれば、
レプリカが、放射状に配置されます。


いかがでしょうか、ノーマルマップの活用。
なかなかおもしろいので、皆さんも色々試してみてください!

※ベイクしたあとは、ベイクされた画像を上書き保存するのを忘れないでください。
※べいくしただけでは、画像は保存されていないので、注意が必要です。

4 件のコメント:

  1. 先日の勉強会でのレプリケータ解説、ありがとうございました。
    ノーマルマップとベイク、どちらもなんとな〜くしかわからないし、どうやってやるのかもよくわからないし、あまり使うこともなさそうだし、と放置してましたが、こちらの記事を読んでちょっと身近になりました。ゲームグラフィクス関連の人が使うもの?とか思ってました。
    詳しい手順も載っているし、見ながら今度実際にやってみます。ありがとうございました。

    返信削除
  2. 大変参考になりました。ありがとうございます。
    これは8bitグレースケール256にカラー情報を得て、
    RGBで三倍8*3=24bitイコール
    約1670万階調あると理解してもよいのでしょうか?
    マッピングの幅が広がった気がします。

    返信削除
  3. hisakoさま

    先日の勉強会、ありがとうございました。
    ノーマルマップはゲームのみならず、映像分野でも活用されていると思います。ベクトル情報という意味合いのマップですので、擬似凹凸として使用するほかにも、ディスプレースメントとして(modoではベクターディスプレースメント)指定すれば、押し出されるポリゴンの方向をコントロールできます。ほかにもファーの生成方向もノーマルマップでコントロールできます。

    POLICEさま
    諧調として、約1670万階調ではないです。
    ノーマルマップはXYZの成分を画像ファイルのRGBチャンネルに割り当てているので、
    XYZの各方向について256階調です。
    さらに各軸の傾きを"-1.0~1.0"の範囲で表現しますので、
    傾いていない"0"は、127となります。
    したがいまして、負の方向には127段階。正の方向にも127段階です。

    なんだか諧調がなめらかじゃない気がしますが、
    これは一般的な24bit画像(各カラーチャンネルが8ビット(256段階))を指定したときのお話です。

    詳しくは解説がややこしくなるので、ふれませんでしたが・・・
    RGB値自体も実は相対的な定義でして、
    CGではRGBを浮動小数点で取り扱います。
    R=255 は R=1.0として取り扱います。

    これは何を意味しているかといいますと、
    小数点以下の段階が指定できるということですので、
    浮動小数点を扱える画像フォーマット(OpenEXRなど)を使用すれば、
    諧調は、ほぼ無限大ですよね。

    ですので、バンプマップにつきましても
    256段階の一般的なフォーマットの場合は、
    先の画像のような諧調飛びがおきてしまっていますが、
    浮動小数点の扱える画像ならば、バンプでも諧調飛びはおきません。

    少し補足でした(^^;

    返信削除
    返信
    1. ご丁寧にありがとうございます!
      スッキリしました(笑)
      概念を知る、って大切ですね。

      これ、いろいろと連動できそうな予感がしました。

      削除