[orx-fx] Add Duotone, DuotoneGradient, LumaHalftone, Posterize, RgbToOkLab, OkLabToRgb

This commit is contained in:
Edwin Jakobs
2022-02-07 09:04:17 +01:00
parent 4fa6c05652
commit 52124ea409
20 changed files with 543 additions and 6 deletions

View File

@@ -0,0 +1,64 @@
#pragma import color.oklab_to_linear_rgb
#pragma import color.linear_rgb_to_oklab
#pragma import color.linear_rgb_to_srgb
#pragma import color.srgb_to_linear_rgb
uniform vec4 tint;
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform vec4 backgroundColor0;
uniform vec4 foregroundColor0;
uniform vec4 backgroundColor1;
uniform vec4 foregroundColor1;
uniform bool labInterpolation;
uniform float rotation;
out vec4 o_color;
void main() {
vec4 c = texture(tex0, v_texCoord0);
if (c.a != 0.0) {
c.rgb /= c.a;
}
float ca = cos(radians(rotation));
float sa = sin(radians(rotation));
mat2 rm = mat2(vec2(ca, sa), vec2(-sa, ca));
float f = (rm * (v_texCoord0 - vec2(0.5)) + vec2(0.5)).x;
vec4 bg0 = backgroundColor0;
bg0.rgb *= backgroundColor0.a;
vec4 fg0 = foregroundColor0;
fg0.rgb *= foregroundColor0.a;
vec4 bg1 = backgroundColor1;
bg1.rgb *= backgroundColor1.a;
vec4 fg1 = foregroundColor1;
fg1.rgb *= foregroundColor1.a;
if (!labInterpolation) {
vec4 bg = mix(bg0, bg1, f);
vec4 fg = mix(fg0, fg1, f);
o_color = mix(bg, fg, c.r) * c.a;
} else {
bg0 = srgb_to_linear_rgb(bg0);
bg0 = linear_rgb_to_oklab(bg0);
fg0 = srgb_to_linear_rgb(fg0);
fg0 = linear_rgb_to_oklab(fg0);
bg1 = srgb_to_linear_rgb(bg1);
bg1 = linear_rgb_to_oklab(bg1);
fg1 = srgb_to_linear_rgb(fg1);
fg1 = linear_rgb_to_oklab(fg1);
vec4 bg = mix(bg0, bg1, f);
vec4 fg = mix(fg0, fg1, f);
vec4 m = mix(bg, fg, c.r);
m = oklab_to_linear_rgb(m);
m *= c.a;
m = linear_rgb_to_srgb(m);
o_color = m;
}
}

View File

@@ -0,0 +1,38 @@
#pragma import color.oklab_to_linear_rgb
#pragma import color.linear_rgb_to_oklab
#pragma import color.linear_rgb_to_srgb
#pragma import color.srgb_to_linear_rgb
uniform vec4 tint;
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform vec4 backgroundColor;
uniform vec4 foregroundColor;
uniform bool labInterpolation;
out vec4 o_color;
void main() {
vec4 c = texture(tex0, v_texCoord0);
if (c.a != 0.0) {
c.rgb /= c.a;
}
vec4 bg = backgroundColor;
bg.rgb *= backgroundColor.a;
vec4 fg = foregroundColor;
fg.rgb *= foregroundColor.a;
if (!labInterpolation) {
o_color = mix(bg, fg, c.r) * c.a;
} else {
bg = srgb_to_linear_rgb(bg);
bg = linear_rgb_to_oklab(bg);
fg = srgb_to_linear_rgb(fg);
fg = linear_rgb_to_oklab(fg);
vec4 m = mix(bg, fg, c.r);
m = oklab_to_linear_rgb(m);
m *= c.a;
m = linear_rgb_to_srgb(m);
o_color = m;
}
}

View File

@@ -0,0 +1,12 @@
#pragma import color.oklab_to_linear_rgb
#pragma import color.linear_rgb_to_srgb
out vec4 o_output;
in vec2 v_texCoord0;
uniform sampler2D tex0;
void main() {
vec4 lab = texture(tex0, v_texCoord0);
vec4 rgba = oklab_to_linear_rgb(lab);
o_output = linear_rgb_to_srgb(rgba);
}

View File

@@ -0,0 +1,26 @@
in vec2 v_texCoord0;
uniform int window;
uniform sampler2D tex0;
uniform int levels;
out vec4 o_output;
void main() {
vec4 c = texture(tex0, v_texCoord0);
vec2 step = 1.0 / textureSize(tex0, 0);
float w = 0.0;
vec3 s = vec3(0.0);
for (int v = -window; v <= window; ++v) {
for (int u = -window; u <= window; ++u) {
vec4 c = texture(tex0, v_texCoord0 + (step/(2*window)) * vec2(u,v) );
if (c.a != 0.0) {
c.rgb /= c.a;
}
vec3 q = min(floor(c.rgb * (levels))/(levels-1), vec3(1.0));
s += q;
w += 1.0;
}
}
vec3 q = s / w;
o_output = vec4(q*c.a, c.a);
}

View File

@@ -0,0 +1,12 @@
#pragma import color.linear_rgb_to_oklab
#pragma import color.srgb_to_linear_rgb
out vec4 o_output;
in vec2 v_texCoord0;
uniform sampler2D tex0;
void main() {
vec4 srgba = texture(tex0, v_texCoord0);
vec4 rgba = srgb_to_linear_rgb(srgba);
o_output = linear_rgb_to_oklab(rgba);
}

View File

@@ -128,10 +128,8 @@ float snoise(vec3 v)
}
vec3 segment(vec3 t, int x, int y) {
float sx = x == 0? t.x : floor(t.x * x) / x;
float sy = y == 0? t.y : floor(t.y * y) / y;
return vec3(sx,sy, t.z);
}

View File

@@ -0,0 +1,62 @@
uniform float scale;
uniform float rotation;
in vec2 v_texCoord0;
uniform sampler2D tex0;
out vec4 o_color;
uniform float threshold;
uniform float freq0;
uniform float freq1;
uniform float gain1;
uniform float phase0;
uniform float phase1;
uniform bool invert;
float cosine_sample(vec2 uv){
float ca = cos(radians(rotation));
float sa = sin(radians(rotation));
vec2 ts = textureSize(tex0, 0);
mat2 rm = mat2(1.0, 0.0, 0.0, ts.x/ts.y) * mat2(vec2(ca, sa), vec2(-sa, ca)) * mat2(1.0, 0.0, 0.0, ts.y/ts.x);
vec2 cuv = (rm * (uv - vec2(0.5))) + vec2(0.5);
float m = fract(phase0 + cuv.x*freq0 + cos(cuv.y*freq1+phase1*3.141592653)*gain1);
vec4 c = texture(tex0, v_texCoord0);
if (c.a != 0.0) {
c.rgb /= c.a;
}
float l = dot(vec3(1.0/3.0), c.rgb);
if (invert) {
l = 1 - l;
}
float t = 0.0;
t = step(threshold, l * m);
return t;
}
float cosine_halftone(vec2 uv) {
int w = 3;
vec2 step = 1.0 / textureSize(tex0, 0);
step /= (2*w);
float weight = 0.0;
float sum = 0.0;
for (int v = -w; v <= w; ++v) {
for (int u = -w; u <= w; ++u) {
sum += cosine_sample(uv + step * vec2(u, v));
weight+=1;
}
}
return sum / weight;
}
void main() {
vec4 c = texture(tex0, v_texCoord0);
float t = cosine_halftone(v_texCoord0);
if (invert) {
t = 1 - t;
}
o_color = vec4(t, t, t, 1.0) * c.a;
}