summaryrefslogtreecommitdiffstats
path: root/libdimension
diff options
context:
space:
mode:
Diffstat (limited to 'libdimension')
-rw-r--r--libdimension/color.c80
-rw-r--r--libdimension/dimension/color.h9
-rw-r--r--libdimension/tests/render.c16
3 files changed, 61 insertions, 44 deletions
diff --git a/libdimension/color.c b/libdimension/color.c
index efa4f4a..39f9b3d 100644
--- a/libdimension/color.c
+++ b/libdimension/color.c
@@ -97,69 +97,83 @@ const dmnsn_color dmnsn_cyan = {
.trans = 0.0,
};
-/** Inverse function of sRGB's `C' function, for the reverse conversion. */
-static double
-dmnsn_sRGB_C_inv(double CsRGB)
+/* sRGB's `C' function. */
+static inline double
+dmnsn_sRGB_C(double Clinear)
{
/*
- * If C represents R, G, and B, then the Clinear values are now found as
- * follows:
+ * If C represents R, G, and B, then the sRGB values are now found as follows:
*
- * { Csrgb/12.92, Csrgb <= 0.04045
- * Clinear = { 1/2.4
- * { ((Csrgb + 0.055)/1.055) , Csrgb > 0.04045
+ * { 12.92*Clinear, Clinear <= 0.0031308
+ * Csrgb = { 1/2.4
+ * { (1.055)*Clinear - 0.055, Clinear > 0.0031308
*/
- if (CsRGB == 1.0) {
+ if (Clinear == 1.0) {
return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */
- } else if (CsRGB <= 0.040449936) {
- return CsRGB/12.92;
+ } else if (Clinear > 0.0031308) {
+ return 1.055*pow(Clinear, 1.0/2.4) - 0.055;
} else {
- return pow((CsRGB + 0.055)/1.055, 2.4);
+ return 12.92*Clinear;
}
}
-/* Convert from sRGB space */
+/* Export dmnsn_sRGB_C */
+double
+dmnsn_sRGB_gamma(double Clinear)
+{
+ return dmnsn_sRGB_C(Clinear);
+}
+
+/* Convert to sRGB space */
dmnsn_color
-dmnsn_color_from_sRGB(dmnsn_color color)
+dmnsn_color_to_sRGB(dmnsn_color color)
{
dmnsn_color ret = {
- .R = dmnsn_sRGB_C_inv(color.R),
- .G = dmnsn_sRGB_C_inv(color.G),
- .B = dmnsn_sRGB_C_inv(color.B),
+ .R = dmnsn_sRGB_C(color.R),
+ .G = dmnsn_sRGB_C(color.G),
+ .B = dmnsn_sRGB_C(color.B),
.trans = color.trans,
.filter = color.filter,
};
return ret;
}
-/** sRGB's `C' function. */
-static double
-dmnsn_sRGB_C(double Clinear)
+/* Inverse function of sRGB's `C' function, for the reverse conversion. */
+double
+dmnsn_sRGB_C_inv(double CsRGB)
{
/*
- * If C represents R, G, and B, then the sRGB values are now found as follows:
+ * If C represents R, G, and B, then the Clinear values are now found as
+ * follows:
*
- * { 12.92*Clinear, Clinear <= 0.0031308
- * Csrgb = { 1/2.4
- * { (1.055)*Clinear - 0.055, Clinear > 0.0031308
+ * { Csrgb/12.92, Csrgb <= 0.04045
+ * Clinear = { 1/2.4
+ * { ((Csrgb + 0.055)/1.055) , Csrgb > 0.04045
*/
- if (Clinear == 1.0) {
+ if (CsRGB == 1.0) {
return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */
- } else if (Clinear <= 0.0031308) {
- return 12.92*Clinear;
+ } else if (CsRGB <= 0.040449936) {
+ return CsRGB/12.92;
} else {
- return 1.055*pow(Clinear, 1.0/2.4) - 0.055;
+ return pow((CsRGB + 0.055)/1.055, 2.4);
}
}
-/* Convert to sRGB space */
+/* Export dmnsn_sRGB_C_inv */
+double
+dmnsn_sRGB_inverse_gamma(double CsRGB)
+{
+ return dmnsn_sRGB_C_inv(CsRGB);
+}
+
+/* Convert from sRGB space */
dmnsn_color
-dmnsn_color_to_sRGB(dmnsn_color color)
+dmnsn_color_from_sRGB(dmnsn_color color)
{
dmnsn_color ret = {
- .R = dmnsn_sRGB_C(color.R),
- .G = dmnsn_sRGB_C(color.G),
- .B = dmnsn_sRGB_C(color.B),
+ .R = dmnsn_sRGB_C_inv(color.R),
+ .G = dmnsn_sRGB_C_inv(color.G),
+ .B = dmnsn_sRGB_C_inv(color.B),
.trans = color.trans,
.filter = color.filter,
};
diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h
index 8470957..295400b 100644
--- a/libdimension/dimension/color.h
+++ b/libdimension/dimension/color.h
@@ -85,10 +85,15 @@ dmnsn_color_saturate(dmnsn_color color)
/* Perceptual color manipulation */
-/** Convert from sRGB space. */
-dmnsn_color dmnsn_color_from_sRGB(dmnsn_color color);
+/** Apply sRGB gamma */
+double dmnsn_sRGB_gamma(double Clinear);
/** Convert to sRGB space. */
dmnsn_color dmnsn_color_to_sRGB(dmnsn_color color);
+/** Remove sRGB gamma */
+double dmnsn_sRGB_inverse_gamma(double CsRGB);
+/** Convert from sRGB space. */
+dmnsn_color dmnsn_color_from_sRGB(dmnsn_color color);
+
/** Greyscale color intensity. */
double dmnsn_color_intensity(dmnsn_color color);
/** Add two colors together. */
diff --git a/libdimension/tests/render.c b/libdimension/tests/render.c
index ae4a644..abd88d6 100644
--- a/libdimension/tests/render.c
+++ b/libdimension/tests/render.c
@@ -31,11 +31,7 @@ dmnsn_test_scene_set_defaults(dmnsn_scene *scene)
default_finish->ambient = dmnsn_new_basic_ambient(
dmnsn_color_from_sRGB(dmnsn_color_mul(0.1, dmnsn_white))
);
- default_finish->diffuse = dmnsn_new_lambertian(
- dmnsn_color_intensity(
- dmnsn_color_from_sRGB(dmnsn_color_mul(0.7, dmnsn_white))
- )
- );
+ default_finish->diffuse = dmnsn_new_lambertian(dmnsn_sRGB_inverse_gamma(0.7));
}
static void
@@ -130,9 +126,10 @@ dmnsn_test_scene_add_hollow_cube(dmnsn_scene *scene)
cube->texture = dmnsn_new_texture();
cube->texture->pigment = dmnsn_new_solid_pigment(cube_color);
- dmnsn_color reflect = dmnsn_color_mul(0.5, dmnsn_white);
- cube->texture->finish.reflection
- = dmnsn_new_basic_reflection(dmnsn_black, reflect, 1.0);
+ dmnsn_color reflect =
+ dmnsn_color_from_sRGB(dmnsn_color_mul(0.5, dmnsn_white));
+ cube->texture->finish.reflection =
+ dmnsn_new_basic_reflection(dmnsn_black, reflect, 1.0);
cube->interior = dmnsn_new_interior();
cube->interior->ior = 1.1;
@@ -140,7 +137,8 @@ dmnsn_test_scene_add_hollow_cube(dmnsn_scene *scene)
dmnsn_object *sphere = dmnsn_new_sphere();
sphere->texture = dmnsn_new_texture();
sphere->texture->pigment = dmnsn_new_solid_pigment(dmnsn_green);
- sphere->texture->finish.specular = dmnsn_new_phong(0.2, 40.0);
+ sphere->texture->finish.specular =
+ dmnsn_new_phong(dmnsn_sRGB_inverse_gamma(0.2), 40.0);
sphere->trans = dmnsn_scale_matrix(dmnsn_new_vector(1.25, 1.25, 1.25));
dmnsn_object *hollow_cube = dmnsn_new_csg_difference(cube, sphere);