Implementation of Worley cellular noise with Worley fractal modulation.
The Euclidian flavor is closely equivalent to Voronoi texturing.
Jim Blue's random number generator was essential to its development.
Additional methods of fractal modulation have been added based upon the
Worley model.
class REB_TrapShapeWorleyTextures(common.ulb:TrapShape) {
; Implementation of Worley cellular noise with Worley fractal modulation. <br>
; <p>
; The Euclidian flavor is closely equivalent to Voronoi texturing.
; Jim Blue's random number generator was essential to its development.
; Additional methods of fractal modulation have been added based upon the
; Worley model.
public:
import "common.ulb"
import "jlb.ulb"
; Constructor
func REB_TrapShapeWorleyTextures(Generic pparent)
TrapShape.TrapShape(pparent)
rndi = new JLB_Random(0)
rndi.Init(@seed)
rndi.SetNMax(5000)
endfunc
; Call this for each iteration being trapped.
float func Iterate(complex pz)
TrapShape.Iterate(pz)
complex fz[10]
complex fzc[10]
complex fzz[10]
float dst[10]
float dst2[10]
complex fzc1[10]
complex fzc2[10]
complex fzc3[10]
complex fzc4[10]
float dist = 1e20
float dist2 = 1e20
complex cells[12,10]
float distance = 0
float test = 0
float sum = 0
float a = 1
complex diff = 0
int rnds[24]
float fac[10]
float rp[12,10]
float ip[12,10]
int i = 1
int j = 0
int jmax = 0
rnds[0] = rndi.RandomIntInRange(@seed)
while i < 24
rnds[i] = rndi.RandomIntInRange(0)
i = i + 1
endwhile
i = 0
fac[0] = 1
while i < 10
dst[i] = 1e10
dst2[i] = 1e10
if i > 0
fac[i] = fac[i-1]*(i+1)
endif
i = i + 1
endwhile
complex near = 0
complex fnear[10]
if @mode == 0
jmax = 1
else
jmax = 5
endif
if @type == "Mosaic"
jmax = 1
endif
while j < jmax
if @v_trapshapeworleytextures < 103
complex z = pz/@psize
else
complex z = (pz+(10,10))/@psize
endif
if @mode == 1 || @mode == 2
if j == 0
a = @cbl + @ctl + @cbr + @ctr + @cc;/20
elseif j == 1
z = z + @eps*(-1,-1)
a = -@cbl
elseif j == 2
z = z + @eps*(-1,1)
a = -@ctl
elseif j == 3
z = z + @eps*(1,-1)
a = -@cbr
elseif j == 4
z = z + @eps*(1,1)
a = -@ctr
endif
else
a = 1
endif
j = j + 1
int f = 0
repeat
if @nfrac == "2^x"
fz[f] = z*2^f
elseif @nfrac == "exp(x)"
fz[f] = z*exp(f)
elseif @nfrac == "cosh(x)"
fz[f] = z*cosh(f)
elseif @nfrac == "cos(x)"
fz[f] = z*cos(f)
elseif @nfrac == "sec(x)"
fz[f] = z/cos(f)
elseif @nfrac == "sech(x)"
fz[f] = z/cosh(f)
elseif @nfrac == "factorial(x+1)"
fz[f] = z*fac[f]
endif
fzc[f] = round(fz[f])
fzz[f] = fz[f] - fzc[f]
; create the grid
fzc1[f] = fzc[f] + (1,1)/2
fzc2[f] = fzc[f] + (1,-1)/2
fzc3[f] = fzc[f] + (-1,1)/2
fzc4[f] = fzc[f] + (-1,-1)/2
; create the random points
; cell 1
rp[0,f] = ((real(fzc1[f])-rnds[0])^5%rnds[6] - (imag(fzc1[f])+rnds[12])^3%rnds[18])^2 %2 - 1
ip[0,f] = ((real(fzc1[f])-rnds[1])^5%rnds[7] - (imag(fzc1[f])+rnds[13])^3%rnds[19])^2 %2 - 1
rp[1,f] = ((real(fzc1[f])-rnds[2])^5%rnds[8] - (imag(fzc1[f])+rnds[14])^3%rnds[20])^2 %2 - 1
ip[1,f] = ((real(fzc1[f])-rnds[3])^5%rnds[8] - (imag(fzc1[f])+rnds[15])^3%rnds[21])^2 %2 - 1
rp[2,f] = ((real(fzc1[f])-rnds[4])^5%rnds[10] - (imag(fzc1[f])+rnds[16])^3%rnds[22])^2 %2 - 1
ip[2,f] = ((real(fzc1[f])-rnds[5])^5%rnds[11] - (imag(fzc1[f])+rnds[17])^3%rnds[23])^2 %2 - 1
; cell 2
rp[3,f] = ((real(fzc2[f])-rnds[0])^5%rnds[6] - (imag(fzc2[f])+rnds[12])^3%rnds[18])^2 %2 - 1
ip[3,f] = ((real(fzc2[f])-rnds[1])^5%rnds[7] - (imag(fzc2[f])+rnds[13])^3%rnds[19])^2 %2 - 1
rp[4,f] = ((real(fzc2[f])-rnds[2])^5%rnds[8] - (imag(fzc2[f])+rnds[14])^3%rnds[20])^2 %2 - 1
ip[4,f] = ((real(fzc2[f])-rnds[3])^5%rnds[8] - (imag(fzc2[f])+rnds[15])^3%rnds[21])^2 %2 - 1
rp[5,f] = ((real(fzc2[f])-rnds[4])^5%rnds[10] - (imag(fzc2[f])+rnds[16])^3%rnds[22])^2 %2 - 1
ip[5,f] = ((real(fzc2[f])-rnds[5])^5%rnds[11] - (imag(fzc2[f])+rnds[17])^3%rnds[23])^2 %2 - 1
; cell 3
rp[6,f] = ((real(fzc3[f])-rnds[0])^5%rnds[6] - (imag(fzc3[f])+rnds[12])^3%rnds[18])^2 %2 - 1
ip[6,f] = ((real(fzc3[f])-rnds[1])^5%rnds[7] - (imag(fzc3[f])+rnds[13])^3%rnds[19])^2 %2 - 1
rp[7,f] = ((real(fzc3[f])-rnds[2])^5%rnds[8] - (imag(fzc3[f])+rnds[14])^3%rnds[20])^2 %2 - 1
ip[7,f] = ((real(fzc3[f])-rnds[3])^5%rnds[8] - (imag(fzc3[f])+rnds[15])^3%rnds[21])^2 %2 - 1
rp[8,f] = ((real(fzc3[f])-rnds[4])^5%rnds[10] - (imag(fzc3[f])+rnds[16])^3%rnds[22])^2 %2 - 1
ip[8,f] = ((real(fzc3[f])-rnds[5])^5%rnds[11] - (imag(fzc3[f])+rnds[17])^3%rnds[23])^2 %2 - 1
; cell 4
rp[9,f] = ((real(fzc4[f])-rnds[0])^5%rnds[6] - (imag(fzc4[f])+rnds[12])^3%rnds[18])^2 %2 - 1
ip[9,f] = ((real(fzc4[f])-rnds[1])^5%rnds[7] - (imag(fzc4[f])+rnds[13])^3%rnds[19])^2 %2 - 1
rp[10,f] = ((real(fzc4[f])-rnds[2])^5%rnds[8] - (imag(fzc4[f])+rnds[14])^3%rnds[20])^2 %2 - 1
ip[10,f] = ((real(fzc4[f])-rnds[3])^5%rnds[8] - (imag(fzc4[f])+rnds[15])^3%rnds[21])^2 %2 - 1
rp[11,f] = ((real(fzc4[f])-rnds[4])^5%rnds[10] - (imag(fzc4[f])+rnds[16])^3%rnds[22])^2 %2 - 1
ip[11,f] = ((real(fzc4[f])-rnds[5])^5%rnds[11] - (imag(fzc4[f])+rnds[17])^3%rnds[23])^2 %2 - 1
; put into the grids
cells[0,f] = (rp[0,f] + flip(ip[0,f]) + (1,1))/2
cells[1,f] = (rp[1,f] + flip(ip[1,f]) + (1,1))/2
cells[2,f] = (rp[2,f] + flip(ip[2,f]) + (1,1))/2
cells[3,f] = (rp[3,f] + flip(ip[3,f]) + (1,-1))/2
cells[4,f] = (rp[4,f] + flip(ip[4,f]) + (1,-1))/2
cells[5,f] = (rp[5,f] + flip(ip[5,f]) + (1,-1))/2
cells[6,f] = (rp[6,f] + flip(ip[6,f]) + (-1,1))/2
cells[7,f] = (rp[7,f] + flip(ip[7,f]) + (-1,1))/2
cells[8,f] = (rp[8,f] + flip(ip[8,f]) + (-1,1))/2
cells[9,f] = (rp[9,f] + flip(ip[9,f]) + (-1,-1))/2
cells[10,f] = (rp[10,f] + flip(ip[10,f]) + (-1,-1))/2
cells[11,f] = (rp[11,f] + flip(ip[11,f]) + (-1,-1))/2
i = 0
while i < 12
diff = fzz[f] - cells[i,f]
if @flavor == "Euclidian"
test = cabs(diff)
elseif @flavor == "Manhattan"
test = (abs(real(diff))^real(@mp) + abs(imag(diff))^imag(@mp))
elseif @flavor == "Chebychev"
if abs(real(diff)) > abs(imag(diff))
test = abs(real(diff))
else
test = abs(imag(diff))
endif
elseif @flavor == "Minkovsky"
test = (abs(real(diff))^@ex + abs(imag(diff))^@ex)^(1/@ex)
elseif @flavor == "Exp/Log Manhattan"
test = log(exp(abs(real(diff))) + exp(abs(imag(diff))))
endif
if test < dst[f]
dst2[f] = dst[f]
dst[f] = test
fnear[f] = fzc[f] + cells[i,f]
elseif test < dst2[f]
dst2[f] = test
endif
i = i + 1
endwhile
i = 0
f = f + 1
until (f-1) == @fmax
f = 0
repeat
if f == 0
dist = dst[0]
dist2 = dst2[0]
near = fnear[0]
else
if @nfrac == "2^x"
dist = dist + 2^(-f)*dst[f]
dist2 = dist2 + 2^(-f)*dst2[f]
near = near + 2^(-f)*fnear[f]
elseif @nfrac == "exp(x)"
dist = dist + exp(-f)*dst[f]
dist2 = dist2 + exp(-f)*dst2[f]
near = near + exp(-f)*fnear[f]
elseif @nfrac == "cosh(x)"
dist = dist + 1/cosh(f)*dst[f]
dist2 = dist2 + 1/cosh(f)*dst2[f]
near = near + 1/cosh(f)*fnear[f]
elseif @nfrac == "cos(x)"
dist = dist + 1/cos(f)*dst[f]
dist2 = dist2 + 1/cos(f)*dst2[f]
near = near + 1/cos(f)*fnear[f]
elseif @nfrac == "sec(x)"
dist = dist + cos(f)*dst[f]
dist2 = dist2 + cos(f)*dst2[f]
near = near + cos(f)*fnear[f]
elseif @nfrac == "sech(x)"
dist = dist + cosh(f)*dst[f]
dist2 = dist2 + cosh(f)*dst2[f]
near = near + cosh(f)*fnear[f]
elseif @nfrac == "factorial(x+1)"
dist = dist + 1/fac[f]*dst[f]
dist2 = dist2 + 1/fac[f]*dst2[f]
near = near + 1/fac[f]*fnear[f]
endif
endif
f = f + 1
until (f-1) == @fmax
if @type == "Distance"
distance = dist^@thick
elseif @type == "2nd Distance"
distance = (@smod*dist2-dist)^@thick
elseif @type == "2nd Distance variant"
distance = dist2^@thick
elseif @type == "Mosaic"
distance = cabs(1000*near) + 1000*atan(cabs(near)+#pi)%1
endif
if @mode != 2
sum = sum + a*distance
else
sum = sum + a*abs(distance)
endif
distance = 0
endwhile
if @mode == 2
sum = 3*abs(sum)
endif
if @mode == 1
distance = sum/(10*@eps*(abs(@cbl + @ctl + @cbr + @ctr)+1))
else
distance = sum
endif
if @dmod != 0
distance = distance*@dmod
endif
if @type != "Mosaic"
if @invert
distance = abs(1-distance)
endif
else
distance = distance % 1
endif
m_LastZ = exp(flip(2 * #pi * sqrt(2) * distance))
return distance
endfunc
protected:
JLB_Random rndi
default:
title = "Worley Textures"
int param v_trapshapeworleytextures
caption = "Version (Trap Shape Worley Textures)"
default = 102
hint = "This version parameter is used to detect when a change has been made to the formula that is incompatible with the previous version. When that happens, this field will reflect the old version number to alert you to the fact that an alternate rendering is being used."
visible = @v_trapshapeworleytextures < 102
endparam
param flavor
caption = "Flavor"
default = 4
enum = "Chebychev" "Euclidian" "Manhattan" "Exp/Log Manhattan" "Minkovsky"
endparam
float param ex
caption = "Minkovsky param"
default = 4
visible = @flavor == "Minkovsky"
endparam
complex param mp
caption = "Manhattan pwr"
default = (1,1)
visible = @flavor == "Manhattan"
endparam
param type
caption = "Worley type"
default = 2
enum = "Distance" "2nd Distance" "2nd Distance variant" "Mosaic"
endparam
float param smod
caption = "2nd dist mod"
default = 1.0
visible = @type == "2nd Distance"
endparam
param psize
caption = "Pattern Size"
default = .15
endparam
float param thick
caption = "Thickness"
default = 0.1
endparam
float param dmod
caption = "Dist modulator"
default = 0.0
min = 0.0
endparam
int param fmax
caption = "Fractal iterations"
default = 4
max = 9
endparam
param nfrac
caption = "Fractal function"
default = 0
enum = "2^x" "factorial(x+1)" "cos(x)" "cosh(x)" "exp(x)" "sec(x)" "sech(x)"
endparam
bool param invert
caption = "Invert"
default = false
visible = @type != "Mosaic"
endparam
int param seed
caption = "Worley seed"
default = 123
endparam
param mode
caption = "Mode"
default = 0
enum = "Normal" "Convolution" "Absolute Convolution"
visible = @type != "Mosaic"
endparam
param cc
caption = "Center Extra Weight"
default = 0.0
visible = @mode != "Normal" && @type != "Mosaic"
endparam
param cbl
caption = "Bottom Left Weight"
default = 1.0
visible = @mode != "Normal" && @type != "Mosaic"
endparam
param ctl
caption = "Top Left Weight"
default = 0.0
visible = @mode != "Normal" && @type != "Mosaic"
endparam
param cbr
caption = "Bottom Right Weight"
default = 0.0
visible = @mode != "Normal" && @type != "Mosaic"
endparam
param ctr
caption = "Top Right Weight"
default = 0.0
visible = @mode != "Normal" && @type != "Mosaic"
endparam
param eps
caption = "Epsilon"
default = 0.006
visible = @mode != "Normal" && @type != "Mosaic"
endparam
}