Reptorian G'MIC Filters

Nice! There are at least 2 less dos. The less loopy loops, the less labouring. :slight_smile:

I have pushed rep_primelist cli and rep_prime_surface (The algorithm is slow, but miles faster than the earlier one), better version of Grouped Pixels Shift filter, some undeveloped cli only pushed there for development purpose and backup.


2/10/2020

Object Size Filtering has been upgraded. It’s a bit harder to use now, but also far more flexible

Other details:

  1. I fixed descriptor for Nebulous

  2. I have added credits to @Asmageddon Prince in Logarithmic Distortion series.


2/22/2020

Rewrite of Object Size Filtering GUI again. I think there exists dynamic gui issue on the auto side of things because of alpha threshold. It’ll do for now.


2/25/2020

Small new feature added to Glass Vignette - Len Size (%)

All this does is change the size of len distortion. Now the extension of TechnoRobbo’s PDN Glass Vignette is completed. I wanted to do this for a while.


2/26/2020

3 New Filters

  1. Point Warp
  2. Prime Surface
  3. Pixel Push

2/27/2020

I am now working on the donut distortion filter again! Literally! I am a bit closer to doing it. I looked at cos graph to figure out the variety of modes in here by finding the relationship between y and x location using pi as base. - Donut distortion Effect Plugin - Plugins - Publishing ONLY! - paint.net Forum .

EDIT: New Code. This one actually supports relative coordinate. So, now you can place the distortion elsewhere by editing shift.

#$1=_torus_circu_min_dimension_percent_1#
#$2=_torus_circu_min_dimension_percent_2#
#$3=_mode_1#
#$4=_mode_2#
#$5=_mode_percent_comb#
#$6=_offset#
#$7=_offset_duplicates#
#$8=_interpolation#
#$9=_boundary#
#$10=_eff_mix#

{w*2},{h*2},1,1,"
    begin(
    ww=w-1;
    hh=h-1;
    sd=max(w,h)/min(w,h);
    sx=w>h?sd:1;
    sy=w>h?1:sd;
    torus_val_1=.85;
    torus_val_2=.05;
    new_min=min(torus_val_1,torus_val_2);
    new_max=max(torus_val_1,torus_val_2);
    old_max=max(1,0);
    old_min=min(1,0);
    nm(v)=((old_max-old_min)/(new_max-new_min))*(v-new_max)+new_max;
    oldcut(v)=v>old_max?old_max:(v<old_min?old_min:v);
    bndcut(v)=v>old_max||v<old_min?0:1;
);
xx=(x/ww-.5)*2*sx;
yy=(y/hh-.5)*2*sy;
radial_gradient=sqrt(xx^2+yy^2);
[oldcut(nm(radial_gradient)),bndcut(nm(radial_gradient))];
"

r2dx. 50%,3
r. 100%,100%,100%,2

f. "begin(
    dist=min(w,h)/2;
    sd=max(w,h)/min(w,h);
    sx=w>h?sd:1;
    sy=w>h?1:sd;
    ww=w-1;
    hh=h-1;
    max_ang=20;
    max_ang*=-1;
    ang2rad(v)=pi*(v/180);
    rot_x(a,b,c)=a*cos(ang2rad(c))-b*sin(ang2rad(c));
    rot_y(a,b,c)=a*sin(ang2rad(c))+b*cos(ang2rad(c));
    softmode(v)=(cos(v*(2*pi)-pi)+1)/2;
    midmode(v)=abs(cos(v*pi+pi/2));
    hardmode(v)=sqrt(1-(abs(v-.5)*2)^2);
    distroymode(v)=cos(v*pi)*i1;
    invdistroymode(v)=(cos(v*pi)*-1)*i1;
    quadextrudemode(v)=1-abs(v-.5)*2;
    hexextrudemode(v)=(r=(1-abs(v-.5)*2)*2;r>1?1:r);
);
z_depth=hexextrudemode(i0)*max_ang;
xx=(x/ww-.5)*2*sx;
yy=(y/hh-.5)*2*sy;
XX=rot_x(xx,yy,z_depth);
YY=rot_y(xx,yy,z_depth);
XX/=2*sx;
YY/=2*sy;
XX+=.5;
YY+=.5;
XX*=ww;
YY*=hh;
[x-XX,y-YY]
"

