Browse Source

Increase precision in linear_to_srgb and srgb_to_linear

This avoids the situation where white stops being white after conversion. While maintaining as much floating point ops as possible
clayjohn 10 tháng trước cách đây
mục cha
commit
46ce499b6f
2 tập tin đã thay đổi với 12 bổ sung6 xóa
  1. 6 6
      core/math/color.h
  2. 6 0
      tests/core/math/test_color.h

+ 6 - 6
core/math/color.h

@@ -187,16 +187,16 @@ struct [[nodiscard]] Color {
 
 	_FORCE_INLINE_ Color srgb_to_linear() const {
 		return Color(
-				r < 0.04045f ? r * (1.0f / 12.92f) : Math::pow((r + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f),
-				g < 0.04045f ? g * (1.0f / 12.92f) : Math::pow((g + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f),
-				b < 0.04045f ? b * (1.0f / 12.92f) : Math::pow((b + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f),
+				r < 0.04045f ? r * (1.0f / 12.92f) : Math::pow(float((r + 0.055) * (1.0 / (1.0 + 0.055))), 2.4f),
+				g < 0.04045f ? g * (1.0f / 12.92f) : Math::pow(float((g + 0.055) * (1.0 / (1.0 + 0.055))), 2.4f),
+				b < 0.04045f ? b * (1.0f / 12.92f) : Math::pow(float((b + 0.055) * (1.0 / (1.0 + 0.055))), 2.4f),
 				a);
 	}
 	_FORCE_INLINE_ Color linear_to_srgb() const {
 		return Color(
-				r < 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * Math::pow(r, 1.0f / 2.4f) - 0.055f,
-				g < 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * Math::pow(g, 1.0f / 2.4f) - 0.055f,
-				b < 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * Math::pow(b, 1.0f / 2.4f) - 0.055f, a);
+				r < 0.0031308f ? 12.92f * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055,
+				g < 0.0031308f ? 12.92f * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055,
+				b < 0.0031308f ? 12.92f * b : (1.0 + 0.055) * Math::pow(b, 1.0f / 2.4f) - 0.055, a);
 	}
 
 	static Color hex(uint32_t p_hex);

+ 6 - 0
tests/core/math/test_color.h

@@ -160,6 +160,12 @@ TEST_CASE("[Color] Linear <-> sRGB conversion") {
 	CHECK_MESSAGE(
 			color_srgb.srgb_to_linear().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)),
 			"The sRGB color converted back to linear color space should match the expected value.");
+	CHECK_MESSAGE(
+			Color(1.0, 1.0, 1.0, 1.0).srgb_to_linear() == (Color(1.0, 1.0, 1.0, 1.0)),
+			"White converted from sRGB to linear should remain white.");
+	CHECK_MESSAGE(
+			Color(1.0, 1.0, 1.0, 1.0).linear_to_srgb() == (Color(1.0, 1.0, 1.0, 1.0)),
+			"White converted from linear to sRGB should remain white.");
 }
 
 TEST_CASE("[Color] Named colors") {