平均輝度をいかに求めるか、輝度変換をいかに行うか
トーンマッピングは平均輝度をいかに求めるか、どういった手法で輝度変換を行うのかがポイントとなる。
前回までに解説したように、HDRレンダリングしてできあがった映像フレームはそのままでは表示することが出来ない(あるいは表示しても意図した表示にならない)。
そこで必要となるのが、表示に適した輝度レンジに変換してやる処理、すなわち「トーンマッピング」(Tone Mapping)の処理だ。
カメラや人間の視覚がそうであるように、正しく映像と知覚できるのは、ある一定の輝度範囲に限られるので、そのHDRフレームの平均輝度を求め、そこを中心にして一定の輝度範囲に変換し、表示可能な映像を生成する。
これら3つは同一シーンの映像だが、どの輝度を基準に映像を調整することで、シーンの見せ方を変えられる。これが「トーンマッピング」の基本的な概念(※Recovering High Dynamic Range Radiance Maps from Photographs/Paul Debevecより) |
求めた平均輝度が暗ければ、HDRフレーム中の暗い色であってもそれなりに明るく持ち上げられるし、表示範囲を大きく超えた輝度のピクセルはみんな白に飽和してしまうことになる。
求めた基準となる平均輝度値をキーにして、HDRフレーム内のピクセルカラーを表示可能な1677万色に重みを付けて丸めていく処理が「トーンマッピング」の処理なのだ。
最も単純なのは、平均輝度を中心にして線形に変換してしまう処理だが、一般に、このトーンマッピングに用いる変換関数のカーブは、非線形なものの方が現実的な視覚に近くなってリアルになることが分かっている。
具体的には輝度が低いところはやや持ち上げ気味にして、明るいところはそれほどでもない……というような変換カーブがよいとされる。非線形の実装が難しいという場合には、異なる複数の傾きの線形変換を組み合わせたマルチバンド式が実装されることもある。
キーポイントとなる平均輝度の取得技法はいくつかの手法が考案されている。
「Half-Life 2:EPISODE ONE」では、連続するフレームに対して、各バンドのヒストグラムを測定するという方法で平均輝度を求めている。例えば8バンド(8段階)のヒストグラムを求めるときには、最初は真っ黒から1/8の階調までの輝度の画素を数え、続くフレームでは次の1/8階調の輝度の画素を数える。つまり、8フレームかかって全バンドのヒストグラムを得るというわけだ。もちろんリアルタイム3Dグラフィックスである以上、1フレーム単位に異なる映像になるため、正しいヒストグラムではないはずなのだが、連続的なフレーム間は似通っているので大きな問題にはならないとしている。
具体的に数えた結果をどう反映させるかなのだが、その数え方は意外に単純だ。レンダリング時、ピクセルシェーダで調べたい輝度レンジのピクセルがあったらMRTを使って対応する非表示のステンシルバッファにマークする。このステンシルバッファに対して非同期のocclusion queryを実行して、マーク出来たピクセル数を取得するのだ。
フレーム単位に計測する対象輝度を切り換えて、複数フレームに渡って計測することでヒストグラムを求めている「Half-Life 2:EPISODE ONE」(VALVE,2006)。なお、測定対象は画面の中央寄りに限定するという重み付けもしている |
平均輝度の測定方法には別なシンプルな方法もある。それはHDRフレームをダウンサンプルして1×1テクセルまで縮小して求めるという手法だ。この場合も、これで求めた平均輝度情報は次回のフレームのトーンマッピングに活用する方針で問題ない。
トーンマッピングはリアルタイムに行うよりも、若干の遅延を伴って行ったほうが、人間やカメラの明るさへの順応に若干時間がかかる様を再現できてリアルになるとされる。また、複数フレームにまたがって行うことでフィルレートの節約にもなるという副次的な恩恵も得られる。
(トライゼット西川善司)