Problem with my Perlin Noise implementation?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Lowsun
Posts: 29
Joined: 14 Apr 2019 17:22

Problem with my Perlin Noise implementation?

#1 Post by Lowsun » 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.

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=
This is what it looks like with

Code: Select all

SET /A "gr[dimensions]=3","gr[width]=4","gr[height]=4"
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

Code: Select all

SET /A "gr[dimensions]=12","gr[width]=2","gr[height]=2"
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 :)

T3RRY
Posts: 243
Joined: 06 May 2020 10:14

Re: Problem with my Perlin Noise implementation?

#2 Post by T3RRY » 10 Jul 2020 04:21

Just though a bit of quick testing, as dimensions increase, the value of px[final] scales to the point it (far) exceeds the 255 value limit of the RGB values hence the washed out colours.

I added the following code to your script to generate the attatched log in order see whats happening with the variable vaules for each cell.
The test was on the parameters: SET /A "gr[dimensions]=12","gr[width]=2","gr[height]=2"

Code: Select all

		>>"%~dp0Outfile.Txt" (
		Set px[
		Set gr[
		Set d[
		Set lerp
		)
I place the above in the nested for loop imediately below the line:

Code: Select all

                <NUL SET /P "=%ESC%[38;2;100;!px[final]!;!px[final]!m█"
Attachments
Outfile.Txt
(260.01 KiB) Downloaded 267 times

Post Reply