Unity
Shader
ShaderLab
shaderforge

ShaderForge 上で独自に環境マップを得て IBL を行う

追記

 本記事の手法は Skybox 画像の取得に限る。Scene の Environment Lighting の設定を反映させるのであれば、以下の記事のコードを Code ノードに記述して環境光を取得した方が良い。

https://qiita.com/Santarh/items/0f0980564b53de6e9797

要旨

 ShaderForge はシェーダを構築する上でイテレーション速度を上げることができる非常に重要なツールだ。しかしデフォルトで用意されている Blinn-PhongPBL ライティングを逸脱する場合に作りづらい機能が多く存在する。この記事ではそのひとつである IBL の取得を例に挙げ、PBL ライティングの Specular 項を使わずに IBL を実現する。

環境

  • Unity 2017.2.0f3
  • ShaderForge v1.38

ShaderForge の PBL ライティングにおける IBL (Image based lighting)

 IBL 、つまり金属のような周辺環境の映り込みを実現するライティングを行うには ShaderForge の用意する PBR ライティングを用いて Specular 項を制御すれば良い。この例を図 1 に示す。プレビュー画像の通り Unity の Default-Skybox が表面に映り込んでいることが分かる。
 しかし ShaderForge の PBL ライティングは Unity の Standard Shader のライティング計算マクロに基づいており、また、ノードも無いため IBL の取得は完全に隠蔽され、IBL を独自のライティングに反映させることができない。

図 1
図 1: ShaderForge デフォルトの PBL ライティングを用いて IBL を反映させる例. 残念ながら IBL は内部に隠蔽されている.

Unity の環境マップ取得マクロを用いた IBL

 Unity では Vertex and fragment shader examples の Environment reflection using world-space normals 節で示されている通り、環境マップと法線ベクトルを入力に UNITY_SAMPLE_TEXCUBE をマクロを用いることで環境光を取得することができる。幸い環境マップは Global なプロパティであるし、法線ベクトルもノードで取得できるため Code ノードを用いることで容易に実現可能だ。この例を図 2 に示す。

図 2
図 2: Code ノードに IBL 取得マクロを記述することで、環境光をそのまま表示する例.

環境マップのボケ具合を加味する

 前節で挙げたシェーダはひとつ気になる点が見える。それは環境マップがあまりにもくっきりはっきりと映り込んでいることだ。できれば図 1 の Glossiness プロパティのようなボケ方を制御するパラメータが欲しい。
 Unity の環境マップは LOD を利用して、何段階かにボカした環境マップを取得することができる。そのボケの段階数は UnityStandardConfig.cgincUNITY_SPECCUBE_LOD_STEPS として定義されているので利用する。実装を図 3 に示す。

図 3
図 3: LOD を利用してボカした環境マップを取得、適用した例.

さいごに

 これで綺麗に IBL を取得したと言えるだろう。環境の映り込みは現代的なレンダリングに欠かせない要素のひとつであるため、さまざまな応用範囲が考えられる。正直 ShaderForge にノードとして実装して欲しいが、Forum を見る限り、Unity のあやふやな仕様には追従する気はあまりないらしい。