From ed9c0dd74df796dfae60aaf0f9698f54b96fae2b Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Apr 2016 02:35:26 -0400 Subject: [PATCH] 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. --- libraries/gpu/src/gpu/Texture.cpp | 40 +++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 9f10f2e2b6..db4b444ce7 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -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) � 2007-2014 "