# Linear 2D Noise Code

#### © 1996 Harriet Fell for CSG140 (formerly COM3370) Computer Graphics

Below are Pascal implementations of Linear Noise and Turbulence. Marble and simple Clouds are built on them. See Linear 2D Noise Images.

```program LinearNoise96;
uses
simpleWindows, Cwindows, stringTools, IOTools, randomTools;
const
size = 39;{multiple of 3 for splines}
type
noiseArray = array[0..size, 0..size] of real;
var
noiseB, noiseR, noiseG: noiseArray;

h, v: longint;							{pixel coordinates}
divisor: longint;						{for spreading out the noise}

x, y: real;								{x = h/divisor, y= v/divisor are sent to LinearNoise function}
factorR, factorG, factorB, factor: real;{to set the proportions of Red, Green, Blue}
myColor: rgbColor;						{The color that the pixel is set to}
start: integer;							{for starting scale}
choice: integer;						{ which procedure to call}
normalize: boolean;
procedure openWindows;
begin
{ set defaults for drawing window - see simpleCwindows }
with Coptions do
begin
title := '';
framewidth := 3;
framecolor := white;
fieldcolor := black;
end;

hideall;
macii_minitext;
miniCdraw;
writeln('Uniform Linear Noise Samples');
random_seed(tickCount);
end;

procedure setNoises;
var
i, j, k: integer;
sum: real;
begin
for i := 0 to size - 1 do
for j := 0 to size - 1 do
begin
noiseR[i, j] := random_real(0, 1);	{set all but last row and column to random reals between 0 and 1}
noiseG[i, j] := random_real(0, 1);
noiseB[i, j] := random_real(0, 1);
end;
for j := 1 to size - 1 do
begin
noiseR[size, j] := noiseR[0, j];		{set the last row and column to match the first row and column}
noiseR[j, size] := noiseR[j, 0];
noiseG[size, j] := noiseG[0, j];
noiseG[j, size] := noiseG[j, 0];
noiseB[size, j] := noiseB[0, j];
noiseB[j, size] := noiseB[j, 0];
end;

noiseR[size, size] := noiseR[0, 0];			{set the last corner to complete the wrap}
noiseG[size, size] := noiseG[0, 0];
noiseB[size, size] := noiseB[0, 0];
end;

function linearNoise (u, v: real; var noise: noiseArray): real;
var
iu, iv, ip, iq: integer;
du, dv, bot, top: real;
begin
iu := trunc(u);
iv := trunc(v);
du := u - iu;
dv := v - iv;

iu := iu mod size;
iv := iv mod size;
ip := (iu + 1);
iq := (iv + 1);

bot := noise[iu, iv] + du * (noise[ip, iv] - noise[iu, iv]);
top := noise[iu, iq] + du * (noise[ip, iq] - noise[iu, iq]);

linearNoise := bot + dv * (top - bot);
end;

function Lturbulence (u, v: real; var noise: noiseArray): real;
var
t, scale: real;
begin
scale := start;
t := 0;
while scale >= 1 / divisor do {1 / divisor}
begin
t := t + linearNoise(u / scale, v / scale, noise) * scale;
scale := scale / 2;
end;
if normalize then {normalized turbulence}
t := t / 2 / start;
Lturbulence := t;
end;

function marble (x, y: real; var noise: noiseArray): real;
var
marb: real;
begin
marble := abs(sin(x + Lturbulence(x, y, noise)));
end;

function cloud (x, y: real; var noise: noiseArray): real;
begin
cloud := sin(x + Lturbulence(x, y, noise));
end;

procedure noiseColor (x, y: real);
begin
factorR := linearNoise(x, y, noiseR);
factorG := linearNoise(x, y, noiseG);
factorB := linearNoise(x, y, noiseB);

with myColor do
begin
red := round(2 * factorR * maxint);
green := round(2 * factorG * maxint);
blue := round(2 * factorB * maxint);
end;
end;

procedure turbulenceColor (x, y: real);
begin
factorR := Lturbulence(x, y, noiseR);
factorG := Lturbulence(x, y, noiseG);
factorB := Lturbulence(x, y, noiseB);

with myColor do
begin
red := round(2 * factorR * maxint);
green := round(2 * factorG * maxint);
blue := round(2 * factorB * maxint);
end;
end;

procedure marbleColor (x, y: real);
begin
{    factorR := marble(x, y, noiseR);	}
{square factorR to make a narrower band of yellow where red adds to green}
{    factorR := factorR * factorR;}
factorG := sqrt(marble(x, y, noiseG));{take the square root to fatten the green bands, leaving thin blue veins}
with myColor do
begin
red := 0;{trunc(factorR * maxint);}
green := trunc(2 * factorG * maxint);
blue := trunc(maxint);
end;
end;

procedure cloudColor (x, y: real);
begin
factorR := abs(cloud(x, y, noiseR));
factorG := abs(cloud(y, x, noiseG));	{note that x and y are flipped; fuzziness in two directions}
factor := abs(factorR + factorG) / 2;	{factor scales from blue to white}

with myColor do
begin
red := maxint + trunc(factor * maxint);
green := maxint + trunc(factor * maxint);
blue := maxint + trunc((1 - factor / 2) * maxint);
end;
end;

{------main----------------------------------------------------------------------}
begin
openWindows;
setNoises;
divisor := 1;
start := 1;
choice := 2;
repeat
start := request_integer('Enter scale = ', start);
divisor := request_integer('Enter divisor = ', divisor);
writeln('Choose one: 1. noise');
writeln('            2. turbulence');
writeln('            3. marble');
writeln('            4. clouds');
choice := request_integer('Enter choice = ', choice);
if (choice = 2) or (choice = 3) or (choice = 4) then
normalize := confirm('Normalize turbulence? ', false);
with CdrawingRect do
begin
for v := 0 to bottom do
for h := 0 to right do
begin
x := h / divisor;
y := v / divisor;

case choice of
1:
noiseColor(x, y);
2:
turbulenceColor(x, y);
3:
marbleColor(x, y);
4:
cloudColor(x, y);
otherwise
;
end; {case}
setCPixel(h, v, myColor);
end;
end;

until not confirm('Continue? ', true);