I am looking for a simple way to generate something similar to procedural\perlin noise in matlab.
It just needs to have the general perlin noise traits, not to replicate ken perlin's method exactly.
Perlin noise is a popular procedural generation algorithm invented by Ken Perlin. It can be used to generate things like textures and terrain procedurally, meaning without them being manually made by an artist or designer. The algorithm can have 1 or more dimensions, which is basically the number of inputs it gets.
Ken Perlin developed Perlin noise in 1983 as a result of his frustration with the "machine-like" look of computer-generated imagery (CGI) at the time. He formally described his findings in a SIGGRAPH paper in 1985 called An Image Synthesizer.
Use offsets. Add a random value between -10000 and 10000 to your perlin noise x and y values before you generate a point. However, these random values need to be initialized once in a start function for example. Don't randomize them every time you sample a point.
Minecraft is specifically using Perlin noise calculations, like the kind you'd use to create a rough-looking texture for a 3D model.
An easy way to do it in in Matlab, as shown in Octave by the Nullprogramm blog is:
n = 64;
m = 64;
im = zeros(n, m);
im = perlin_noise(im);
figure; imagesc(im); colormap gray;
function im = perlin_noise(im)
[n, m] = size(im);
i = 0;
w = sqrt(n*m);
while w > 3
i = i + 1;
d = interp2(randn(n, m), i-1, 'spline');
im = im + i * d(1:n, 1:m);
w = w - ceil(w/2 - 1);
end
perlin noise implementation already exists in several programming languages and is freely available on the internet. For instance, there is a java class on Ken Perlin's homepage (3D version / 4D version) that could be used with Matlab.
However, if you absolutely want to use Matlab language, I guess it is just a matter of "translating" which should be pretty straightforward. Here is a try for dimensions 1 to 3 which should work. It is not optimized nor thoroughly tested (seem to have some border problems). Hope it helps you.
function noise=perlin(values,x,y,z)
if(numel(values)~=512)
values=randperm(256)-1;
values=[values values];
end
x=abs(x);
X=bitand(floor(x),255);
x=x-floor(x);
u=fade(x);
A=values(1+X);
noise=linterp(u,grad1d(values(1+X),x),grad1d(values(1+X+1),x-1));
if(nargin>2)
y=abs(y);
Y=bitand(floor(y),255);
y=y-floor(y);
v=fade(y);
A=A+Y;
B=values(1+X+1)+Y;
noise=linterp(u,linterp(u,grad2d(values(1+A),x,y),grad2d(values(1+B),x-1,y)),linterp(u,grad2d(values(1+A+1),x,y-1),grad2d(values(1+B+1),x-1,y-1)));
end
if(nargin>3)
z=abs(z);
Z=bitand(floor(z),255);
z=z-floor(z);
w=fade(z);
AA=values(1+A)+Z;
AB=values(1+A+1)+Z;
BA=values(1+B)+Z;
BB=values(1+B+1)+Z;
noise=linterp( w, ...
linterp(v, ...
linterp(u, ...
grad3d(values(1+AA),x,y,z), ...
grad3d(values(1+BA),x-1,y,z)), ...
linterp(u, ...
grad3d(values(1+AB),x,y-1,z), ...
grad3d(values(1+BB),x-1,y-1,z))), ...
linterp(v, ...
linterp(u, ...
grad3d(values(1+AA+1),x,y,z-1), ...
grad3d(values(1+BA+1),x-1,y,z-1)), ...
linterp(u, ...
grad3d(values(1+AB+1),x,y-1,z-1), ...
grad3d(values(1+BB+1),x-1,y-1,z-1))));
end
end
function l=linterp(t,a,b)
l=a+t*(b-a);
end
function t=fade(t)
t=6*t^5-15*t^4+10*t^3;
end
function g=grad1d(hash,x)
if(bitand(hash,1))
g=-x;
else
g=x;
end
end
function g=grad2d(hash,x,y)
h=bitand(hash,3);
if(bitand(h,2))
u=-x;
else
u=x;
end
if(bitand(h,1))
v=-y;
else
v=y;
end
g=u+v;
end
function g=grad3d(hash,x,y,z)
h=bitand(hash,15);
if(h<8)
u=x;
else
u=y;
end
if(h<4)
v=y;
elseif(h==12 || h==14)
v=x;
else
v=z;
end
if(bitand(h,1))
if(bitand(h,2))
g=-u-v;
else
g=-u+v;
end
else
if(bitand(h,2))
g=u-v;
else
g=u+v;
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With