Perlin noise: Difference between revisions

add evaldraw (.kc) solution for Perlin Noise Task
(→‎{{header|Raku}}: shorten slightly)
(add evaldraw (.kc) solution for Perlin Noise Task)
Line 415:
=={{header|Delphi}}==
See [https://rosettacode.org/wiki/Perlin_noise#Pascal Pascal].
 
 
=={{header|Evaldraw}}==
{{trans|C}}
 
This is a translation of the C version, with the gradient function borrowed from the Go version.
This evaldraw version computes the correct output. The array doesnt have to be 512 elements, we can rely on the wrap around when
accessing indices out of bounds since power of 2 arrays are anded with their size on access. Evaldraw has a built-in noise(x,y,z) function
that behaves like perlin noise, but does not give the exact same result as the original implementation in Java by Ken Perlin. There
is a comparison, so we can see the similarity in output visually.
 
<syntaxhighlight lang="c">
static p[256] = {
151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,
99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,
11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,
139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,
46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,
169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,
250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,
182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,
167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,178,185,112,104,218,
246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,
14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,
150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
};
 
()
{
cls(0);
x=3.14; y=42; z=7;
val = perlin_noise(x,y,z);
// expect val=0.13691995878400012
moveto(0,256);
setcol(255,255,255);
printf("Perlin Noise for (%g,%g,%g) is %.17lf\n",x,y,z,val);
val = noise(x,y,z);
printf("Evaldraw builtin noise for (%g,%g,%g) is %.17lf",x,y,z,val);
t = 2*klock(0);
freq = 8;
scale = freq/255;
for(y=0; y<256; y++)
for(x=0; x<256; x++)
{
val = 128+128 * perlin_noise(x * scale,y * scale,t);
setcol(48+.25*val,64+1*val,200+1.5*val);
setpix(x,y);
val = 128+128 * noise(x * scale,y * scale,t);
setcol(48+.25*val,64+1*val,200+1.5*val);
setpix(x+256,y);
}
}
 
fade(t) { t * t * t * (t * (t * 6 - 15) + 10); }
 
lerp(t,a,b) { a + t * (b - a); }
 
grad(hash, double x, double y, double z) {
// convert 4 bits of hash into 12 gradient vectors
h = int(hash % 15);
// Evaldraw rscript compiler doesnt handle
// chained terniary statements gracefully, use if-else instead.
if (h==0 || h==12)
return x + y;
else if (h==1 || h==14)
return y - x;
else if (h==2)
return x - y;
else if (h==3)
return -x - y;
else if (h==4)
return x + z;
else if (h==5)
return z - x;
else if (h==6)
return x - z;
else if (h==7)
return -x - z;
else if (h==8)
return y + z;
else if (h==9 || h==13)
return z - y;
else if (h==10)
return y - z;
// case 11, 16:
return -y - z;
}
perlin_noise(x,y,z) {
// Find cube corner from xyz
cubx = floor(x);
cuby = floor(y);
cubz = floor(z);
x -= floor(x);
y -= floor(y);
z -= floor(z);
// Curves for x,y,z
u = fade(x);
v = fade(y);
w = fade(z);
// Hash coords of 8 cube corners
A = p[cubx]+cuby; AA = p[A]+cubz; AB = p[A+1]+cubz,
B = p[cubx+1]+cuby; BA = p[B]+cubz; BB = p[B+1]+cubz;
// Blended results from 8 corners in cube
return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ),
grad(p[BA ], x-1, y , z )),
lerp(u, grad(p[AB ], x , y-1, z ),
grad(p[BB ], x-1, y-1, z ))),
lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ),
grad(p[BA+1], x-1, y , z-1 )),
lerp(u, grad(p[AB+1], x , y-1, z-1 ),
grad(p[BB+1], x-1, y-1, z-1 ))));
}
}</syntaxhighlight>
 
[[File:Evaldrawperlinnoise.png|thumb|alt=builtin noise function is faster|Perlin noise function vs builtin noise]]
 
=={{header|Factor}}==
63

edits