OpenGL 照明にガンマ補正を実装したいのですが、ガンマ補正を適用すると、結果がまったく線形に見えません。
また、 OpenGL: ガンマ補正された画像が線形に見えないこともわかりました。これは私の問題と非常によく似ていますが、まだ回答を受け取っておらず、実際の拡散光についても議論していません。
例として、線形空間で定義された次の 4 つの明るい色があります。
glm::vec3 lightColors[] = {
glm::vec3(0.25),
glm::vec3(0.50),
glm::vec3(0.75),
glm::vec3(1.00)
};
各光源を分離し、基本的な線形減衰を拡散照明方程式に適用すると、次の結果が得られます。
これはフラグメント シェーダーです。
void main()
{
vec3 lighting = vec3(0.0);
for(int i = 0; i < 4; ++i)
lighting += Diffuse(normalize(fs_in.Normal), fs_in.FragPos, lightPositions[i], lightColors[i]);
// lighting = pow(lighting, vec3(1.0/2.2));
FragColor = vec4(lighting, 1.0f);
}
ガンマ補正されたライトとの明るさの違いがほとんど見られないだけでなく、減衰もガンマ補正によって歪んでいます。私の理解によると、すべての計算 (減衰を含む) は線形空間で行われ、ガンマを修正することで、モニターはそれを正しく表示する必要があります (出力として再び修正されないため)。照明の色だけに基づくと、一番右の円は左の円の 4 倍、2 番目の円の 2 倍の明るさになるはずですが、実際にはそうではないようです。
明るさの違いを正しく認識できるほど私の感度が悪いだけなのか、それとも何か問題があるのでしょうか。
私が試した他のことは、ガンマ補正なしとガンマ補正ありで、正確な光の色をデフォルトのフレームバッファに出力することです。
左は未補正、右はガンマ補正あり。赤い数字は、Photoshop のカラー ピッカーからの RGB 強度を示します。Photoshop の RGB 値が最終的な出力画像を表していないことはわかっています (Photoshop は RGB 値をモニター出力として読み取らないため)。直感的には左の画像の方が優れているように見えますが、RGB 強度値に基づくと、右端の画像はフラグメント シェーダーによって実際に正しくガンマ補正されていると言えます。これらの強度のそれぞれがモニターを通過し、正しい強度で私の目に入るからです。たとえば、0.88 ガンマ補正された 0.75 強度は、モニターの出力として 0.88^2.2 = 0.75 になります。
右の画像は本当に正しいですか?また、他の画像と比べて実際の照明がこれほどずれているのはなぜですか?