I'm interested in the math formula behind your coloring technique if you're okay with sharing it
.
The "math formula" is not really a singular thing.
First, there's several color gradients with different repeat periods. All of those have three to five colors that are cycled, and Bezier spline interpolation is used to shade smoothly among them, except for one. That one is a gradient that can be logmapped to the whole iteration range (or treated in other ways) and can have any number of points. I've got that implemented in the UF-version now as using the UF gradient while the rest use numeric or color parameters to the coloring formula in UF.
Also, the outputs of four of the gradients supply the inputs to another of them. That's how a color scheme can shade into another whole color scheme over a longer period.
Finally, there are some different rules for combining these. The general rule is that hues add in a cyclical manner, with red at the zero point. (Fortunately, UF's hsl functions also put red at the zero point, though UF hues range from 0 to 6 instead of 0 to 1.) Saturations and luminances add in a manner resembling how velocities add in (one-space-dimension) special relativity, so they can approach but never reach the extreme of 1. This is modified so that they can also approach but never reach 0. So one generally gets some contrast reduction when the waves add up to very dark or very light in an area, but not its complete eradication let alone vast swathes of iterations clamped at black, white, or grey.
However some of the rules are user-selectable. For instance "rgb bias" makes a component add in by a relativity-modified addition of the rgb components. So if "hsl bias" (the usual) is used to add a pale bluish color to a region of gradient, that region is hue-rotated by about 2/3 along the rainbow and brightened; if "rgb bias" is used instead, that region is tinted blue and brightened. The "rgb bias" is most useful on the logmap gradient: a neutral grey (0 saturation, 1/2 full luminance) is the "identity element" for "rgb bias" and can be used to get no tinting, desaturation, brightening, dimming, or anything, and shaded to tint particular depths towards particular colors, or force e.g. saturated yellows for minibrot filaments at the highest end of the iteration scale, or whatever. For "hsl bias" the "identity element" is a somewhat desaturated red: 50% saturation, 50% luminance, red hue. Reducing the saturation desaturates what it mixes with and increasing it increases saturation, etc ("rgb bias" cannot lower saturation).
Anyway, here's UF code that seems to work. It's probably not got the best documentation. I suggest setting the UF gradient to a flat 50%-saturated red at first, setting the merge modes to "rgb bias", leaving everything else alone in the coloring settings, putting the iteration limit up to at least a million (including the coloring's logmap options, near the bottom -- set the range from 1 to 1 million), then zooming into Seahorse Valley and experimenting with the coloring settings once there.
The code's quite long, basically because it has several repetitions of an algorithm for bezier splines. I didn't have time to go digging into UF5 fucntions, classes, and nonsuch so it's all one monolithic chunk. Since the bulk of it runs only once per pixel there's no worry about slowups of the iteration loop from cache misses from that, I don't think. I think it still requires UF5 because it uses Color objects and parameters extensively. And yes, it's direct-coloring as I thought it would have to be.
Copy and paste the code as-is into a .ucl file, put that where UF will look for it, and browse for it. Let me know if you have any problems. Consider it dedicated to the public domain for copyright purposes -- you may use it as you see fit, modify, play around with it, adapt it for other fractal software, etc.
MandelMultiwave {
global:
color c2x0 = hsl(0,0.5,0.5 + @lmag/2)
color c2x1 = hsl(0,0.5,0.5)
color c2x2 = hsl(0,0.5,0.5 - @lmag/2)
color c2x3 = hsl(0,0.5,0.5)
color c3x0 = hsl(0,0.5,0.5 + @lmag2/2)
color c3x1 = hsl(0,0.5,0.5)
color c3x2 = hsl(0,0.5,0.5 - @lmag2/2)
color c3x3 = hsl(0,0.5,0.5)
color c4x0 = hsl(0,0.5,0.5 + @lmag3/2)
color c4x1 = hsl(0,0.5,0.5)
color c4x2 = hsl(0,0.5,0.5 - @lmag3/2)
color c4x3 = hsl(0,0.5,0.5)
color c5x0 = hsl(0,0.5,0.5)
color c5x1 = hsl(0,0.5,0.5 - @lmag4/2)
color c5x2 = hsl(0,0.5,0.5)
color c5x3 = hsl(0,0.5,0.5 + @lmag4/2)
init:
complex il = 1/log(@power) ; Inverse log (power).
float lp = log(log(@bailout)) ; log(log bailout).
final:
float i = real(#numiter + il*lp - il*log(log(cabs(#z)))) + @displacement
IF (i < 1)
i = 1
ENDIF
i = (i - 1)*@rescale + 1
float ix = (i - 1)/@hfreq2
ix = ix - trunc(ix)
color c1a
color c1b
color c1c
color c1d
color c2a
color c2b
color c2c
color c2d
color c3a
color c3b
color c3c
color c3d
color c4a
color c4b
color c4c
color c4d
IF (ix < 1/5)
ix = ix*5
c1a = @c1e
c1b = @c1a
c1c = @c1b
c1d = @c1c
c2a = @c2e
c2b = @c2a
c2c = @c2b
c2d = @c2c
c3a = @c3e
c3b = @c3a
c3c = @c3b
c3d = @c3c
c4a = @c4e
c4b = @c4a
c4c = @c4b
c4d = @c4c
ELSEIF (ix < 2/5)
ix = (ix - 1/5)*5
c1a = @c1a
c1b = @c1b
c1c = @c1c
c1d = @c1d
c2a = @c2a
c2b = @c2b
c2c = @c2c
c2d = @c2d
c3a = @c3a
c3b = @c3b
c3c = @c3c
c3d = @c3d
c4a = @c4a
c4b = @c4b
c4c = @c4c
c4d = @c4d
ELSEIF (ix < 3/5)
ix = (ix - 2/5)*5
c1a = @c1b
c1b = @c1c
c1c = @c1d
c1d = @c1e
c2a = @c2b
c2b = @c2c
c2c = @c2d
c2d = @c2e
c3a = @c3b
c3b = @c3c
c3c = @c3d
c3d = @c3e
c4a = @c4b
c4b = @c4c
c4c = @c4d
c4d = @c4e
ELSEIF (ix < 4/5)
ix = (ix - 3/5)*5
c1a = @c1c
c1b = @c1d
c1c = @c1e
c1d = @c1a
c2a = @c2c
c2b = @c2d
c2c = @c2e
c2d = @c2a
c3a = @c3c
c3b = @c3d
c3c = @c3e
c3d = @c3a
c4a = @c4c
c4b = @c4d
c4c = @c4e
c4d = @c4a
ELSE
ix = (ix - 4/5)*5
c1a = @c1d
c1b = @c1e
c1c = @c1a
c1d = @c1b
c2a = @c2d
c2b = @c2e
c2c = @c2a
c2d = @c2b
c3a = @c3d
c3b = @c3e
c3c = @c3a
c3d = @c3b
c4a = @c4d
c4b = @c4e
c4c = @c4a
c4d = @c4b
ENDIF
float rp0 = red(c1b)
float gp0 = green(c1b)
float bp0 = blue(c1b)
float rm0 = (red(c1c) - red(c1a))/2
float gm0 = (green(c1c) - green(c1a))/2
float bm0 = (blue(c1c) - blue(c1a))/2
float rp1 = red(c1c)
float gp1 = green(c1c)
float bp1 = blue(c1c)
float rm1 = (red(c1d) - red(c1b))/2
float gm1 = (green(c1d) - green(c1b))/2
float bm1 = (blue(c1d) - blue(c1b))/2
float ixt2 = ix^2
float ixt3 = ix^3
float ixa = 2*ixt3 - 3*ixt2 + 1
float ixb = ixt3 - 2*ixt2 + ix
float ixc = -2*ixt3 + 3*ixt2
float ixd = ixt3 - ixt2
float rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
float ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
float bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
color c1 = rgb(rrr,ggg,bbb)
rp0 = red(c2b)
gp0 = green(c2b)
bp0 = blue(c2b)
rm0 = (red(c2c) - red(c2a))/2
gm0 = (green(c2c) - green(c2a))/2
bm0 = (blue(c2c) - blue(c2a))/2
rp1 = red(c2c)
gp1 = green(c2c)
bp1 = blue(c2c)
rm1 = (red(c2d) - red(c2b))/2
gm1 = (green(c2d) - green(c2b))/2
bm1 = (blue(c2d) - blue(c2b))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
color c2 = rgb(rrr,ggg,bbb)
rp0 = red(c3b)
gp0 = green(c3b)
bp0 = blue(c3b)
rm0 = (red(c3c) - red(c3a))/2
gm0 = (green(c3c) - green(c3a))/2
bm0 = (blue(c3c) - blue(c3a))/2
rp1 = red(c3c)
gp1 = green(c3c)
bp1 = blue(c3c)
rm1 = (red(c3d) - red(c3b))/2
gm1 = (green(c3d) - green(c3b))/2
bm1 = (blue(c3d) - blue(c3b))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
color c3 = rgb(rrr,ggg,bbb)
rp0 = red(c4b)
gp0 = green(c4b)
bp0 = blue(c4b)
rm0 = (red(c4c) - red(c4a))/2
gm0 = (green(c4c) - green(c4a))/2
bm0 = (blue(c4c) - blue(c4a))/2
rp1 = red(c4c)
gp1 = green(c4c)
bp1 = blue(c4c)
rm1 = (red(c4d) - red(c4b))/2
gm1 = (green(c4d) - green(c4b))/2
bm1 = (blue(c4d) - blue(c4b))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
color c4 = rgb(rrr,ggg,bbb)
ix = (i - 1)/@hfreq1
ix = ix - trunc(ix)
color ca
color cb
color cc
color cd
IF (ix < 1/4)
ix = ix*4
ca = c4
cb = c1
cc = c2
cd = c3
ELSEIF (ix < 1/2)
ix = (ix - 1/4)*4
ca = c1
cb = c2
cc = c3
cd = c4
ELSEIF (ix < 3/4)
ix = (ix - 1/2)*4
ca = c2
cb = c3
cc = c4
cd = c1
ELSE
ix = (ix - 3/4)*4
ca = c3
cb = c4
cc = c1
cd = c2
ENDIF
rp0 = red(cb)
gp0 = green(cb)
bp0 = blue(cb)
rm0 = (red(cc) - red(ca))/2
gm0 = (green(cc) - green(ca))/2
bm0 = (blue(cc) - blue(ca))/2
rp1 = red(cc)
gp1 = green(cc)
bp1 = blue(cc)
rm1 = (red(cd) - red(cb))/2
gm1 = (green(cd) - green(cb))/2
bm1 = (blue(cd) - blue(cb))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
c2 = rgb(rrr,ggg,bbb)
ix = (i - 1)/@sfreq
ix = ix - trunc(ix)
IF (ix < 1/3)
ix = ix*3
ca = @cz
cb = @cx
cc = @cy
cd = @cz
ELSEIF (ix < 2/3)
ix = (ix - 1/3)*3
ca = @cx
cb = @cy
cc = @cz
cd = @cx
ELSE
ix = (ix - 2/3)*3
ca = @cy
cb = @cz
cc = @cx
cd = @cy
ENDIF
rp0 = red(cb)
gp0 = green(cb)
bp0 = blue(cb)
rm0 = (red(cc) - red(ca))/2
gm0 = (green(cc) - green(ca))/2
bm0 = (blue(cc) - blue(ca))/2
rp1 = red(cc)
gp1 = green(cc)
bp1 = blue(cc)
rm1 = (red(cd) - red(cb))/2
gm1 = (green(cd) - green(cb))/2
bm1 = (blue(cd) - blue(cb))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
c3 = rgb(rrr,ggg,bbb)
float hh = hue(c2)
float ss = sat(c2)
float ll = lum(c2)
IF (ll != 1.0 && lum(c3) != 1.0)
ll = 1 - 1/((1/(1 - ll) - 1)*(1/(1 - lum(c3)) - 1) + 1)
ENDIF
IF (@smode == 0)
ss = ss*(1 - sat(c3)*(((1 - cos((hh - hue(c3))*#pi/3))/2)^@spow))
ELSE
hh = (hh + hue(c3))%6
IF (ss != 1.0 && sat(c3) != 1.0)
ss = 1 - 1/((1/(1 - ss) - 1)*(1/(1 - sat(c3)) - 1) + 1)
ENDIF
ENDIF
c1 = hsl(hh,ss,ll)
ix = (i - 1)/@lfreq
ix = ix - trunc(ix)
IF (ix < 1/4)
ix = ix*4
ca = c2x3
cb = c2x0
cc = c2x1
cd = c2x2
ELSEIF (ix < 1/2)
ix = (ix - 1/4)*4
ca = c2x0
cb = c2x1
cc = c2x2
cd = c2x3
ELSEIF (ix < 3/4)
ix = (ix - 1/2)*4
ca = c2x1
cb = c2x2
cc = c2x3
cd = c2x0
ELSE
ix = (ix - 3/4)*4
ca = c2x2
cb = c2x3
cc = c2x0
cd = c2x1
ENDIF
rp0 = red(cb)
gp0 = green(cb)
bp0 = blue(cb)
rm0 = (red(cc) - red(ca))/2
gm0 = (green(cc) - green(ca))/2
bm0 = (blue(cc) - blue(ca))/2
rp1 = red(cc)
gp1 = green(cc)
bp1 = blue(cc)
rm1 = (red(cd) - red(cb))/2
gm1 = (green(cd) - green(cb))/2
bm1 = (blue(cd) - blue(cb))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
c2 = rgb(rrr,ggg,bbb)
ix = (i - 1)/@lfreq2
ix = ix - trunc(ix)
IF (ix < 1/4)
ix = ix*4
ca = c3x3
cb = c3x0
cc = c3x1
cd = c3x2
ELSEIF (ix < 1/2)
ix = (ix - 1/4)*4
ca = c3x0
cb = c3x1
cc = c3x2
cd = c3x3
ELSEIF (ix < 3/4)
ix = (ix - 1/2)*4
ca = c3x1
cb = c3x2
cc = c3x3
cd = c3x0
ELSE
ix = (ix - 3/4)*4
ca = c3x2
cb = c3x3
cc = c3x0
cd = c3x1
ENDIF
rp0 = red(cb)
gp0 = green(cb)
bp0 = blue(cb)
rm0 = (red(cc) - red(ca))/2
gm0 = (green(cc) - green(ca))/2
bm0 = (blue(cc) - blue(ca))/2
rp1 = red(cc)
gp1 = green(cc)
bp1 = blue(cc)
rm1 = (red(cd) - red(cb))/2
gm1 = (green(cd) - green(cb))/2
bm1 = (blue(cd) - blue(cb))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
c3 = rgb(rrr,ggg,bbb)
ix = (i - 1)/@lfreq3
ix = ix - trunc(ix)
IF (ix < 1/4)
ix = ix*4
ca = c4x3
cb = c4x0
cc = c4x1
cd = c4x2
ELSEIF (ix < 1/2)
ix = (ix - 1/4)*4
ca = c4x0
cb = c4x1
cc = c4x2
cd = c4x3
ELSEIF (ix < 3/4)
ix = (ix - 1/2)*4
ca = c4x1
cb = c4x2
cc = c4x3
cd = c4x0
ELSE
ix = (ix - 3/4)*4
ca = c4x2
cb = c4x3
cc = c4x0
cd = c4x1
ENDIF
rp0 = red(cb)
gp0 = green(cb)
bp0 = blue(cb)
rm0 = (red(cc) - red(ca))/2
gm0 = (green(cc) - green(ca))/2
bm0 = (blue(cc) - blue(ca))/2
rp1 = red(cc)
gp1 = green(cc)
bp1 = blue(cc)
rm1 = (red(cd) - red(cb))/2
gm1 = (green(cd) - green(cb))/2
bm1 = (blue(cd) - blue(cb))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
c4 = rgb(rrr,ggg,bbb)
ix = (i - 1)/@lfreq4
ix = ix - trunc(ix)
IF (ix < 1/4)
ix = ix*4
ca = c5x3
cb = c5x0
cc = c5x1
cd = c5x2
ELSEIF (ix < 1/2)
ix = (ix - 1/4)*4
ca = c5x0
cb = c5x1
cc = c5x2
cd = c5x3
ELSEIF (ix < 3/4)
ix = (ix - 1/2)*4
ca = c5x1
cb = c5x2
cc = c5x3
cd = c5x0
ELSE
ix = (ix - 3/4)*4
ca = c5x2
cb = c5x3
cc = c5x0
cd = c5x1
ENDIF
rp0 = red(cb)
gp0 = green(cb)
bp0 = blue(cb)
rm0 = (red(cc) - red(ca))/2
gm0 = (green(cc) - green(ca))/2
bm0 = (blue(cc) - blue(ca))/2
rp1 = red(cc)
gp1 = green(cc)
bp1 = blue(cc)
rm1 = (red(cd) - red(cb))/2
gm1 = (green(cd) - green(cb))/2
bm1 = (blue(cd) - blue(cb))/2
ixt2 = ix^2
ixt3 = ix^3
ixa = 2*ixt3 - 3*ixt2 + 1
ixb = ixt3 - 2*ixt2 + ix
ixc = -2*ixt3 + 3*ixt2
ixd = ixt3 - ixt2
rrr = ixa*rp0 + ixb*rm0 + ixc*rp1 + ixd*rm1
ggg = ixa*gp0 + ixb*gm0 + ixc*gp1 + ixd*gm1
bbb = ixa*bp0 + ixb*bm0 + ixc*bp1 + ixd*bm1
IF (rrr < 0.0)
rrr = 0.0
ELSEIF (rrr > 1.0)
rrr = 1.0
ENDIF
IF (ggg < 0.0)
ggg = 0.0
ELSEIF (ggg > 1.0)
ggg = 1.0
ENDIF
IF (bbb < 0.0)
bbb = 0.0
ELSEIF (bbb > 1.0)
bbb = 1.0
ENDIF
color c5 = rgb(rrr,ggg,bbb)
float mn = @fitminit
float mx = @fitmaxit
ix = i
IF (@transfer == 1)
ix = ix^(1/@transpower)
mn = mn^(1/@transpower)
mx = mx^(1/@transpower)
ELSEIF (@transfer == 2)
ix = log(ix)
mn = log(mn)
mx = log(mx)
ENDIF
IF (@fit)
IF (ix < mn)
ix = 0
ELSE
ix = (ix - mn)/(mx - mn)
ENDIF
ix = ix * @fittimes
ELSE
ix = 0.05*ix
ENDIF
color c6 = gradient(ix)
IF (@mmode == 1)
hh = (hue(c1)+hue(c6))%6
float sc1 = sat(c1)
float sc6 = sat(c6)
IF (sc1 > 0.99)
sc1 = 0.99
ENDIF
IF (sc6 > 0.99)
sc6 = 0.99
ENDIF
sc1 = 1/(1 - sc1) - 1
sc6 = 1/(1 - sc6) - 1
ss = sc1*sc6
ss = 1 - 1/(ss + 1)
float ll1 = lum(c1)
float ll2 = lum(c2)
float ll3 = lum(c3)
float ll4 = lum(c4)
float ll5 = lum(c5)
float ll6 = lum(c6)
IF (ll1 == 1.0 || ll2 == 1.0 || ll3 == 1.0 || ll4 == 1.0 || ll5 == 1.0 || ll6 == 1.0)
ll = 1.0
ELSE
ll1 = 1/(1 - ll1) - 1
ll2 = 1/(1 - ll2) - 1
ll3 = 1/(1 - ll3) - 1
ll4 = 1/(1 - ll4) - 1
ll5 = 1/(1 - ll5) - 1
ll6 = 1/(1 - ll6) - 1
ll = ll1*ll2*ll3*ll4*ll5*ll6
ll = 1 - 1/(ll + 1)
ENDIF
IF (ss < 0)
ss = 0
ELSEIF (ss > 1)
ss = 1
ENDIF
IF (ll < 0)
ll = 0
ELSEIF (ll > 1)
ll = 1
ENDIF
#color = hsl(hh,ss,ll)
ELSE
hh = hue(c1)
ss = sat(c1)
float ll1 = lum(c1)
float ll2 = lum(c2)
float ll3 = lum(c3)
float ll4 = lum(c4)
float ll5 = lum(c5)
IF (ll1 == 1.0 || ll2 == 1.0 || ll3 == 1.0 || ll4 == 1.0 || ll5 == 1.0)
ll = 1.0
ELSE
ll1 = 1/(1 - ll1) - 1
ll2 = 1/(1 - ll2) - 1
ll3 = 1/(1 - ll3) - 1
ll4 = 1/(1 - ll4) - 1
ll5 = 1/(1 - ll5) - 1
ll = ll1*ll2*ll3*ll4*ll5
ll = 1 - 1/(ll + 1)
ENDIF
IF (ll < 0)
ll = 0
ELSEIF (ll > 1)
ll = 1
ENDIF
IF (@mmode == 0)
c1 = hsl(hh,ss,ll)
float rr6 = red(c6)
float gg6 = green(c6)
float bb6 = blue(c6)
IF (rr6 > 0.99)
rr6 = 0.99
ENDIF
IF (gg6 > 0.99)
gg6 = 0.99
ENDIF
IF (bb6 > 0.99)
bb6 = 0.99
ENDIF
float rr1 = red(c1)
float gg1 = green(c1)
float bb1 = blue(c1)
IF (rr1 > 0.99)
rr1 = 0.99
ENDIF
IF (gg1 > 0.99)
gg1 = 0.99
ENDIF
IF (bb1 > 0.99)
bb1 = 0.99
ENDIF
rr6 = 1/(1 - rr6) - 1
gg6 = 1/(1 - gg6) - 1
bb6 = 1/(1 - bb6) - 1
rr1 = 1/(1 - rr1) - 1
gg1 = 1/(1 - gg1) - 1
bb1 = 1/(1 - bb1) - 1
float rrr = 1 - 1/(rr6*rr1 + 1)
float ggg = 1 - 1/(gg6*gg1 + 1)
float bbb = 1 - 1/(bb6*bb1 + 1)
#color = rgb(rrr,ggg,bbb)
ELSE
float aa = alpha(c5)
float omaa = 1 - aa
IF (@mmode == 2)
c1 = hsl(hh,ss,ll)
float rrr = red(c6)*aa + red(c1)*omaa
float ggg = green(c6)*aa + green(c1)*omaa
float bbb = blue(c6)*aa + blue(c1)*omaa
#color = rgb(rrr,ggg,bbb)
ELSE
hh = (hue(c6)+hh)%6
ss = sat(c6)*aa + ss*omaa
ll = lum(c6)*aa + ll*omaa
#color = hsl(hh,ss,ll)
ENDIF
ENDIF
ENDIF
default:
title = "Mandelbrot Multiwave Coloring"
param power
caption = "Exponent"
default = (2,0)
hint = "This should be set to match the exponent of the \
formula you are using. For Mandelbrot, this is 2. \
Only needed when coloring divergent points."
endparam
color param c1a
caption = "Hue 1A"
default = rgb(130/255,91/255,40/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c2a
caption = "Hue 2A"
default = rgb(186/255,153/255,102/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c3a
caption = "Hue 3A"
default = rgb(248/255,114/255,12/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c4a
caption = "Hue 4A"
default = rgb(74/255,0,0)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
param hfreq1
caption = "Short hue shift period (iters)"
default = 530.0
hint = "Changes the period of the short hue modification cycle. Early in the long cycle it will cycle among the four colors above."
endparam
color param c1b
caption = "Hue 1B"
default = rgb(77/255,49/255,19/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c2b
caption = "Hue 2B"
default = rgb(195/255,179/255,131/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c3b
caption = "Hue 3B"
default = rgb(231/255,227/255,23/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c4b
caption = "Hue 4B"
default = rgb(240/255,164/255,0)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c1c
caption = "Hue 1C"
default = rgb(0,72/255,16/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c2c
caption = "Hue 2C"
default = rgb(133/255,146/255,128/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c3c
caption = "Hue 3C"
default = rgb(179/255,220/255,72/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c4c
caption = "Hue 4C"
default = rgb(243/255,224/255,83/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c1d
caption = "Hue 1D"
default = rgb(24/255,23/255,103/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c2d
caption = "Hue 2D"
default = rgb(144/255,143/255,163/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c3d
caption = "Hue 3D"
default = rgb(64/255,153/255,192/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c4d
caption = "Hue 4D"
default = rgb(31/255,173/255,131/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c1e
caption = "Hue 1E"
default = rgb(120/255,22/255,22/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c2e
caption = "Hue 2E"
default = rgb(177/255,129/255,130/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c3e
caption = "Hue 3E"
default = rgb(189/255,65/255,68/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param c4e
caption = "Hue 4E"
default = rgb(33/255,31/255,79/255)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
param hfreq2
caption = "Long hue shift period (iters)"
default = 5147.0
hint = "Changes the period of the long hue modification cycle."
endparam
color param cx
caption = "Superslow bias color 1"
default = rgb(0.5,0.5,0.5)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param cy
caption = "Superslow bias color 2"
default = hsl(0,0.5,0.7)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
color param cz
caption = "Superslow bias color 3"
default = hsl(5,1.0,0.3)
hint = "Altering these hues will alter the way the gradient is modified."
endparam
param sfreq
caption = "Superslow bias period (iters)"
default = 82117.0
hint = "Changes the period of the superslow bias cycle."
endparam
param smode
caption = "Superslow bias mode"
enum = "saturation bias" "hsl bias"
default = 1
hint = "Luminances adjust luminance of colors above; in saturation bias mode hue/saturation adjusts saturation. Hues matching this hue are unchanged, hues opposite have their saturation reduced the higher this color's saturation. The effect is to suppress opposite hues; set this to saturated red to suppress cyan for example. Neutral gray has no effect. In hsl bias mode hsl addition is used instead."
endparam
param spow
caption = "Superslow bias sensitivity"
default = 4.0
min = 0.01
hint = "Higher values narrow the range of hues desaturated; lower ones widen the range. 2 and 0.5 have opposite effects."
endparam
param lfreq
caption = "First luminance shift period (iters)"
default = 17.0
hint = "Changes the period of the first luminance modification cycle. The four colors of the short cycle will change gradually to the second set of four, then the third, then the fourth, before returning."
endparam
param lmag
caption = "First luminance shift amplitude"
default = 0.2
min = 0.0
max = 1.0
hint = "Changes the amplitude of the first luminance modification cycle."
endparam
param lfreq2
caption = "Second luminance shift period (iters)"
default = 94.0
hint = "Changes the period of the second luminance modification cycle."
endparam
param lmag2
caption = "Second luminance shift amplitude"
default = 0.4
min = 0.0
max = 1.0
hint = "Changes the amplitude of the second luminance modification cycle."
endparam
param lfreq3
caption = "Third luminance shift period (iters)"
default = 2544.0
hint = "Changes the period of the third luminance modification cycle."
endparam
param lmag3
caption = "Third luminance shift amplitude"
default = 0.6
min = 0.0
max = 1.0
hint = "Changes the amplitude of the third luminance modification cycle."
endparam
param lfreq4
caption = "Fourth luminance shift period (iters)"
default = 18544.0
hint = "Changes the period of the fourth luminance modification cycle."
endparam
param lmag4
caption = "Fourth luminance shift amplitude"
default = 0.6
min = 0.0
max = 1.0
hint = "Changes the amplitude of the fourth luminance modification cycle."
endparam
param mmode
caption = "Primary gradient merge mode"
enum = "rgb bias" "hsl bias" "rgb blend" "hsl blend"
default = 1
hint = "Affects how the gradient is applied to the color ripples; the blend options use the gradient's alpha"
endparam
param fit
caption = "Fit Gradient to Range"
default = true
hint = "Check this to spread the gradient out over the range of iteration values."
endparam
param fittimes
caption = "Number of repetitions"
default = 1.0
min = 1.0
hint = "Repeats gradient the specified number of times over the range of iteration values."
endparam
param fitminit
caption = "Start iteration"
default = 1.0
min = 1.0
hint = "Gradient begins at this iteration number. It is best if it's approximately the lowest \
actual number of iterations in the image. You can find the exact number by looking at \
Statistics after generating the image once."
endparam
param fitmaxit
caption = "End iteration"
default = 1000.0
min = 1.0
hint = "Gradient fitting is based on this range of iterations. Can be profitably made lower than \
maxiter -- try reducing it by factors of 10 until the gradient doesn't fit well, then raise \
it by a factor of 10 once."
endparam
param transfer
caption = "Super transfer function"
enum = "Linear" "Power" "Log"
default = 2
hint = "Linear distributes gradient evenly over iterations. \
Power weights gradient towards lower iterations for powers > 1. \
Log weights gradient towards lower iterations."
endparam
param transpower
caption = "Transfer power"
default = 3.0
hint = "Larger values weight gradient more towards low iterations. \
3.0 with a regular transfer function of Linear and a super transfer \
function of Linear with a regular transfer function of CubeRoot \
produce the same results."
visible = (@transfer == 1)
endparam
param bailout
caption = "Bail-out value"
default = 100000.0
hint = "Larger gives smoother coloring, up to a point."
min = 1
endparam
param displacement
caption = "Displacement"
default = 0.0
hint = "Skips the first N iterations of the color gradient, effectively shifting the whole color scheme to lower iterations as a block. Use this for testing."
min = 0.0
endparam
param rescale
caption = "Rescaling"
default = 1.0
hint = "Compresses the entire color gradient by this factor, after application of displacement. Use this for testing."
min = 1.0
endparam
}