Code archives/3D Graphics - Maths/Improved Perlin Noise 2D and 3D

This code has been declared by its author to be Public Domain code.

Download source code

Improved Perlin Noise 2D and 3D by MusicianKool2010
Update, I have converted the Improved perlin noise into a user library. the examples below will only work with the blitz3d perlin code. But can be modified to work with the User library.

Download the Blitz3d Userlib:
http://www.mediafire.com/?kwno5wnty4i (Final)
http://www.mediafire.com/?2ynmwqyoqmz (version 3)

Updated the 3d perlin mesh deform (little vector glitch).

Added Color Gradient by Krischan to the lib. (Hope thats ok.) Found in the code archives.
http://www.blitzbasic.com/codearcs/codearcs.php?code=2415

Mesh deform used from the code archives as well.
http://www.blitzbasic.com/codearcs/codearcs.php?code=1120

Fixed small bug that would sometimes access outside a banks size/range.

The Library.



3D Mesh deformation!


3D Texture example!


2D Example!
...

Comments

MusicianKool2010
Update, Huge speed increase with 3d Perlin Mesh deformation.


lo-tekk2010
I got a MAV running the 3d mesh example in line:

WritePixelFast x,y,rgb,IB
in the include file.


MusicianKool2010
Try changing the line near the top from

Image = createtexture(imagesize,imagesize,257)
to
Image = createtexture(imagesize,imagesize)

The 3D mesh Deformation example will only work on my system with the 257 flag.


Krischan2010
This is really nice and very fast. Here some caribbean-style islands generated in runtime:






slenkar2010
looks good, dont really use B3D much anymore though


Ian Thompson2010
Really nice, well done and thanks!


MusicianKool2010
Well spent most of yesterday trying to make This improved perlin noise into a .dll and have done so success fully. a huge speed increase came with it as well. on my system, it draws a 512*512 image in 2670 millisecs, with blitz code it takes 7880 so I think its worth making it a userLib. as soon as I figure out were to host it, I'll put it up.

ok Here you go.

http://www.mediafire.com/?d0lmdzkm2h4

just put the .dll and .decls in your blitz3d userlib folder.

You must use InitPerlinNoise() at least once before you can use Perlin3D( )


Krischan2010
Well done, here my island code with your DLL, takes now 707ms compared to 1276ms before = 45% faster!:




_PJ_2010
Overall, it really is exceptionally fast in real terms. Very nice functions, thanks :)

@Krischan - I'm sure there's more optimisation can be done there, but overall I doubt it would make a really significant improvement and probably not worth the effort put in to doing so.

I'm (slowly, amongst a million other bots and pieces) using this to patch together a super-terrain of tiles... possibly for making into a sphere, hopefiully I'll get a neat method for matching the edges :)


Krischan2010
You could try to port this code to BB, this is a complete "infinite" planet, done in Darkbasic:

http://forumfiles.thegamecreators.com/download/1527504

It could look like that (same technique):

http://www.youtube.com/watch?v=DCzDKj3hjOE&feature=related


MusicianKool2010
fun little screen saver like thing. a cube traversing through volumetric Perlin space.




MusicianKool2010
Aw poop. I released the Lib to soon, I just made it faster.

ok...

smaller and faster

http://www.mediafire.com/?wzg2ymntxmg

..And done.. wait, made faster ... err maybe not.. whatever it's good enough done!..


Krischan2010
Well done, now only 610ms, excellent oO


MusicianKool2010
@ Krischan: Your Island code takes my sad laptop, 2000 ms. I need to upgrade..


MusicianKool2010
[quote]
You could try to port this code to BB, this is a complete "infinite" planet, done in Darkbasic:

http://forumfiles.thegamecreators.com/download/1527504
[\quote]

I dont think blitz3d can do this, cause you cant delete verticies.


puki2010
You can do that in Blitz3D.


MusicianKool2010
@puki oh.. you can make your own lod?

I'm gonna try it then.


puki2010
Yep.


