DCC→エンジンの色合わせ|リニア・sRGB・色空間の実務

Substance Painter で見たときは赤味の効いた良い色だったのに、Unreal や Unity で開いたら妙にくすんで見える──こうした「色がズレる」事故は、ほぼ例外なく 色空間(リニア / sRGB)の取り違え が原因です。
本記事では、リニアと sRGB の違い、テクスチャ種別ごとの色空間の使い分け、DCC とエンジンのデフォルト挙動、そしてトーンマッピングの影響までを、現場で「色合わせのトラブルを切り分けられる」粒度で整理します。前提として PBR の理論(CR-01) を読んでおくと、リニア計算が必要な理由が腑に落ちやすくなります。
夕宮たいだふぁ……みんな〜、色がズレる事故、現場でほんとよく見るんだぁ。今日は「リニア・sRGB・トーンマッピング」をいっしょに整理していこ〜。
1. なぜ色がズレるのか
ひとことで:色の符号化(sRGB / リニア)と計算空間(リニア)の取り違えが、ほぼすべての原因です。
色がズレる現象を分解すると、登場人物は次の3者です。
- 画像ファイル:JPG / PNG は標準で sRGB として保存されている
- シェーダー計算:物理的に正しい結果を出すには、リニア空間 で行う必要がある
- モニタ表示:最終的に sRGB 空間で出力する必要がある
DCC やエンジンは、この3者の間で「読み込み時にリニアへ変換するか」「表示時に sRGB に戻すか」を自動的に処理してくれます。ただし、デフォルト挙動と設定 UI が DCC ごとに違う ため、ここで取り違えが発生します。
2. ガンマと sRGB の正体
ひとことで:人間の目の暗部に敏感な特性を、効率的に符号化したカーブです。
ガンマ 2.2 の歴史的背景
ガンマ 2.2 は、もともと CRT モニタの応答特性 から来ています。電圧を倍にしても光量が倍にならない、というハード由来のクセです。偶然にも、これが 人間の目が暗部に敏感 な特性とよく合っていたため、限られた 8 ビット(256 段階)の階調を「人間が違いを感じやすい暗部」に厚く配分する符号化として標準化されました。
sRGB
1996 年に標準化された色空間で、ガンマ 2.2 をベースにした「画像保存用」の規格です。現代の JPG / PNG は事実上すべて sRGB です。下図のように、入力値(記録値)と出力値(実際の明るさ)の関係が カーブ になっています。





うぐぅ……ガンマ 2.2 ってむずかしいねぇ。でもね、要は「目の特性に合わせた省エネ符号化」って思っとけば、本筋は外さないよぉ。
3. リニアワークフローの全貌
ひとことで:「読み込み時にリニア化、表示前に sRGB 化」が原則です。
シェーダーがやりたい計算は、たとえばランバート反射(CR-02)の dot(N, L) です。「光が2倍なら結果も2倍」が成り立つ世界、つまり リニア空間 で計算する必要があります。sRGB のまま計算すると、「2倍に見える明るさ」と「数値の2倍」がズレ、PBR の物理的整合性が崩れます。
そこで、現代のレンダリングは リニアワークフロー で組まれています。下図のような流れです。


1. テクスチャ読み込み(sRGB → リニア変換) 2. シェーダー計算(リニア空間で実行) 3. ポストプロセス(リニア HDR のまま) 4. トーンマッピング(HDR → LDR、まだリニア) 5. 表示(リニア → sRGB 変換、モニタへ送出)
「入口でリニアにし、出口で sRGB に戻す」が標語です。途中の計算はすべてリニア、これだけ覚えておけば見通しが立ちます。逆に言えば、入口か出口のどちらかで変換が抜けると、画面の色は二度ガンマがかかった(または抜けた)状態になり、明らかに不自然な見え方になります。
4. テクスチャ別の色空間の使い分け
ひとことで:「色」は sRGB、「データ」はリニアで扱います。
PBR で扱うテクスチャを色空間で整理します。


