ガンマのはなし その8
2011年07月31日(Sun)
人間の目は暗い部分ほど敏感で、明るい部分ほど変化に疎くなるという性質を持っている。ガンマ値で例えるなら約0.5の「明るい歪み」だ。人間の目に映る世界は、実際に目に入ってくる光の量より明るく歪んでいるのである。3DCGソフトは物理的な光の量を計算するものなので、レンダリング結果が暗く感じられるのは当然のことだったのだ。したがってレンダリング結果を人間が感じる明るさに近づけるには、ガンマカーブで明るく歪めてやらなければならない。ただし、人間の目の明るさの感じ方は固定ではないので、シーンに応じて適用量を調整する必要がある。
Poser以外のソフト、たとえばD|SやShadeでは、レンダリング結果のガンマとゲインを操作することができる。ガンマは文字通りガンマカーブをかけるものであり、ゲインは明るさの最大値を指定することでシーン内の輝度差を決定する。なので、明るさの最大値を決め打ちしている(と思われる)Poserのトーンマッピングと異なり、D|Sユーザは自分でシーン内の最も明るい部分に合わせてゲインを調整する必要がある。
ここまでが前回のおさらい。
13. 物理的に正しい色
さて、トーンマッピングを使用することで「物理的な光の量」を「人間の目が感じる明るさ」に修正することが可能になった。シーン内のオブジェクトが真っ白か真っ黒なものばかりだったなら、リニアワークフローはこれで完結しただろう。ところがそれ以外、灰色や他の色を使おうとすると問題が起こる。それまで指定していた色が、トーンマッピングを使うことで明るく淡く、ものによっては色相まで変わってしまうのだ。

色が変わってしまう理屈はそんなに難しくない。人間の目には赤・緑・青の各波長を感じ取る受容体があり、人間の脳はそれぞれの受容体から送られる信号の、最も強いものと二番目に強いものの比を色相として捉えている。また、一番弱い信号の弱さで彩度を判断している。たとえば赤と緑が等量なら黄色で、RGB = (1, 1, 0) なら黄色、RGB = (0.5, 0.5, 0) なら暗い黄色、RGB = (1, 1, 0.5) なら淡い黄色といった具合である。

トーンマッピングで歪みをかけると、RGB各成分の比率が変わってしまうために色相が変化したように感じてしまうのだ。
トーンマッピングを使うと色が変わる。ということはつまり、私たちが普段見ている色はもともと歪んでいたということである。このことはすでに第一回で書いている。「見た目には50%の灰色でも、物理的な光の量は四分の1程度しかない」という部分だ。そして、本来マテリアルで指定しなければならないのは、見た目の色ではなくこの「物理的な光の量」だったのである。
物理的な光の量というのは、つまり物質の反射率である。たとえば人間の肌の反射率は、赤い波長がだいたい55%ぐらい、緑の波長が30%ぐらい、青の波長が15%ぐらい、ということらしい。もちろん中間の波長が0%ということはないので、可視光線の全波長を合計すればそれぞれはもっと大きな値になるはずだ。また別の資料では、入射光に対して肌の表面上で反射するものが5%ぐらい、吸収されるのが40%ぐらい、残りが拡散反射や皮下分散する分、らしい。これらのことから、RGBの比をだいたい11:6:3にして、トータルの値が白の約55%になるようにすれば、おおむね物理的に正しい反射率ということになる。

鏡面反射とかバンプとか色ムラを加えてみてこんな感じ。

