[orx-fx] Refactor CMYKHalftone to support customizable elements/colors

This commit is contained in:
Edwin Jakobs
2025-03-10 10:59:52 +01:00
parent b74ad477c7
commit 977be4ee6f
2 changed files with 106 additions and 40 deletions

View File

@@ -2,14 +2,31 @@
package org.openrndr.extra.fx.dither package org.openrndr.extra.fx.dither
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.Filter1to1 import org.openrndr.draw.Filter1to1
import org.openrndr.draw.filterShaderFromCode
import org.openrndr.extra.fx.fx_cmyk_halftone import org.openrndr.extra.fx.fx_cmyk_halftone
import org.openrndr.extra.fx.mppFilterShader import org.openrndr.extra.parameters.ColorParameter
import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.extra.shaderphrases.sdf.sdCirclePhrase
@Description("CMYK Halftone") @Description("CMYK Halftone")
class CMYKHalftone: Filter1to1(mppFilterShader(fx_cmyk_halftone, "cmyk-halftone")) { class CMYKHalftone(
domainWarpFunction: String = "vec2 domainWarp(vec2 p) { return p; }",
elementFunction: String = """
$sdCirclePhrase
float element(in vec2 p, float v) {
return sdCircle(p, v * dotSize);
}""".trimIndent()
) : Filter1to1(
filterShaderFromCode(
fx_cmyk_halftone.split("#pragma INSERT_PHRASES").let {
listOf(it[0], elementFunction, domainWarpFunction, it[1])
}.joinToString("\n"),
"cmyk-halftone"
)
) {
@DoubleParameter("scale", 1.0, 30.0, precision = 4) @DoubleParameter("scale", 1.0, 30.0, precision = 4)
var scale: Double by parameters var scale: Double by parameters
@@ -19,9 +36,45 @@ class CMYKHalftone: Filter1to1(mppFilterShader(fx_cmyk_halftone, "cmyk-halftone"
@DoubleParameter("rotation", -180.0, 180.0) @DoubleParameter("rotation", -180.0, 180.0)
var rotation: Double by parameters var rotation: Double by parameters
@DoubleParameter("cyan rotation", -180.0, 180.0, precision = 4)
var cyanRotation: Double by parameters
@DoubleParameter("magenta rotation", -180.0, 180.0, precision = 4)
var magentaRotation: Double by parameters
@DoubleParameter("yellow rotation", -180.0, 180.0, precision = 4)
var yellowRotation: Double by parameters
@DoubleParameter("black rotation", -180.0, 180.0, precision = 4)
var blackRotation: Double by parameters
@ColorParameter("cyan color")
var cyanColor: ColorRGBa by parameters
@ColorParameter("magenta color")
var magentaColor: ColorRGBa by parameters
@ColorParameter("yellow color")
var yellowColor: ColorRGBa by parameters
@ColorParameter("black color")
var blackColor: ColorRGBa by parameters
var phase: Double by parameters
init { init {
blackRotation = 45.0
magentaRotation = 75.0
cyanRotation = 15.0
yellowRotation = 0.0
cyanColor = ColorRGBa.CYAN
magentaColor = ColorRGBa.MAGENTA
yellowColor = ColorRGBa.YELLOW
blackColor = ColorRGBa.BLACK
scale = 3.0 scale = 3.0
rotation = 0.0 rotation = 0.0
dotSize = 1.0 dotSize = 0.9
phase = 0.0
} }
} }

View File

@@ -1,17 +1,27 @@
/* Based on CMYK Halftone by tsone https://www.shadertoy.com/view/Mdf3Dn */ /* Based on CMYK Halftone by tsone https://www.shadertoy.com/view/Mdf3Dn */
uniform float dotSize; uniform float dotSize;
#define SST 0.888
#define SSQ 0.288
uniform float scale; uniform float scale;
uniform float rotation; uniform float rotation;
uniform float phase;
uniform float blackRotation;
uniform float yellowRotation;
uniform float magentaRotation;
uniform float cyanRotation;
uniform vec4 blackColor;
uniform vec4 yellowColor;
uniform vec4 magentaColor;
uniform vec4 cyanColor;
in vec2 v_texCoord0; in vec2 v_texCoord0;
uniform sampler2D tex0; uniform sampler2D tex0;
out vec4 o_color; out vec4 o_color;
#pragma INSERT_PHRASES
vec4 rgb2cmyki(in vec3 c) vec4 rgb2cmyki(in vec3 c)
{ {
float k = max(max(c.r, c.g), c.b); float k = max(max(c.r, c.g), c.b);
@@ -31,10 +41,10 @@ vec3 u(vec4 c) {
} }
vec4 cmyki2rgba(in vec4 cmyk) { vec4 cmyki2rgba(in vec4 cmyk) {
vec4 c = vec4(0.0, 1.0, 1.0, 1.0)*(1.0-cmyk.r); vec4 c = cyanColor * (1.0 - cmyk.r);
vec4 m = vec4(1.0, 0.0, 1.0, 1.0)*(1.0-cmyk.g); vec4 m = magentaColor * (1.0 - cmyk.g);
vec4 y = vec4(1.0, 1.0, 0.0, 1.0)*(1.0-cmyk.b); vec4 y = yellowColor * (1.0 - cmyk.b);
vec4 k = vec4(0.0, 0.0, 0.0, 1.0)*(1.0-cmyk.a); vec4 k = blackColor * (1.0 - cmyk.a);
vec4 f = c; vec4 f = c;
f = (1.0 - f.a) * m + f.a * vec4(u(f) * u(m), 1.0) * m.a + (1.0 - m.a) * f; f = (1.0 - f.a) * m + f.a * vec4(u(f) * u(m), 1.0) * m.a + (1.0 - m.a) * f;
@@ -56,43 +66,46 @@ vec2 grid(in vec2 px)
vec4 ss(in vec4 v) vec4 ss(in vec4 v)
{ {
return smoothstep(vec4(SST-SSQ), vec4(SST+SSQ), v); vec4 vw = fwidth(v);
return smoothstep(vec4(-vw), vec4(vw), v);
} }
vec4 halftone(in vec2 fc,in mat2 m)
float halftone(in vec2 fc, in mat2 m, int channel)
{ {
vec2 smp = (grid(m * fc) + 0.5 * scale) * m; vec2 smp = (grid(m * fc) + 0.5 * scale) * m;
float s = min(length(fc-smp) / (dotSize*0.5*scale), 1.0);
float s = length(fc - smp) / (dotSize * 2.0 * scale);
vec2 d2 = m * ((fc) - smp) / (dotSize * 0.5 * scale);
vec3 texc = texture(tex0, px2uv(smp + vec2(textureSize(tex0, 0)) / 2.0)).rgb; vec3 texc = texture(tex0, px2uv(smp + vec2(textureSize(tex0, 0)) / 2.0)).rgb;
vec4 c = rgb2cmyki(texc); float c = 1.0 - rgb2cmyki(texc)[channel];
return c+s; return element(d2, c);
} }
mat2 rotm(in float r) mat2 rotm(in float r) {
{
float cr = cos(r); float cr = cos(r);
float sr = sin(r); float sr = sin(r);
return mat2( return mat2(cr, -sr, sr, cr);
cr,-sr,
sr,cr
);
} }
void main() { void main() {
vec2 fc = v_texCoord0 * vec2(textureSize(tex0, 0)) - vec2(textureSize(tex0, 0))/2.0; vec2 fc = (v_texCoord0 - vec2(0.5)) * vec2(textureSize(tex0, 0));
fc = domainWarp(fc);
mat2 mc = rotm(rotation + radians(15.0)); mat2 mc = rotm(rotation + radians(cyanRotation));
mat2 mm = rotm(rotation + radians(75.0)); mat2 mm = rotm(rotation + radians(magentaRotation));
mat2 my = rotm(rotation); mat2 my = rotm(rotation + radians(yellowRotation));
mat2 mk = rotm(rotation + radians(45.0)); mat2 mk = rotm(rotation + radians(blackRotation));
float k = halftone(fc, mk).a; vec4 c = cmyki2rgba(
vec4 c = cmyki2rgba(ss(vec4( ss(vec4(
halftone(fc, mc).r, halftone(fc, mc, 0),
halftone(fc, mm).g, halftone(fc, mm, 1),
halftone(fc, my).b, halftone(fc, my, 2),
halftone(fc, mk).a halftone(fc, mk, 3)
))); )
)
);
o_color = c; o_color = c;
} }