common
Class TrapShapeNoise
Object
common:Generic
common:TrapShape
common:TrapShapeNoise
class
- TrapShape:TrapShapeNoise
Simple noise trap shape.
Most trap shapes have a clearly-defined shape. However, in some
cases where texturing is desired, a noise basis function may be
required. This class provides a simple, modified Perlin noise
basis function which can be used as a stand-alone trap shape or
as the foundation on which to build more sophisticated textures.
If you are writing a function that needs a noise basis function
you should use this class (or any of its derivatives) to provide
it. Then, users may select any other TrapShapeNoise-derived
class. If you use TrapShape as your parameter, the user may be
confused by the appearance of other trap shapes which will not
work well as noise basis functions.
If you want to write your own noise basis function, you should
derive from this class so that your noise basis can be selected
to replace any other TrapShapeNoise objects. These should give
a result over the entire complex plane ranging from 0 to 1 (but
occasional deviations outside this range should be accepted).
The original code came from an Intel application note on using
MMX instructions for procedural texture mapping. Perlin's
original algorithm used a table of pre-generated random numbers
but at the time this algorithm was ported to Ultra Fractal
(1998) there was no ability to set up this table in a global:
section. Intel's adaptation was therefore useful as it uses a
more direct (but slightly less random) random number generation
scheme.
Ultra Fractal Source
Toggle UF Source Code Display
class TrapShapeNoise(TrapShape) {
; Simple noise trap shape.
; <p>
; Most trap shapes have a clearly-defined shape. However, in some
; cases where texturing is desired, a noise basis function may be
; required. This class provides a simple, modified Perlin noise
; basis function which can be used as a stand-alone trap shape or
; as the foundation on which to build more sophisticated textures.
; <p>
; If you are writing a function that needs a noise basis function
; you should use this class (or any of its derivatives) to provide
; it. Then, users may select any other TrapShapeNoise-derived
; class. If you use TrapShape as your parameter, the user may be
; confused by the appearance of other trap shapes which will not
; work well as noise basis functions.
; <p>
; If you want to write your own noise basis function, you should
; derive from this class so that your noise basis can be selected
; to replace any other TrapShapeNoise objects. These should give
; a result over the entire complex plane ranging from 0 to 1 (but
; occasional deviations outside this range should be accepted).
; <p>
; The original code came from an Intel application note on using
; MMX instructions for procedural texture mapping. Perlin's
; original algorithm used a table of pre-generated random numbers
; but at the time this algorithm was ported to Ultra Fractal
; (1998) there was no ability to set up this table in a global:
; section. Intel's adaptation was therefore useful as it uses a
; more direct (but slightly less random) random number generation
; scheme.
public:
func TrapShapeNoise(Generic pparent)
TrapShape.TrapShape(pparent)
endfunc
float func Iterate(complex pz)
TrapShape.Iterate(pz)
; determine integer coordinate for corners of square
; surrounding pz
float bx0 = floor(real(pz)) % real(@p_tilesize)
float by0 = floor(imag(pz)) % imag(@p_tilesize)
if (bx0 < 0)
bx0 = bx0 + real(@p_tilesize)
endif
if (by0 < 0)
by0 = by0 + imag(@p_tilesize)
endif
float bx1 = (bx0 + 1) % real(@p_tilesize)
float by1 = (by0 + 1) % imag(@p_tilesize)
; offset these
bx0 = bx0 + real(@p_tileoffset)
bx1 = bx1 + real(@p_tileoffset)
by0 = by0 + imag(@p_tileoffset)
by1 = by1 + imag(@p_tileoffset)
; determine the fractional distance to each corner
float rx0 = real(pz) - floor(real(pz))
float ry0 = imag(pz) - floor(imag(pz))
float rx1 = rx0 - 1
float ry1 = ry0 - 1
; create a "random" index for each corner
; (this is where Intel's version differs from Perlin's)
float b00 = (bx0^@p_power % 65536 + by0)^@p_power % 65536
float b10 = (bx1^@p_power % 65536 + by0)^@p_power % 65536
float b01 = (bx0^@p_power % 65536 + by1)^@p_power % 65536
float b11 = (bx1^@p_power % 65536 + by1)^@p_power % 65536
; produce a "random" vector for each corner
float g_b00_0 = (b00)^@p_power*0.25 % 512 - 256
float g_b10_0 = (b10)^@p_power*0.25 % 512 - 256
float g_b01_0 = (b01)^@p_power*0.25 % 512 - 256
float g_b11_0 = (b11)^@p_power*0.25 % 512 - 256
float g_b00_1 = (b00+1)^@p_power*0.25 % 512 - 256
float g_b10_1 = (b10+1)^@p_power*0.25 % 512 - 256
float g_b01_1 = (b01+1)^@p_power*0.25 % 512 - 256
float g_b11_1 = (b11+1)^@p_power*0.25 % 512 - 256
; normalize each vector
float d = 0.0;
d = 1 / sqrt(sqr(g_b00_0) + sqr(g_b00_1))
g_b00_0 = g_b00_0 * d
g_b00_1 = g_b00_1 * d
d = 1 / sqrt(sqr(g_b10_0) + sqr(g_b10_1))
g_b10_0 = g_b10_0 * d
g_b10_1 = g_b10_1 * d
d = 1 / sqrt(sqr(g_b01_0) + sqr(g_b01_1))
g_b01_0 = g_b01_0 * d
g_b01_1 = g_b01_1 * d
d = 1 / sqrt(sqr(g_b11_0) + sqr(g_b11_1))
g_b11_0 = g_b11_0 * d
g_b11_1 = g_b11_1 * d
; produce "colors" for each corner
float u1 = rx0 * g_b00_0 + ry0 * g_b00_1
float v1 = rx1 * g_b10_0 + ry0 * g_b10_1
float u2 = rx0 * g_b01_0 + ry1 * g_b01_1
float v2 = rx1 * g_b11_0 + ry1 * g_b11_1
; interpolate between corners using
; bilinear filtering
float sx = sqr(rx0) * (3 - rx0*2)
float sy = sqr(ry0) * (3 - ry0*2)
float a = u1 + sx*(v1-u1)
float b = u2 + sx*(v2-u2)
return (a + sy*(b-a))
endfunc
default:
title = "Noise"
int param v_trapshapenoise
caption = "Version (TrapShapeNoise)"
default = 100
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_trapshapenoise < 100
endparam
complex param p_tileoffset
caption = "Noise Offset"
default = (0,0)
hint = "Moves the noise pattern around. Note that this algorithm works best when the offset components are integers. Also note that if you use this object inside another one which calls it repeatedly (such as an fBm object) this offset will be applied each time."
endparam
float param p_power
caption = "Noise Exponent"
default = 2.15755844
hint = "Sets the exponent used to generate random numbers. This acts very much like a random number seed; different values will produce different noise patterns. Use fractional values between 2.0 and 3.0 for best results."
endparam
complex param p_tilesize
caption = "Tile Size"
default = (256,256)
hint = "Sets the full size of the noise algorithm. Points outside this range will 'wrap' at the edges."
endparam
}
Method Summary |
float |
Iterate(complex pz)
call this for each iteration being trapped |
Methods inherited from class Object |
|
TrapShapeNoise
public TrapShapeNoise(Generic pparent)
TrapShapeNoise
public TrapShapeNoise()
Iterate
public float Iterate(complex pz)
- Description copied from class:
TrapShape
- call this for each iteration being trapped
- Overrides:
Iterate
in class TrapShape