Remember Me の物理ベースレンダリング (GDC Europe 2013)の説明
概要
参考文献
- Remember Me のアートとグラフィックス GDC Europe 2013
物理ベースレンダリングの利点(hanecciの個人的な意見)
今回のゲームの物理ベースレンダリングの特徴は ?
- あらゆる場面でフレネルが考慮されます.
- スペキュラのハイライトのエネルギー保存則があります.
- 具体的にはスペキュラのハイライトの大きさと輝度が関連していて, ハイライトの大きさが大きくなると, 輝度が低くなります.
- 一方でディフューズ反射とスペキュラ反射の両方を考慮したエネルギー保存則は, Remember Me では扱っていないとのことです.
Remember Me のシェーディングモデル
- まずは, いつものレンダリング方程式です.
- 次に「直接光によるライティングでのシェーディング」をどうするか?についてです.
- よく行われるように BRDF である f(l,v) を, ディフューズ反射用の BRDF とスペキュラ反射用の BRDF に分離します.
- ディフューズ反射用の BRDF はいつもの完全ランバート反射です.
- スペキュラ反射用の BRDF は正規化 Blinn-Phong です.
- そして, 「間接光によるライティングのシェーディング」をどうするか ? についてです.
- 「間接光によるライティングのシェーディング」 = 「ディフューズ間接光によるシェーディング」 + 「スペキュラ間接光によるシェーディング」 に分けます.
ディフューズ間接光によるシェーディング
- Remember Me では動的な環境変化がないので, ディフューズ間接光の計算に静的な焼付けが利用できます.
- 地形にはライトマップ(Directional LightMap, 別名 Radiosity Normal Map)を利用しています.
- キャラクターにはライトプローブを利用しています.
- 今回使うライトマップやライトプローブはどの方向からどれだけのライティングが入射したか ? の情報を持っているので, 法線マップを後から適用することができます.
- Remember Me は Unreal Engine 3 を使って開発されているので, LightMass を使ってライトマップやライトプローブを焼き付けているのだと思います.
参照 URL
- Unreal Engine 3 LightMass
- Half Life2 : Valve の Radiosity Normal Map の資料
スペキュラ間接光
- スペキュラ間接光については事前計算するにもそのまま計算するには複雑なので, フレネルの部分は一定だと近似して積分∫の外に出します.
- そして, フレネルの部分 F_glossy (後述) については GPU で計算し, 残りの半球方向から入射する光(環境マップ)とスペキュラシェーディングの乗算の半球積分については環境キューブマップとして事前計算しておきます.
- 似たような方法で, スペキュラ間接光を近似計算する手法は”Unreal Engine4 のリアルシェーディング”の説明 - OLD hanecci’s blog : 旧 はねっちブログ でも行われていました.
- 上図の右側の積分の部分に相当する環境キューブマップ側の処理については Remember Me でのスペキュラシェーディングの計算式を使い, スペキュラ用のスムースネスが滑らか->粗いものごとにキューブマップに対してフィルタリングして, ミップマップレベルの低い->高い順に書き込んでおきます.
- 事前計算には Modified CubeMap Gen というオープンソースのツールを利用します.
- フレネルの計算部分についてはグロッシーなフレネル F_glossy と呼んでいて, (通常の視線ベクトルと法線の角度に依存した)フレネル反射率だけでなく, マテリアルの粗さによっても結果が変わるものになっています.
- 但し近似計算で, また計算が軽く見た目的にもそこそこ良いものを使っています.
- 下がスペキュラ直接光を計算するコードと, スペキュラ間接光を計算するコードです.
エリアライト
- Remember Me では従来のような面積がないゲーム用のライト(ポイントライトなど)をエリアライトとして扱うために, CEDEC 2011 で tri-Ace が発表したスペキュラのハックを利用していました.
- 具体的には, ポイントライトのサイズやライトと物体間の距離に応じて, スペキュラのシャイニネスを修正することで, 面積を持ったエリアライトっぽく見せる方法です.
- 下は CEDEC 2011 の tri-Ace の資料のスライドを貼り付けたものです.
- 下はポイントライトをエリアライトとして扱う際のシェーダコードです.
- そういえば, SIGGRAPH 2012 で Epic Games が同様の手法として "Specular D modification" (参照:”Unreal Engine4 のリアルシェーディング”の説明 - OLD hanecci’s blog : 旧 はねっちブログ )という手法を使っていました.
濡れた面への対応
- 雨で濡れた面の表現に対してどう対応したかについてです.
- 従来どおりの手法だと, ディフューズを暗くしてスペキュラを強めにするという方法があります.
- 実際に雨による天候変化に対して濡れたマテリアルをそれっぽく見せる手法については Assasin's Creed 3 (GDC2013)や Tomb Raider2013 (GDC2013)でも行われていました.
- しかし, 実際の現実世界ではディフューズが暗くなり, スペキュラが明るくなるだけでなく色相や彩度も変化しています.
- また全ての面が濡れたことでそのように変化するのではなく, 浸透性(porous)があるマテリアルだけそのように変化します.
- 但し, 上の方法を実際にシェーディングモデルとしてそのまま導入するには複雑すぎます.
- 従って, Remember Me ではシェーダーによってテクスチャを調整するアプローチを最初に取ろうとしました.
- 具体的には表面が粗くて非金属な表面は浸透性があると仮定して, 濡れた際にシェーディングの変化が起きるようにシェーダー内でテクスチャを調整していました.
- シェーダー内でのテクスチャの調整についてはディフューズアルベドを減衰させ, スペキュラの滑らかさを上げてハイライトが鋭くなるようにしています. 一方で, スペキュラリフレクタンスについては変化させていないです.
- 下が今回の Remember Me で使われたマテリアルが濡れているように見せるためのシェーダーコードです. (後述するように実際のゲームには使われていないです. )
- 上記のように, シェーダー内でマテリアルのテクスチャを調整することで濡れた表面のように見せることができました.
- ですが, 結局 Remember Me では雨が降る前から後へと遷移するシーンがなく, またシェーダーの処理の最適化のために上記のシェーダーをゲーム内では利用しませんでした.
- その代わりに, アーティストが濡れたマテリアルに見せるためのテクスチャを事前に用意して利用したそうです.
Remember Me のテクスチャ作成について
- Remember Me ではアートワークの素材がどういうマテリアルであるか? を実作業のチームに伝えるために, アルベドのリファレンスの値やマテリアルを言葉で明確に定義して実作業のチームに伝えていました.
- Remember Me で直接光を元にディフューズシェーディングやスペキュラシェーディングを計算する際に, 数式と各項目に対応するテクスチャは以下のようになります.
ディフューズアルベドテクスチャの作成のガイドライン
- ディフューズアルベドテクスチャの作成についてです.
- テクスチャにはライティングの情報を書き込まないようにします.
- しかし, マイクロオクルージョン(Cavity?)についてはランタイムのシェーダーで計算しないので, Remember Me ではディフューズアルベドテクスチャに書き込むことを行っています.
- ディフューズアルベドテクスチャについてはアーティストが過度に暗くし過ぎてしまうということがよくあります.
- そこで, ディフューズアルベドテクスチャ用のリファレンスチャートをテクスチャ作成のガイドラインを作っていました.
- ディフューズアルベドテクスチャについては sRGB で値は 32-243 にしておきます.
- 32 は最も暗い炭で, 243 は新雪で, 純粋な金属にはディフューズアルベドテクスチャを使わないようにしていました.
- あと, 現実世界で撮影した写真の素材を取り込んで, ディフューズアルベドテクスチャとして利用する際にはカラーチェッカーパスポートによるカラー補正などを行います.
スペキュラリフレクタンスのテクスチャの作成のガイドライン
- スペキュラリフレクタンスについてで, これには実際には物質の屈折率に基づいた物理的な値が設定されます.
- このスペキュラリフレクタンスについては正確な言葉で言うと, 空気から他の物体に対して光が面に対して真上から垂直に入射するときのフレネル反射率 F(0°)となります. ( 参照: フレネル反射率について - OLD hanecci’s blog : 旧 はねっちブログ
- そして, この値が視線ベクトルと法線ベクトル間の角度によって, 強くなったりします.
- 金属のスペキュラリフレクタンスF(0°)は高い値(0.8-1.0)でしかも RGB です.
- 一方で非金属については低めの値(0.0-0.25)かつグレースケールの値です.
- スペキュラリフレクタンス用のリファレンスチャートが用意されていました.
- 非金属については sRGB で 43-65 の値でデフォルト値は 59 です.
- 金属については sRGB で 186-255 の値で, この値は金属の種類によってほぼ一意に決まります.
スムースネス(ラフネス)テクスチャの作成のガイドライン
- スムースネスのテクスチャはスペキュラのハイライトのぼけ具合を調整します.
- 値が 0 のときは表面が粗いのでスペキュラのハイライトが拡散してぼけ, 値が 255 のときは 表面が非常に滑らかでスペキュラのハイライトがシャープになるようにしていました.
- またここでアーティストが直感的にわかりやすいように, 白(255)を滑らかな面となるようにしていました.
- 下図がスムースネスのリファレンスチャート(グレースケール)です.
- リファレンスチャートには表現したい物体の表面の粗さに応じて, どのぐらいの値にしたらいいかがわかるようになっています.
- この値は実際にシェーダーで渡されて, その中でハイライトのぼけ具合が計算されるようになっています.