Kaksivärinen perlin noise/diamondsquare2D... o_O

Voit pyytää apua ohjelmointiongelmiin täältä.
Post Reply
User avatar
Misthema
Advanced Member
Posts: 312
Joined: Mon Aug 27, 2007 8:32 pm
Location: Turku, Finland
Contact:

Kaksivärinen perlin noise/diamondsquare2D... o_O

Post by Misthema »

Jou, eli ongelmana on sellanen jännä juttu, etten saa aikaiseksi millään järkevällä tavalla m1c:n DiamondSquare2D funktiota piirtämään "height"-mappeja kaksivärisiksi. Tietysti kun roughness:ia ja multiplier:iä on tarpeeksi (esim. 255, 2) niin tulee hienosti kahtaväristä karttaa, mutta liikaa yksinäisiä pikseleitä, ei mitään järkevää tai selkeän näköistä "mannerta". Perlin noise:sta taas minulla ei ole mitään hajua!

Jos joku kippari-kalle käyttäis massiivisia aivolihaksiaan ja tekisi minulle jonkinlaisen esimerkin tai yksinkertaistaisi minulle perlin noise:n käyttöä.
Kaikki on sallittua.
regalis
Advanced Member
Posts: 268
Joined: Mon Aug 27, 2007 9:44 pm

Re: Kaksivärinen perlin noise/diamondsquare2D... o_O

Post by regalis »

Tuossa olisi funktio perlin noisen tekemiseen. Koodi oli alunperin täältä, mutta pienillä muutoksilla menee CB-koodina.

Code: Select all

// -------------------------------------------------------------------------------------------------------------------
// Perlin Noise Heightmap Generator - Copyright 2003 - Shawn C. Swift
// -------------------------------------------------------------------------------------------------------------------

Const MAX_HEIGHTMAP_SIZE = 1024

Dim HeightMap(MAX_HEIGHTMAP_SIZE, MAX_HEIGHTMAP_SIZE) As Float
Dim NoiseMap(MAX_HEIGHTMAP_SIZE+1, MAX_HEIGHTMAP_SIZE+1) As Float

