色空間とガンマ補正
画像の合成や陰影が「なんとなく汚い」を根絶できます。ガンマとリニアの違い、なぜ計算はリニアで行うか、HDR やトーンマッピング、色域の差までを筋道立てて理解しましょう。
- 1.sRGB のピクセル値は輝度に比例しない非線形符号(ガンマ約2.2)で、ブレンド・フィルタ・ライティングは一度リニア空間へ戻してから計算する必要がある。
- 2.リニアワークフローとは「入力をデガンマ→リニアで全計算→出力でエンコード(ガンマ)」の一貫した流れで、破綻しない合成と物理的に正しい陰影の前提になる。
- 3.色域(sRGB/DCI-P3/Rec.2020)は表現できる色の範囲、ガンマ/PQ/HLG は明るさの符号化方式であり、両者は独立した別の軸である。
ピクセル値は「明るさ」ではない
多くの人が暗黙に「ピクセルの 0〜255 は明るさに比例する」と考えますが、これは誤りです。sRGB をはじめとする一般的な画像フォーマットのピクセル値は、物理的な輝度(放射輝度)に比例しない非線形な符号として格納されています。値 128 は白(255)の物理的なちょうど半分の明るさではなく、実際には約 5 分の 1 程度の輝度しかありません。
この非線形性が「ガンマ」です。ガンマを正しく扱えるかどうかが、画像の合成・拡大縮小・ライティングが物理的に正しく見えるかを左右します。まず「なぜ非線形なのか」から押さえます。
ガンマの起源と知覚的な合理性
ガンマの直接の起源は CRT ディスプレイの物理特性です。CRT は入力電圧に対して輝度が 輝度 ∝ 電圧^γ(γ ≒ 2.2)のべき乗で応答しました。この非線形性を打ち消すため、カメラ側や信号側で逆のべき(約 1/2.2)をあらかじめ掛けておく——これが本来の「ガンマ補正」です。両者が打ち消し合って、全体として直線的な明るさが再現される、という発想でした。
CRT が消えた現在もガンマが残るのは、人間の視覚が明るさを対数的(べき乗的)に知覚するため、この符号化が都合よく効率的だからです。人間は暗部の微妙な差には敏感で、明部の差には鈍感です。8 ビットの限られた符号を輝度に線形に割り当てると、暗部に階調が足りずバンディング(縞)が出ます。ガンマ符号化は暗部に符号を厚く配分するので、同じ 8 ビットでも知覚的に均一な階調が得られます。
「sRGB = ガンマ2.2」と略されがちですが、sRGB の伝達関数は単純な x^(1/2.2) ではありません。暗部(おおむね 0.0031 未満のリニア値)では傾き 12.92 の直線、それ以上ではオフセット付きのべき乗 1.055・x^(1/2.4) − 0.055 という区分関数です。直線部を入れるのは、原点付近で微分が発散して暗部ノイズが増幅されるのを避けるためです。全体を平均すると実効的にガンマ約2.2 相当になります。
リニアとエンコード済みを区別する
議論を明確にするため、2 つの空間を厳密に分けます。
| 空間 | 値の意味 | 主な用途 |
|---|---|---|
| リニア(線形) | 物理的な光の量に比例。2倍の値=2倍の光子 | 加算・積分・畳み込み・ライティング計算 |
| エンコード済み(ガンマ/sRGB) | 知覚均一になるよう非線形圧縮された符号 | 8ビット格納・伝送・ディスプレイ入力 |
決定的な事実は、光の物理は加算的で線形だということです。2 つの光源が同じ面を照らせば、そこに届く放射輝度は単純な和になります。半透明のガラス越しに見える色は、背後の光と手前の光の線形な重み付き和です。ところが sRGB 値どうしを直接足したり平均したりすると、この線形性が崩れます。非線形符号の平均は、対応する光の量の平均には一致しないからです。
なぜ合成・フィルタは破綻するのか
具体例で破綻を見ます。純赤 (255,0,0) と純緑 (0,255,0) を 50:50 でアルファブレンドすることを考えます。素朴に sRGB 値を平均すると (128,128,0) になり、これは暗くくすんだオリーブ色です。しかし物理的には、赤の光と緑の光を等量重ねた中間色はもっと明るい黄土色になるべきです。差が出るのはブレンドをエンコード済み空間で行ったからです。
正しいアルファブレンド(不透明度 a で前景を背景に重ねる):
1. 前景・背景をそれぞれデガンマしてリニアへ:
fg_lin = decode(fg_srgb)
bg_lin = decode(bg_srgb)
2. リニア空間で線形補間:
out_lin = a・fg_lin + (1 - a)・bg_lin
3. 表示・格納のためエンコードして戻す:
out_srgb = encode(out_lin)
誤り(よくあるバグ):
out_srgb = a・fg_srgb + (1 - a)・bg_srgb ← 暗部が沈み色がくすむ
同じ問題はあらゆる「複数ピクセルを混ぜる操作」に潜みます。画像の縮小(複数テクセルの平均)、ガウシアンぼかし(重み付き和)、アンチエイリアス(カバレッジに応じた混合)、ミップマップ生成——これらをエンコード済み空間で行うと、一様に暗く沈み、細い明線が痩せます。とくに白背景に黒文字を縮小すると、リニアで処理した場合よりエッジが太く滲んで見えます。すべて「非線形値を線形操作した」ことに由来します。
リニアワークフローという一貫した規律
個々のバグを潰すのではなく、パイプライン全体を一つの規律で貫くのがリニアワークフローです。原則は単純です。
入力(テクスチャ・素材) ──decode──▶ [ すべての計算はリニア空間 ] ──encode──▶ 出力(画面・ファイル)
sRGB / ガンマ符号 ライティング・合成・フィルタ sRGB / ガンマ符号
要点は「境界でのみ変換し、内部は一貫してリニアに保つ」ことです。実務では次の非対称性に注意します。
- アルベド(基本色)テクスチャは色なので sRGB 符号化されている。読み込み時にデガンマが必要。
- 法線マップ・粗さ・メタルネス・ハイトマップは色ではなくデータ(方向や係数)で、リニアに格納されている。これをデガンマしてはいけない。誤ってガンマを掛けると法線がねじれ陰影が壊れる。
現代の GPU は sRGB のデコード/エンコードをテクスチャサンプラとレンダーターゲットのハードウェアで無償で行えます。sRGB フォーマット(例 ..._SRGB)で確保したテクスチャは、サンプリング時に自動でリニアへ展開され、しかもバイリニア補間がリニア空間で正しく行われます。同様に sRGB のレンダーターゲットへ書けば書き込み時に自動エンコードされます。シェーダ内で手動の pow を書くよりも速く、フィルタリングも正しくなります。この経路の土台になる GPU 側の仕組みは /hardware-components/ 系の記事も参照してください。
リニアワークフローだからといって中間バッファを 8 ビットのリニアで持つと、暗部の階調が足りずバンディングが出ます。ガンマ符号化はもともと 8 ビットで暗部を救う仕組みなので、それを外したリニア値は最低でも半精度浮動小数点(fp16)などの高ビット深度で保持するのが原則です。最終出力の直前でエンコードして 8 ビットに落とします。
HDR とトーンマッピング
リニア空間で物理的にライティングすると、値は 0〜1 に収まりません。太陽や光源のハイライトは 1.0 をはるかに超える放射輝度を持ちます。これが HDR(High Dynamic Range)レンダリングで、内部計算は上限のない浮動小数点で行います。問題は、この広いダイナミックレンジを、限られた表示レンジへどう写すかです。
トーンマッピングは HDR のリニア輝度を表示可能な範囲へ圧縮する非線形変換です。単純にクリップ(1.0 で頭打ち)すると、明るい部分がすべて真っ白に飛び、ハイライトのディテールが失われます。そこで、暗部・中間部の階調をできるだけ保ちつつ明部をなだらかに丸め込む曲線(Reinhard、ACES フィルミックなど)を使います。
HDR パイプラインの並び(順序が重要):
リニアHDR(範囲無制限, fp16)
→ トーンマッピング(レンジ圧縮, まだリニア寄りの表示リニア)
→ エンコード(sRGB や PQ で符号化)
→ 出力
注意: トーンマッピングはエンコード(ガンマ)の前に行う。
先にエンコードしてから圧縮すると輝度関係が崩れる。
ここで用語の混同に注意します。SDR 表示向けのトーンマッピングは「HDR で計算した結果を 8 ビット sRGB に収める」処理を指します。一方、HDR ディスプレイ(HDR10 など)へ出力する場合は、sRGB ではなく PQ(Perceptual Quantizer, SMPTE ST 2084) や HLG(Hybrid Log-Gamma) という別の伝達関数でエンコードします。PQ は絶対輝度(cd/m²、ニト)を最大 10000 ニトまで符号化する方式で、相対値だった sRGB とは設計思想が異なります。
色域はガンマとは別の軸
最後に、しばしばガンマと混同される「色域(gamut)」を切り分けます。ガンマ(伝達関数)は明るさの符号化方式であり、色域は表現できる色の範囲です。両者は直交する独立した概念です。
色域は、色度図の上で 3 つの原色(赤・緑・青の頂点)が作る三角形の面積として表されます。原色が飽和して外側にあるほど三角形は広く、鮮やかな色まで表現できます。
| 色域 | 相対的な広さ | 主な用途 |
|---|---|---|
| sRGB / Rec.709 | 標準(最も狭い) | Web・SDR 動画・一般ディスプレイ |
| DCI-P3 / Display P3 | sRGB の約1.25倍 | デジタルシネマ・近年のスマホ/PC |
| Rec.2020 | 非常に広い | UHD/HDR 放送の目標色域 |
| ACEScg | Rec.2020 より広い | 映像制作の内部作業用(シーンリニア) |
同じ (255,0,0) でも、それが sRGB の赤なのか Display P3 の赤なのかで、実際に発光する色は違います。したがって色は必ず色空間の指定(プロファイル)とセットで扱う必要があります。異なる色域の間で色を移すには、白色点を合わせたうえで原色の座標系を変換する行列演算(色域マッピング)が要り、送り先の三角形からはみ出す色は境界へ丸めます(ガマットマッピング)。この「符号化(ガンマ/PQ)」と「色域」を別々に指定する考え方は、資格試験でも実務でも取り違えやすい最重要ポイントです。
「sRGB」という語は二重の意味を持ちます。(1) 伝達関数(あのガンマ約2.2 の区分関数)と、(2) 色域(Rec.709 と同じ原色三角形)。この 2 つは切り離せます。たとえば「Display P3」は色域は広い P3 なのに伝達関数は sRGB と同じものを使う、という組み合わせです。問われたら「明るさの符号化」と「色の範囲」を必ず分けて答えること。混同すると変換行列を組み間違えます。
まとめ
- sRGB 等のピクセル値は輝度に比例しない**非線形符号(ガンマ)**で、暗部に階調を厚く配る知覚的効率のために存在する。
- 光の物理は線形なので、ブレンド・縮小・ぼかし・ライティングは必ずデガンマしてリニア空間で計算し、出力時に再エンコードする(リニアワークフロー)。
- 色テクスチャはデガンマが要るが、法線・粗さ等のデータテクスチャはリニア格納なのでデガンマしてはならない。中間バッファは高ビット深度で持つ。
- HDR は上限なしのリニアで計算し、トーンマッピングでレンジ圧縮してからエンコードする。HDR 表示は sRGB でなく PQ/HLG を使う。
- 色域(表現できる色の範囲)と伝達関数(明るさの符号化)は独立した別軸。色は必ずプロファイルとセットで扱う。
グラフィックス Article
色空間とガンマ補正を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
色空間
比較で見る軸
難易度: advanced / カテゴリ: グラフィックス / タグ数: 6
導入後に効く点
リニアワークフローとは「入力をデガンマ→リニアで全計算→出力でエンコード(ガンマ)」の一貫した流れで、破綻しない合成と物理的に正しい陰影の前提になる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- グラフィックス
- タグ数
- 6
判断チェックリスト
- 自社の用途が「色空間 / ガンマ補正」に近いか確認する。
- 強みである「sRGB のピクセル値は輝度に比例しない非線形符号(ガンマ約2.2)で、ブレンド・フィルタ・ライティングは一度リニア空間へ戻してから計算する必要がある。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。