Jump to content
How to Install Plugins ×

Popcorn Fractal - 3/27/2022


Recommended Posts

This filter will generate a Popcorn Fractal on your canvas. It is computationally-intensive (Special note for that below).

 

Preview:

h8LoE6gGS2vRbihcB-M4FYzsa-u_tZXIIefbHt38

How to use:

 

1. Download Plugin -Popcorn Fractal.zip

2. Install into Paint.NET

3. Load Paint.NET and go into Effect->Render.

4. See how parameters work and change them until your desired result comes.

 

- Parameters -

 

Points - Amount of times a point will be calculated per subpixels
Density -  The size of subpixel.
H - Main Internal Function Multiplier
K - Trigonometric Function Multiplier

Zoom - Scale of Fractal
Angle - Angle of Fractal
Origin - Location of coordinate 0,0 in respect to canvas center
Trig Mode - Defines whether to use Trig-4 or Trig-6
X-S - First Trigonometric Function for X-Axis

X-T - Second Trigonometric Function for X-Axis
X-U -Third Trigonometric Function for X-Axis (Unavailable for Trig-4)

Y-S - First Trigonometric Function for Y-Axis

Y-T - Second Trigonometric Function for Y-Axis
Y-U -Third Trigonometric Function for Y-Axis (Unavailable for Trig-4)

Midpoint Shift - Shift Value toward 0 or 1 depending of whether this value is negative or positive
Multiplier - Multiply the value of Fractal. Only Applicable if norm is false.
Normalize - Just as name said. It results in 0-255.

 

- Special note -

 

For larger images, you may note that this plugin takes a lot of time rendering Popcorn Fractal. That is because the plugin use serial processing rather than parallel processing. I just had updated the G'MIC-QT version of this plugin which actually utilize parallel processing to address that issue. Until there is a solution for adding parallel processing to this plugin version, you may need to resort to g'mic-qt version of Popcorn Fractal though it's only 150%+ faster with larger images on 4 CPU computers.

 

- Source Codes -

License: CeCILL v2.0 - http://cecill.info/licences/Licence_CeCILL_V2-en.html

 

C# Codelab

Spoiler
// Name: Popcorn Fractal
// Submenu: Render
// Author: Reptorian, otuncelli
// Title: Popcorn Fractal
// Version: 2
// Desc: Render Popcorn Fractal into canvas. 
// Keywords: fractal
// URL: https://forums.getpaint.net/profile/85868-reptillian/
// Help: 
#region UICode
IntSliderControl pts = 50; // [1,100] Points
DoubleSliderControl var_density = 1; // [0.01,2] Density
DoubleSliderControl H = 0.05; // [-5,5] H
DoubleSliderControl K = 3; // [-75,75] K
DoubleSliderControl var_zoom = 1; // [0.1,4] Zoom
AngleControl var_ang = 0; // [-180,180] Angle
PanSliderControl Origin = Pair.Create(0.000, 0.000); // Origin
ListBoxControl TrigMode = 0; // Trig Mode|Trig-4|Trig-6
ListBoxControl func_x1 = 0; // X-S|Sinusoidal|Cosinusoidal|Tangent|Arc-Tangent
ListBoxControl func_x2 = 2; // X-T|Sinusoidal|Cosinusoidal|Tangent|Arc-Tangent
ListBoxControl func_x3 = 1; // {!TrigMode} X-U|Sinusoidal|Cosinusoidal|Tangent|Arc-Tangent
ListBoxControl func_y1 = 0; // Y-S|Sinusoidal|Cosinusoidal|Tangent|Arc-Tangent
ListBoxControl func_y2 = 2; // Y-T|Sinusoidal|Cosinusoidal|Tangent|Arc-Tangent
ListBoxControl func_y3 = 1; // {!TrigMode} Y-U|Sinusoidal|Cosinusoidal|Tangent|Arc-Tangent
DoubleSliderControl var_midpoint_shift = 0; // [-1,1] Midpoint Shift
DoubleSliderControl multiplier = 1; // [0.01,10] {!norm} Multiplier
CheckboxControl norm = false; // Normalize
#endregion

double rot_x(double a, double b, double cos_ang,double sin_ang){
    return a * cos_ang - b * sin_ang;
}

