lygia
/color
/space
/rgb2ryb
)Converts a color from RGB to RYB color space. Based on http://nishitalab.org/user/UEI/publication/Sugita_IWAIT2015.pdf and https://bahamas10.github.io/ryb/assets/ryb.pdf
Dependencies:
Use:
<vec3|vec4> ryb2rgb(<vec3|vec4> ryb)
#ifndef RYB_LERP
#define RYB_LERP(A, B, t) cubicMix(A, B, t)
#endif
#ifndef FNC_RGB2RYB
#define FNC_RGB2RYB
#ifdef RYB_FAST
vec3 rgb2ryb(vec3 rgb) {
// Remove the white from the color
float w = mmin(rgb);
float bl = mmin(1.0 - rgb);
rgb -= w;
float max_g = mmax(rgb);
// Get the yellow out of the red & green
float y = mmin(rgb.rg);
vec3 ryb = rgb - vec3(y, y, 0.);
// If this unfortunate conversion combines blue and green, then cut each in half to preserve the value's maximum range.
if (ryb.b > 0. && ryb.y > 0.) {
ryb.b *= .5;
ryb.y *= .5;
}
// Redistribute the remaining green.
ryb.b += ryb.y;
ryb.y += y;
// Normalize to values.
float max_y = mmax(ryb);
ryb *= (max_y > 0.) ? max_g / max_y : 1.;
// Add the white back in.
#ifdef RYB_FAST
return ryb + w;
#else
return ryb + bl;
#endif
}
#else
vec3 rgb2ryb(vec3 rgb) {
const vec3 rgb000 = vec3(1., 1., 1.); // Black
const vec3 rgb100 = vec3(1., 0., 0.); // Red
const vec3 rgb010 = vec3(0., 1., .483); // Green
const vec3 rgb110 = vec3(0., 1., 0.); // Yellow
const vec3 rgb001 = vec3(0., 0., 1.); // Blue
const vec3 rgb101 = vec3(.309, 0., .469); // Magenta
const vec3 rgb011 = vec3(0., .053, .210); // Turquoise
const vec3 rgb111 = vec3(0., 0., 0.); // White
return RYB_LERP(RYB_LERP(
RYB_LERP(rgb000, rgb001, rgb.z),
RYB_LERP(rgb010, rgb011, rgb.z),
rgb.y), RYB_LERP(
RYB_LERP(rgb100, rgb101, rgb.z),
RYB_LERP(rgb110, rgb111, rgb.z),
rgb.y), rgb.x);
}
#endif
vec4 rgb2ryb(vec4 rgb) { return vec4(rgb2ryb(rgb.rgb), rgb.a); }
#endif
Dependencies:
Use:
<float3|float4> ryb2rgb(<float3|float4> ryb)
#ifndef RYB_LERP
#define RYB_LERP(A, B, t) cubicMix(A, B, t)
#endif
#ifndef FNC_RGB2RYB
#define FNC_RGB2RYB
#ifdef RYB_FAST
float3 rgb2ryb(float3 rgb) {
// Remove the white from the color
float w = mmin(rgb);
float bl = mmin(1.0 - rgb);
rgb -= w;
float max_g = mmax(rgb);
// Get the yellow out of the red & green
float y = mmin(rgb.rg);
float3 ryb = rgb - float3(y, y, 0.);
// If this unfortunate conversion combines blue and green, then cut each in half to preserve the value's maximum range.
if (ryb.b > 0. && ryb.y > 0.) {
ryb.b *= .5;
ryb.y *= .5;
}
// Redistribute the remaining green.
ryb.b += ryb.y;
ryb.y += y;
// Normalize to values.
float max_y = mmax(ryb);
ryb *= (max_y > 0.) ? max_g / max_y : 1.;
// Add the white back in.
#ifdef RYB_FAST
return ryb + w;
#else
return ryb + bl;
#endif
}
#else
float3 rgb2ryb(float3 rgb) {
const float3 rgb000 = float3(1., 1., 1.); // Black
const float3 rgb100 = float3(1., 0., 0.); // Red
const float3 rgb010 = float3(0., 1., .483); // Green
const float3 rgb110 = float3(0., 1., 0.); // Yellow
const float3 rgb001 = float3(0., 0., 1.); // Blue
const float3 rgb101 = float3(.309, 0., .469); // Magenta
const float3 rgb011 = float3(0., .053, .210); // Turquoise
const float3 rgb111 = float3(0., 0., 0.); // White
return RYB_LERP(RYB_LERP(
RYB_LERP(rgb000, rgb001, rgb.z),
RYB_LERP(rgb010, rgb011, rgb.z),
rgb.y), RYB_LERP(
RYB_LERP(rgb100, rgb101, rgb.z),
RYB_LERP(rgb110, rgb111, rgb.z),
rgb.y), rgb.x);
}
#endif
float4 rgb2ryb(float4 rgb) { return float4(rgb2ryb(rgb.rgb), rgb.a); }
#endif
Dependencies:
Use:
<float3|float4> ryb2rgb(<float3|float4> ryb)
#ifndef RYB_LERP
#define RYB_LERP(A, B, t) cubicMix(A, B, t)
#endif
#ifndef FNC_RGB2RYB
#define FNC_RGB2RYB
#ifdef RYB_FAST
float3 rgb2ryb(float3 rgb) {
// Remove the white from the color
float w = mmin(rgb);
float bl = mmin(1.0 - rgb);
rgb -= w;
float max_g = mmax(rgb);
// Get the yellow out of the red & green
float y = mmin(rgb.rg);
float3 ryb = rgb - float3(y, y, 0.);
// If this unfortunate conversion combines blue and green, then cut each half to preserve the value's maximum range.
if (ryb.b > 0. && ryb.y > 0.) {
ryb.b *= .5;
ryb.y *= .5;
}
// Redistribute the remaining green.
ryb.b += ryb.y;
ryb.y += y;
// Normalize to values.
float max_y = mmax(ryb);
ryb *= (max_y > 0.) ? max_g / max_y : 1.;
// Add the white back in.
#ifdef RYB_FAST
return ryb + w;
#else
return ryb + bl;
#endif
}
#else
float3 rgb2ryb(float3 rgb) {
constant float3 rgb000 = float3(1., 1., 1.); // Black
constant float3 rgb100 = float3(1., 0., 0.); // Red
constant float3 rgb010 = float3(0., 1., .483); // Green
constant float3 rgb110 = float3(0., 1., 0.); // Yellow
constant float3 rgb001 = float3(0., 0., 1.); // Blue
constant float3 rgb101 = float3(.309, 0., .469); // Magenta
constant float3 rgb011 = float3(0., .053, .210); // Turquoise
constant float3 rgb111 = float3(0., 0., 0.); // White
return RYB_LERP(RYB_LERP(
RYB_LERP(rgb000, rgb001, rgb.z),
RYB_LERP(rgb010, rgb011, rgb.z),
rgb.y), RYB_LERP(
RYB_LERP(rgb100, rgb101, rgb.z),
RYB_LERP(rgb110, rgb111, rgb.z),
rgb.y), rgb.x);
}
#endif
float4 rgb2ryb(float4 rgb) { return float4(rgb2ryb(rgb.rgb), rgb.a); }
#endif
Dependencies:
Use:
<vec3f> ryb2rgb(<vec3f> ryb)
fn rgb2ryb(rgb: vec3f) -> vec3f {
let rgb000 = vec3f(1., 1., 1.); // Black
let rgb100 = vec3f(1., 0., 0.); // Red
let rgb010 = vec3f(0., 1., .483); // Green
let rgb110 = vec3f(0., 1., 0.); // Yellow
let rgb001 = vec3f(0., 0., 1.); // Blue
let rgb101 = vec3f(.309, 0., .469); // Magenta
let rgb011 = vec3f(0., .053, .210); // Turquoise
let rgb111 = vec3f(0., 0., 0.); // White
return cubeMix3(cubeMix3(
cubeMix3(rgb000, rgb001, rgb.z),
cubeMix3(rgb010, rgb011, rgb.z),
rgb.y), cubeMix3(
cubeMix3(rgb100, rgb101, rgb.z),
cubeMix3(rgb110, rgb111, rgb.z),
rgb.y), rgb.x);
}
LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.
Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).
It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.
Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository