Post processing

Tone Mapping / Filmic / ACES

トーンマッピング

広い輝度を画面に表示できる範囲へ収める。

3 / 10

Interactive demo

Preparing the demo…

Tone Mapping / Filmic / ACES

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

計算上の明るさ(太陽は数万、室内の照明は数十、暗い影は 0.01 …)は非常に広い範囲にわたりますが、画面が表示できるのは 0〜1 だけです。トーンマッピングは、この広い明るさの範囲を、画面に表示できる範囲へなめらかに圧縮する処理です。そのまま 1 で切り捨てると明るい部分が真っ白に飛んでしまうので、フィルムや目の感じ方をまねた曲線で、明るい部分にも階調を残します。

ゲームでの使いどころ

  • 物理ベースの照明(HDR レンダリング):PBR で現実的な明るさの差(屋外と屋内、太陽と影)を計算するゲームでは必須です。
  • 明暗差の大きい場面:暗い洞窟から明るい外を見る、夜の街のネオン、爆発の閃光。
  • 自動露出との組み合わせ:画面の平均的な明るさに合わせて露出を変え(暗い所に入ると目が慣れる)、その後でトーンマッピングする。
  • 作品の見た目:ACES のコントラストの強い映画調、AgX の自然な色の飛び方など、選ぶ曲線で画面の印象が変わる。

しくみ

入力の明るさ xx(露出を掛けた後)を、0〜1 の出力 yy に写す曲線を使います。

方式特徴
切り捨て(Linear)y=min⁡(x,1)y = \min(x, 1)。1 を超えるとすべて同じ白になる
Reinhardy=x/(1+x)y = x / (1 + x)。単純で白飛びしないが、全体に眠い画になる
ACES Filmic映画業界の規格に基づく S 字曲線。暗部を締め、明部を緩やかに圧縮する。明るい色は黄色や白へ寄る
AgX明るい色が自然に白へ向かって彩度を落とす。Blender 4 の標準
Khronos PBR Neutral0.8 程度までは元の色をほぼそのまま保ち、それ以上だけを圧縮する。製品の色を正確に見せたいときに向く

多くの曲線は「暗い部分はほぼそのまま(または少し締める)、明るくなるほど緩やかに 1 に近づける」形です。

露出:トーンマッピングの前に、明るさ全体に係数(2EV2^{EV})を掛けます。カメラの露出と同じで、暗い場面では上げ、明るい場面では下げます。

色の扱い:RGB を別々に曲線に通すと、明るい色ほど彩度が落ち、色相もずれます(明るい青が水色〜白になる)。これを「好ましい」とみなす方式(ACES)と、色相をなるべく保つ方式(AgX、Neutral)があります。

実装のポイント

  • 計算はすべて線形の HDR で:照明の計算、ブルーム、モーションブラーなどは、浮動小数点のバッファにトーンマッピング前の値で行い、最後に 1 回だけトーンマッピングします。
  • UI はトーンマッピングしない:UI やテキストはトーンマッピングの後に描きます。
  • 自動露出:画面の平均輝度(対数平均やヒストグラム)を求め、ゆっくり追従させると、明暗の移動が自然になります。

つまずきやすい点

  • 二重のトーンマッピング:レンダーターゲットに描くときと最後の表示で 2 回かけると、画が眠くなります。
  • 白が白くならない:Reinhard では、入力がかなり大きくても出力が 1 に届かず、白い物がくすみます。白の明るさを指定する拡張版を使います。
  • ACES の色ずれ:明るい青や赤が不自然な色になりやすく、エフェクトの色が狙いと変わることがあります。

デモで試すこと

  1. 「なし(1 で切り捨て)」では、投光器の当たった床や看板が真っ白に飛んで、形が分かりません。「白飛びした画素を表示」をオンにすると、赤い斜線の範囲が広いことが分かります。
  2. ACES Filmic、AgX、Neutral に切り替えると、明るい部分に階調が戻ります。右下のグラフで、曲線が明るい側で緩やかに寝ていることが分かります。
  3. 「露出」を上げ下げすると、画面全体の明るさが変わり、白飛びする範囲も変わります。

References

Unreal Engine Post Process Effects ↗

A general reference for this subcategory.