// -------------------------------------------------------------------------------------------------------------------
// HeightmapSize must ba a power of 2.
// Scale# is the maximum height of the most frequent and smallest bumps in the terrain.
// Multiplier# is how much each successive pass multiplies scale# by.
// -------------------------------------------------------------------------------------------------------------------
Function Generate_Heightmap(HeightMapSize, Scale#, Multiplier#)

	// Set the maximum height of the first noise pass.
	Max_Height# = Scale#

	// Do the first pass seprately from the other passes since we can do it very cheaply.
	
		For Noise_Y = 0 To HeightMapSize
			For Noise_X = 0 To HeightMapSize
				HeightMap(Noise_X, Noise_Y) = Rnd(0, Max_Height#)
			Next noise_x
		Next noise_y

	// Now start with the second highest frequency noise//
	// The second largest noise map with slightly larger bumps than the first pass.
	NoiseMapSize = HeightMapSize/2
	
	// Multiply the maximum height for the start of the second pass.
	Max_Height# = Max_Height# * Multiplier#
		
	Repeat
	
		// Generate a noise map.
		For Noise_Y = 0 To NoiseMapSize
			For Noise_X = 0 To NoiseMapSize
				NoiseMap(Noise_X, Noise_Y) = Rnd(0, Max_Height#)
			Next noise_x
		Next noise_y

		// Calculate the diffrence in scale between the noisemap and the heightmap.		
		ScaleDifference = HeightMapSize / NoiseMapSize
		
		// Calculate how large of steps across the noise map we need to take for each pixel of the heightmap.
		StepSize# = 1.0 / Float(ScaleDifference)

		// Stretch the noise map over the heightmap using bilinear filtering.
		For Noise_Y = 0 To NoiseMapSize-1
			For Noise_X = 0 To NoiseMapSize-1

				N1# = NoiseMap(Noise_X,   Noise_Y)  
				N2# = NoiseMap(Noise_X+1, Noise_Y)  
				N3# = NoiseMap(Noise_X,   Noise_Y+1)
				N4# = NoiseMap(Noise_X+1, Noise_Y+1)
			
				Hx = Noise_X*ScaleDifference
				Hy = Noise_Y*ScaleDifference
			
				Iy# = 0
				For Height_Y = 0 To ScaleDifference-1

					// Calculate cosine-weighted bilinear average.
	
						ICy# = 1.0 - ((Cos(Iy#*180.0) + 1.0) / 2.0)
					
					Ix# = 0			
					For Height_X = 0 To ScaleDifference-1
				
						// Calculate cosine-weighted bilinear average.
						//
						// Cosine weighting makes the map smoother, removing unsightly diamond artifacts from the
						// bilinear filtering. 
						//
						// Essentially it "pushes" the four corner pixel colors towards the center, reducing the area
						// which is the average of the colors.  So the corner pixels go from a blurry diamond shape
						// to a blurry circle.
						//
						// It is of course, slower to calculate than regular bilinear filtering, though by using a 
						// lookup table one could possibly speed the operation a litle.
													
							ICx# = 1.0 - ((Cos(Ix#*180.0) + 1.0) / 2.0)

							Na# = N1#*(1.0-ICx#)
							Nb# = N2#*ICx#
							Nc# = N3#*(1.0-ICx#)
							Nd# = N4#*ICx#
							
							HeightMap(Hx+Height_X, Hy+Height_Y) = HeightMap(Hx+Height_X, Hy+Height_Y) + (Na#+Nb#)*(1.0-ICy#) + (Nc+Nd#)*ICy#

						Ix# = Ix# + StepSize#

					Next height_x
					
					Iy# = Iy# + StepSize#	

				Next height_y
		
			Next noise_x
			
		Next noise_y
		
		// Reduce the frequency of the noise by half. 				
		NoiseMapSize = NoiseMapSize/2
		
		// Increase the maximum height of the noise.
		Max_Height# = Max_Height# * Multiplier#
			
	Until NoiseMapSize <= 1

End Function
User avatar
Misthema
Advanced Member
Posts: 312
Joined: Mon Aug 27, 2007 8:32 pm
Location: Turku, Finland
Contact:

Re: Kaksivärinen perlin noise/diamondsquare2D... o_O

Post by Misthema »

Koitin tota jo enkä saanut sillä sen kummempia heightmappeja aikaseks kun m1c:n tekemällä diamondsquare:lla (vai oliko se squarediamond?).
regalis
Advanced Member
Posts: 268
Joined: Mon Aug 27, 2007 9:44 pm

Re: Kaksivärinen perlin noise/diamondsquare2D... o_O

Post by regalis »

Jaah, mikä niissä sitten oli vikana? :O Kyllä tuolla saa parametreja säätelemällä aika monenlaista kohinaa, esimerkiksi tällaista tai tällaista.
User avatar
Misthema
Advanced Member
Posts: 312
Joined: Mon Aug 27, 2007 8:32 pm
Location: Turku, Finland
Contact:

Re: Kaksivärinen perlin noise/diamondsquare2D... o_O

Post by Misthema »

Et tainnut ihan ymmärtää ideaa: haluan kaksivärisiä karttoja jossa on mustaa ja valkoista - pelkästään - ei mitään sävyjä sen väliltä tms.
Mutta ongelma on silti jo ohi. Kiitos kuitenkin vastauksista.
User avatar
Ilmuri
Developer
Developer
Posts: 277
Joined: Sun Aug 26, 2007 2:46 pm
Location: \o

Re: Kaksivärinen perlin noise/diamondsquare2D... o_O

Post by Ilmuri »

Mikäli joku tätä tulevaisuudessa tulee miettimään: tämä onnistuu käymällä valmiin korkeuskartan läpi ja muuttamalla jokaisen pikselin joko mustaksi tai valkoiseksi jos se on jonkin tietyn korkeuspisteen ylä- tai alapuolella.
Oikean korkeuspisteen valinta voi olla haastavaa, mutta esimerkiksi kaikkien pikselien korkeuksien keskiarvo on hyvä lähtökohta, joka tietysti tulee laskea ennen mustavalkokonversiota.

Toinen mahdollisuus on muuttaa diamond square-algoritmiä niin, että jokaisella pisteellä on vain kaksi mahdollista arvoa ja uusien pisteiden arvo valitaan satunnaisesti naapurien arvoista.
CoolBasic henkilökuntaa
Kehittäjä
CoolBasic Classic
Post Reply