この記事は 【unityプロ技】 Advent Calendar 2019 の12/3の記事です。(もともとQiitaに投稿したものでしたが、こちらに移植・加筆修正しました。)
Contents
異方性反射とは
従来のUnityでは難しかった異方性反射表現が、High-Definition Render Pipeline(HDRP)で可能になりました。異方性反射とは、ライティングの反射光を上下左右に細長く変形させるテクニックで、アニソトロピー(Anisotropy)と呼ばれます。分かりやすい例を挙げると、鍋の裏やCDといった筋の入った金属表現です。
プリレンダリングのCGソフトでは、割とメジャーなライティング表現です。しかしながら、UnityのHDRPはまだユーザーが少ないということもあって、アニソトロピー用のテクスチャ作成方法がいまいち文章化されていませんでした。そこで今回は、Unityの異方性反射についての説明も含めた、アニソトロピー用テクスチャ作成方法をより詳しく解説します。
アニソトロピーマップはただのマスク
まず初めに、インスペクタに設定できるアニソトロピーマップは、レッド(R)成分を採用するマスクマップでしかありません。変化させたい部分をRで描き、マスクしたい部分は黒で塗りつぶしましょう。ちょうどこのようなマップを描いたとすると、ライティングはこんな感じになります。
インスペクター内のスライダーで調整するスケールは、引き延ばす方向に左右します。-1でV方向、1でU方向に作用します。ワールドやローカルにおけるxyz軸には関係がありません。メッシュのUV座標を基準とします。
タンジェントマップで反射方向をコントロールする
異方性反射ライティングを行う上で重要なのは、こちらのマップです。タンジェントマップは、メッシュの接線方向を定義するために使用します。
モデルを形成するポリゴンの法線は各々一つしか持ちえませんが、ポリゴンの接線は必ず一つとは限りません。普段意識することがないのは、値を設定しないかぎり、テクスチャ座標上のU方向を接線ベクトルとして扱っているからです。タンジェントマップを使用すると、その接線ベクトルを任意に設定することができます。
では、なぜわざわざ接線ベクトルを定義する必要があるのでしょうか? それはU方向に偏りがあると、反射光を引き延ばす方向にも偏りが出るためです。簡単な例として、さきほどのメッシュを回転させてみます。その様子がこちら。
反射光が引き延ばされる角度と、引き延ばされない角度があることがわかります。サンプルはアニソトロピースケールを-1でライティングしています。(スケールが-1、つまりV方向に引き延ばしているということです。)
なぜ、反射光が全く変化しない角度が存在するのでしょうか? アニソトロピーライティングの簡単な図解を見てみます。
リアルタイムレンダリングでは、メッシュへの入射角に対してその反射角方向に映るキューブマップをライティングに加算します。キューブマップとは、上下左右前後ろの6枚をあらかじめレンダリングしておき、疑似的な反射光として利用するテクスチャの一種です。Unityではリフレクションプルーブという名前で使われます。
Unityの異方性反射では、この反射角度を回転させることで、キューブマップをずらし、あたかも反射が歪んでいるかのようにライティングしているわけです。正確にはキューブマップを動かしているのではなく、本来取るべきキューブマップのテクスチャ座標をずらしている、ということです。(上の図説は、座標軸もわかりやすく傾けていますが、法線や従法線が実際に傾いているわけではありません。)
先ほどのサンプルでは、タンジェントマップを設定せずにアニソトロピースケールを-1に設定しました。つまりV方向にずらしています。上の図説のように従法線が上向いた状態となります。ですので、従法線方向が奥行になる視点からメッシュをレンダリングすると、反射光が歪んで見えます。一方で、接線方向が奥行になる視点からでは、まったく歪みが現れません。接線が上向いているわけではないからです。逆に、アニソトロピースケールを1に設定すると、接線が上向いた状態となり、反射光がU方向にずれたライティングになります。
以上のことをまとめると、タンジェントマップの役割は、反射角度のヨーを担っているといえます。そして、インスペクターのスケール調整スライダーはロールとピッチを担っているということになります。
また、ノーマルマップとは違って、異方性反射は法線を動かしません。つまり、どの角度から見ても凹んでいるようには見せずに反射光を曲げたライティングができる、ということがアニソトロピー表現の最大の特徴になります。
タンジェントマップの作り方
では、実際にどのようにタンジェントマップを作っていくのでしょうか。
タンジェントマップでは、ベクトルxがレッド(R)成分、yがグリーン(G)成分に相当します。スクリプトを書いて正確に変換する拡張などを用意してもいいのですが、所詮はテクスチャです。それほど正確でなくても、それなりの結果になるので、楽にペイントソフト等で作ってしまうことをおすすめします。
ベクトルを書き込むツールはペイントソフトには搭載されていないので、法線軸の回転(オイラー角)を白黒のグラデーションで書き込み、のちにベクトルに変換する、という方法を使います。
黒を回転角度0、白を回転角度360として扱い、グラデーションマップで色変換を行っていましょう。 グラデーションのかけ方やグラデーションマップの適用方法は割愛しますが、グラデーションマップはgithubにて配布しますので、ご自由にお使いください(ダウンロードはこちら)。
何個かテクスチャを作ってみてわかったことですが、円形に循環するようにタンジェントを組んであげる方がルックを強力にできます。円形にすることで、必ずビュー方向に向くタンジェントが存在するようになり、反射光の拡散が常にライティングされるためです。以下のサンプルだと、左よりも右のタンジェントマップのほうが、異方性拡散を視認しやすくなります。
アニソトロピーの使用例
アニソトロピーマップというより、タンジェントマップの活用例といった方が正しいかもしれません。できるだけ効果を視認しやすいマテリアルを選びました。アニソトロピー表現を実装してみたい方の参考になれば幸いです。
パールメッキ
亜鉛メッキ
ウロコスピン
円形紋様
トライアングル
アニソトロピーマップを使う上での注意点
スムーズネスを1に設定した場合、アニソトロピーマップが無視されて完全反射になります。アニソトロピーマップを使用する際は、スムーズネスを0.99以下に設定してください。
スケールはマイナス方向に動かした方が、ルックがそれっぽくなります。経験則からすると、スムーズネスを0.7、アニソトロピースケールを-0.3にすると、一番映える気がします。
複雑なアルベドマップを作らない方が色味の変化を視認しやすくなります。色を塗る場合は単色で塗るほうが良いです。
まとめ
Unityの異方性反射ライティングは、アニソトロピーマップが難しいのではなく、タンジェントマップがややこしいです。ノーマルマップに比べると、効果が地味な部分もありますが、異方性反射にしかできない質感があります。HDRPでプロジェクトを進めるなら、一度触ってみてください。
参考文献
https://learn.foundry.com/modo/901/content/help/pages/shading_lighting/…
Anisotropic Direction
https://help.sketchfab.com/hc/en-us/articles/360020687812-Anisotropy
Anisotropy, Sketchfab Help Center
おまけ
サンプルをアセットストアに出品しました。アニソトロピー表現を詰め込んだマテリアル集となっております。手早くアニソトロピーを体験したい方は、どうぞお買い求めください。