テクスチャ座標系でブラーさせたことによる弊害(1)~歪み

テクスチャ座標系……すなわち二次元空間で一様にぼかしてしまうと、3D空間上で奥の方が広く強くぼけてしまうことになる。下の図中の白い"□"は二次元上では同じ大きさだが、3D実空間上では耳の方が奥にあるため小さくなっており、これを手前の鼻と同じ径でボカしてしまうと強くぼけすぎる。すなわち皮下散乱しすぎてしまうということになる。

鼻の頭の"□"と耳の部分の"□"とでは、テクスチャ座標系では同じ大きさだが、3D実空間上では耳の方が奥にあるため小さくなる。これを手前の鼻と同じフィルタ径でボカしてしまうと強くぼけすぎる。すなわち皮下散乱しすぎてしまうということになる

これはテクスチャ座標のU,V系と実3D空間上のズレから来る歪みだ。より正しい光散乱を得るためには、この歪みについて補正することを考えなければならない。

これについては、あらかじめ、テクスチャ座標と実3D空間とのズレの度合いを事前に計算してテクスチャデータとして持っておき(歪み補正マップ)、テクスチャ座標系でのボカし処理を行う際に、このズレの度合いをボカし半径のスケール値(縮小率)として利用すればいい。

事前計算で奥行き情報に吟味して計算したストレッチ補正係数を格納したテクスチャを用意しておく。この図の左上が横(U)方向の歪み補正マップ、左下が縦(V)方向の歪み補正マップ。横方向のガウブラーをかけるときには前者に配慮し、縦方向の時には後者を参照する

格子模様でどの程度歪み下の補正が掛かっているかの検証結果(上段と下段ではブラー径が違う)。左側がストレッチ補正をしなかった場合の結果、右側がストレッチ補正をした場合の結果

テクスチャ座標系でブラーさせたことによる弊害(2)~継ぎ目

テクスチャ座標系のガウスブラーを行うと、テクスチャの境界部分にテクスチャメモリ上の初期化色(黒)が滲み入ってきてしまい、最終レンダリング結果でテクスチャの境目が「継ぎ目」として可視化されてしまう問題が発生する。

これについてはNVIDIAはいくつかの解決のアプローチがあるとしている。

例えば、前述の歪みマップを修正して輪郭付近では特別な値を入れ込んでおき、初期化色を参照しないようにする工夫を入れたり、あるいはブラーの元とするテクスチャ側のαチャンネルに対し、エッジ付近か否かのフラグ的に活用するというアイディアもある。これは、NVIDIAの「Adrianne」と「Froggy」の2つのデモではうまく行ったと報告されている。ただし、ピクセルシェーダでの条件分岐処理が必要になりパフォーマンスインパクトは小さくない。

ブラー元のテクスチャはこのように出力されている

このためテクスチャ座標系でただブラーしただけではテクスチャの初期化色がブラー処理によって滲み入ってきてしまい、3Dモデルにテクスチャマッピングしたときに「継ぎ目」が露呈してしまう

最も簡易的な実装としては、そのテクスチャの初期化色を皮膚の平均色としてしまう案がある。NVIDIAによればこれでも十分効果があるとしている

テクスチャ座標系でブラーさせたことによる弊害(3)~ディテールの消失

皮下散乱ブラー元のテクスチャは、3Dモデルに対して拡散反射の陰影処理を行い、画像テクスチャマップを適用し、これをテクスチャ平面に描き出したものであった。

問題は肌の模様や、微細凹凸を記録した法線マップの陰影処理(バンプマッピング)の結果をどう取り扱うか……という点。

バンプマッピングまでを適用してテクスチャ平面にレンダリングし、これに対して皮下散乱ブラー処理を適用してしまうと、このバンプマッピングによる微細凹凸の陰影が薄くなってしまう。

それでは、逆に、「初期の拡散反射ライティングと皮下散乱ブラー」、「画像テクスチャ処理、法線マップ処理」を分離して実行する実装方法はどうか。つまり、3D顔モデルのライティングでは拡散反射の陰影処理だけを行い、これをテクスチャ平面に描き出して、これに対して皮下散乱ブラーを行ってしまい、その結果に、画像テクスチャや法線マップとを掛け合わせるという実装だ。

しかし、この実装法では微細凹凸やシワが強く残りすぎてしまい、皮下散乱ブラーによるしっとりしたライティングとの相性が悪く不自然に見えてしまうことが多いという。

静止画写真では分かりにくいが、最初に拡散反射成分だけを皮下散乱ブラーさせてあとでテクスチャ処理を行うとディテールが残りすぎる傾向がある

NVIDIAによればこの実装は、写真などから作成したテクスチャとは相性がよい、という。これは写真ベースの皮膚テクスチャは皮膚の肌理やシワの微細凹凸が、撮影時点で皮下散乱をしているため適度にぼやけていて、皮下散乱ブラー結果との相性がいいためらしい。

であれば、適度にディテールを残し、適度にディテールを失うような方法がよいのではないか。ということで、NVIDIAは中間的な方法を考案した。

最初の皮下散乱ブラーに用いるためのテクスチャ素材を作成する段階では、拡散反射のライティングを普通に行うも、これとテクスチャ色の掛け合わせについてはテクスチャ色を減退させて行う。そして、この皮下散乱ブラーの結果に対してもう一回、減退させたテクスチャ色を掛け合わせる。皮下散乱ブラーの前後に減退させたテクスチャ処理を行うというようなイメージだ。

演算の観点から見るとテクスチャ色が2回掛け合わされることになるので、この減退のさせ方が重要になってくる。例えば前段階(皮下散乱ブラー前)で半分、後段階(皮下散乱ブラー)で半分として、ただ1/2としてのでは1/2×1/2で1/4となってしまう。2乗で元に戻ればいいのだから、例えば"半分に減退させる"ということであれば平方根(√)を用いればいい。

ただ「1/2で決め打ち」という定数処理では拡張性がなさ過ぎるので、これを一般化するために「べき乗演算」(pow関数)を用いる。例えばXの平方根はXの1/2乗だ。NVIDIAの実験では前段階でテクスチャ色を0.82乗し、後ろ段階で0.18乗した減退率パラメータを用いたとのこと。

この皮下散乱ブラーの前後でテクスチャー処理を行うという処理系は一見、荒唐無稽に思えるがNVIDIAによれば実は物理的にも意味があるとしている。

光は、皮膚の肌理やシワを含む微細凹凸を有するディテール層(光吸収層)に入射もするが、内部で散乱して再び戻ってきてここから出射もするので、実際問題として光は2回、このディテール層に関わってくる。この前後のテクスチャ色の掛け合わせは丁度この現象を近似的に行ったことに相当する、というのだ。(続く)

光の入射と出射でディテール層(吸収層)を通過することの擬似的な再現が、皮下散乱ブラーの前後にテクスチャー処理を行うことに相当する

(トライゼット西川善司)