大きく内容が間違っているようです。そのうちに書き直しますので、内容を参考にしないように宜しくお願いします。
物理ベースレンダリング(PBR)とは
PBRの説明はいろいろなサイトで結構幅があります。それらを読んで僕はこう解釈しました。
- BRDFがエネルギー保存をちゃんとしてる手法を採用している
- 出力される色はリニアである。
出力される色がリニアである?
ここは他サイトに説明を任せようと思います。僕はCygames Engineers' Blog 物理ベースレンダリング -リニアワークフロー編 (1)-が分かりやすかったです。色管理を人間の目の見え方じゃなくて、輝度で管理しましょう。って話ぽいです。
BRDF(双方向反射率分布関数)?
反射表面上のある地点 x に対して、ある方向から光が入射したとき、それぞれの方向へ,どれだけの光が反射されるかを表す、反射地点に固有の関数。非常に大雑把な言い方をすれば、反射率を一般化したものと言える。
双方向反射率分布関数 wikipediaより引用
wikipediaにもある通り、入射した光のうちどれだけ光が反射されるか?を表現する関数です。
何なら、そのまま光を200%反射する変なBRDFを作ってもいいわけです。しかしそれではリアルなCGを表現できません。フォトリアルなCGを表現するために、様々な材質をうまく説明できるBRDFが開発されてきました。それがランバートや、フォンなどのモデルです。
今までの説明のなかで、BRDFとやらはどこで出てきていたのでしょうか?diffuse(ランバートのモデルの場合)やspecular(フォンのモデルの場合)の式を思い出してみましょう。
R_{diffuse}(p) = K_{diffuse}(p) * max(dot(\vec{n},\vec{l}),0) * L(p)\\
R_{specular}(p,\vec{v}) = K_{specular}(p) * dot(\vec{r},\vec{v})^s * L(p)\\
これらの式は以下のように言えます。
R_{目に入る輝度} = BRDF関数 * 地点pに入射する光
diffuse(ランバートのモデルの場合)やspecular(フォンのモデルの場合)のBRDFは以下の様に言えます。
BRDF_{diffuse}(p、\vec{v}、\vec{l}) = K_{diffuse}(p) * max(dot(\vec{n},\vec{l}),0)\\
BRDF_{specular}(p、\vec{v}、\vec{l}) = K_{specular}(p) * dot(\vec{r},\vec{v})^s\\
(\vec{n}や\vec{r}は、p、\vec{v}、\vec{l}から求められる)
エネルギー保存?
ランバートのモデルに注目してみます。ライトが入射したときにどれくらい反射するでしょうか?
ここで半球を想定してみます。あくまで1地点に過ぎなかった視点vですが、ランバート反射は半球全地点に対して等しく反射するのでした。半球全部に反射する光の量を求めてみましょう。
断念した!積分とかわかんないw。だれか数学押してください涙。
詳しい説明は
正規化Lambert by project-asura
をご覧ください。
ここで言いたいのは、見た目だけを考えた式では、「入射光エネルギ < 反射光エネルギー」になってしまうケースがあるということです。ここを「入射光エネルギ => 反射光エネルギー」になるように変更したBRDFを採用することが、物理ベースレンダリングです。
また今まで別々に考えてきたdiffuseとspecularですが、この二つはもとは同じ光を反射しています。ということはこの2つの合計も、入射光エネルギーを超えてはいけないということです。非常にわかりやすい図がUnityのマニュアルにあるので引用します。
拡散反射が強い上の画像より、鏡面反射が強い下の画像のほうが、球体が暗く見えます。鏡面反射にエネルギーが使われているためです。
なんだか説明の雲行きがあやしくなってきました。もともと僕には荷が重かったのは重々承知していましたが、、w。大筋を把握するだけでも良しとしようw
この次は、specularで説明したフォンのモデルではない、別のモデルの説明をしようと思います。