今回の記事は、UE4 の仕様に関する終始技術的なディスカッションの第一弾となります。
こちらは、UE4 で使用されているシェーディング モデルについて、以前お話させていただいた Real Shading in Unreal Engine 4 という講義の続きとなっています。読者の方がこの講義ノート (course notes) をすでに読まれている事を前提にしている事をご留意ください。
前述のプレゼンテーションを行ってから、いくつか小さな変更点がありました。まず Disney によるジオメトリ タームに対する「hotness」修正点を削除しました。Eric Heitz 氏の最近の成果を元に、 シャドウイングとマスキング間に相互性を加えるための改良を今後行う可能性があります。また「Cavity」パラメータは結局実装には至りませんでした。こちらの変更はプレゼンテーション直前に行う予定でしたが、調整可能な誘電性鏡面反射率を利用する事になりました。代わりに Disney のモデルで定義されている「Specular」パラメータを使用しています。
今回はこのシェーディング モデルがどのようにモバイル プラットフォームに適応されたのか、という点について詳しくお話いたします。UE4 のモバイル レンダラーに関する大変分かりやすい概要については、GDC からのこちらのスライドをご覧ください。その応用実例としては、iPad Air 上で 4xMSAA を 1080p @ 30hz で実行していた「Zen」技術デモ、または「Soul」技術デモをご覧ください。
そもそもあった1つの大きな目的が、ハイエンド PC 環境と同じコンテンツの作成ワークフローを構築する事でした。またモバイル デバイスで実行しても出来るだけハイエンド レンダラーと似たものになるように、同じアセットをレンダリング可能にする事も目的でした。つまりガンマを正しくかけるなどの様々な細かい点に加え、マテリアルが PC、据え置き機、モバイルの各環境でも同じように描画されるようシェーディングを調整する必要がありました。これを実現するには、私が以前に説明した同じマテリアル モデルを使用します。「BaseColor」、「Metallic」、「Specular」、「 Roughness」のパラメータはすべて全く同様に動作します。
当然の事ながら、モバイル デバイスに搭載されている演算能力は比較的に低く、各ライティングの BRDF (双方向反射率分布関数) をすべて評価する事は不可能です。実際、動的に計算される指向性の太陽光のみがサポートされています。シャドウは事前計算されており、符号付き距離場 (signed distance field) としてテクスチャ スペース内に保存されています。その他のライティングはライトマップとしてベイクされています。尚、ライトマップにはハイエンド環境と似た HDR エンコードされた SH (球面調和) の指 向性表現が採用されていますが、これは相関性の無い別途のアルファチャンネル圧縮を使わない、より効果的な「PVRTC 圧縮」を使用するよう調整されています。また事前計算されたスペキュラには、ハイエンド環境と同じく事前コンボリューション (畳み込み演算) を行った環境マップが使用されています。これと全く同一の事前コンボリューションが使用されており、また同じようにライトマップによって標準化・スケーリングされています。モバイルにおいては、1 ピクセル毎に取得される環境マップは 1 つのみとなります。
環境 BRDF
ここで面白いのが、ハイエンドではモンテカルロ積分を使って事前計算を行い、2D LUT 内に保存される「環境 BRDF」の計算方法です。ただし依存テキスチャの取得は一部のモバイル ハードウェアにとって非常に厳しいものであり、また OpenGL ES2 の非常に制限のきつい「最大サンプラー数 8 基」という上限がさらなる問題となります。この LUT でサンプラーを使いつぶすというのは手法としては問題外であり、その代替としてDimitar Lazarov 氏の成果を元にした近似解析版を作成する事にしました。形態はほぼ変わりませんが、私達のシェーディング モデルおよび「roughness (ラフネス)」パラメータに適合するように調整されています。この関数は次の通りとなります:
half3 EnvBRDFApprox( half3 SpecularColor, half Roughness, half NoV )
{
const half4 c0 = { -1, -0.0275, -0.572, 0.022 };
const half4 c1 = { 1, 0.0425, 1.04, -0.04 };
half4 r = Roughness * c0 + c1;
half a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
half2 AB = half2( -1.04, 1.04 ) * a004 + r.zw;
return SpecularColor * AB.x + AB.y;
}
以上はイメージ ベース ライティング (IBL) において、妥当なフレネルおよびラフネスの性質を得られる事を意味しています。
ハイエンドで使用する「EnvBRDF」
モバイルで使用する「EnvBRDFApprox」
「Metallic」および「Specular」のマテリアル出力がつながっていない (つまりデフォルトが使用されている) 場合に検知されます。これは一般的な非金属的表面などの場合に発生します。そこで、この関数をさらに最適化する事ができます。
half EnvBRDFApproxNonmetal( half Roughness, half NoV )
{
// Same as EnvBRDFApprox( 0.04, Roughness, NoV )
const half2 c0 = { -1, -0.0275 };
const half2 c1 = { 1, 0.0425 };
half2 r = Roughness * c0 + c1;
return min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
}
また同様の最適化を行い、環境マップの使用そのものを回避する事も可能です。一部のゲームでは鏡面表現無しを前提に最適化していますが、これはリソースの節約には繋がりません。その代わりとして、Roughness=1 に設定し、不変要素を最適化する「完全なラフネス」フラグが設定されています。まず、次のようになっている事が分かります:
EnvBRDFApprox( SpecularColor, 1, 1 ) == SpecularColor * 0.4524 - 0.0024
ここからさらに単純化を行います:
DiffuseColor += SpecularColor * 0.45;
SpecularColor = 0;
このフラグは、さらなるパフォーマンスがどうしても必要となるオブジェクトに対してのみ使用されます。
指向性のライティング
最後に触れておきたいのが、太陽光の演算方法についてです。先程、太陽は唯一動的に計算されている光源であると申し上げましたが、残念ながら完全なハイエンド シェーディング モデルを 1 つ扱うだけでも重過ぎてしまいます。しかしその一部はすでに EnvBRDF を使って、事前統合された近似的な形態として計算されており、また環境マップのサンプリングに使用した反射ベクトルも分かっているはずです。ここで重要となるのが、環境マップの事前フィルタリングに使用される放射相称型ローブ (lobe) の解析的な評価を行い、そして IBL と同じ様にその結果に EnvBRDF 値を掛けるという考えです。これは環境マップのように数値的に統合するのではなく、入ってくる光の方向に対してローブを解析的に統合する、という考え方になります。
まずは GGX NDF をブリン (Blinn) と入れ替えます。次に放射相称型のフォン (Phong) ローブを使ってブリンを近似します。
$$ \newcommand{\nv}{\mathbf{n}} \newcommand{\lv}{\mathbf{l}} \newcommand{\vv}{\mathbf{v}} \newcommand{\hv}{\mathbf{h}} \newcommand{\mv}{\mathbf{m}} \newcommand{\rv}{\mathbf{r}} \newcommand{\ndotl}{\nv\cdot\lv} \newcommand{\ndotv}{\nv\cdot\vv} \newcommand{\ndoth}{\nv\cdot\hv} \newcommand{\ndotm}{\nv\cdot\mv} \newcommand{\vdoth}{\vv\cdot\hv} D_{Blinn}(\hv) = \frac{1}{ \pi \alpha^2 } (\ndoth)^{ \left( \frac{2}{ \alpha^2 } - 2 \right) } \approx \frac{1}{ \pi \alpha^2 } (\rv\cdot\lv)^{ \left( \frac{1}{ 2 \alpha^2 } - \frac{1}{2} \right) } $$
ここに $\rv$ は反射方向 $\rv = 2(\ndotv)\nv - \vv$ となります。
さらに球面ガウス関数 (Spherical Gaussian) によってフォンを近似します:
以上によって、次の最適化された形態に行き着きます:
half D_Approx( half Roughness, half RoL )
{
half a = Roughness * Roughness;
half a2 = a * a;
float rcp_a2 = rcp(a2);
// 0.5 / ln(2), 0.275 / ln(2)
half c = 0.72134752 * rcp_a2 + 0.39674113;
return rcp_a2 * exp2( c * RoL - c );
}
ここで $\frac{1}{\pi}$ は光の色として考慮されます。
最終的には、非常にコストの低いながらも妥当なシェーディング モデルを作り出す事ができました。このモデルはスペキュラはリソースを節約し、かすめ角に対しては適当な挙動を見せ、また解析・イメージ ベースのどちらの光源にも対応しています。最早、モバイル ハードウェアも物理ベースを導入しないための言い訳にはならなくなってしまいました。
Epic Games, Inc. は、帰属に関する要件なく、本記事内のコードを自由に利用・変更・頒布する事を許可いたします。