From ba5fa70b83378307f9f0ddcda7735285ece578c1 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Apr 2016 13:31:50 -0400 Subject: [PATCH] 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;