Apply the correct sRGB conversions.

sRGB does not use a gamma curve of 2.2 - instead it uses a piece-wise
gamma curve that 2.2 is approximate of.  This will cause very subtle
color differences between proper sRGB and "approximate" sRGB -
differences that are noticeable nonetheless.
This commit is contained in:
Geenz 2016-04-25 02:35:26 -04:00
parent 88ab52d340
commit ed9c0dd74d

View file

@ -637,16 +637,48 @@ void SphericalHarmonics::assignPreset(int p) {
}
}
// This is based upon the conversions found in section 8.24 of the OpenGL 4.4 4.4 specification.
// glm::pow(color, 2.2f) is approximate, and will cause subtle differences when used with sRGB framebuffers.
float sRGBValueToLinearValue(float& value) {
const float SRGB_ELBOW = 0.04045f;
float linearValue = 0.0f;
// This should mirror the conversion table found in section 8.24: sRGB Texture Color Conversion
if (value <= SRGB_ELBOW) {
linearValue = value / 12.92f;
} else {
linearValue = powf(((value + 0.055f) / 1.055f), 2.4f);
}
return linearValue;
}
// This is based upon the conversions found in section 17.3.9 of the OpenGL 4.4 specification.
// glm::pow(color, 1.0f/2.2f) is approximate, and will cause subtle differences when used with sRGB framebuffers.
float LinearValueTosRGBValue(float& value) {
const float SRGB_ELBOW_INV = 0.0031308f;
float sRGBValue = 0.0f;
// This should mirror the conversion table found in section 17.3.9: sRGB Conversion
if (value <= 0.0f) {
sRGBValue = 0.0f;
} else if (0 < value < SRGB_ELBOW_INV) {
sRGBValue = 12.92f * value;
} else if (SRGB_ELBOW_INV <= value < 1) {
sRGBValue = 1.055f * powf(value, 0.41666f - 0.055f);
} else {
sRGBValue = 1.0f;
}
return sRGBValue;
}
glm::vec3 sRGBToLinear(glm::vec3& color) {
const float GAMMA_CORRECTION = 2.2f;
return glm::pow(color, glm::vec3(GAMMA_CORRECTION));
return glm::vec3(sRGBValueToLinearValue(color.x), sRGBValueToLinearValue(color.y), sRGBValueToLinearValue(color.z));
}
glm::vec3 linearTosRGB(glm::vec3& color) {
const float GAMMA_CORRECTION_INV = 1.0f / 2.2f;
return glm::pow(color, glm::vec3(GAMMA_CORRECTION_INV));
return glm::vec3(LinearValueTosRGBValue(color.x), LinearValueTosRGBValue(color.y), LinearValueTosRGBValue(color.z));
}
// Originial code for the Spherical Harmonics taken from "Sun and Black Cat- Igor Dykhta (igor dykhta email) <20> 2007-2014 "