standard_surfaceのSSS

さて、一回目はstandard_surfaceのSSSの使い方についてお話しします。

この機能はアランさんが考えた“BSSRDF Importance Sampling”という手法を使用しています。

昔はSSSを計算するのにポイント・クラウドと呼ばれる、明るさの情報を持ったたくさんの点を物体表面に付着させ、シェーディング・ポイント(今見ている点の意味、今後よく出てきますので覚えてください)の周りの点をもとにSSSの計算を行っていました。

これはきちんと動作しますが、いくつポイントを使えばいいのかわからない、メモリをたくさん使ってしまう、また変形する物体があれば、毎回ポイント・クラウドを作り直さなければいけないなど色々な問題がありました。一方アランさんの手法ではこれらの問題が解決されています。

※ただし、あくまで近似であり、本当に光が物体の中を散乱して進む(ブルート・フォースまたは力技といわれることがある)のを再現しているわけではありません。今後はこのより正確な手法に移っていくと思われます。

soft_shadow
半影の計算では、ライトの位置をランダムに動かし、シェーディング・ポイント(青い点)からライトに届くレイを数えます。ここでは3本中1本が遮蔽されているので明るさは2/3になります。(左) ライトの位置を固定したまま、シェーディング・ポイントをランダムに動かすとSSSの近似計算ができます(右)

乱暴に言ってしまうと、シェーディング・ポイントをランダムに少しだけずらすことによって、光のにじみを再現しています。

sss_setting
SSSの設定項目

standard_surfaceではその光がにじむ範囲をRGB型のRadiusとScaleで調整します。Arnold内部で実際に使用される半径はこのRGBのRadiusとScaleを掛け算したものになります。Radius(半径)という名前がついていますが、半径というのは大体この範囲で広がる、という意味で厳密にこの範囲内でしか広がらない、ということではありません。

またR,G,Bはそれぞれ、皮膚の深くまで、中程度まで、浅い部分まで、入る光の半径に対応しているわけではありません。もちろん皮膚ですと青や緑の光は吸収されやすいので、Rが深くまで届く光と考えてもらっても問題はないですが、あくまで、R,G,Bそれぞれの色の広がる範囲を意味しています。

設定の仕方で問題になるのは、その半径の値です。これが大きすぎると不自然な青緑の肌になってしまうことがあります。

どうしてでしょうか?

graph
シェーディング・ポイントは真ん中であると思ってください

RadiusのRが大きかったとしましょう。赤い光は非常に広い範囲に広がります。本来、光が届かなかった場所まで光が届くので、全体のエネルギーの量が保たれるには、それ以外の場所で赤色が弱くなってしまうのです。一方、緑と青はあまり広がりません。つまり、シェーディング・ポイントでは赤に比べ、緑と青が強い、といったことになってしまうのです。

カラーなど他の設定値とは違い、Radiusはレンダリングしている物体の大きさに依存するパラメータになります。

例えば、人の頭をレンダリングしている場合、モデリングがメートル[m]でされていると、0.005(5mmに相当)などといった非常に小さな値を使う必要があります。もしモデルがセンチメートル[cm]で作られていると、0.5(同じく5mmに相当)といった値を使用することになります。ですので、うまくいかない場合は単位をチェックしてください。

Mayaの場合、Render Setting->DiagnosticsでLogのVerbosity LevelをWarnings+InfoにしておくとArnoldがレンダリングしているシーンのサイズが分かります。Output Windowに次のように表示されますので設定値が妥当か見比べてみてください。

scene bounds: (-1.00000024 -0.5 -1.00000012) -> (0.951057136 1.64253187 1.16086376)

Scaleと掛け算されたものが実際の半径になりますから、Radiusは赤やオレンジの色を指定し、Scaleに小さい値を入力するのが楽でよいでしょう。

Colorには肌の色を指定します。簡単ですね。