表皮での反射はBRDFで実装

まずはその表皮で反射する6%の光について考える。

表皮での反射は、リアルタイム3Dグラフィックスでは、フォン(Phong)シェーディングやブリン(Bling)シェーディングといった反射方程式を用いるのが一般的だ。

ただし、「これは人肌の表現には適さない」とNVIDIA デベロッパ・テクノロジ・エンジニアのBryan Dudash氏はいう。

皮膚面を掠めるような角度で見た場合のハイライトの出方の強さがブリンやフォンでは実物とはかけ離れているというのだ。

これを正しくリアルにシェーディングするためには別な方法を模索する必要があるとNVIDIAは判断したようだ。

まずは鏡面反射について考える

PhongとKD BRDFの比較。上段はそれほどの差はない。しかし、下段の、視線が掠めるような面に出るハイライトの出方が明らかに違う。KS BRDFの方が全然リアルだ

そこで彼らが選択したのはCsaba Kelemen、Laszlo Szirmay-Kalosらが2001年に発表した「A Microfacet Based Coupled Specular-Matte BRDF Model with Importance Sampling」の論文ベースのKS BRDF法だ。KSはKelemenとSzirmay-Kalosの頭文字、BRDFはBidirectional Reflectance Distribution Functionの略で日本語訳では双方向反射率分布関数で、光がどう反射するかを、物理現象、光学現象に沿った考え方で一般化したものだ。どう反射するか……、を1つの方程式で表すことが困難な場合は、測定器を使って測定しデータテーブル(テクスチャデータ)を作成し、これをレンダリング時に参照して陰影計算に用いる方法がよくみられる。

KS BRDFで配慮されるパラメータ群と動作条件

NVIDIAが今回実装した鏡面反射のBRDFは調微細な凹凸を表面にもつ材質の表現に適したベックマン分布(Beckmann Distribution)で、計算負荷低減のためにベックマン分布を事前計算してテクスチャデータに落とし込んでいる。

この他、今回の実装では、皮膚の表面の陰影計算に用いるパラメータとして、法線ベクトルN、視線ベクトルV、光源ベクトルLという一般的なものの他にrho_s、粗さm(Roughness)、屈折率etaに配慮する。rho_sとはハイライトの強さの重みを表すパラメータ、粗さは皮膚の超微細凹凸の傾きパラメータ、屈折率はフレネル反射の計算に用いる。

rho_sとmは「Analysis of Human Faces using a Measurement-Based Skin Reflectance Model」(Tim Weyrich,SIGGRAPH 2006)などの研究で149人の様々な肌の色、年齢について顔の10個のエリアについての測定した情報を参考に設定するとよいとのことだが、NVIDIAの実装では平均的な値としてm=0.3,rho_s=0.18を設定したとしている。

フレネル反射にも配慮

左が教科書通りに実装したフレネル反射。右が今回の実装で採用した簡易式フレネル反射。大きな違いはないと判断できる

フレネル反射というと水面や車のボディなどの表現を思い出す人も多いだろう。水面で言えば、「映り込みと水底の度合いを調整するもの」というイメージがあると思う。一般的には入射した光が視線に対してどういう角度の時にどれだけ反射するか/屈折するかを表すものになる。人の顔でも光と視線の角度関係によってハイライトの出方が異なるのでこれに配慮しようというわけだ。この計算には屈折率etaが大きく関わってくるうえに、実際の人間の顔では人によって部位によっても異なるとされる。NVIDIAの実装では全体の平均とされるeta=1.4を使用したとしている。

rho_m,m,etaといったパラメータは実在の人物を測定するのが理想だが、実際はそれも難しいので、NVIDIA実装例のように平均値を用いるか、あるいは実測データを参考にしてアーティストが手描きで作成するのもよい、とした。

また、算出したハイライトの色は、顔の画像テクスチャの色に配慮する必要はなく光源色そのまま(白色光ならば白色)でよい。

粗さのパラメータmは実測データの平均値0.3を採用

こうしたパラメータを実測データから採取したテクスチャを用いたり、経験を元にアーティストが手描きで描いてもよいかもしれない。NVIDIA実装例では平均値やアーティストの感覚などで設定した定数を採用

左が一定の粗さm=0.3の結果。右が実測データによる結果。大きな差はないと判断

ハイライトは光源色でOK。テクスチャ色は無視してOK