Heightmap-Generator, Probleme bei Glättung

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

TheProgrammer

Betreff: Heightmap-Generator, Probleme bei Glättung

BeitragSo, März 19, 2006 11:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi.

Ich möchte eine Heightmap von meinem Programm selber berechnen lassen. Die einzelnen Pixel sollten aber nicht zufällig gesetzt werden, sondern es sollte schon ein gewisser Zusammenhang bestehen, dass z.B. eine Heightmap mit mehreren Hügeln rauskommt.

Die Berechnung sollte anhand mehrerer Parameter ablaufen. (z.B. abgerundet/schroff, größere/kleinere Hügel, große/kleine Höhenunterschiede, ...)

Kennt jemand eine gute Technik, wie ich sowas realisieren könnte?

Mfg
TheProgrammer
aktuelles Projekt: The last day of human being
  • Zuletzt bearbeitet von TheProgrammer am Mi, März 22, 2006 21:20, insgesamt 5-mal bearbeitet

hamZta

Administrator

BeitragSo, März 19, 2006 12:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Such mal nach Perlin noise, das ist eine Technik die von vielen Programmen verwendet wird.

hamZta
Blog.

TheProgrammer

BeitragSo, März 19, 2006 14:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab mal ne Funktion geschrieben.

Die lineare Interpolation klappt schon ganz gut, ich bekomm aber irgendwie keine der flüssigen Interpolationen hin.

Code: [AUSKLAPPEN]

Graphics 320,240,32,1
SetBuffer BackBuffer()
SeedRnd MilliSecs()

heightmap = createHeightmap(128,17)

ClsColor 255,0,255
While Not KeyHit(1)
 Cls

 DrawBlock heightmap,160-65,128-64

 Flip
Wend
FreeImage heightmap
End



