ラフネス
Roughness別名:粗さ
概要
表面の目に見えないほど細かな凹凸の度合いを、0〜1 で表すマテリアルの値。0 に近いほど映り込みがくっきりし、1 に近いほど光が四方に散って、ハイライトが広くぼやける。
デモ
使われる場面
物理ベースのマテリアル設定
金属か非金属か(メタリック)と並んで、質感を決める基本の値である。磨いた床、濡れた路面、ゴム、布の違いの多くはラフネスで作る。
ラフネスマップ
場所ごとにラフネスを変える白黒のテクスチャ。指紋、水たまり、擦れて磨かれた角のような、使い込まれた跡の表現に使う。
素材の描き分け
同じ色のままラフネスだけを変えると、プラスチック、塗装、陶器のような別の素材に見せられる。
判断基準
| こういうとき | こうする |
|---|---|
| 鏡、磨いた金属、濡れた表面のように、周りがはっきり映り込む | 0〜0.2 程度の低い値にする。 |
| 塗装、プラスチック、革のように、ぼんやりしたツヤがある | 0.3〜0.6 程度の中間の値にする。 |
| 布、素焼きの陶器、コンクリートのように、ツヤがほとんどない | 0.7〜1 程度の高い値にする。 |
| 表面全体が同じ値で、のっぺりして作り物に見える | ラフネスマップで場所ごとにわずかな変化を付ける。色の変化より、使い込まれた感じが出やすい。 |
| 光沢度(グロス)で値が書かれた素材データを使う | 光沢度はラフネスの逆なので、1 から引いて変換する。 |
こう見えたら
指示の例
床がつるつるしすぎて、鏡のように周りを映している。ラフネスを 0.4 くらいまで上げて、映り込みをぼかして
磨いた金属のはずなのに、つやがぼやけている。ラフネスを 0.1〜0.2 くらいに下げて
壁全体が同じつやで、のっぺりしている。ラフネスマップで、場所ごとにつやを少し変えて
布やコンクリートにつやがありすぎる。ラフネスを 0.8 以上にして
詳細
細かな凹凸が反射の向きを散らす
光沢のある表面も、拡大すると向きのそろわない微小な面の集まりとして扱える。この微小な面をマイクロファセットと呼び、その向きのばらつき具合を 0〜1 で表したものがラフネスである。ラフネスが低いと微小な面の向きがそろい、光は一つの方向へ反射するので、映り込みがくっきりする。ラフネスが高いと向きがばらつき、反射する方向が散らばるので、映り込みはぼやけ、ハイライトは広がる。
反射する光の総量は、ラフネスでは変わらない。同じ量の光が広い範囲に散るので、ハイライトは広がるほど暗くなる。デモを「点光源だけ」にして左から右へ見ると、小さく鋭いハイライトが、大きく淡い光に変わっていく。
微小な面の向きの分布
物理ベースのシェーダーでは、視線と光のちょうど中間の向き を向いた微小な面がどれだけあるかを、分布関数 で計算する。よく使われる GGX の分布は次の式で、 は広がりの大きさを表す。
多くの実装は、設定されたラフネス を二乗して として使う。そのままでは値の小さい側で見た目が急に変わるので、二乗して、スライダーの動きと見た目の変化がおおよそ比例するようにしている。
float a = roughness * roughness; // 見た目の変化が比例するよう二乗する
float a2 = a * a;
float nh = max(dot(n, h), 0.0);
float d = nh * nh * (a2 - 1.0) + 1.0;
float D = a2 / (PI * d * d); // h を向いた微小な面の割合
周囲の映り込みには、段階的にぼかした環境画像をあらかじめ用意しておき、ラフネスに応じてぼかし具合の違う画像を読み分ける方法がよく使われる。画像を段階的に縮小して持つ点は、ミップマップと同じ仕組みである。
見分け方と落とし穴
ラフネスが変えるのはハイライトの大きさとぼけ方で、色は変えない。色の違いはアルベドやメタリックで作り、ツヤの違いはラフネスで作る、と分けて考えると調整しやすい。
大きさのない点光源では、ラフネスを 0 にするとハイライトが一点に縮み、ほとんど見えなくなる。完全な 0 は避けて、わずかな値を残すことが多い。
ラフネスマップは色ではなく数値のデータなので、sRGB の色として読み込まず、変換なしで読む。sRGB として読むと値が曲がり、全体につやが増えたように見える。