double rot_y(double a, double b, double cos_ang,double sin_ang){
    return a * sin_ang + b * cos_ang;
}


double func_v(double v,int c){
    switch(c){
       case 0: return Math.Sin(v);
       case 1: return Math.Cos(v);
       case 2: return Math.Tan(v);
       case 3: return Math.Atan(v);
    }
    return Math.Atan(v);
}

int maxnum;
int [,] Popcorn_Array;

IEnumerable<double> iter(double fromInclusive, double toExclusive, double step)
{
    for (double v = fromInclusive; v < toExclusive; v += step)
    {
        yield return v;
    }
}

void PreRender(Surface dst, Surface src)
{
    int w = src.Width;
    int h = src.Height;    
    bool sd_cond = w>h;
    double dw = (double)(w);
    double dh = (double)(h);
    if (Popcorn_Array == null){Popcorn_Array = new int [w,h];}
    else {Array.Clear(Popcorn_Array, 0, w*h);}
    bool use_trig6 = TrigMode == 1;
    double density = 1 / var_density;
    double zoom = 1 / var_zoom;
    double ang = (var_ang/180) * Math.PI;
    double origin_x = Origin.First * -1 * zoom;
    double origin_y = Origin.Second * zoom;
    double sd = Math.Max(dw,dh) / Math.Min(dw,dh);
    double sx = sd_cond ? sd : 1  ;
    double sy = sd_cond ? 1  : sd ;
    double cx = dw / 2;
    double cy = dh / 2;
    double osx = origin_x * sx ;
    double osy = origin_y * sy ;
    double cx_zoom = cx / zoom;
    double cy_zoom = cy / zoom;
    double cxsx = cx * sx;
    double cysy = cy * sy;
    double cos_ang = Math.Cos(ang);
    double sin_ang = Math.Sin(ang);
    bool angcondition = (var_ang - 360*Math.Floor(var_ang/360))>0;

    System.Threading.Tasks.Parallel.ForEach(iter(0, dw, density), (ix, loopState) =>
    {
        if (IsCancelRequested)
        {
            loopState.Stop();
            return;
        }

        for (double iy = 0; iy < dh; iy += density)
        {
            double xx = zoom * (ix - cx) / cx;
            double yy = zoom * (iy - cy) / cy;
            double xval, yval, xnew, ynew;
            xx *= sx;
            yy *= sy;
            xx += origin_x;
            yy += origin_y;

            for (int ptn = 0; ptn < pts; ptn++)
            {
                if (use_trig6)
                {
                    xnew = xx - H * func_v(yy + func_v(K * yy + func_v(K * yy, func_x3), func_x2), func_x1);
                    ynew = yy - H * func_v(xx + func_v(K * xx + func_v(K * xx, func_y3), func_y2), func_y1);
                }
                else
                {
                    xnew = xx - H * func_v(yy + func_v(K * yy, func_x2), func_x1);
                    ynew = yy - H * func_v(xx + func_v(K * xx, func_y2), func_y1);
                }

                if (angcondition)
                {
                    xval = ((rot_x(xnew, ynew, cos_ang, sin_ang) - osx) * cx_zoom + cxsx) / sx;
                    yval = ((rot_y(xnew, ynew, cos_ang, sin_ang) - osy) * cy_zoom + cysy) / sy;
                }
                else
                {
                    xval = ((xnew - osx) * cx_zoom + cxsx) / sx;
                    yval = ((ynew - osy) * cy_zoom + cysy) / sy;
                }

                int xpos = (int)(Math.Round(xval));
                int ypos = (int)(Math.Round(yval));

                if ((xpos >= 0 && ypos >= 0) && (xpos < w && ypos < h))
                {
                    int val = Interlocked.Increment(ref Popcorn_Array[xpos, ypos]);
                    if (val > maxnum)
                    {
                        Interlocked.Exchange(ref maxnum, val);
                    }
                }

                xx = xnew;
                yy = ynew;
            }
        }
    });

}

