Nice! There are at least 2 less do
s. The less loopy loops, the less labouring.
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:
-
I fixed descriptor for Nebulous
-
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
- Point Warp
- Prime Surface
- 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
@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.
I’m working on a new filter - Based off TechnoRobbo’s Strange Attractor
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.
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.
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
@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}
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.
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.
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.
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?