lygia
/v1.1.6
/color
/mixOklab
)Mix function by Inigo Quiles (https://www.shadertoy.com/view/ttcyRS) utilizing Bjorn Ottosso's OkLab color space, which is provide smooth stransitions Learn more about it his article
Dependencies:
Use:
<vec3\vec4> mixOklab(<vec3|vec4> colorA, <vec3|vec4> colorB, float pct)
#ifndef FNC_MIXOKLAB
#define FNC_MIXOKLAB
vec3 mixOklab( vec3 colA, vec3 colB, float h ) {
#ifdef MIXOKLAB_COLORSPACE_SRGB
colA = srgb2rgb(colA);
colB = srgb2rgb(colB);
#endif
// https://bottosson.github.io/posts/oklab
const mat3 kCONEtoLMS = mat3(
0.4121656120, 0.2118591070, 0.0883097947,
0.5362752080, 0.6807189584, 0.2818474174,
0.0514575653, 0.1074065790, 0.6302613616);
const mat3 kLMStoCONE = mat3(
4.0767245293, -1.2681437731, -0.0041119885,
-3.3072168827, 2.6093323231, -0.7034763098,
0.2307590544, -0.3411344290, 1.7068625689);
// rgb to cone (arg of pow can't be negative)
vec3 lmsA = pow( kCONEtoLMS * colA, vec3(1.0/3.0) );
vec3 lmsB = pow( kCONEtoLMS * colB, vec3(1.0/3.0) );
// lerp
vec3 lms = mix( lmsA, lmsB, h );
// cone to rgb
vec3 rgb = kLMStoCONE*(lms*lms*lms);
#ifdef MIXOKLAB_COLORSPACE_SRGB
return rgb2srgb(rgb);
#else
return rgb;
#endif
}
vec4 mixOklab( vec4 colA, vec4 colB, float h ) {
return vec4( mixOklab(colA.rgb, colB.rgb, h), mix(colA.a, colB.a, h) );
}
#endif
Dependencies:
Use:
<float3\float4> mixOklab(<float3|float4> colorA, <float3|float4> colorB, float pct)
#ifndef FNC_MIXOKLAB
#define FNC_MIXOKLAB
float3 mixOklab( float3 colA, float3 colB, float h ) {
#ifdef MIXOKLAB_COLORSPACE_SRGB
colA = srgb2rgb(colA);
colB = srgb2rgb(colB);
#endif
// https://bottosson.github.io/posts/oklab
const float3x3 kCONEtoLMS = float3x3(
0.4121656120, 0.2118591070, 0.0883097947,
0.5362752080, 0.6807189584, 0.2818474174,
0.0514575653, 0.1074065790, 0.6302613616);
const float3x3 kLMStoCONE = float3x3(
4.0767245293, -1.2681437731, -0.0041119885,
-3.3072168827, 2.6093323231, -0.7034763098,
0.2307590544, -0.3411344290, 1.7068625689);
float factor = 1.0/3.0;
// rgb to cone (arg of pow can't be negative)
float3 lmsA = pow( mul(kCONEtoLMS, colA), float3(factor, factor, factor) );
float3 lmsB = pow( mul(kCONEtoLMS, colB), float3(factor, factor, factor) );
// lerp
float3 lms = lerp( lmsA, lmsB, h );
// gain in the middle (no oaklab anymore, but looks better?)
// lms *= 1.0+0.2*h*(1.0-h);
// cone to rgb
float3 rgb = mul(kLMStoCONE, lms*lms*lms);
#ifdef MIXOKLAB_COLORSPACE_SRGB
return rgb2srgb(rgb);
#else
return rgb;
#endif
}
float4 mixOklab( float4 colA, float4 colB, float h ) {
return float4( mixOklab(colA.rgb, colB.rgb, h), lerp(colA.a, colB.a, h) );
}
#endif
fn mixOklab( colA: vec3<f32>, colB: vec3<f32>, h: f32 ) -> vec3<f32> {
let kCONEtoLMS = mat3x3<f32>(
vec3<f32>(0.4121656120, 0.2118591070, 0.0883097947),
vec3<f32>(0.5362752080, 0.6807189584, 0.2818474174),
vec3<f32>(0.0514575653, 0.1074065790, 0.6302613616) );
let kLMStoCONE = mat3x3<f32>(
vec3<f32>(4.0767245293, -1.2681437731, -0.0041119885),
vec3<f32>(-3.3072168827, 2.6093323231, -0.7034763098),
vec3<f32>(0.2307590544, -0.3411344290, 1.7068625689));
// rgb to cone (arg of pow can't be negative)
let lmsA = pow( kCONEtoLMS*colA, vec3<f32>(1.0/3.0) );
let lmsB = pow( kCONEtoLMS*colB, vec3<f32>(1.0/3.0) );
let lms = mix( lmsA, lmsB, h );
// gain in the middle (no oaklab anymore, but looks better?)
//lms *= 1.0+0.2*h*(1.0-h);
// cone to rgb
return kLMStoCONE*(lms*lms*lms);
}
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