puki2010
For a cheaper way of doing it, have a look at 'Blitz3D\Samples\Blitz 3D Samples\birdie\lodBalls\'.


MusicianKool2010
Updated The Lib for the last time.

InitPerlinNoise() now requires a random seed
InitPerlinNoise(seed)

I did this so that a map or terrain or whatever will look the same every time that seed is used. Perlin3D no longer takes a seed as it was never really a seed, it was just adding the value to the x,y,z location in Perlin space. The seed now generates the Permutation , gradient,and fade arrays so the perlin noise is truly dependent on the seed.


Download here: http://www.mediafire.com/?wzg2ymntxmg
Includes the free basic source.


MusicianKool2010
I guess I lied... I've added a lot and changed a lot.

FNL.dll (Fractal noise library)

Added :
Fractal Browian Motion - fBm
Ridged Multifractal (2 versions) - RidgedMF and RidgedMF2
Turbulence Fractal - Turbulence

Download here: http://www.mediafire.com/?nyjnyw2dyyr

Here is the basic flow now.



And because I've changed the name of the dll you will need to delete all other versions of the library first before you can use this one.

Future:
Simplex noise
Voronoi
..not sure what else to add but then I might not add them. dont know


Krischan2010
Very nice! What you could add: Hetero Multifractal, Hybrid Multifractal, take a look at these pages to see examples:

http://www.ylilammi.com/BerconNoise.shtml (has source, too)
http://ypoart.com/downloads/Musgrave.htm

Tiled Voronoi would be nice :-)


DareDevil2010
Good work :)

hi have changed your code for zoom image



;Fractal Noise Library 
Graphics3D 800,600,32,2
SetBuffer BackBuffer()

size = 128
img = CreateTexture(size,size,1+2+256)

n1 = InitNoise(MilliSecs())
n2 = InitNoise(MilliSecs())
n3 = InitNoise(MilliSecs())
n4 = InitNoise(MilliSecs())
n5 = InitNoise(MilliSecs()) 

camera = CreateCamera()
PositionEntity camera,0,0,0 

plane=CreateSprite(camera)
PositionEntity(plane,0,0,1.4)
EntityTexture(plane,img)


While Not KeyHit(1)
	Cls
	Local l_BufTex%= TextureBuffer(img)
	LockBuffer(l_BufTex)
	SetBuffer(l_BufTex)
	For x = 0 To size-1
		For y = 0 To size-1
			
			f1# = fBm#(n1,x,y,z,9,.5,1)					;Fractal Browian Motion
			f2# = Perlin3D(n2,x,y,z,size,0,999)  		;Fractal Perlin 
			f3# = RidgedMF2#(n3,x,y,z,9,.5,1.5,.3)		;Ridged MultiFractal(staticy)  
			f4# = RidgedMF#(n4,x,y,z,size,0,999,1,.8)	;Ridged MultiFractal 
			f5# = Turbulence#(n5,x,y,z,size,0,999)		;Turbulence Fractal 
			
			f# =  ( f2 + f4 + f5 ) / 3          ;Combine all Fractal noise types
			
			col = (f*255)
			If col < 0 Then col = 0
			If col > 255 Then col = 255 
			argb = GetRGB(col,col,col)
			WritePixelFast x,y,argb
		Next
	Next 
	UnlockBuffer(l_BufTex)
	
	SetBuffer(BackBuffer())
	UpdateWorld()
	RenderWorld()
	
	;Framecounter--------------------------------------------
	Framecounter_counter=Framecounter_counter+1
	If Framecounter_time=0 Then Framecounter_time=MilliSecs()
	If Framecounter_time+1001 <MilliSecs() Then
		Framecounter_framerate=Framecounter_counter
		Framecounter_counter=0
		Framecounter_time=MilliSecs()
	EndIf
	Locate 0,0:Color 255,255,255
	Print "FPS: " + Framecounter_framerate
	;========================================================
	Flip  0
	z = z + 1 
