我想对我的 OpenGL 照明实施伽马校正,但应用伽马校正后,我的结果似乎根本不是线性的。
我还发现OpenGL: Gamma Corrected image doesn't appear linear这与我的问题非常相似,但还没有收到答案,也没有讨论过实际的漫射光。
作为说明,我在线性空间中定义了以下 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 倍,但似乎并非如此。
只是我不够敏感,无法感知正确的亮度差异还是有什么问题?
我尝试的其他方法是简单地将精确的浅色输出到默认帧缓冲区,无需和使用伽马校正。
左边是未校正的,右边是带有伽马校正的;红色数字表示来自 Photoshop 颜色选择器的 RGB 强度。我知道 Photoshop RGB 值并不代表最终输出图像(因为 Photoshop 不会将 RGB 值读取为显示器输出)。左边的图像直观地看起来更好,但基于 RGB 强度值,我想说最右边的图像确实被我的片段着色器正确地进行了伽马校正;因为这些强度中的每一个都会通过显示器并以正确的强度进入我的眼睛。例如,当 0.88 伽马校正后的 0.75 强度变为 0.88^2.2 = 0.75 作为监视器的输出。
正确的图像真的正确吗?而且,与其他图像相比,实际照明为何如此偏暗?