void Render(Surface dst, Surface src, Rectangle rect)
{
    double midpoint = 1 - Math.Abs(var_midpoint_shift);
    bool cond_midpoint = var_midpoint_shift>=0;
    double pval;
    int val;

    for (int y = rect.Top; y < rect.Bottom; y++)
    {        
        for (int x = rect.Left; x < rect.Right; x++)
        {
            pval = (double)(Popcorn_Array[x,y])/(double)(maxnum);
            if (cond_midpoint){pval=Math.Pow(pval,midpoint);}
            else {pval=1-(Math.Pow(1-pval,midpoint));}
            if(norm){pval*=255;}
            else {pval*=(double)(maxnum)*multiplier;}
            val=(int)(pval);
            dst[x,y]=ColorBgra.FromBgraClamped(val,val,val,255);
        }
    }
}
 

 

 

G'MIC-QT

Spoiler
#@cli rep_pfrac : eq. to 'rep_popcorn_fractal' : (+)
rep_pfrac: rep_popcorn_fractal $*
#@cli rep_popcorn_fractal: _points>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,_mode,_f1={ 0=sin | 1=cos | 2=tan | 3=atan},...
#@cli : Generates Pickover Popcorn Fractal. Code was adapted from Paul Bourke's c code, and extended for more possibilities. Fractal is attributed to Clifford Pickover.\n
#@cli : _points defines the maximum number of points to be added on image based on pixel location.
#@cli : _density defines the frequency of points to be added along row and height of image. A value of one implies n points to be added per pixel.
#@cli : _H is the function multiplier used to subtract from the new found values from each iteration.
#@cli : _K is the inner multiplier for the inside function. See popcorn_x(a,b), and popcorn_y(a,b) embedded within the code of rep_popcorn_fractal for more information.
#@cli : _zoom defines the magnification of image. A negative value will "shrink" the structure of generated fractal.
#@cli : _rotation_angle defines the function angle of fractal.
#@cli : _origin_x defines the position of fractal. Center of image row will be treated as zero, and the ranges for image row are treated as -1,1.
#@cli : _origin_y defines the position of fractal. Center of image column will be treated as zero, and the ranges for image column are treated as -1,1.
#@cli : _mode defines whether to use 4 trigonometric functions or 6 trigonometric functions. Each halves of functions are used on 2 functions used by different axis.
#@cli : _fn defines individual function used for the popcorn fractal.\n
#@cli : Author: Reptorian.
#@cli : Default values: '_points=50','density=1','H=.05','_K=3','zoom=1','_rotation_angle=0','_origin_x=0','_origin_y=0','_mode=0',...\n
#@cli : \ \ \ \ If _mode=0: ... = '_f1=_f3=0','_f2=_f4=2'
#@cli : \ \ \ \ If _mode=1: ... = '_f1=_f4=0','_f2=_f5=1','_f3=_f6=2'\n
rep_popcorn_fractal:
skip ${1=50},${2=1},${3=.05},${4=3},${5=1},${6=0},${7=0},${8=0},${9=0},${10=},${11=},${12=},${13=},${14=},${15=}

if ($6-360*floor($6/360))?1
 fvx=((rot_x(xnew,ynew)-osx)*icx_zoom+cxsx)/sx
 fvy=((rot_y(xnew,ynew)-osy)*icy_zoom+cysy)/sy
else
 fvx=((xnew-osx)*icx_zoom+cxsx)/sx
 fvy=((ynew-osy)*icy_zoom+cysy)/sy
fi

iw={w-1}
ih={h-1}

channels. 0 f. 0