shift. 0%,0%,0,0,2,1

f[^-1] "i(x-i(#-1,x,y,z,0),y-i(#-1,x,y,z,1),z,c,1,3)"
rm.

2/29/2020

New filter released! Donut Distortion

EDIT: It’s now Rotate By Torus Map

2 Likes

@garagecoder I think I have discovered the secret of your warp filter.

channels 0
f "
xx=x/w-.5;
yy=y/h-.5;
xx*=2;yy*=2;
1-sqrt(xx^2+yy^2);
"
f "
vert_top=i+j(0,-1,z,c,0,1);
vert_bottom=i+j(0,1,z,c,0,1);
vert=vert_bottom-vert_top;
land_top=i+j(-1,0,z,c,0,1);
land_bottom=i+j(1,0,z,c,0,1);
land=land_top-land_bottom;
((atan2(land,-vert)+pi)/(2*pi))*255;
"

The result looks good too. I see the direction in which the slope is going. So, I think I can make my own warp filters. This is my own approach where I wanted the center pixel to be factored in.

The Rotate by Torus Top filter I have made on top of this finding did made me realize that I can make plugins such as Squirkle Warp for Paint.NET as well as clipboard warp filter.

Try making a Lensball Springrimw. :wink:

I’m working on a new filter - Based off TechnoRobbo’s Strange Attractor

image

Sadly, I don’t get results like these so often. So, I believe I would need to implement an auto redo system here.

srand 2353252
max_width=${-max_w}
max_height=${-max_h}
$max_width,$max_height,1,1
Algo=4

eval ${-math_lib}"
Density=5;
interpolate(a,b)=a*-b+(1-a)*b;

cenx="$max_width"/2;
ceny="$max_height"/2;

xc=0;
yc=0;
zc=0;

Amount=vector9(u(0,1),u(0,1),u(0,1),u(0,1),u(0,1),u(0,1),u(0,1),u(0,1),u(0,1));

ap="$Algo";

if(ap<=4,
    a=interpolate(Amount[0],3);
    b=interpolate(Amount[1],3);
    
    if(ap!=3&&ap<4,
        c=interpolate(Amount[2],3);
        d=interpolate(Amount[3],3);
    ,
        e=interpolate(Amount[4],3);
        f=interpolate(Amount[5],3);
    );
    
    if(ap<2,xc=.5;yc=.5;,
    if(ap==2,xc=-1;
    );
    );
,
    if(ap==5,
        a=interpolate(Amount[0],2);
        b=interpolate(Amount[1],2);
        c=interpolate(Amount[2],2);
        d=interpolate(Amount[3],2);
        e=interpolate(Amount[4],2);
        f=interpolate(Amount[5],2);
        g=interpolate(Amount[6],2);
        h=interpolate(Amount[7],2);
        i=interpolate(Amount[8],2);
        ,
        a=interpolate(Amount[0],3);
        b=interpolate(Amount[1],3);
        c=interpolate(Amount[2],3);
        d=interpolate(Amount[3],3);
        e=interpolate(Amount[4],3);
        f=interpolate(Amount[5],3);
    );
);

if(ap==0,
    xnf(coordx,coordy)=sin(coordy*b)+c*sin(b*coordx);
    ynf(coordx,coordy)=sin(a*coordx)+d*sin(a*coordy);,
if(ap==1,
    xnf(coordx,coordy)=sin(coordy*a)+cos(c*coordx);
    ynf(coordx,coordy)=sin(c*coordx)-cos(d*coordy);,
if(ap==2,
    xnf(coordx,coordy)=abs(sin(coordy*a)^3)+cos(c*coordx);
    ynf(coordx,coordy)=abs(sin(c*coordx)^2)-cos(d*coordy)^2;,
if(ap==3,
    xnf(coordx,coordy)=sin(coordy*a)+cos(a*coordx);
    ynf(coordx,coordy)=sin(b*coordx)-cos(b*coordy);,
if(ap==4,
    xnf(coordx,coordy,coordz)=coordz*sin(a*coordx)-cos(b*coordy);
    ynf(coordx,coordy,coordz)=coordx*cos(c*coordy)+sin(d*coordz);
    znf(coordx,coordy,coordz)=coordy*sin(e*coordz)-cos(f*coordy);,
if(ap==5,
    xnf(coordx,coordy,coordz)=coordy*sin(a*coordx)+cos(b*coordy)+sin(c*coordz);
    ynf(coordx,coordy,coordz)=coordz*sin(d*coordx)+cos(e*coordy)+sin(f*coordz);
    znf(coordx,coordy,coordz)=coordx*sin(g*coordx)+cos(h*coordy)+sin(i*coordz);
#if[ap==6#,
    xnf_3d(coordx,coordy,coordz)=coordz*sin(a*coordx)+cos(b*coordy);
    ynf_3d(coordx,coordy,coordz)=coordx*sin(c*coordy)+cos(d*coordz);
    znf_3d(coordx,coordy,coordz)=coordy*sin(e*coordz)+cos(f*coordx);
);
);
);
);
);
);

