26

私は、ガンマ補正パイプラインが次のようになると仮定しています。

  • ( ) にロードされたすべてのテクスチャに sRGB 形式を使用GL_SRGB8_ALPHA8します。これは、すべてのアート プログラムが事前にファイルをガンマ補正するためです。シェーダーでテクスチャからサンプリングする場合GL_SRGB8_ALPHA8、OpenGL は自動的に線形空間に変換します。
  • すべての照明計算、後処理などを線形空間で行います。
  • 画面に表示される最終的な色を書き込むときに、sRGB 空間に変換し直します。

私の場合、最終的な色の書き込みには、FBO (リニア RGB テクスチャ) からバック バッファーへの書き込みが含まれることに注意してください。

私の仮定は、最終段階でガンマ補正したかのように、色が本来よりも明るくなったように挑戦されました. 値 { 255, 106 , 0 }のライトによって単色が描画されるように設定しましたが、レンダリングすると { 255, 171 , 0 } になります (プリント スクリーニングとカラー ピッキングによって決定されます)。オレンジの代わりに黄色になります。最終ステップでガンマ補正を行わないと、{ 255, 106 , 0 } という正確な値が得られます。

いくつかのリソースによると、最新の LCD 画面は CRT ガンマを模倣しています。彼らはいつもですか?そうでない場合、ガンマ補正が必要かどうかをどのように判断できますか? 私はどこかで間違っていますか?


編集 1

ライトで書いた色は正しくても、テクスチャの色を使用する場所が正しくないことに気付きました (ただし、ガンマ補正なしで予想されるよりもはるかに暗いです)。この格差がどこから来るのかわかりません。


編集 2

GL_RGBA8の代わりにテクスチャを試してみたところGL_SRGB8_ALPHA8、ライティング計算でテクスチャ値を使用した場合でも、すべてが完璧に見えます (ライトの強度を半分にすると、出力カラー値も半分になります)。

私のコードはどこでもガンマ補正を考慮しなくなり、私の出力は正しいように見えます。

これは私をさらに混乱させます.ガンマ補正はもはや必要/使用されていませんか?


編集 3 - datenwolf の回答に応じて

もう少し実験した後、ここでいくつかの点で混乱しています。

1 - ほとんどの画像形式は非線形に保存されます (sRGB 空間)

いくつかの画像 (私の場合は .png と .bmp の両方の画像) を読み込んで、生のバイナリ データを調べました。画像編集プログラムでピクセルの値をプログラムで取得したバイト配列と比較すると、それらが完全に一致するように、画像が実際にRGB色空間にあるように見えます。イメージ エディタが RGB 値を提供するので、これは RGB で保存されたイメージを示します。

私は stb_image.h/.c を使用して画像をロードし、.png をロードするまでずっとそれをたどりましたが、ロード中に画像をガンマ補正した場所はどこにもありませんでした。また、16 進エディタで .bmps を調べたところ、ディスク上の値が一致していました。

これらの画像が実際に線形 RGB 空間でディスクに保存されている場合、画像が sRGB 空間にあると指定するタイミングを (プログラムで) どのように知ることができますか? より注目の画像ローダーが提供する可能性がある、これを照会する方法はありますか? それとも、イメージをガンマ補正して保存するか (またはしないか) は、イメージ作成者次第です。つまり、規則を確立し、特定のプロジェクトでそれに従うことを意味します。何人かのアーティストに尋ねましたが、どちらもガンマ補正とは何かを知りませんでした。

画像が sRGB であると指定した場合、最終的にガンマ補正を行わないと画像が暗すぎます (モニターが sRGB を使用して出力する場合は理解できますが、ポイント 2 を参照してください)。

2 - 「ほとんどのコンピュータでは、効果的なスキャンアウト LUT は線形です!これはどういう意味ですか?」

この考えがあなたの回答のどこで終わっているのか、私にはわかりません。

私が経験したことから、私がテストしたすべてのモニターは、出力線形値でテストしました。全画面クワッドを描画し、ガンマ補正のないシェーダーでハードコーディングされた値で色を付けると、指定した正しい値がモニターに表示されます。

上記のあなたの回答と私の結果から引用した文は、最新のモニターが線形値を出力する (つまり、CRT ガンマをエミュレートしない)ということを信じさせます。

アプリケーションのターゲット プラットフォームは PC です。このプラットフォーム (CRT または非常に古いモニターを使用している人を除く) の場合、#1 に対する応答が何であれ、#2 はガンマ補正を行わない(つまり、最終的な RGB->sRGB 変換を実行しない - 手動でも) のが合理的でしょうか?またはGL_FRAMEBUFFER_SRGBを使用していますか)?

もしそうなら、GL_FRAMEBUFFER_SRGB が意図されているプラ​​ットフォーム (または今日それを使用することが有効な場所) は何ですか、またはリニア RGB を使用するモニターは本当に新しいものですか (GL_FRAMEBUFFER_SRGB が 2008 年に導入されたことを考えると)?

--

私は学校の他の数人のグラフィックス開発者と話をしましたが、その音から、誰もガンマ補正を考慮に入れておらず、間違ったことに気づいていませんでした (一部の開発者はそれに気づいていませんでした)。特にある開発者は、ガンマを考慮したときに誤った結果が得られたため、ガンマについて心配しないことに決めたと述べました。オンラインで取得している/プロジェクトで見ている情報が矛盾しているため、ターゲットプラットフォームのプロジェクトで何をすべきかわかりません。


編集 4 - datenwolf の更新された回答に応じて

はい、そうです。シグナル チェーンのどこかで非線形変換が適用されているが、画像からディスプレイへのすべてのピクセル値が変更されない場合、その非線形性は画像のピクセル値に事前に適用されています。つまり、画像はすでに非線形色空間にあるということです。

ディスプレイ上の画像を調べていれば、あなたの反応は理にかなっています。明確にするために、画像のバイト配列を調べていると言ったのは、画面上の画像出力ではなく、テクスチャのメモリ内の数値を調べていたことを意味します (これはポイント 2 で行いました) . 私にとって、あなたが言っていることが真実であることを確認できる唯一の方法は、画像エディターがsRGB空間で値を与えていた場合です。

また、モニターで出力を調べたり、テクスチャの色を変更したり(たとえば、半分に分割したり、2 倍にしたり) したりして、出力が正しく表示されたことにも注意してください (以下で説明する方法を使用して測定)。

信号応答をどのように測定しましたか?

残念ながら、私の測定方法はあなたのものよりもはるかに粗雑です. モニターで実験したと言ったのは、シェーダーで色がハードコーディングされたソリッドカラーのフルスクリーンクワッドをプレーンな OpenGL フレームバッファー (書き込み時に色空間変換を行わない) に出力するということでした。白、75% グレー、50% グレー、25% グレー、黒を出力すると、正しい色が表示されます。ここで、私の正しい色の解釈は間違いなく間違っている可能性があります。スクリーンショットを撮り、画像編集プログラムを使用してピクセルの値を確認します (また、値が意味を成していることを確認するための視覚的な評価も行います)。私が正しく理解している場合、モニターが非線形である場合、モニターが正しく表示されるようにするには、ディスプレイ デバイスに表示する前に RGB->sRGB 変換を実行する必要があります。

嘘をつくつもりはありません。2 番目の混乱点 (最終的な RGB->sRGB 変換) に対する解決策は、微調整可能な明るさの設定であり、デバイスで正しく見えるようにデフォルト設定される (ガンマ補正なし) と考えています。

4

1 に答える 1