めんどくさいね(笑)。
物理的に正しいレンダリングとはこういうことなのである。物質の分光反射率から各波長の反射率を求め、鏡面反射と拡散反射を区別し、レンダリング後はトーンマッピングで人間の目の歪みを付加する。だがしかし、すべての物質の分光反射率をいちいち調べ上げるなど、どだい無理な話である。どこかで近似するしかなく、というかもともと鏡面反射だって本来なら全部レイトレース反射で計算するべきだし、全方位に光を反射している拡散反射と一方向のみに反射する鏡面反射が同じ尺度で設定されているのもおかしな話だし、つまりこういったモロモロが適当に片付けられている現状では、物理的な正確さなんてそもそも実現するはずがないのである。
14. ガンマコレクション(ガンマ補正)
現在のところ、3DCGで物理的に正しいレンダリングを実現するのは幻想である。とはいえ近似でいいならできることはあるわけで、正確な反射率が分からなくてもだいたいの色を再現することはできる。テクスチャや色に対してガンマカーブをかけ、人間の目が感じている明るい歪みを取り除いてやるのである。これをガンマコレクションという。収集(collect)じゃなくて補正(correct)。
Poserでガンマコレクションと銘打たれた機能がついているのはPoser Pro 2010のみだが、画像や色にガンマカーブをかけることなら、実はPoser 5の時代から可能だ。マテリアルルームで演算すればいいのである。

画像の各画素に対してガンマ値を累乗したいのだから、数値演算色(Color_Math)ノードの値1に画像を接続し、引数に累乗(Pow)を指定する。値2には乗数を入力するんだけど、カラーパレットでは黒から白(0~1)までの値しか入力できないので、とりあえず白にしておいて数値演算関数(Math_Function)ノードから値を入力する。
画像処理ソフトで直接テクスチャにレベル補正をかけても構わないけど、あんまりおすすめしない。なぜなら画像フォーマットで保存した時点で値が256階調に丸められてしまって、中間調の情報が大幅に失われてしまうからだ。Poser上の演算なら端数が切り捨てられることはない。
ところで、乗数であるガンマ値にはどんな値を指定すればいいだろうか。懲りずに「自分のモニタのガンマ値が2.2なら2.2を…」と考えた人、冷静に考えてみよう。表示しているモニタによって補正値を変えるなら、50%グレーをWindows上のCGソフトでは0.21で、Mac上のCGソフトでは0.29で計算することになる。本来マテリアルで指定する色は「物質の反射率」のはずなのに、二通りの(あるいはユーザの設定によっては無数の)反射率が存在してしまうことになる。
正解は「その画像が作成されたモニタのガンマ値、ただし作者がちゃんとモニタをキャリブレーションしていて、なおかつ『現実の色』を描いていた場合に限る」である。
画像は保存されたときのガンマ値をそのまま持っている。それはモニタガンマかもしれないし、出力時にsRGBに変換されているなら約2.2かもしれない。確率から言えば2.2が圧倒的に多いだろうが、プロファイルが埋め込まれてでもないかぎり断言はできない。
さらに、作者本人が「現実的な色」を目指していなかった場合はどうしようもない。以前のV4やM4のテクスチャを比較した記事(さらにトラックバックしてもらっているJezzさんちの記事)を見てもらえば一目瞭然だけど、肌の色はキャラ作家さんによってマチマチである。(もっともあの記事はマテリアルはいじってないから、テクスチャ自体がどんな色をしているかはあの比較画像からは判断できないけれども。)
なので、結局は自分のモニタを見ながら微調整していくしかない。カラーピッカーで選択する単色の場合は、自分のモニタのガンマ値を割り引いたらいいんだけど。
5月のM3復興会議企画のDD Magazineでは、自分の担当ページ(p7~p9とp12~p13。ReBirth絵はベーシックな三点照明)でこの手法を用いている。Poser 8でIDLを使用し、マテリアルに数値演算色ノードを挟んでトーンマッピングをかけている。ライトはレイトレース影の無限光1灯と拡散IBLまたはドーム状の環境光用Prop。生M3と生M4に使用しているのはDAZの標準皮だ。

というわけで。
これまでのことをまとめると、リニアワークフローを実現するためには色や画像に対してガンマ補正をかけて物理的な色(反射率)に修正し、レンダリング後、トーンマッピングを使って人間の目の感じ方を模した明るい歪みをかける、ということになる。

リニアと言う割にはなんか歪めてばっかりだったり、肝心な部分は目分量で微調整するしかなかったりで、結局リニアなんちゃらってカンジなのがご理解いただけたかと思う。
さて、長々と続いたガンマの話もそろそろ終わりにしたいところだ(だいぶ飽きてきた)。次回、Poser Pro 2010のガンマコレクションに触れて、簡単なシーンでも作って締めにしようと思う。