Function CreateHeightmap(size%=64,detail%=3)

   img = CreateImage(size%,size%)
   
   LockBuffer ImageBuffer(img)
   For y = 0 To detail%+1
    For x = 0 To detail%+1
     col = Rand(0,255)
     rgb=255*$1000000+col*$10000+col*$100+col
     WritePixelFast Float(x)*(Float(size-1)/(Float(detail)+1.0)),Float(y)*(Float(size-1)/(Float(detail)+1.0)),rgb,ImageBuffer(img)
    Next
   Next
   
   ; Linien
   For y = 0 To detail%+1
    For x = 0 To detail%
     x1% = Float(x)*(Float(size-1)/(Float(detail)+1.0))
     y1% = Float(y)*(Float(size-1)/(Float(detail)+1.0))
     x2% = Float(x+1)*(Float(size-1)/(Float(detail)+1.0))
     rgb1 = ReadPixelFast(x1%,y1%,ImageBuffer(img))
     rgb2 = ReadPixelFast(x2%,y1%,ImageBuffer(img))
   
     col1=rgb1 And $FF
     col2=rgb2 And $FF
   
     col_new# = col1
     diff = col2-col1
     dist = x2%-x1%
     plus# = Float(diff)/Float(dist)
     For I = x1%+1 To x2%-1
      col_new# = col_new + plus# ; <- interpolation
      col% = col_new
      rgb_new=255*$1000000+col*$10000+col*$100+col
      WritePixelFast I,y1,rgb_new,ImageBuffer(img)
     Next
   
    Next
   Next
   
   For y = 0 To detail%
    For x = 0 To detail%+1
     x1% = Float(x)*(Float(size-1)/(Float(detail)+1.0))
     y1% = Float(y)*(Float(size-1)/(Float(detail)+1.0))
     y2% = Float(y+1)*(Float(size-1)/(Float(detail)+1.0))
     rgb1 = ReadPixelFast(x1%,y1%,ImageBuffer(img))
     rgb2 = ReadPixelFast(x1%,y2%,ImageBuffer(img))
   
     col1=rgb1 And $FF
     col2=rgb2 And $FF
   
     col_new# = col1
     diff = col2-col1
     dist = y2%-y1%
     plus# = Float(diff)/Float(dist)
     For I = y1%+1 To y2%-1
      col_new# = col_new + plus# ; <- interpolation
      col% = col_new
      rgb_new=255*$1000000+col*$10000+col*$100+col
      WritePixelFast x1,I,rgb_new,ImageBuffer(img)
     Next
   
    Next
   Next
   
   ; ausfüllen
   For y = 0 To detail
    For x = 0 To detail
   
     x1% = Float(x)*(Float(size-1)/(Float(detail)+1.0))
     y1% = Float(y)*(Float(size-1)/(Float(detail)+1.0))
     x2% = Float(x+1)*(Float(size-1)/(Float(detail)+1.0))
     y2% = Float(y+1)*(Float(size-1)/(Float(detail)+1.0))
   
     For posy = y1+1 To y2-1
      For posx = x1+1 To x2-1
      
       rgb1 = ReadPixelFast(posx,y1,ImageBuffer(img))
       rgb2 = ReadPixelFast(posx,y2,ImageBuffer(img))
       rgb3 = ReadPixelFast(x1,posy,ImageBuffer(img))
       rgb4 = ReadPixelFast(x2,posy,ImageBuffer(img))
       col1 = rgb1 And $FF
       col2 = rgb2 And $FF
       col3 = rgb3 And $FF
       col4 = rgb4 And $FF
   
       col_new1# = col3
       diff = col4-col3
       dist = x2%-x1%
       plus# = Float(diff)/Float(dist)
      col_new1 = col_new1 + (plus#*(posx-x1)) ; <- interpolation
      
       col_new2# = col1
       diff = col2-col1
       dist = y2%-y1%
       plus# = Float(diff)/Float(dist)
      col_new2 = col_new2 + (plus#*(posy-y1)) ; <- interpolation
      
      col = (col_new1+col_new2)/2
      rgb = 255*$1000000+col*$10000+col*$100+col
   
       WritePixelFast posx,posy,rgb,ImageBuffer(img)
   
      Next
     Next
   
    Next
   Next
   UnlockBuffer ImageBuffer(img)
   
   Return img

End Function


Die Interpolationsstellen sind durch ; <- interpolation gekennzeichnet.
Ich hoffe, ihr könnt mir helfen ^^

Mfg
TheProgrammer
aktuelles Projekt: The last day of human being

TheProgrammer

BeitragSo, März 19, 2006 17:01
Antworten mit Zitat
Benutzer-Profile anzeigen
-> Ich hab mal noch ne Möglichkeit ausprobiert. Ich habs bei der linearen Interpolation belassen und nach der Generierung die heightmap komplett verwischt. Die einzigen Probleme: Die Generierung dauert ganze 25 Sekunden bei einer größe von 64x64 und am rechten und unteren Rand ist es irgendwie abgedunkelt.

Code: [AUSKLAPPEN]

Graphics 320,240,32,1
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Global max_size=256
Dim pixel%(max_size,max_size)

t = MilliSecs()
heightmap = createHeightmap(64,17,5)
t2 = MilliSecs()-t

ClsColor 255,0,255
While Not KeyHit(1)
 Cls

 DrawBlock heightmap,160-32,120-32
 Color 0,0,0
 Text 0,0,t2/1000+" Sekunden gebraucht"

 Flip
Wend
FreeImage heightmap
End



Function CreateHeightmap(size%=64,detail%=3,smear%=0)

   img = CreateImage(size%,size%)
   
   LockBuffer ImageBuffer(img)
   For y = 0 To detail%+1
    For x = 0 To detail%+1
     col = Rand(0,255)
     rgb=255*$1000000+col*$10000+col*$100+col
     WritePixelFast Float(x)*(Float(size-1)/(Float(detail)+1.0)),Float(y)*(Float(size-1)/(Float(detail)+1.0)),rgb,ImageBuffer(img)
    Next
   Next
   
   For y = 0 To detail%+1
    For x = 0 To detail%
     x1% = Float(x)*(Float(size-1)/(Float(detail)+1.0))
     y1% = Float(y)*(Float(size-1)/(Float(detail)+1.0))
     x2% = Float(x+1)*(Float(size-1)/(Float(detail)+1.0))
     rgb1 = ReadPixelFast(x1%,y1%,ImageBuffer(img))
     rgb2 = ReadPixelFast(x2%,y1%,ImageBuffer(img))
   
     col1=rgb1 And $FF
     col2=rgb2 And $FF
   
     col_new# = col1
     diff = col2-col1
     dist = x2%-x1%
     plus# = Float(diff)/Float(dist)
     For I = x1%+1 To x2%-1
      col_new# = col_new + plus#
      col% = col_new
      rgb_new=255*$1000000+col*$10000+col*$100+col
      WritePixelFast I,y1,rgb_new,ImageBuffer(img)
     Next
   
    Next
   Next
   
   For y = 0 To detail%
    For x = 0 To detail%+1
     x1% = Float(x)*(Float(size-1)/(Float(detail)+1.0))
     y1% = Float(y)*(Float(size-1)/(Float(detail)+1.0))
     y2% = Float(y+1)*(Float(size-1)/(Float(detail)+1.0))
     rgb1 = ReadPixelFast(x1%,y1%,ImageBuffer(img))
     rgb2 = ReadPixelFast(x1%,y2%,ImageBuffer(img))
   
     col1=rgb1 And $FF
     col2=rgb2 And $FF
   
     col_new# = col1
     diff = col2-col1
     dist = y2%-y1%
     plus# = Float(diff)/Float(dist)
     For I = y1%+1 To y2%-1
      col_new# = col_new + plus#
      col% = col_new
      rgb_new=255*$1000000+col*$10000+col*$100+col
      WritePixelFast x1,I,rgb_new,ImageBuffer(img)
     Next
   
    Next
   Next
   
   For y = 0 To detail
    For x = 0 To detail
   
     x1% = Float(x)*(Float(size-1)/(Float(detail)+1.0))
     y1% = Float(y)*(Float(size-1)/(Float(detail)+1.0))
     x2% = Float(x+1)*(Float(size-1)/(Float(detail)+1.0))
     y2% = Float(y+1)*(Float(size-1)/(Float(detail)+1.0))
   
     For posy = y1+1 To y2-1
      For posx = x1+1 To x2-1
      
       rgb1 = ReadPixelFast(posx,y1,ImageBuffer(img))
       rgb2 = ReadPixelFast(posx,y2,ImageBuffer(img))
       rgb3 = ReadPixelFast(x1,posy,ImageBuffer(img))
       rgb4 = ReadPixelFast(x2,posy,ImageBuffer(img))
       col1 = rgb1 And $FF
       col2 = rgb2 And $FF
       col3 = rgb3 And $FF
       col4 = rgb4 And $FF
   
       col_new1# = col3
       diff = col4-col3
       dist = x2%-x1%
       plus# = Float(diff)/Float(dist)
      col_new1 = col_new1 + (plus#*(posx-x1))
      
       col_new2# = col1
       diff = col2-col1
       dist = y2%-y1%
       plus# = Float(diff)/Float(dist)
      col_new2 = col_new2 + (plus#*(posy-y1))
      
      col = (col_new1+col_new2)/2
      rgb = 255*$1000000+col*$10000+col*$100+col
   
       WritePixelFast posx,posy,rgb,ImageBuffer(img)
   
      Next
     Next
   
    Next
   Next
   
   If smear% Then
    For y = 0 To size
     For x = 0 To size
      rgb = ReadPixelFast(x,y,ImageBuffer(img))
      pixel(x,y) = rgb And $FF
     Next
    Next
   
    For y = 0 To size
     For x = 0 To size
      
      count = 0
      col = 0
      For posy = 0 To size
       For posx = 0 To size
        
        If Sqr( (posx-x)^2 + (posy-y)^2 ) =< smear% Then
         count = count + 1
         col = col + pixel(posx,posy)
        EndIf
   
       Next
      Next
   
      col = col / count
      rgb = 255*$1000000+col*$10000+col*$100+col
      WritePixelFast x,y,rgb,ImageBuffer(img)
   
     Next
    Next
   EndIf
   
   UnlockBuffer ImageBuffer(img)
   
   Return img

End Function
aktuelles Projekt: The last day of human being

Geeecko

BeitragSo, März 19, 2006 17:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, der is geiL Very Happy

Wenn du noch was einbaust, das man ihn noch verändern kann und er es ein bischen nach kreterien die man vorher eingeben kann generiert benutzte ich ihn für meine spiele Very Happy
 

ke^kx

BeitragSo, März 19, 2006 17:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Du weißt schon, dass TheProgrammer den Code bisher nicht zur freien Benutzung freigegeben hat. Und außerdem hat er ein Problem und will kein Projekt vorstellen... Aber gut Mad

Jiriki
http://i3u8.blogspot.com
Asus Striker II
Intel Core2Quad Q9300 @ 2,5 GHz (aber nur zwei Kerne aktiv aufgrund der Instabilität -.-)
Geforce 9800 GTX
2GB RAM
  • Zuletzt bearbeitet von ke^kx am So, März 19, 2006 20:02, insgesamt 2-mal bearbeitet

TheProgrammer

BeitragSo, März 19, 2006 17:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Du kannst ja die Anzahl der Hügel und die Verwisch-intensität einstellen.

Aber das Problem kann man doch bestimmt auch anders lösen, das Verwischen ist ja nur die Notlösung.

PS.: Du kannst den Generator dann gerne für deine Zwecke benutzen Wink
aktuelles Projekt: The last day of human being
 

ke^kx

BeitragSo, März 19, 2006 20:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, *zurücknehm* wenn er einverstanden ist... Mich störte nur irgendwie dein Ton Wink

Jiriki
http://i3u8.blogspot.com
Asus Striker II
Intel Core2Quad Q9300 @ 2,5 GHz (aber nur zwei Kerne aktiv aufgrund der Instabilität -.-)
Geforce 9800 GTX
2GB RAM

Geeecko

BeitragMo, März 20, 2006 15:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich benutze ihn auch nur wenn ich es darf.

Aber so ein Genarator gehört doch ins projekte-forum wenn er fertig ist Very Happy
 

FBI-blitz

BeitragMo, März 20, 2006 15:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Gaia hat Folgendes geschrieben:
Ich benutze ihn auch nur wenn ich es darf.

Aber so ein Genarator gehört doch ins projekte-forum wenn er fertig ist Very Happy


Eher ins Codearchiv.. finde ich^^

Ich hab mich auch mal an so nem generator versucht.. vor 2 JAhren oder so.. bin aber recht früh gescheitert^^
Computer 1: AMD Athlon64 3500+ | nVidia GF 7900GT | 1024 MB DDR-RAM | ASUS A8N-SLI Preimium | 250 GB SATA 2 || WindowsXP | Blitz3D | Blitz+
Computer 2: AMD AthlonXP 2400+ | ATI Radeon 9500 | 512 MB DDR-RAM | MSI K7N2 | 80 GB IDE | 160 GB IDE || WindowsXP | Blitz3D | Blitz+
Computer 3: Intel Pentium MMX | onBoard-Grafik | 32 MB RAM | 1 GB IDE || Windows 98 SE | Blitz+

TheProgrammer

BeitragMo, März 20, 2006 18:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Jut, dann können wir ja nochmal auf das problem zurückkommen ^^
Also ich habe mich entschieden, den Generator von der Technik so zu lassen und die Glättung zu verwenden (durchschnittliche Generierungszeit: 15 Sekunden). Dann besteht nur noch ein Problem. Die Streifen an der rechten und unteren Seite.

Hier nochmal der Code zur Glättung:

Code: [AUSKLAPPEN]

   If smear% Then
    For y = 0 To size
     For x = 0 To size
      rgb = ReadPixelFast(x,y,ImageBuffer(img))
      pixel(x,y) = rgb And $FF
     Next
    Next
   
    For y = 0 To size
     For x = 0 To size
      
      count = 0
      col = 0
      For posy = 0 To size
       For posx = 0 To size
        
        If Sqr( (posx-x)^2 + (posy-y)^2 ) =< smear% Then
         count = count + 1
         col = col + pixel(posx,posy)
        EndIf
   
       Next
      Next
   
      col = Float(col) / Float(count)
      rgb = 255*$1000000+col*$10000+col*$100+col
      WritePixelFast x,y,rgb,ImageBuffer(img)
   
     Next
    Next
   EndIf



Ich kann den Fehler echt nicht finden.
Ich hoffe, ihr könnt mir helfen ^^

Mfg
TheProgrammer
aktuelles Projekt: The last day of human being

TheProgrammer

BeitragMi, März 22, 2006 17:39
Antworten mit Zitat
Benutzer-Profile anzeigen
So, dann setz ich mal mein Selbstgespräch fort:

Ich habe das Problem jetzt (etwas unelegant) gelöst. Ich habe einfach eine Heightmap erstellt, die um soviel größer ist, wieviel Rand übrig bleibt und die Streifen dann einfach "abgeschnitten". So komm ich dann wieder auf die geforderte Größe. Diese Methode ist für mich jedoch noch viel zu unelegant. Ich hoffe, ihr habt noch Lösungsvorschläge.

Mfg
TheProgrammer
aktuelles Projekt: The last day of human being
 

lettorTrepuS

BeitragMi, März 22, 2006 20:53
Antworten mit Zitat
Benutzer-Profile anzeigen
-aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger.

TheProgrammer

BeitragMi, März 22, 2006 21:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Ah, vielen Dank!
Der hat auch die Pixel außerhalb des Bildes mitgezählt und die waren schwarz und haben die Glättungs-Farbwerte nach unten gerissen, deshalb die dunklen Streifen ^^

Ich hab viel zu kompliziert gedacht! Wink

Mfg
Theprogrammer
aktuelles Projekt: The last day of human being
 

lettorTrepuS

BeitragMi, März 22, 2006 21:29
Antworten mit Zitat
Benutzer-Profile anzeigen
-aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger.

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group