| テクスチャ種類 | 色空間 | 理由 |
|---|---|---|
| BaseColor / Albedo | sRGB | 人間の目で見た「色」を保存している |
| Normal | リニア | 方向ベクトルの数値であり、色ではない |
| Metallic | リニア | 0 か 1 を表す物理値 |
| Roughness | リニア | 0〜1 の物理値、見た目の明るさではない |
| AO | リニア | 暗くする倍率の数値 |
| Emissive | sRGB | 色(明るさが必要なら HDR 値で強度を別管理) |
ノーマルマップが青〜紫っぽい見た目なのは、色として見せているのではなく、方向ベクトルの数値を RGB に詰めているだけ です。これを sRGB として読むと、変換カーブが効いて方向ベクトルが歪み、CR-04 の「面が暗い」「ノーマルの効きが弱い」事故になります。



ほよ? 種類で違うんだぁ。「色は sRGB、数値はリニア」って覚えると、迷わないねぇ。
5. 各DCC のデフォルト挙動
ひとことで:DCC ごとに色空間の前提と設定 UI が違うので、初期に把握します。
Maya + Arnold
リニアワークフローが前提です。Render Settings で OCIO(OpenColorIO)プロファイル を選択し、テクスチャ単位で sRGB / リニアを指定します。Arnold 側でテクスチャタイプを認識して自動変換することも多く、明示指定とのダブルチェックが安全です。
Substance Painter
内部計算はリニア、ビューポートには sRGB に変換して表示しています。Texture Set のチャンネル設定で各マップの色空間を明示的に持っており、出力時にも「BaseColor は sRGB として」「Roughness はリニアとして」と書き出しテンプレートで分けて指定します。
Houdini
MPlay(プレビュー)は OCIO 設定に依存し、COP / VOP / Karma で色空間の扱いが微妙に異なります。Solaris(USD)では USD 側の colorSpace 属性が尊重されるため、USD ベースのワークフローではここを揃えるのが先です。



ていねいに整理するねぇ。DCC ごとに UI も用語も違うけど、やってることは「読込時にリニア化、表示時に sRGB 化」で全部同じだよぉ。
6. UE / Unity の色設定
ひとことで:エンジン側で「リニアワークフロー」が有効になっているかが大前提です。
Unreal Engine
内部レンダリングは常にリニアです。テクスチャインポート時に sRGB チェックボックスで色空間を指定します。
- BaseColor / Emissive:sRGB ON(sRGB → リニアに自動変換)
- Normal / Metallic / Roughness / AO:sRGB OFF(リニアのまま使用)
加えて、ACES トーンマッピングがデフォルトで有効、Auto Exposure(Eye Adaptation)も有効です。色合わせ時は両方を一時的に OFF にして比較するのが定石です。
Unity
Project Settings → Player → Color Space で Linear に設定する必要があります。Gamma 設定のままでは PBR の物理的整合性が崩れ、Roughness の効きや HDR ライティングの結果が想定外になります。テクスチャインポーターの「sRGB (Color Texture)」チェックで個別マップの扱いを管理します。トーンマッピングは HDRP / URP / Built-in で実装が異なるため、プロジェクトのレンダーパイプラインを確認してから合わせ込みに入ります。
7. トーンマッピングの影響
ひとことで:HDR の広い値域を、画面表示できる狭い値域に「圧縮」する非線形変換です。
リニア空間での明るさは、1.0 を超える HDR(High Dynamic Range:明暗の幅が広い表現)値を自由に持てます。空や太陽の反射は 100.0 でも 1000.0 でも構いません。一方、画面に出せるのは 0〜1 の LDR(Low Dynamic Range:通常モニタで表示できる明暗範囲)値です。そこで、明るい部分ほど強く圧縮するカーブをかけて、HDR を LDR に押し込めます。これがトーンマッピングです。
代表的なトーンマッパーは次のとおりです。
- ACES:映画業界標準。コントラストが高め。UE デフォルト
- Filmic:シネマティックな仕上がり、Blender / Unity HDRP でも採用
- Reinhard:シンプル、初期のトーンマッピング