Wend  
FreeNoise(n1)
FreeNoise(n2)
FreeNoise(n3)
FreeNoise(n4)
FreeNoise(n5)
End

;ARGB to A,R,G,B and vis versa
Function GetRGB(r,g,b,a=255)
	Return b Or (g Shl 8) Or (r Shl 16) Or (a Shl 24)
End Function

Function GetA(RGB)
	Return RGB Shr 24 And %11111111
End Function

Function GetR(RGB)
	Return RGB Shr 16 And %11111111
End Function

Function GetG(RGB)
	Return RGB Shr 8 And %11111111
End Function

Function GetB(RGB)
	Return RGB And %11111111
End Function




Krischan2010
I found a problem - the noise doesn't tile correct with the new version. Here is a demo of a sphere texture cut off the noise cloud, with the old version it tiles perfect. Is it a bug or is it a mistake by me? LMB creates a new random planet.

Old version:



New Version:




MusicianKool2010
its not you christian, not a bug either. if your using ridged multifractal its in the way it combines together to make a ridge in the noise.

Here is why its not tile perfect:
;this is the main code behind ridged multifractal.
WHILE(ImageSize >= 1.0) AND MaxOctaves > MinOctaves
        value = (*this).ridge((*this).Noise(x / ImageSize, y / ImageSize, z / ImageSize),offset) '* ImageSize

; this line and the next is why it's not tile perfect. 
;it uses the previous noise value retreaved to make a ridge. 
; not sure how to fix this but I will look into it.
        sum += value * amplitude * prev 
        prev = value ;

        ImageSize = ImageSize / 2.0
        amplitude *=  Gain
        MaxOctaves = MaxOctaves - 1
    WEND


I will have to find out if there is a tile perfect ridged multi fractal.

Edit: errm, guess i should have looked at your code first, has to be a bug in the lib.


MusicianKool2010
Well I kind of figured out the bug... but I'm not sure what I can do about it.. it has to do with type handling from free basic to blitz3d or vise verse. I'm still looking for answers.


MusicianKool2010
a quick fix i guess would be to :
Perlin3d(noise handle, x+1000,y+1000,z+1000 ....)
until I get the next version out. will be soon.


MusicianKool2010
OK updated!

http://www.mediafire.com/?2ynmwqyoqmz


MusicianKool2010
Christian: you need to add FreeNoise(id) to your second example. the noise is not deleted if you create a new one, and you will never be able to delete it later on over write the pointer. you will get an overload error eventually.

This works without any memory errors:




you can however use a random offset to the X,Y,Z achieve the same thing. Should be slightly faster too:



slenkar2010
any chance of a blitzmax.minib3d version ? :)


MusicianKool2010
if you want to port it, then yep. otherwise I don't have bmax so....I can't.
But here is the source so far:
http://www.mediafire.com/?xqudnowmt2y


MusicianKool2010
using Christians terrain code here is Volcanic islands.



MusicianKool2010
arrg!... o.k. I'm going to change the structure of the Lib again.
Why, cause you can then make your own Noise fractals in Blitz3D!
It is however slightly slightly slower (on a 512*512 pic its 20 ms slower then FNL lib) .
It will work in the same way as FNL, but instead of calling the function Perlin3D(...) you will need to write the function Perlin3D(....) in Blitz.
This way its easier for me, as this makes the lib only about 400 lines of code instead of the 3 or 4 thousand it could be for every combination of noise engine and Fractal algorithm.
Will post soon.


MusicianKool2010
Ok here it is. Now you can make your own noise fractals.
Plus it now has voronoi (the lib has one included inside of it and I have made a quick blitz3d version of the code(although flawed)). all the information you need is in the "MultiFractals.bb" file it's not commented but you should beable to get the idea. If not then wait or ask and I or someone else will post a code snip of the type of noise fractal you desire.

Download: http://www.mediafire.com/?kwno5wnty4i


MusicianKool2010
Continue the conversation here: http://www.blitzbasic.com/Community/posts.php?topic=90465


Code Archives Forum