Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate procedural\perlin noise in matlab

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.

like image 575
olamundo Avatar asked Sep 08 '11 11:09

olamundo


People also ask

Is Perlin noise procedural generation?

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.

How was Perlin noise created?

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.

How do you randomize Perlin noise?

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.

Does Minecraft use 2d or 3D Perlin noise?

Minecraft is specifically using Perlin noise calculations, like the kind you'd use to create a rough-looking texture for a 3D model.


2 Answers

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
like image 186
Maurits Avatar answered Sep 24 '22 06:09

Maurits


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
like image 33
Aabaz Avatar answered Sep 20 '22 06:09

Aabaz