td=Density*10^6;
mnX=0;
MnX=0;
mnY=0;
MnY=0;

if(ap>3,
    for(n=0,n<td,n++,
        xn=xnf(xc,yc);
        yn=ynf(xc,yc);
        xc=xn;
        yc=yn;
        nX=xn*150+cenx;
        nY=yn*150+ceny;
        if(inrange(nX,0,"$max_width",1)&&inrange(nY,0,"$max_height",1),
            i(#-1,nX,nY,z,0)+=1;
        );
    );
,
    for(n=0,n<td,n++,
        xn=xnf(xc,yc,zc);
        yn=ynf(xc,yc,zc);
        zn=znf(xc,yc,zc);
        xc=xn;
        yc=yn;
        zc=zn;
        nX=xn*200;
        nY=yn*200;
        MnX=max(MnX,nX);
        mnX=min(mnX,nX);
        MnY=max(MnY,nY);
        mnY=min(mnY,nY);
        px=(MnX-mnX)/2;
        py=(MnY-mnY)/2;
        nX+=px;
        nY+=py;
        if(inrange(nX,0,"$max_width",1)&&inrange(nY,0,"$max_height",1),
            i(#-1,nX,nY,z,0)+=1;
        );
    );
);


"
k.
1 Like

Maybe the Wiki entry I linked to earlier (Newton Fractals - #14 by afre) has helpful info…

I’ll have a look at that. I think I will have to try to play around with the formula to see if I can get more consistent result and more of what I’m looking for.

Never mind. I solved it by changing - to +.


I am figuring out how to create color scheme for attractor filter. Might take a while to figure out exactly how to make it.

First create a grayscale gradient. Then, shift the midgray. That’s easy though with the formula provided by the Pixel Pusher filter, but also exponential formula will work just as well. I would also need random colors. The random colors will then have to be mapped to the midgray shifted gray gradient. Finally, assign the coloring to the attractor. I get something like this below.


It seems that I have a possible way to define coloring of attractor fractal.

to_gray

out1=4
out2=2
out3=0

if   $out1==0 col_formula_a="(sin(a*pi)+1)/2";
elif $out1==1 col_formula_a="(cos(a*pi)+1)/2";
elif $out1==2 col_formula_a="(sin(a*pi+pi)^3+1)/2";
elif $out1==3 col_formula_a="(cos(a*pi+pi)^3+1)/2";
elif $out1==4 col_formula_a="((cos(a*pi+pi/2)*sin(a*pi+pi/2))^3+.125)*4";
fi


if   $out2==0 col_formula_b="(sin(a*pi+pi/2)+1)/2";
elif $out2==1 col_formula_b="(cos(a*pi+pi/2)+1)/2";
elif $out2==2 col_formula_b="(sin(a*pi+pi/2)^3+1)/2";
elif $out2==3 col_formula_b="(cos(a*pi+pi/2)^3+1)/2";
elif $out2==4 col_formula_b="((cos(a*pi+pi/4)*sin(a*pi+pi/4))^3+.125)*4";
fi


if   $out3==0 col_formula_c="(sin(a*pi+pi)+1)/2";
elif $out3==1 col_formula_c="(cos(a*pi+pi)+1)/2";
elif $out3==2 col_formula_c="(sin(a*pi)^3+1)/2";
elif $out3==3 col_formula_c="(cos(a*pi)^3+1)/2";
elif $out3==4 col_formula_c="((cos(a*pi)*sin(a*pi))^3+.125)*4";
fi


256,1,1,3,"
begin(
ww=w-1;
hh=h-1;

ch0=100%; mch0=1; vsf0=0; mwl0=1; out1=1; end2col1=0;
ch1=100%; mch1=1; vsf1=0; mwl1=1; out2=2; end2col2=0;
ch2=100%; mch2=1; vsf2=0; mwl2=1; out3=0; end2col3=0;

col_formula_a(a)="$col_formula_a";
col_formula_b(a)="$col_formula_b";
col_formula_c(a)="$col_formula_c";

);
slope=x/ww;

col_chan_zero = col_formula_a( mch0 * (slope^lerp(ch0*(1-slope),1,ch0)+vsf0));
col_chan_one  = col_formula_b( mch1 * (slope^lerp(ch1*(1-slope),1,ch1)+vsf1));
col_chan_two  = col_formula_c( mch2 * (slope^lerp(ch2*(1-slope),1,ch2)+vsf2));

mul_chan_zero = lerp( col_chan_zero , slope * col_chan_zero , mwl0 );
mul_chan_one  = lerp( col_chan_one  , slope * col_chan_one  , mwl1 );
mul_chan_two  = lerp( col_chan_two  , slope * col_chan_two  , mwl1 );

gray2col_zero = lerp( slope , mul_chan_zero , end2col1 );
gray2col_one  = lerp( slope , mul_chan_one  , end2col2 );
gray2col_two  = lerp( slope , mul_chan_two  , end2col3 );
[mul_chan_zero,mul_chan_one,mul_chan_two]

"
map.. . rm.
1 Like

@hover

I have released the Attractor filter. However, I decided to keep it grayscale as coloring is easily doable with 3 main programs that use it (GIMP, Krita, and Paint.NET) while not having much luck with trigonometric mapping.

Here’s a png result of the filter with some bit of trigonometric mapping

strange attractor


@David_Tschumperle I figured it out! This is what I did to make trigonometry filter has sync’d options.

fx_rep_tg3_preview:
cc1,cc2,cc3,cc4,cc5,cc6=$4,$5,$6,$7,$8,$9
cc=[$cc1,$cc2,$cc3,$cc4,$cc5,$cc6]
cc={($cc)[$3]}
cc1,cc2,cc3,cc4,cc5,cc6={[$cc,$cc,$cc,$cc,$cc,$cc]}
gui_split_preview "fx_rep_tg3 ${1-30}",${-3--1}
u "{$1}"\
"{$2}"\
"{$3}"\
"{"$cc1"}_"{$3==0?2:0}\
"{"$cc2"}_"{$3==1?2:0}\
"{"$cc3"}_"{$3==2?2:0}\
"{"$cc4"}_"{$3==3?2:0}\
"{"$cc5"}_"{$3==4?2:0}\
"{"$cc6"}_"{$3==5?2:0}
2 Likes

2 Likes

That’s just beautiful.


RPG Tiler filter V3 has been finished. I have added constants to some of my filters, so hopefully, I didn’t screw anything up.


I am about to fix two of my filters. Picture Mosaic and Stitch. Stitch works, however, I feel that it is not perfect. There is going to be a new posterize filter, but it’s just a fun filter. Picture Mosaic will have better cli support. By the end of this month, I will take a break as tiler filter was pretty long.


I have committed a new upgrade to my own picture mosaic filter.

New Filter - Grouped Pixels Shift By Rectangular Polar Transformation

Note: It’s kinda very buggy right now. Not that it’s hard to get around. :confused:

3 Likes

When you finish this would there be a way to add custom functions and/or maps for the gravity to follow?

Well, I consider it finished right now despite the bugs as I can’t solve them, but it works for the most part.

But, theoretically, it is doable. The way the current version of the filter works is using rectangular-polar transformation, and g’mic supports curves. So, if you figure out how to create a curve and make a shape out of it, and then find the point perpendicular to each end. But, that’s a bit complicated.

The other solution is to use a layer as a aid, and then erase based on the information found from the reference layer. Kind of a guide layer. If you can find the weighted center based on the reference layer. You can have the filter automatically find the point. I supposed I can use a pass argument to do this.

@Joan_Rake1 is getting restless. :slight_smile:
Me awaiting for the next creation. :crossed_fingers:

There will be only bug fixes for now and code refactoring. I think you noticed I have added const recently. I decided to focus back on Krita development.

At most, I will add neumann shifting to the tiler tool and grid option to tileset window.

If I feel like it, I’ll make a way to generate isometric tiles from image(s).

Why is this error showing up? Debug tells me zilch.

Operator '=': Invalid name specified for argument 1 when defining macro 'orddith()', in expression '... ); orddith(8ipx,cc,coefcount,ditherpattern)=int((((cc-1)*c(...)...'.```
#@cli rep_lpasc_ordith: 'eq to. rep_loupasc_ordered_dithered' : (+)
rep_lpasc_ordith: rep_loupasc_ordered_dithered $*
#@cli rep_loupasc_ordered_dithered : _dither_method={ 0=checkerboard | 1=dispersed | 2=arcade | 3=ordered | 4=lines | 5=custom | 6=rand }, _palette={ 0=Binary | 1= EGA | 2= Web-safe | 3=12-bit }
#@cli: Color reduction with dithering using algorithm provided by Pascal Ollive.
rep_loupasc_ordered_dithered:
f "begin(
    color_count=[2,4,6,16];
    custom_matrix=[34,14,3,22,6,27,21,8,26,13,30,1,29,18,33,5,20,12,9,0,19,28,10,32,16,31,7,17,2,25,4,24,15,35,23,11];
    line_matrix=[8,9,6,7,1,0,3,2,4,5,9,8,2,3,0,1,4,5,7,6,1,0,3,2,4,5,8,9,6,7,0,1,4,5,7,6,9,8,2,3,4,5,8,9,6,7,1,0,3,2,7,6,9,8,2,3,0,1,4,5,6,7,1,0,3,2,4,5,8,9,2,3,0,1,4,5,7,6,9,8,3,2,4,5,8,9,6,7,1,0,4,5,7,6,9,8,2,3,0,1];
    mat_rev(n)=(
        n = int(n);
        n = (n & 0x55555555) << 1 | (n >> 1) & 0x55555555;
        n = (n & 0x33333333) << 2 | (n >> 2) & 0x33333333;
        n = (n & 0x0f0f0f0f) << 4 | (n >> 4) & 0x0f0f0f0f;
        n = (n << 24) | ((n & 0xff00) << 8) | ((n >> 8) & 0xff00) | (n >> 24);
    );
    orddith(8ipx,cc,coefcount,ditherpattern)=int((((cc-1)*coefcount+1)*8ipx+255*ditherpattern-1)/(255*coefcount));
    randdit(8ipx,cc,nx,ny)=(
        sd=(mat_rev(ny)>>23)<<22|mat_rev(nx)>>10;
        ditp=(48271*sd)%2147483647;
    );
    if($1==0,appdit(8ipx,cc,nx,ny)=orddith(8ipx,cc,2,xor(nx,ny)&0x1);,
    if($1==1,appdit(8ipx,cc,nx,ny)=orddith(8ipx,cc,4,((xor(nx,ny)&0x1)<<1)|(ny&0x1)),
    if($1==2,appdit(8ipx,cc,nx,ny)=orddith(8ipx,cc,8,2+(ny&0x3));,
    if($1==3,appdit(8ipx,cc,nx,ny)=orddith(8ipx,cc,5,line_matrix[20*(ny%5)+2*(nx%5)]>>1);,
    if($1==4,appdit(8ipx,cc,nx,ny)=orddith(8ipx,cc,10,line_matrix[10*(ny%10)+(nx%10)]);,
    if($1==5,appdit(8ipx,cc,nx,ny)=orddith(8ipx,cc,36,custom_matrix[6*(ny%6)+(nx%6)]);,
             appdit(8ipx,cc,nx,ny)=randdit(8ipx,cc,nx,ny);
    );
    );
    );
    );
    );
    );
    const cc=color_count[$2];
    const cs=255/(cc-1);
);
appdit(i,cc,x,y);
"

A variable name cannot start with a number.

1 Like

Yeah, that what I found out. Obvious solution here. Feeling dumb now.


New filter Ordered Dithering! There’s some limitation, and there’s a source code.

I have a question here. Would anyone appreciate a filter something akin to apply_channels, but for every layers that a command has been applied to, they get cropped to their original dimension, and you can specify their relative location?