From ed9c0dd74df796dfae60aaf0f9698f54b96fae2b Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Apr 2016 02:35:26 -0400 Subject: [PATCH 1/9] 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 " From 97931d96b8609f4386002573d7ae87ff55b795b9 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Apr 2016 12:59:16 -0400 Subject: [PATCH 2/9] 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 From ba5fa70b83378307f9f0ddcda7735285ece578c1 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Apr 2016 13:31:50 -0400 Subject: [PATCH 3/9] Convert sRGB values for materials. --- libraries/model/src/model/Material.cpp | 6 +++--- libraries/model/src/model/Material.h | 6 +++--- libraries/shared/src/ColorUtils.h | 29 +++++++++++++++++++------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index 802650df93..022242d1b5 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -55,7 +55,7 @@ Material::~Material() { void Material::setEmissive(const Color& emissive, bool isSRGB) { _key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f)))); _schemaBuffer.edit()._key = (uint32) _key._flags.to_ulong(); - _schemaBuffer.edit()._emissive = (isSRGB ? ColorUtils::toLinearVec3(emissive) : emissive); + _schemaBuffer.edit()._emissive = (isSRGB ? ColorUtils::sRGBToLinearVec3(emissive) : emissive); } void Material::setOpacity(float opacity) { @@ -67,7 +67,7 @@ void Material::setOpacity(float opacity) { void Material::setAlbedo(const Color& albedo, bool isSRGB) { _key.setAlbedo(glm::any(glm::greaterThan(albedo, Color(0.0f)))); _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); - _schemaBuffer.edit()._albedo = (isSRGB ? ColorUtils::toLinearVec3(albedo) : albedo); + _schemaBuffer.edit()._albedo = (isSRGB ? ColorUtils::sRGBToLinearVec3(albedo) : albedo); } void Material::setRoughness(float roughness) { @@ -79,7 +79,7 @@ void Material::setRoughness(float roughness) { void Material::setFresnel(const Color& fresnel, bool isSRGB) { //_key.setAlbedo(glm::any(glm::greaterThan(albedo, Color(0.0f)))); - _schemaBuffer.edit()._fresnel = (isSRGB ? ColorUtils::toLinearVec3(fresnel) : fresnel); + _schemaBuffer.edit()._fresnel = (isSRGB ? ColorUtils::sRGBToLinearVec3(fresnel) : fresnel); } void Material::setMetallic(float metallic) { diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index c500e9ec10..59a3fad917 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -245,16 +245,16 @@ public: const MaterialKey& getKey() const { return _key; } void setEmissive(const Color& emissive, bool isSRGB = true); - Color getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get()._emissive) : _schemaBuffer.get()._emissive); } + Color getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_schemaBuffer.get()._emissive) : _schemaBuffer.get()._emissive); } void setOpacity(float opacity); float getOpacity() const { return _schemaBuffer.get()._opacity; } void setAlbedo(const Color& albedo, bool isSRGB = true); - Color getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get()._albedo) : _schemaBuffer.get()._albedo); } + Color getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_schemaBuffer.get()._albedo) : _schemaBuffer.get()._albedo); } void setFresnel(const Color& fresnel, bool isSRGB = true); - Color getFresnel(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get()._fresnel) : _schemaBuffer.get()._fresnel); } + Color getFresnel(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_schemaBuffer.get()._fresnel) : _schemaBuffer.get()._fresnel); } void setMetallic(float metallic); float getMetallic() const { return _schemaBuffer.get()._metallic; } diff --git a/libraries/shared/src/ColorUtils.h b/libraries/shared/src/ColorUtils.h index 192f7f9da4..47e7520afa 100644 --- a/libraries/shared/src/ColorUtils.h +++ b/libraries/shared/src/ColorUtils.h @@ -30,10 +30,18 @@ public: inline static glm::vec3 sRGBToLinearVec3(const glm::vec3& srgb); inline static glm::vec3 tosRGBVec3(const glm::vec3& srgb); + inline static glm::vec4 sRGBToLinearVec4(const glm::vec4& srgb); + inline static glm::vec4 tosRGBVec4(const glm::vec4& 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... @@ -46,19 +54,26 @@ 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); -} - +// Convert from sRGB color space to linear color space. inline glm::vec3 ColorUtils::sRGBToLinearVec3(const glm::vec3& srgb) { return glm::vec3(sRGBToLinearFloat(srgb.x), sRGBToLinearFloat(srgb.y), sRGBToLinearFloat(srgb.z)); } +// Convert from linear color space to sRGB color space. inline glm::vec3 ColorUtils::tosRGBVec3(const glm::vec3& linear) { return glm::vec3(tosRGBFloat(linear.x), tosRGBFloat(linear.y), tosRGBFloat(linear.z)); } +// Convert from sRGB color space with alpha to linear color space with alpha. +inline glm::vec4 ColorUtils::sRGBToLinearVec4(const glm::vec4& srgb) { + return glm::vec4(sRGBToLinearFloat(srgb.x), sRGBToLinearFloat(srgb.y), sRGBToLinearFloat(srgb.z), srgb.w); +} + +// Convert from linear color space with alpha to sRGB color space with alpha. +inline glm::vec4 ColorUtils::tosRGBVec4(const glm::vec4& linear) { + return glm::vec4(tosRGBFloat(linear.x), tosRGBFloat(linear.y), tosRGBFloat(linear.z), linear.w); +} + // 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) { @@ -84,9 +99,9 @@ inline float ColorUtils::tosRGBFloat(const float &linear) { // 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) { + } else if (0 < linear && linear < SRGB_ELBOW_INV) { sRGBValue = 12.92f * linear; - } else if (SRGB_ELBOW_INV <= linear < 1) { + } else if (SRGB_ELBOW_INV <= linear && linear < 1) { sRGBValue = 1.055f * powf(linear, 0.41666f - 0.055f); } else { sRGBValue = 1.0f; From d6ee569963d3e1ab005e6852f44e4175fd518b8e Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Apr 2016 23:52:33 -0400 Subject: [PATCH 4/9] Add sRGB conversions to shaders. --- libraries/gpu/src/gpu/Color.slh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/Color.slh b/libraries/gpu/src/gpu/Color.slh index d4d9ba7b81..4330b34b90 100644 --- a/libraries/gpu/src/gpu/Color.slh +++ b/libraries/gpu/src/gpu/Color.slh @@ -11,9 +11,14 @@ <@if not GPU_COLOR_SLH@> <@def GPU_COLOR_SLH@> +float sRGBFloatToLinear(float value) { + const float SRGB_ELBOW = 0.04045; + + return (value <= SRGB_ELBOW) ? value / 12.92 : pow((value + 0.055) / 1.055, 2.4); +} + vec3 colorToLinearRGB(vec3 srgb) { - const float GAMMA_22 = 2.2; - return pow(srgb, vec3(GAMMA_22)); + return vec3(sRGBFloatToLinear(srgb.r), sRGBFloatToLinear(srgb.g), sRGBFloatToLinear(srgb.b)); } vec4 colorToLinearRGBA(vec4 srgba) { From ae5ef6d94860d98061bbc68b5b42c19968ebba13 Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 26 Apr 2016 17:00:59 -0400 Subject: [PATCH 5/9] Remove toLinearVec3 from ColorUtils toGamma22Vec3 should probably stay since that is a valid conversion from linear to a gamma space of 2.2. --- libraries/shared/src/ColorUtils.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/libraries/shared/src/ColorUtils.h b/libraries/shared/src/ColorUtils.h index 47e7520afa..5ee9254bc9 100644 --- a/libraries/shared/src/ColorUtils.h +++ b/libraries/shared/src/ColorUtils.h @@ -21,8 +21,7 @@ class ColorUtils { public: inline static glm::vec3 toVec3(const xColor& color); - // Convert from gamma 2.2 space to linear - inline static glm::vec3 toLinearVec3(const glm::vec3& srgb); + // Convert to gamma 2.2 space from linear inline static glm::vec3 toGamma22Vec3(const glm::vec3& linear); // Convert from sRGB gamma space to linear. @@ -42,12 +41,6 @@ inline glm::vec3 ColorUtils::toVec3(const xColor& color) { 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... - return glm::vec3(glm::pow(srgb.x, GAMMA_22), glm::pow(srgb.y, GAMMA_22), glm::pow(srgb.z, GAMMA_22)); -} - inline glm::vec3 ColorUtils::toGamma22Vec3(const glm::vec3& linear) { const float INV_GAMMA_22 = 1.0f / 2.2f; // Couldn't find glm::pow(vec3, vec3) ? so did it myself... From ef7098b39aae5243ea19a1f7ea223e900da93292 Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 26 Apr 2016 17:12:04 -0400 Subject: [PATCH 6/9] Missed a few. --- libraries/entities/src/ParticleEffectEntityItem.h | 8 ++++---- libraries/render-utils/src/text/Font.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index ba6f32b51f..28af5d5d59 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -49,7 +49,7 @@ public: const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } - glm::vec3 getColorRGB() const { return ColorUtils::toLinearVec3(toGlm(getXColor())); } + glm::vec3 getColorRGB() const { return ColorUtils::tosRGBVec3(toGlm(getXColor())); } static const xColor DEFAULT_COLOR; void setColor(const rgbColor& value) { memcpy(_color, value, sizeof(_color)); } @@ -62,17 +62,17 @@ public: bool _isColorStartInitialized = false; void setColorStart(const xColor& colorStart) { _colorStart = colorStart; _isColorStartInitialized = true; } xColor getColorStart() const { return _isColorStartInitialized ? _colorStart : getXColor(); } - glm::vec3 getColorStartRGB() const { return _isColorStartInitialized ? ColorUtils::toLinearVec3(toGlm(_colorStart)) : getColorRGB(); } + glm::vec3 getColorStartRGB() const { return _isColorStartInitialized ? ColorUtils::tosRGBVec3(toGlm(_colorStart)) : getColorRGB(); } bool _isColorFinishInitialized = false; void setColorFinish(const xColor& colorFinish) { _colorFinish = colorFinish; _isColorFinishInitialized = true; } xColor getColorFinish() const { return _isColorFinishInitialized ? _colorFinish : getXColor(); } - glm::vec3 getColorFinishRGB() const { return _isColorStartInitialized ? ColorUtils::toLinearVec3(toGlm(_colorFinish)) : getColorRGB(); } + glm::vec3 getColorFinishRGB() const { return _isColorStartInitialized ? ColorUtils::tosRGBVec3(toGlm(_colorFinish)) : getColorRGB(); } static const xColor DEFAULT_COLOR_SPREAD; void setColorSpread(const xColor& colorSpread) { _colorSpread = colorSpread; } xColor getColorSpread() const { return _colorSpread; } - glm::vec3 getColorSpreadRGB() const { return ColorUtils::toLinearVec3(toGlm(_colorSpread)); } + glm::vec3 getColorSpreadRGB() const { return ColorUtils::tosRGBVec3(toGlm(_colorSpread)); } static const float MAXIMUM_ALPHA; static const float MINIMUM_ALPHA; diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index e7604544bd..532e5efcdd 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -363,7 +363,7 @@ void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, c batch._glUniform1i(_outlineLoc, (effectType == OUTLINE_EFFECT)); // need the gamma corrected color here - glm::vec4 lrgba = glm::vec4(ColorUtils::toLinearVec3(glm::vec3(*color)), color->a); + glm::vec4 lrgba = glm::vec4(ColorUtils::tosRGBVec3(glm::vec3(*color)), color->a); batch._glUniform4fv(_colorLoc, 1, (const float*)&lrgba); batch.setInputFormat(_format); From 83d6f7f1e34b6c3c2ad7c60fbcf189c4ff25346c Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 26 Apr 2016 18:49:03 -0400 Subject: [PATCH 7/9] Quick fix for incorrect conversion. We want sRGB to linear, not linear to sRGB. --- libraries/entities/src/ParticleEffectEntityItem.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 28af5d5d59..4538a1bb43 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -49,7 +49,7 @@ public: const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } - glm::vec3 getColorRGB() const { return ColorUtils::tosRGBVec3(toGlm(getXColor())); } + glm::vec3 getColorRGB() const { return ColorUtils::sRGBToLinearVec3(toGlm(getXColor())); } static const xColor DEFAULT_COLOR; void setColor(const rgbColor& value) { memcpy(_color, value, sizeof(_color)); } @@ -62,17 +62,17 @@ public: bool _isColorStartInitialized = false; void setColorStart(const xColor& colorStart) { _colorStart = colorStart; _isColorStartInitialized = true; } xColor getColorStart() const { return _isColorStartInitialized ? _colorStart : getXColor(); } - glm::vec3 getColorStartRGB() const { return _isColorStartInitialized ? ColorUtils::tosRGBVec3(toGlm(_colorStart)) : getColorRGB(); } + glm::vec3 getColorStartRGB() const { return _isColorStartInitialized ? ColorUtils::sRGBToLinearVec3(toGlm(_colorStart)) : getColorRGB(); } bool _isColorFinishInitialized = false; void setColorFinish(const xColor& colorFinish) { _colorFinish = colorFinish; _isColorFinishInitialized = true; } xColor getColorFinish() const { return _isColorFinishInitialized ? _colorFinish : getXColor(); } - glm::vec3 getColorFinishRGB() const { return _isColorStartInitialized ? ColorUtils::tosRGBVec3(toGlm(_colorFinish)) : getColorRGB(); } + glm::vec3 getColorFinishRGB() const { return _isColorStartInitialized ? ColorUtils::sRGBToLinearVec3(toGlm(_colorFinish)) : getColorRGB(); } static const xColor DEFAULT_COLOR_SPREAD; void setColorSpread(const xColor& colorSpread) { _colorSpread = colorSpread; } xColor getColorSpread() const { return _colorSpread; } - glm::vec3 getColorSpreadRGB() const { return ColorUtils::tosRGBVec3(toGlm(_colorSpread)); } + glm::vec3 getColorSpreadRGB() const { return ColorUtils::sRGBToLinearVec3(toGlm(_colorSpread)); } static const float MAXIMUM_ALPHA; static const float MINIMUM_ALPHA; From bf31fc728aab18b37eed8c8e8633e93aa9275d28 Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 26 Apr 2016 18:54:02 -0400 Subject: [PATCH 8/9] And another. --- libraries/render-utils/src/text/Font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 532e5efcdd..3607aa5803 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -363,7 +363,7 @@ void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, c batch._glUniform1i(_outlineLoc, (effectType == OUTLINE_EFFECT)); // need the gamma corrected color here - glm::vec4 lrgba = glm::vec4(ColorUtils::tosRGBVec3(glm::vec3(*color)), color->a); + glm::vec4 lrgba = ColorUtils::sRGBToLinearVec4(*color); batch._glUniform4fv(_colorLoc, 1, (const float*)&lrgba); batch.setInputFormat(_format); From 043fe3508a950225603adbcdb66aa8f41679ea7f Mon Sep 17 00:00:00 2001 From: Geenz Date: Sat, 30 Apr 2016 15:47:42 -0400 Subject: [PATCH 9/9] Add SRGBA color format. --- libraries/gpu/src/gpu/Format.cpp | 1 + libraries/gpu/src/gpu/Format.h | 1 + 2 files changed, 2 insertions(+) diff --git a/libraries/gpu/src/gpu/Format.cpp b/libraries/gpu/src/gpu/Format.cpp index 7c603919fd..b7a8380f78 100644 --- a/libraries/gpu/src/gpu/Format.cpp +++ b/libraries/gpu/src/gpu/Format.cpp @@ -11,6 +11,7 @@ using namespace gpu; const Element Element::COLOR_RGBA_32{ VEC4, NUINT8, RGBA }; +const Element Element::COLOR_SRGBA_32{ VEC4, NUINT8, SRGBA }; const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA }; const Element Element::VEC2F_UV{ VEC2, FLOAT, UV }; const Element Element::VEC2F_XY{ VEC2, FLOAT, XY }; diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 9c08e45bec..6b2bc4b93e 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -245,6 +245,7 @@ public: } static const Element COLOR_RGBA_32; + static const Element COLOR_SRGBA_32; static const Element VEC4F_COLOR_RGBA; static const Element VEC2F_UV; static const Element VEC2F_XY;