|
|
Mike Andrews wrote:
> Hi Folks,
>
> Here's the scene file for the comparison of the 'improved noise' to the
> noise generators in PoV.
>
> Comments welcomed ...
Andrew, I really like your idea of implementing this in SDL.
I wanted to try to make a function similar to your's that evaluates
faster, so that it can be used in real scenes.
I also wanted to put it all in a macro.
Now I have done this.
In order to test a fuction that the macro produced, I tried to render
the upper left superellipsoid (only) in your scene at 512x384 AA 0.3.
The results was 1m52s vs. 3m20s. - So it seems to be faster, but I'm
afraid that it is still to slow to be used in complex scenes :(
Maybe I'll try to make macros for some other dimensions later.
Btw.: Wouldn't noise in 4 dimensions be useful for animations ?
Tor Olav
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2004 by Tor Olav Kristensen
// Email: t o r _ o l a v _ k [ a t ] h o t m a i l . c o m
// http://subcube.net
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#version 3.6;
// Improved Perlin Noise macro
// A macro that will make a function which can produce Ken Perlin's
// "Improved Noise". The function will return values in the interval
// from Min to Max. N defines a range from -<N, N, N> to <N, N, N>
// in 3D space for which the noise will not repeat itself (?).
// Seed can be any positive integer. The trick to store the hash
// array in a linear spline function was borrowed from Mike Andrews.
// References:
// http://mrl.nyu.edu/~perlin/noise/
// Mike Andrews' post to povray.binaries.scene-files, 29. June 2004:
// Subject: "Perlin's Improved Noise - SDL version"
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro PerlinNoise3DFunction(Seed, N, Min, Max)
#local S_CurveFn = function (T) { ((6*T - 15)*T + 10)*pow(T, 3) }
#local HashArray = array[N]
#local Cnt = 0;
#while (Cnt < N)
#local HashArray[Cnt] = Cnt;
#local Cnt = Cnt + 1;
#end // while
#local S = seed(Seed);
#local Cnt = 0;
#while (Cnt < N)
#local I = int(rand(S)*N);
#local Temp = HashArray[Cnt];
#local HashArray[Cnt] = HashArray[I];
#local HashArray[I] = Temp;
#local Cnt = Cnt + 1;
#end // while
#local P_Fn =
function {
spline {
linear_spline
#local Cnt = 0;
#while (Cnt < 2*N)
Cnt, HashArray[mod(Cnt, N)]*<1, 0>
#if (Cnt < 2*N - 1)
,
#end // if
#local Cnt = Cnt + 1;
#end // While
}
}
#local GradFn =
function(x, y, z, H) {
select(
H , 0, +x+y,
select(
H - 1, 0, -x+y,
select(
H - 2, 0, +x-y,
select(
H - 3, 0, -x-y,
select(
H - 4, 0, +x+z,
select(
H - 5, 0, -x+z,
select(
H - 6, 0, +x-z,
select(
H - 7, 0, -x-z,
select(
H - 8, 0, +y+z,
select(
H - 9, 0, -y+z,
select(
H - 10, 0, +y-z,
select(
H - 11, 0, -y-z,
0
)
)
)
)
)
)
)
)
)
)
)
)
}
#local LERP_Fn = function (A, B, T) { A + T*(B - A) }
#local LERP_Z_Fn =
function (x, y, z, HashXY, IZ) {
LERP_Fn(
GradFn(x, y, z , mod(P_Fn(HashXY + IZ ).u, 12)),
GradFn(x, y, z - 1, mod(P_Fn(HashXY + IZ + 1).u, 12)),
S_CurveFn(z)
)
}
#local LERP_Y_Fn =
function (x, y, z, HashX, IY, IZ) {
LERP_Fn(
LERP_Z_Fn(x, y , z, P_Fn(HashX + IY ).u, IZ),
LERP_Z_Fn(x, y - 1, z, P_Fn(HashX + IY + 1).u, IZ),
S_CurveFn(y)
)
}
#local LERP_X_Fn =
function (x, y, z, IX, IY, IZ) {
LERP_Fn(
LERP_Y_Fn(x , y, z, P_Fn(IX ).u, IY, IZ),
LERP_Y_Fn(x - 1, y, z, P_Fn(IX + 1).u, IY, IZ),
S_CurveFn(x)
)
}
#local LERP_XYZ_Fn =
function(x, y, z, FX, FY, FZ) {
LERP_X_Fn(
x - FX, y - FY, z - FZ,
FX - N*floor(x/N), FY - N*floor(y/N), FZ - N*floor(z/N)
)
}
function {
(
1 + LERP_XYZ_Fn(x, y, z, floor(x), floor(y), floor(z))
)/2*(Max - Min) + Min
}
#end // macro PerlinNoise3DFunction
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
Post a reply to this message
|
|