{int(w*abs($2))},{int(h*abs($2))},1,1,":begin_t(
  const nw=w-1;
  const nh=h-1;
  const ww=$iw;
  const hh=$ih;
  const icx=ww/2;
  const icy=hh/2;
  const pts=$1;
  const H=$3;
  const K=$4;
  const zoom=1/$5;
  const ang=($6/180)*pi;
  const origin_x=$7*-1*zoom;
  const origin_y=$8*zoom;
  const sd=max(w,h)/min(w,h);
  const sx=w>h?sd:1;
  const sy=w>h?1:sd;
  const sx_zoom=sx*zoom;
  const sy_zoom=sy*zoom;
  const cx=(nw-1)/2;
  const cy=(nh-1)/2;
  const osx=origin_x*sx;
  const osy=origin_y*sy;
  const icx_zoom=icx/zoom;
  const icy_zoom=icy/zoom;
  const cxsx=icx*sx;
  const cysy=icy*sy;
  const cos_ang=cos(ang);
  const sin_ang=sin(ang);
  rot_x(a,b)=a*cos_ang-b*sin_ang;
  rot_y(a,b)=a*sin_ang+b*cos_ang;
  
  $9?(
  
   if(narg($10),
    const argpos10=$10%4;
    argpos10==0?func_a(a)=sin(a):
    argpos10==1?func_a(a)=cos(a):
    argpos10==2?func_a(a)=tan(a):
    argpos10==3?func_a(a)=atan(a);
    ,func_a(a)=sin(a);
   );
   
   if(narg($11),
    const argpos11=$11%4;
    argpos11==0?func_b(a)=sin(a):
    argpos11==1?func_b(a)=cos(a):
    argpos11==2?func_b(a)=tan(a):
    argpos11==3?func_b(a)=atan(a);
    ,func_b(a)=cos(a);
   ); 
   
   if(narg($12),
    const argpos12=$12%4;
    argpos12==0?func_c(a)=sin(a):
    argpos12==1?func_c(a)=cos(a):
    argpos12==2?func_c(a)=tan(a):
    argpos12==3?func_c(a)=atan(a);
    ,func_c(a)=tan(a);
   );
   
   if(!narg($13),
    if(narg($10),
     argpos10==0?func_d(a)=sin(a):
     argpos10==1?func_d(a)=cos(a):
     argpos10==2?func_d(a)=tan(a):
     argpos10==3?func_d(a)=atan(a);
     ,func_d(a)=sin(a);
    );,
   const argpos13=$13%4;
   argpos13==0?func_d(a)=sin(a):
   argpos13==1?func_d(a)=cos(a):
   argpos13==2?func_d(a)=tan(a):
   argpos13==3?func_d(a)=atan(a);
   );
   
   if(!narg($14),
    if(narg($11),
     argpos11==0?func_e(a)=sin(a):
     argpos11==1?func_e(a)=cos(a):
     argpos11==2?func_e(a)=tan(a):
     argpos11==3?func_e(a)=atan(a);
     ,func_e(a)=cos(a);
    );,
   const argpos14=$14%4;
   argpos14==0?func_e(a)=sin(a):
   argpos14==1?func_e(a)=cos(a):
   argpos14==2?func_e(a)=tan(a):
   argpos14==3?func_e(a)=atan(a);
   );
   
   if(!narg($15),
    if(narg($12),
     argpos12==0?func_f(a)=sin(a):
     argpos12==1?func_f(a)=cos(a):
     argpos12==2?func_f(a)=tan(a):
     argpos12==3?func_f(a)=atan(a);
     ,func_f(a)=tan(a);
    );,
   const argpos15=$15%4;
   argpos15==0?func_f(a)=sin(a):
   argpos15==1?func_f(a)=cos(a):
   argpos15==2?func_f(a)=tan(a):
   argpos15==3?func_f(a)=atan(a);
   );
   
   popcorn_x(a,b)=(Kb=K*b;a-H*func_a(b+func_b(Kb+func_c(Kb))));
   popcorn_y(a,b)=(Ka=K*a;b-H*func_d(a+func_e(Ka+func_f(Ka))));
   
  ):(
  
   if(narg($10),
    const argpos10=$10%4;
    argpos10==0?func_a(a)=sin(a):
    argpos10==1?func_a(a)=cos(a):
    argpos10==2?func_a(a)=tan(a):
    argpos10==3?func_a(a)=atan(a);
    ,func_a(a)=sin(a);
   );
   
   if(narg($11),
    const argpos11=$11%4;
    argpos11==0?func_b(a)=sin(a):
    argpos11==1?func_b(a)=cos(a):
    argpos11==2?func_b(a)=tan(a):
    argpos11==3?func_b(a)=atan(a);
    ,func_b(a)=tan(a);
   );
   
   if(!narg($12),
    if(narg($10),
     argpos10==0?func_c(a)=sin(a):
     argpos10==1?func_c(a)=cos(a):
     argpos10==2?func_c(a)=tan(a):
     argpos10==3?func_c(a)=atan(a);
     ,func_c(a)=sin(a);
    );,
   const argpos12=$12%4;
   argpos12==0?func_c(a)=sin(a):
   argpos12==1?func_c(a)=cos(a):
   argpos12==2?func_c(a)=tan(a):
   argpos12==3?func_c(a)=atan(a);
   );
   
   if(!narg($13),
    if(narg($11),
     argpos11==0?func_d(a)=sin(a):
     argpos11==1?func_d(a)=cos(a):
     argpos11==2?func_d(a)=tan(a):
     argpos11==3?func_d(a)=atan(a);
     ,func_d(a)=tan(a);
    );,
   const argpos13=$13%4;
   argpos13==0?func_d(a)=sin(a):
   argpos13==1?func_d(a)=cos(a):
   argpos13==2?func_d(a)=tan(a):
   argpos13==3?func_d(a)=atan(a);
   );
   
   popcorn_x(a,b)=a-H*func_a(b+func_b(K*b));
   popcorn_y(a,b)=b-H*func_c(a+func_d(K*a));
   
  );
 );
 xx=sx_zoom*(x-cx)/cx;
 yy=sy_zoom*(y-cy)/cy;
 xx+=origin_x;
 yy+=origin_y;
 repeat(pts,
  xnew=popcorn_x(xx,yy);
  ynew=popcorn_y(xx,yy);
  xval="$fvx";
  yval="$fvy";
  xpos=round(xval);
  ypos=round(yval);
  i(#-1,xpos,ypos)++;
  xx=xnew;
  yy=ynew;
 );"
 
rm.
#@gui Popcorn Fractal: fx_rep_pfrac,fx_rep_pfrac_preview
#@gui :_=note("Fractal attributed to Clifford Pickover. Code adapted from Paul Bourke's C code."),_=separator()
#@gui :_=note("<b>Main</b>")
#@gui :Points=int(50,1,200)
#@gui :Density=float(1,.01,2)
#@gui :H Variable=float(.05,-5,5)
#@gui :K Variable=float(3,-75,75)
#@gui :Zoom=float(1,.1,10)
#@gui :Angle=float(0,-180,180)
#@gui :Origin=point(50,50,0,1,255,255,255,255)
#@gui :_=separator(),_=note("<b>Trigonometric</b>")
#@gui :Mode=choice(0,"Trig-4","Trig-6")
#@gui :XY-Axis Mode?=bool(1)
#@gui :X-Axis Formula S=choice(0,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :X-Axis Formula T=choice(1,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :X-Axis Formula U=choice(2,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :Y-Axis Formula S=choice(0,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :Y-Axis Formula T=choice(1,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :Y-Axis Formula U=choice(2,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :XY-Axis Formula S=choice(0,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :XY-Axis Formula T=choice(1,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :XY-Axis Formula U=choice(2,"Sinusoidal","Cosinusoidal","Tangent","Arc-Tangent")
#@gui :_=separator(),_=note("<b>Output</b>")
#@gui :Midpoint Shift=float(0,-1,1)
#@gui :Multiplier=float(1,.1,10)
#@gui :Normalize=bool(0)
#@gui :_=separator(),_=note("<b>Preview</b>")
#@gui :Show Fill Ratio?=bool(0)
#@gui :_=note("<small>Fill Ratio provides information on whether there is sufficient filled pixels on canvas. The closer to 100%, the more the canvas is filled.</small>")
#@gui :_=separator(),_=note("<small>Author: Reptorian. Latest Update: <i>2020/11/1</i>.</small>")
fx_rep_pfrac:
ox={(($7-50)/100)*2}
oy={(($8-50)/100)*-2}
setarg=${1-6},$ox,$oy
midpoint_shift={1-abs($20)}
if $10
 if $9 setarg2=${17-19}
 else setarg2=$17,$19
 fi
else
 if $9 setarg2=${11-16}
 else setarg2=$11,$13,$14,$16
 fi
fi
l[0]
 rep_pfrac $setarg,$9,$setarg2
 val_max={iM}
 n 0,1
 if $20>=0 f i^$midpoint_shift
 else f 1-((1-i)^$midpoint_shift)
 fi
 if $22 n 0,255
 else * {$21*$val_max}
 fi
done
fx_rep_pfrac_preview:
fx_rep_pfrac ${1-22}
if $23
 +f[0] i>0?1
 fillperc={ia*100} rm.
 fillperc_l={int($fillperc)}
 fillperc_r={int(($fillperc-$fillperc_l)*100)}
 fillratio=$fillperc_l
 fillratio.=.
 fillratio.=$fillperc_r
 fillratio.=%
 to[0] $fillratio,.5~,.5~,18%
fi
k[0]

a={!$10?2:0}
b={$10?2:0}
c={!$10?($9?2:0):0}
d={$10?($9?2:0):0}

u "{$1}"\
"{$2}"\
"{$3}"\
"{$4}"\
"{$5}"\
"{$6}"\
"{$7,$8}"\
"{$9}"\
"{$10}"\
"{$11}_"$a\
"{$12}_"$c\
"{$13}_"$a\
"{$14}_"$a\
"{$15}_"$c\
"{$16}_"$a\
"{$17}_"$b\
"{$18}_"$d\
"{$19}_"$b\
"{$20}"\
"{$21}_"{$22?1:2}\
"{$22}"\
"{$23}"

 

 

EDIT in 10/27/2020 : Bug fix. Now, you can have different functions for different axis in Trig-6 mode.

EDIT in 11/1/2020: Added special note which is to point out to workaround for now.

 

Edited by Reptillian
  • Thanks 1
  • Upvote 3
  • You're a Smart Cookie! 1

G'MIC Filter Developer

Link to comment
Share on other sites

I suggest you change

Popcorn_Array = new int [w,h];

to

if (Popcorn_Array == null)
	Popcorn_Array = new int [w,h];

 

I don't see any reason for reallocating the array each time a control is changed. Though it probably wont have major consequences performance-wise, it does force more garbage collection.

Link to comment
Share on other sites

4 minutes ago, MJW said:

I suggest you change


Popcorn_Array = new int [w,h];

to


if (Popcorn_Array == null)
	Popcorn_Array = new int [w,h];

 

I don't see any reason for reallocating the array each time a control is changed. Though it probably wont have major consequences performance-wise, it does force more garbage collection.

I'll do that in the morning. You're welcome to post your own modification here as I will push it immediately as it is open-source.

G'MIC Filter Developer

Link to comment
Share on other sites

11 minutes ago, MJW said:

 

I'd prefer to leave any changes to you.

Got it. I actually inserted changes just as now when I realized I didn't publish the correct build.

 

EDIT: Actually, the changes you suggested @MJW created a phantom image bug. I will not use it. new will guarantee everything resets to 0.

Edited by Reptillian

G'MIC Filter Developer

Link to comment
Share on other sites

30 minutes ago, Reptillian said:

Actually, the changes you suggested @MJW created a phantom image bug.

 

I should have said that you need to clear the array when you don't allocate it. Otherwise it will have the left-over image from the previous time.

 

if (Popcorn_Array == null)
	Popcorn_Array = new int [w,h];
else
	Array.Clear(Popcorn_Array, 0, w*h);

 

Link to comment
Share on other sites

21 minutes ago, MJW said:

 

I should have said that you need to clear the array when you don't allocate it. Otherwise it will have the left-over image from the previous time.

 


if (Popcorn_Array == null)
	Popcorn_Array = new int [w,h];
else
	Array.Clear(Popcorn_Array, 0, w*h);

 

That works. Thanks. Now, I think the plugin can be said to be finished.

G'MIC Filter Developer

Link to comment
Share on other sites

  • Reptillian changed the title to Popcorn Fractal - 10/27/2020

I had some fun playing with this!  Thanks @Reptillian

 

After many iterations - I ran into a problem resetting the dropdown controls. Would it be possible to add a Reset button which covers all the controls?

Link to comment
Share on other sites

14 minutes ago, Ego Eram Reputo said:

After many iterations - I ran into a problem resetting the controls. Would it be possible to add a Reset button?

I don't really have that much knowledge to do so, and c# isn't exactly what I'll be focused on. So, no unless you can give a example on making that, I will try to add a reset button.

Edited by Reptillian

G'MIC Filter Developer

Link to comment
Share on other sites

@Reptillian  I had some fun playing with this plugin. The results yield a lot of glassy-looking threads. Different blend modes and some coloring, voila!

 

 Thanks for making this!  😊

 

popcornfractal.png

 

  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...
  • 8 months later...
  • Reptillian changed the title to Popcorn Fractal - 3/27/2022

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...