Blenderでゲームエンジン用のノーマルマップを生成

Blenderで作られたモデルをノーマル(法線)マップとして書き出す事ができます。細かいモデルをこのようにノーマルとして書き出すことによって、効率よくUnityやUnreal Engineでレンダリングする事ができます。しかし、Blenderが内部で扱っているノーマルの形式が一般的に使われるノーマルマップの形式と違うので、変換に注意が必要です。

まず、目指すノーマルマップはこんな感じです。

出典:Wikimedia

Blenderでいくつかのオブジェクトを並べて同様なシーンを用意しておきます。(もちろん、これはチュートリアル用のシーンです。)

まず、出力フォーマットを確認しましょう。レンダーエンジンはeeveeでもCyclesでもいいです。

シーン設定で、解像度を2の累乗にします。1024、2048と4096が一般的です。

次は重要な設定があります。Blenderの標準設定で、色を「綺麗」に出力するようになっています。これでレンダリングの写実性がぐんとあがりますが、今回はその調整が邪魔です。

シーン設定の一番したにある「カレーマネジメント」で「ビュー変換」を「Raw」に変えます。

次は、ノーマル情報をレンダリングした時に書き出してもらうように設定します。

カメラはある程度自由ですが、平行投影のカメラで真正面から見るようにしておきます。

キーパッドの0でカメラ目線でシーンを見て、カメラ平行投影スケールパラメータを調整して、すべてのオブジェクトが映るようにします。

これで、準備ができたのでレンダリング(F12)を行います。レンダリングが完了したら、「Compositing」タブに移動します。

最初は何もないですが、「ノードを使用」にチェックを入れると、コンポジット用のノードが表示されます。

ここで書き出される画像を処理することができます。結果を見るために、下の領域に「画像エディタ」を表示します。

表示する画像を「Render Result」にします。

今はなにもせずに、レンダリングされた画像を書き出しますが、代わりにノーマルをコンポジットノードの「画像」入力に接続するとこうなります。

予想していた色と違いますね。ノーマルマップは法線ベクトルを画像のRGBで記録します。法線ベクトルのx、y、z値は必ず-1から1までに収まります。RGB画像はマイナス値がないので、-1を0%にして、1を100%にして記録します。

(R: 50%, G: 100%, B: 50%)
(R: 100%, G: 50%, B: 50%)
(R: 50%, G: 0%, B: 50%)
(R: 0%, G: 50%, B: 50%)
(R: 50%, G: 50%, B: 100%)

しかし、Blenderではこうなります。

(R: 0, G: 0, B: 1)
(R: 1, G: 0, B: 0)
(R: 0, G: 0, B: -1)
(R: -1, G: 0, B: 0)
(R: 0, G: -1, B: 0)

Blenderでは、上下方向がz値(つまり、青チャンネル)で、前後がy値(緑チャンネル)ですが、標準のノーマルマップでは、上下がyで、前後がzになります。

さらに、Blenderでは、「前」方向がマイナスですが、標準のノーマルマップはプラス方向になります。

では、変換するので、shift+Aで新しいノードを追加します。必要なのはこれです:

  • RGBA分離
  • RGBA合成
  • 数式

いずれも、コンバーターカテゴリーにあります。数式ノードは「積和算」にします。

この積和算が3つ必要ですので、shift+Dで複製します。RGBA分離ノードのRGB出力をそれぞれの積和算ノードの「値」入力に繋ぎます。出力はGとBが逆なのでそういう風にRGBA合成に接続します。

でが、3つの積和算の値を以下の通りに設定します。

基本的に「Multiplier」も「Addend」も「0.5」にしますが、入力のGは「-0.5」にかけます。

入出力ノードに繋いで、全体がこうなります。

コンポジット結果は正しそうです。

画像を保存します。

Unityのマテリアルで試しに使ってみると大丈夫です。

Leave a Reply

Your email address will not be published. Required fields are marked *

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください