From 97931d96b8609f4386002573d7ae87ff55b795b9 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Apr 2016 12:59:16 -0400 Subject: [PATCH] Move sRGB calcs to ColorUtils And start consolidating any conversions with calls into ColorUtils. --- libraries/gpu/src/gpu/Texture.cpp | 48 ++---------------------- libraries/shared/src/ColorUtils.h | 62 ++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 50 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index db4b444ce7..2362926c84 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -18,6 +18,8 @@ #include "GPULogging.h" #include "Context.h" +#include "ColorUtils.h" + using namespace gpu; static int TexturePointerMetaTypeId = qRegisterMetaType(); @@ -637,50 +639,6 @@ 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) { - return glm::vec3(sRGBValueToLinearValue(color.x), sRGBValueToLinearValue(color.y), sRGBValueToLinearValue(color.z)); -} - -glm::vec3 linearTosRGB(glm::vec3& color) { - 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 " void sphericalHarmonicsAdd(float * result, int order, const float * inputA, const float * inputB) { const int numCoeff = order * order; @@ -835,7 +793,7 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< float(data[pixOffsetIndex+2]) * UCHAR_TO_FLOAT); // Gamma correct - clr = sRGBToLinear(clr); + clr = ColorUtils::sRGBToLinearVec3(clr); // scale color and add to previously accumulated coefficients sphericalHarmonicsScale(shBuffB.data(), order, diff --git a/libraries/shared/src/ColorUtils.h b/libraries/shared/src/ColorUtils.h index b47e7c3a98..192f7f9da4 100644 --- a/libraries/shared/src/ColorUtils.h +++ b/libraries/shared/src/ColorUtils.h @@ -24,13 +24,16 @@ public: // Convert from gamma 2.2 space to linear inline static glm::vec3 toLinearVec3(const glm::vec3& srgb); inline static glm::vec3 toGamma22Vec3(const glm::vec3& linear); + + // Convert from sRGB gamma space to linear. + // This is pretty different from converting from 2.2. + inline static glm::vec3 sRGBToLinearVec3(const glm::vec3& srgb); + inline static glm::vec3 tosRGBVec3(const glm::vec3& srgb); + + inline static float sRGBToLinearFloat(const float& srgb); + inline static float tosRGBFloat(const float& linear); }; -inline glm::vec3 ColorUtils::toVec3(const xColor& color) { - const float ONE_OVER_255 = 1.0f / 255.0f; - return glm::vec3(color.red * ONE_OVER_255, color.green * ONE_OVER_255, color.blue * ONE_OVER_255); -} - inline glm::vec3 ColorUtils::toLinearVec3(const glm::vec3& srgb) { const float GAMMA_22 = 2.2f; // Couldn't find glm::pow(vec3, vec3) ? so did it myself... @@ -43,4 +46,53 @@ inline glm::vec3 ColorUtils::toGamma22Vec3(const glm::vec3& linear) { return glm::vec3(glm::pow(linear.x, INV_GAMMA_22), glm::pow(linear.y, INV_GAMMA_22), glm::pow(linear.z, INV_GAMMA_22)); } +inline glm::vec3 ColorUtils::toVec3(const xColor& color) { + const float ONE_OVER_255 = 1.0f / 255.0f; + return glm::vec3(color.red * ONE_OVER_255, color.green * ONE_OVER_255, color.blue * ONE_OVER_255); +} + +inline glm::vec3 ColorUtils::sRGBToLinearVec3(const glm::vec3& srgb) { + return glm::vec3(sRGBToLinearFloat(srgb.x), sRGBToLinearFloat(srgb.y), sRGBToLinearFloat(srgb.z)); +} + +inline glm::vec3 ColorUtils::tosRGBVec3(const glm::vec3& linear) { + return glm::vec3(tosRGBFloat(linear.x), tosRGBFloat(linear.y), tosRGBFloat(linear.z)); +} + +// 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. +inline float ColorUtils::sRGBToLinearFloat(const float &srgb) { + 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 (srgb <= SRGB_ELBOW) { + linearValue = srgb / 12.92f; + } else { + linearValue = powf(((srgb + 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. +inline float ColorUtils::tosRGBFloat(const float &linear) { + 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 (linear <= 0.0f) { + sRGBValue = 0.0f; + } else if (0 < linear < SRGB_ELBOW_INV) { + sRGBValue = 12.92f * linear; + } else if (SRGB_ELBOW_INV <= linear < 1) { + sRGBValue = 1.055f * powf(linear, 0.41666f - 0.055f); + } else { + sRGBValue = 1.0f; + } + + return sRGBValue; +} + #endif // hifi_ColorUtils_h \ No newline at end of file