Perlin noise: Difference between revisions
Content added Content deleted
(→{{header|Raku}}: shorten slightly) |
(add evaldraw (.kc) solution for Perlin Noise Task) |
||
Line 415: | Line 415: | ||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
See [https://rosettacode.org/wiki/Perlin_noise#Pascal Pascal]. |
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}}== |
=={{header|Factor}}== |