# Simplex noise heightmap

I'm currently working on a game with an "infinite" programmatically generated terrain. The terrain is being generated by creating a heightmap using simplex noise.

I've followed a tutorial and ended up with the following code (it's vb.net by the way):

Public Shared Function GetNoise(ByVal xin As Double, ByVal yin As Double, ByVal zin As Double) As Single
Dim n0, n1, n2, n3 As Double ' Noise contributions from the four corners
' Skew the input space to determine which simplex cell we're in
Dim s As Double = (xin + yin + zin) * F3 ' Very nice and simple skew factor for 3D
Dim i As Integer = fastfloor(xin + s)
Dim j As Integer = fastfloor(yin + s)
Dim k As Integer = fastfloor(zin + s)
Dim t As Double = (i + j + k) * G3
Dim X00 As Double = (i - t) ' Unskew the cell origin back to (x,y,z) space
Dim Y00 As Double = (j - t)
Dim Z00 As Double = (k - t)
Dim x0 As Double = (xin - X00) ' The x,y,z distances from the cell origin
Dim y0 As Double = (yin - Y00)
Dim z0 As Double = (zin - Z00)
' For the 3D case, the simplex shape is a slightly irregular tetrahedron.
' Determine which simplex we are in.
Dim i1, j1, k1 As Integer ' Offsets for second corner of simplex in (i,j,k) coords
Dim i2, j2, k2 As Integer ' Offsets for third corner of simplex in (i,j,k) coords
If (x0 >= y0) Then
If (y0 >= z0) Then ' X Y Z order
i1 = 1
j1 = 0
k1 = 0
i2 = 1
j2 = 1
k2 = 0
ElseIf (x0 >= z0) Then ' X Z Y order
i1 = 1
j1 = 0
k1 = 0
i2 = 1
j2 = 0
k2 = 1
Else ' Z X Y order
i1 = 0
j1 = 0
k1 = 1
i2 = 1
j2 = 0
k2 = 1
End If
Else                ' x0<y0
If (y0 < z0) Then ' Z Y X order
i1 = 0
j1 = 0
k1 = 1
i2 = 0
j2 = 1
k2 = 1
ElseIf (x0 < z0) Then ' Y Z X order
i1 = 0
j1 = 1
k1 = 0
i2 = 0
j2 = 1
k2 = 1
Else ' Y X Z order
i1 = 0
j1 = 1
k1 = 0
i2 = 1
j2 = 1
k2 = 0
End If
End If
' A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
' a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
' a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
' c = 1/6.
Dim x1 As Double = ((x0 - i1) + G3) ' Offsets for second corner in (x,y,z) coords
Dim y1 As Double = ((y0 - j1) + G3)
Dim z1 As Double = ((z0 - k1) + G3)
Dim x2 As Double = ((x0 - i2) + (2 * G3)) ' Offsets for third corner in (x,y,z) coords
Dim y2 As Double = ((y0 - j2) + (2 * G3))
Dim z2 As Double = ((z0 - k2) + (2 * G3))
Dim x3 As Double = ((x0 - 1) + (3 * G3)) ' Offsets for last corner in (x,y,z) coords
Dim y3 As Double = ((y0 - 1) + (3 * G3))
Dim z3 As Double = ((z0 - 1) + (3 * G3))
' Work out the hashed gradient indices of the four simplex corners
Dim ii As Integer = (i And 255)
Dim jj As Integer = (j And 255)
Dim kk As Integer = (k And 255)
Dim gi0 As Integer = permMod12((ii + perm((jj + perm(kk)))))
Dim gi1 As Integer = permMod12((ii + (i1 + perm((jj + (j1 + perm((kk + k1))))))))
Dim gi2 As Integer = permMod12((ii + (i2 + perm((jj + (j2 + perm((kk + k2))))))))
Dim gi3 As Integer = permMod12((ii + (1 + perm((jj + (1 + perm((kk + 1))))))))
' Calculate the contribution from the four corners
Dim t0 As Double = (0.6 - ((x0 * x0) - ((y0 * y0) - (z0 * z0)))) ' change to 0.5 if you want

If (t0 < 0) Then
n0 = 0
Else
t0 = (t0 * t0)
n0 = (t0 * (t0 * dot(grad3(gi0), x0, y0, z0)))
End If

Dim t1 As Double = (0.6 - ((x1 * x1) - ((y1 * y1) - (z1 * z1)))) ' change to 0.5 if you want

If (t1 < 0) Then
n1 = 0
Else
t1 = (t1 * t1)
n1 = (t1 * (t1 * dot(grad3(gi1), x1, y1, z1)))
End If

Dim t2 As Double = (0.6 - ((x2 * x2) - ((y2 * y2) - (z2 * z2)))) ' change to 0.5 if you want

If (t2 < 0) Then
n2 = 0
Else
t2 = (t2 * t2)
n2 = (t2 * (t2 * dot(grad3(gi2), x2, y2, z2)))
End If

Dim t3 As Double = (0.6 - ((x3 * x3) - ((y3 * y3) - (z3 * z3)))) ' change to 0.5 if you want

If (t3 < 0) Then
n3 = 0
Else
t3 = (t3 * t3)
n3 = (t3 * (t3 * dot(grad3(gi3), x3, y3, z3)))
End If
' Add contributions from each corner to get the final noise value.
' The result is scaled to stay just inside [-1,1] (now [0, 1])
Return (CType(((32 * (n0 + (n1 + (n2 + n3)))) + 1), Single) * 0.5!) ' change to 76.0 if you want

End Function


I've been told that a function like this should return a value between -1 and 1. However, calling GetNoise(0,2,0) for instance returns -6,240867.

Since the returned value of most points next to eachother are quite close to eachother, I believe most of the code is correct. However, with a few of these weird results, my heightmap obviously looks terrible.

Can anybody explain what I'm doing wrong/what I have missed? I've read quite some info as to how perlin/simplex noise works, and I understand the basics. I must however admit that I don't yet fully understand everything that comes with it.

EDIT: As Alexandre Desbiens mentioned, it may be best to show you my heightmap output. Because rgb values don't allow negative values, I can only show you the map I created using the height data. here it is: • It could be nice if you uploaded an image of one of the heightmap generated. I guess it could be of help. – Alexandre Desbiens Jun 19 '15 at 17:15
• You're absolutely right. I edited the question to give you an image of what the height data looks like. – Peethor Jun 19 '15 at 18:55

Assuming you have translated this from the original Java code it looks like you have been a bit careless in adding brackets in a few places. For example the original code has:

double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;


while you have:

Dim t0 As Double = (0.6 - ((x0 * x0) - ((y0 * y0) - (z0 * z0))))


which if you remove the brackets is actually:

Dim t0 As Double = 0.6 - x0 * x0 + y0 * y0 + z0 * z0


While I'm not familiar with VB.NET I think most of the brackets you added are not required and end up making things more difficult to understand as well as introducing errors like this. It looks like you did the same thing in the t1, t2 and t3` variables and possibly elsewhere.

• Though you're absolutely right about the fact that it makes the code a bit convoluted, they don't change any of its function. I hope I have time today to walk through the code, clean it up, and edit my question. Thanks for your input. – Peethor Jun 20 '15 at 6:13
• Alright, you were right. I hadn't even read your answer properly. It DOES change its function. I never thought I would lose sight of PEMDAS, but I did. I stand utterly corrected. Thank you. – Peethor Jun 20 '15 at 10:11