ぁぅ……ここ、見落としやすいんだぁ。Painter で完璧な色を作っても、UE の ACES を通したら別物に見えること、ほんとよくあるんだよぉ。
Auto Exposure / Eye Adaptation
トーンマッピングと並んで、Auto Exposure(自動露出) も色合わせを難しくする要因です。暗いシーンを自動で明るく、明るいシーンを暗く調整する機能で、「同じテクスチャでも環境光で見え方が変わる」現象の正体です。色合わせを始めるときは 一旦 OFF にする のが鉄則です。
8. ハンズオン演習
ひとことで:BaseColor(sRGB)と Roughness(リニア)の取り違えを、実機で再現してみましょう。
1. Painter で適当なメッシュに BaseColor と Roughness を作成、書き出し 2. UE または Unity に両方インポート 3. Roughness を「sRGB ON」で意図的に間違えて読み込む 4. マテリアルに接続して結果を見る:Roughness の値が想定より小さく解釈され、ハイライトが強く・表面が滑らかに見える 5. Roughness を「sRGB OFF」に戻して、正しい結果と並べて比較


「sRGB として読むと、暗部側に圧縮されたカーブで解釈される」現象を、目で確認できます。一度体験しておくと、現場で「ハイライトが妙に強い」と感じたときに、最初に色空間設定を疑える反射神経が身につきます。
9. チェックリスト
ひとことで:色合わせ前のセルフチェック項目です。
- [ ] エンジン側で Linear Color Space が有効になっている(Unity は Linear、UE はデフォルトでリニア)
- [ ] BaseColor / Emissive は sRGB 読込
- [ ] Normal / Metallic / Roughness / AO はリニア読込
- [ ] DCC とエンジンで同じトーンマッパー設定で比較している
- [ ] Auto Exposure / Eye Adaptation を OFF にして色比較している
- [ ] OCIO 設定が DCC・エンジン間で齟齬がない
- [ ] テクスチャ命名やサフィックス(
_albedo_n_ormなど)と sRGB 設定が連動している
10. よくある間違い・トラブルシュート
ひとことで:Roughness の sRGB 化・Normal の sRGB 化・トーンマッピング忘れ・色空間設定不一致、の4つが定番です。
Roughness を sRGB として読み込み
- 症状:ハイライトが想定より強い、表面が想定より滑らかに見える
- 対処:インポート設定で sRGB を OFF。チャンネルパッキングで ORM テクスチャを使う場合(CR-05)も、ORM 全体は sRGB OFF が正しい
Normal を sRGB として読み込み
- 症状:凹凸の効きが弱い、ノーマルが浅く感じる
- 対処:インポート設定で sRGB OFF。CR-04 のタンジェント問題(緑反転やスムージング不一致)と症状が似るので、まず色空間を疑う
DCC とエンジンで色空間設定が違う
- 症状:DCC で正しく見える色が、エンジンで違う
- 対処:両者の OCIO・トーンマッパー・Linear/Gamma 設定を揃える。プロジェクト初期に文書化するのが事故予防の一番
トーンマッピングを忘れて色合わせ開始
- 症状:DCC のレンダラとエンジンで色が違う、と原因不明のまま延々追いかける
- 対処:トーンマッパーを揃えるか、両者で一旦 OFF にして基準色を合わせ、その後トーンマッパーを ON で最終調整



ふぁ……色合わせまわり、ハマりどころは出尽くしたかなぁ。次はライティング基礎やチャンネルパッキングに進めるよぉ。
11. 次に読む記事
ひとことで:色空間の知識を、ライティングとテクスチャ運用に繋げていきましょう。
- CR-01 PBRの理論:リニア計算が必要な物理的背景
- CR-04 ノーマルマップとタンジェント空間:Normal の色空間と並ぶ落とし穴
- CR-05 チャンネルパッキング戦略:ORM テクスチャと色空間の関係
- CR-13 ライティング基礎:DCC ↔ エンジンのライティング差の整理
- CR-02 リアルタイムレンダリングの基礎数学:dot積などリニア計算の根拠
- SP-B04 Painter PBR入門:Painter での実機ワークフロー(公開準備中)
—








