Jump to content
How to Install Plugins ×

Smooth Julia Fractal [v1.0] [2023-04-22]


pascal

Recommended Posts

Smooth Julia Fractal

This plugin is able to render any fractal from the Julia set. As opposed to my previous plugin Advanced Julia Fractal, this new plugin makes use of normalized iteration counting to blend smoothly between colors. Increasing Iterations and Quality will result in a high quality fractal. The exposure controls can be used to fix the brightness. As always, you can use my other plugin Duotone Gradient Mapping to add coloring.

 

sample.jpg.49038985f5016f64b912401d9a597f96.jpg

Download

Located in: Effects > Render > Smooth Julia Fractal

smoothfractal.zip

 

Code

Spoiler
#region UICode
DoubleSliderControl CONSTANT_A = 0; // [-2,2] Real constant
DoubleSliderControl CONSTANT_B = 0; // [-2,2] Imaginary constant
DoubleSliderControl ZOOM = 20; // [1,1000] Zoom
DoubleSliderControl OFFSET_X = 0; // [-2,2] Offset X
DoubleSliderControl OFFSET_Y = 0; // [-2,2] Offset Y
IntSliderControl ITER = 100; // [1,500] Iterations
DoubleSliderControl MIN_V = 0.0; // [-10.0, 0.0] Min exposure
DoubleSliderControl MAX_V = 1.0; // [0.001, 100.0] Max exposure
IntSliderControl QUALITY = 0; // [0,5] Quality
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle selection = EnvironmentParameters.SelectionBounds;
    ColorBgra currentPixel;
    int samples = 1 + QUALITY * 2;
    int qmin = -(samples / 2);
    int qmax = samples + qmin;
    double zoom = ZOOM * ZOOM;
    double multiplier = (MAX_V - MIN_V) * 255.0 / (double) (samples * ITER);
    double min = MIN_V * 255.0;

    double[] sampleOffsets = new double[samples];
    for (int i = 0; i < samples; i++)
    {
        sampleOffsets[i] = (i + qmin) / (samples * zoom);
    }

    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
        {
            currentPixel = src[x,y];
            
            double value = 0.0;
            double fx = (x - selection.Left - selection.Width / 2.0) / zoom;
            double fy = (y - selection.Top - selection.Height / 2.0) / zoom;

            foreach (double offset in sampleOffsets)
            {
                double newX = fx + offset + OFFSET_X;
                double newY = fy + offset + OFFSET_Y;

                value += smoothFractalValue(newX, newY, ITER);
            }

            double mapped = value * multiplier + min;
            byte lightness =  (byte) Math.Clamp(mapped, 0.0, 255.0);

            currentPixel.R = lightness;
            currentPixel.G = lightness;
            currentPixel.B = lightness;
            
            dst[x,y] = currentPixel;
        }
    }
}


double smoothFractalValue(double a, double b, int n)
{
    double smoothValue = 0.0;
    
    for (int i = 0; i < n && a * a + b * b < 8.0; i++)
    {
        double p = a;
        a = a * a - b * b + CONSTANT_A;
        b = 2 * p * b + CONSTANT_B;

        smoothValue += Math.Exp(-Math.Sqrt(a * a + b * b));
    }

    return smoothValue;
}

 

  • Like 2
  • Upvote 2

pdnsignature.jpg.bb235358debfd06bf4d9023c840e8aa2.jpg

Link to comment
Share on other sites

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...