Problem with my Perlin Noise implementation?
Posted: 09 Jul 2020 17:18
I was interested in procedural generation and tried to implement the perlin noise algorithm in Batch. It seems to work fine in some cases, however there are some really weird spots that just pop out of nowhere. Here is the code that generates a texture. After reading the article, I assumed that there are "cells", and each corner of the cell has a random vector assigned to it. So to create a larger image, the script stitches them together. This is what the parameters mean:
gr[dimensions] is how many characters are in each cell, starting from 0. So gr[dimensions] of 2 is actually 3 characters.
gr[width] is how many cells in length
gr[height] is how many cells in height
All the math is directly taken from https://mzucker.github.io/html/perlin-n ... h-faq.html. I've tried to comment what each part does.
This is what it looks like with
https://imgur.com/PNJtxg4
And it looks okay, but sometimes there are some glaring "bright spots" that don't make sense, especially with larger cell numbers. For example, with
https://imgur.com/ZgLI7zX
Which is obviously wrong. I'm not exactly sure what I'm doing wrong, except that I know the results are wrong. If anyone has any clues or tips, it'd be really appreciated! Thanks
gr[dimensions] is how many characters are in each cell, starting from 0. So gr[dimensions] of 2 is actually 3 characters.
gr[width] is how many cells in length
gr[height] is how many cells in height
All the math is directly taken from https://mzucker.github.io/html/perlin-n ... h-faq.html. I've tried to comment what each part does.
Code: Select all
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
(CHCP 65001)>NUL
::gr = gradient, d = dummy, px = pixel
::parameters
SET /A "gr[dimensions]=2","gr[width]=4","gr[height]=4"
::Other variables needed. gr[itery] and gr[iterx] is how many times to actually iterate
SET /A "gr[width]*=gr[dimensions]","gr[height]*=gr[dimensions]","gr[itery]=gr[height]-gr[dimensions]","gr[iterx]=gr[width]-gr[dimensions]"
SET lerp="a=d[dot1]", "b=d[dot2]", "c=wei[x]", "px[x#]=(10-c)*a+(c*b)"
CALL :MACROS
ECHO Generating...
::Make gradient vectors
FOR /L %%Y in (0, %gr[dimensions]%, %gr[height]%) DO (
FOR /L %%X in (0, %gr[dimensions]%, %gr[width]%) DO (
SET /A "d[x]=!RANDOM!*(2+2+1)/32768-1","d[y]=!RANDOM!*(2+2+1)/32768-2"
SET "gr[%%X][%%Y]=!d[x]!;!d[y]!"
)
)
::starting point of texture to 5 down, 10 right
<NUL SET /P "=%ESC%[2J%ESC%[5;10H"
::loop through and create. the first 2 for loops are to get the randoms vectors, and the inner 2 for loops are for each character
::also, for the final px[final], I do (px[final]*4)+150 for the colour value, since it is pretty small
FOR /L %%Y in (0, %gr[dimensions]%, %gr[itery]%) DO (
FOR /L %%X in (0, %gr[dimensions]%, %gr[iterx]%) DO (
SET /A "gr[x]=%%X+gr[dimensions]","gr[y]=%%Y+gr[dimensions]"
FOR /L %%y in (0, 1, %gr[dimensions]%) DO (
FOR /L %%x in (0, 1, %gr[dimensions]%) DO (
%perlin% %%x %%y %%X %%Y !gr[x]! !gr[y]!
SET /A "px[final]=(px[final]*4)+150"
<NUL SET /P "=%ESC%[38;2;100;!px[final]!;!px[final]!m█"
)
<NUL SET /P "=%ESC%[%gr[dimensions]%D%ESC%[D%ESC%[B"
)
<NUL SET /P "=%ESC%[%gr[dimensions]%C%ESC%[C%ESC%[%gr[dimensions]%A%ESC%[A"
)
SET /A "d[num]=(gr[dimensions]+1)*((gr[iterx]/gr[dimensions])+1)"
<NUL SET /P "=%ESC%[!d[num]!D%ESC%[%gr[dimensions]%B%ESC%[B"
)
PAUSE
EXIT /B
::This function returns 2 dot products : x y and the values of gx1 gy1, and x y and the values of gx2 gy2
:DOTPRODUCT <x> <y> <gx1> <gy1> <gx2> <gy2>
FOR /F "tokens=1-4 delims=;" %%A in ("!gr[%3][%4]!;!gr[%5][%6]!") DO (
SET /A "d[dot1]=((%1-%3)*%%A)+((%2-%4)*%%B)","d[dot2]=((%1-%5)*%%C)+((%2-%6)*%%D)"
)
GOTO :EOF
:MACROS
SET ^"LF=^
^" Above empty line is required - do not remove
SET ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
::<x> <y> <bx> <by> <nx> <ny>
::this is follows the same steps as the link provided, except the "weight" is just a normal exponential curve
::returns px[final] as the number
SET perlin=FOR %%# in (1, 1, 2) DO IF %%#==2 ( FOR /F "tokens=1-6" %%A in ("^!args^!") DO (%\n%
SET /A "wei[x]=%%A*%%A","wei[y]=%%B*%%B"%\n%
CALL :DOTPRODUCT %%A %%B %%C %%D %%E %%D%\n%
SET /A %lerp:#=1% %\n%
CALL :DOTPRODUCT %%A %%B %%C %%F %%E %%F%\n%
SET /A %lerp:#=2% %\n%
SET /A "a=px[x1]","b=px[x2]", "c=wei[y]", "px[final]=((10-c)*a+(c*b))/100"%\n%
)) else SET args=
Code: Select all
SET /A "gr[dimensions]=3","gr[width]=4","gr[height]=4"
And it looks okay, but sometimes there are some glaring "bright spots" that don't make sense, especially with larger cell numbers. For example, with
Code: Select all
SET /A "gr[dimensions]=12","gr[width]=2","gr[height]=2"
Which is obviously wrong. I'm not exactly sure what I'm doing wrong, except that I know the results are wrong. If anyone has any clues or tips, it'd be really appreciated! Thanks
