Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Mär 28, 2024 22:39

Foren-Übersicht » Sonstiges » Community-Projekte
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 50 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4  Nächste
Autor Nachricht
 Betreff des Beitrags:
BeitragVerfasst: Di Nov 08, 2005 18:29 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 13, 2004 11:00
Beiträge: 229
Wohnort: Steinhude
ich würde sagen, dass hier schonmal ein wurm liegt:
Code:
  1.   L_IntX  := Trunc(X);
  2.   L_FracX := X - L_IntX;
  3.  
  4.   L_IntY  := Trunc(Y);
  5.   L_FracY := Y - L_IntY;
  6.  
  7.   L_V1 := GetValueFromOctaveByAbsolute(L_IntX,     L_IntY    , pOctave);
  8.   L_V2 := GetValueFromOctaveByAbsolute(L_IntX + 1, L_IntY    , pOctave);
  9.   L_V3 := GetValueFromOctaveByAbsolute(L_IntX,     L_IntY + 1, pOctave);
  10.   L_V4 := GetValueFromOctaveByAbsolute(L_IntX + 1, L_IntY + 1, pOctave);
  11.  
  12.   L_ResX1 := Interpolate(L_V1, L_V2, L_FracX);
  13.   L_ResX2 := Interpolate(L_V3, L_V4, L_FracX);
  14.  
  15.   result := Interpolate(L_ResX1, L_ResX2, L_FracY);
  16.  


das problem ist, dass du bei um nur ein pixel versetzten werten aus GetValueFromOctaveByAbsolute für niedrige octaven immer den gleichen wert kriegst, da dort ja die koordinaten umgerechnet werden und du dich somit ziemlich viel auf einem Pixel bewegst. somit müsstest du die umrechnung der Koordinaten aus GetValueFromOctaveByAbsolute in die Prozedur GetValue ziehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 11, 2005 18:44 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1944
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Habe gerade mal die Funktion (Rand), die die Zufallswerte zurückliefert, durch ein einfaches random ersetzt, damit ich auch garantiert zufällige Werte bekomme, die sich stark unterscheiden. Das Ergebnis davon scheint deine These zu bestätigen, jedoch wüsste ich im Moment nicht, wie ich die Umrechnung aus GetValueFromOctaveByAbsolute so umformen könnte, dass unterschiedlichere Werte herauskommen. Denke, der Fehler liegt am Konzept... Wird mal Zeit, dass ich mal beschreib', was ich eigentlich vorhab'. Vielleicht geht es ja prinzipiell gar nicht ;)

Bei der normalen Art, Perlin Noise zu berechnen, ruft man ja für jeden Pixel GetValue auf. Dort werden dann meist Acht Mal, je nach Anzahl der Oktaven/Ebenen, Zufallswerte berechnet und addiert.
Die unterste Ebene hat ja bekanntlich 4 verschiedene Werte (2*2), wenn man noch nicht interpoliert. Bedenkt man, dass bei einem 512er Perlin Noise insgesamt allein für diese Oktave 512*512 Werte berechnet werden, obwohl die Berechnung von lediglich 4 relevanten Werten zum gleichen Ergebnis führen müsste, wird deutlich, dass dort ein gewisses Optimierungspotenzial vorhanden ist ;)

Ich lege also für jede Oktave ein Zweidimensionales Array of single an, jeweils mit der Größe der Oktave. Also hat die Oktave 0 ein 2*2 Array, die Oktave 1 ein 4*4 Array usw..

Soweit verständlich, was ich meine? ;)

Sobald alle Oktaven mit Werten gefüllt sind, kann ein einzelner Punkt aus dem fertigen Perlin-Noise berechnet werden. Dazu liefert die Funktion GetValueFromOctaveByAbsolute, die selbst den gewünschten X- und Y-Wert, sowie die verlangte Oktave entgegennimmt, den Wert zurück, den man erhalten würde, wenn man ... äh... kleines Beispiel: *g*

Benötigt wird der Punkt [500, 506] aus Oktave 0. GetValueFromOctaveByAbsolute rechnet die Koordinaten [500, 506] nun um zu "Koordinaten", die in den Bereich des Arrays hineinpassen. Also bei Oktave 0 wäre das der Punkt unten rechts, also [1, 1]. Die Funktion liefert jedoch nicht diese Umrechnung zurück, sondern den Wert, der im Oktavenarray an dieser Stelle steht.

In dieser Funktion muss irgendwo ein Fehler drin sein. Ich befürchte z.B., dass ich die Interpolation bereits an dieser Stelle durchführen müsste.

Außerdem werden bei der finalen Zusammenrechnung die Amplitude nicht genau beachtet. Sodass Werte herauskommen, die über 255 liegen und damit etwas strange im Bild aussehen. Das ist jedoch nur eine Vermutung mit der ich mir einige Merkwürdigkeiten im Noise zu erklären versuche ;)

Im Anhang noch eine aktualisiertere Version, bei der man nun auch die einzelnen Oktaven einsehen kann, die Berechnungstiefe einstellen kann und zwischen dem bisherigen Zufallsgenerator und demjenigen, der die Standard-Random funktion verwendet wählen kann.


Dateianhänge:
Perlin Noise.zip [234.86 KiB]
475-mal heruntergeladen

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 12:14 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1944
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Hier mal ein paar Ergebnis-Bilder, die zu verschiedensten Entwicklungs-Stadien entstanden... Eines davon zeigt sogar schon fast das, was ich will. Aber eben nur fast ;)


Dateianhänge:
Dateikommentar: Hier erneut ein Versuch mit einer zu hohen Amplitude und einem Seed, der nicht zufällig genug war ;)
perlin-noise.png
perlin-noise.png [ 138.88 KiB | 10647-mal betrachtet ]
Dateikommentar: Ein kleines Tier, was ich in einem Perlin-Noise mit zu hoher Amplitude entdeckt hatte ;)
Perlin-Tier.png
Perlin-Tier.png [ 1.78 KiB | 10647-mal betrachtet ]
Dateikommentar: Eine Art Küstenlinie, die entstand, als ich die Amplitude zu hoch gewählt hatte
Perlin-Noise2.png
Perlin-Noise2.png [ 65.77 KiB | 10647-mal betrachtet ]
Dateikommentar: Mein erster Versuch, ein kachelbares Perlin Noise herzustellen
noise.jpg
noise.jpg [ 51.06 KiB | 10648-mal betrachtet ]

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 17:05 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 13, 2004 11:00
Beiträge: 229
Wohnort: Steinhude
Vor deiner Erklärung hatte ich dein Vorgehen verstanden.
ich hab mich mal dran gesetzt und einige Fehler beseitigt. Die effeckte scheinen mir jetz im wesentlichen noch von falscher amplitude zu kommen.

die korrigiert hab ich in calculate ( in der inneren schleife *L_Frequency entfernt), und GetValueFromOctaveByAbsolute, InterpolatedOctave was ich schon erwähnt hab).

Was ich allerdings noch nicht verstehe is wo der Sinn dahinter ist, die Oktaven vorzuberechnen, aber die Interpolation bei der Abfrage jedes Pixels zu machen.
Durch die Vorberechnung der Oktaven wird der Noise zu einem Zeitpunkt quasi komplett festgelegt, dann kann man auch gleich die Ergebniswerte berechnen (wodurch man aufgrund deutlicher Einsparungen der Interpolationen deutlich schneller wird), wenn man es nicht vorberechnet kann man dafür beliebige werte abfragen, also quasi unendliche Flächen erzeugen.
Den Mittelweg den du benutzt empfinde ich irgendwie als weder fisch noch fleisch, da er die nachteile des Berechnens von allem auf einem schlag (festgelegte größe, veränderungen nur über komplette neuberechnung möglich) mit den nachteilen eines komplett auf Berechnungen bei Abfrage des Pixels (sehr geringe Geschwindigkeit (bei mir mit kompletter berechnung auf einmal brauch er die ~600ms die diese Methode bei dir für eine 256*256 Ausgabe brauch für 1024*1024))kombiniert.
Wenn du interesse daran hast kann ich meins mal hochladen (auch wenn es zugegebenermaßennicht besonders schön programmiert ist, heute würde ich das nicht mehr so machen, aber die überarbeitete, scriptgesteuerte Variante ist noch nicht fertig)


Dateianhänge:
Perlin.zip [2.47 KiB]
462-mal heruntergeladen
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 18:18 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1944
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Achso... Da sind wirklich ein paar ganz fiese Denkfehler reingeraten.
Hab' mich schon gewundert, warum ich meine Herangehensweise nirgendswo im Netz entdecken konnte ;) Hab' das bis jetzt darauf zurückgeführt, dass ich nicht gut genug gesucht habe, scheint aber mehr an der Methode selbst zu liegen...

600ms für 1024x1024??? :shock: ... Immerhin ist meine Methode nicht wesentlich langsamer als die von Lyr... Naja... bei halber Bildgröße. ;)

Erstmal Thx für die Hilfe und ja, ich hätte interesse an deinem Perlin Noise.

...

600 ms... unfassbar...

Ich kenn' halt von TerraFormer2 die nette Möglichkeit, basierend auf einer Matrix (in dem Fall eine Oktave), ein Perlin Noise drüber gehen zu lassen, sodass die generierte Landschaft als Basis deine Eingabe hat, aber total realistisch aussieht. Aber das ging auch viel schneller... ;)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 18:50 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 13, 2004 11:00
Beiträge: 229
Wohnort: Steinhude
Die 600ms waren natürlich auch nur mit Quadratischem resize, den du ja auch nutzt. der bicubische brauch ca doppelt so lang
die Erklärung dafür ist relativ einfach:
du rufst pro Pixel und Oktave 3 Resizes auf.
Bei mir werden zunächst die Zeilen horizontal interpoliert und dann vertikal zusammeninterpoliert. dadurch spare ich natürlich grad bei niedrigen Oktaven deutlich rechenleistung.

Das ist aber deinitiv noch steigerungsfähig, da ich in der Neuauflage festgestellt hab, dass ich die Reiszeroutinen durch leichte Verbesserungen im Algorithmus (und im Fall vom Bicubischem Resize massivem Einsatz von Asm+SSE) noch beschleunigen konnte (am Ende war der mit Bicubic resize dann fast bei 600ms iirc).

Hier wie versprochen die alte (also funktionierende Variante von mir)


Dateianhänge:
Dateikommentar: Mein Perlin Noise.
Warnung: kein schöner Code

Perlin N.zip [60.92 KiB]
452-mal heruntergeladen
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 20:04 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1944
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
So arg kompliziert find' ich den Code jetzt nicht. Es ist nur ziemlich viel und in einzelnen Methoden, statt in einer Klasse.

Auf den ersten Blick fiel mir auf, dass du einen anderen Zufallsgenerator verwendest mit größeren Primzahlen. Als ich mal testweise meinen reintat, waren die Ergebnisse sehr oft extrem dunkel... Dein Noise erzeugt auch für den Seed 12345 ganz andere Ergebnisse als meins beispielsweise. Du musst dein Perlin Noise also irgendwie anders berechnen...

Was ist der Grund, warum du einen anderen Generator verwendest? Bzw. warum spuckt
Code:
  1. n := x + y * 57 + Seed;
  2. n := ( n shl 13 ) xor n;
  3. rand := 1 - ( (n * (n * n * 15731 + 789221) + 1376312589) and $7fffffff) / 1073741824;

bei dir andere Ergebnisse aus als bei mir?

Ach... und woher weißt du eigentlich, wie man solchen Code so verdammt fix macht? ;)

P.S.: Fällt mir gerade auf: Wo stellst du eigentlich die Frequenz ein?

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 20:14 
Offline
DGL Member

Registriert: Sa Jan 22, 2005 21:10
Beiträge: 225
Is jetzt vielleicht was offtopic, aber http://freespace.virgin.net/hugo.elias/ ... perlin.htm beschreibt nicht wirklich Perlin Noise. Der original Perlin Noise wird über Gradienten berechnet, da Ken Perlin zu Tron-Zeiten zwar (für damalige verhältnisse) relativ viel Rechenleistung hatte, aber wenig Arbeitsspeicher. Eine sehr gute Beschreibung des eigentlichen Algos gibt es hier:

http://www.mandelbrot-dazibao.com/Perlin/Perlin1.htm
http://www.mandelbrot-dazibao.com/Perlin/Perlin2.htm

_________________
[18:30] tomok: so wie ich das sehe : alles. was nich was anderes ist als nen Essay ist nen Essay

hi, i'm a signature viruz, plz set me as your signature and help me spread :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 20:44 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 13, 2004 11:00
Beiträge: 229
Wohnort: Steinhude
Das das bei mir andere Ergebnisse als bei dir ausspuckt liegt vermutlich an einer anderen Veränderung der Randseed bei mir ( bei dir wird die jeweils nach einer Oktave mit der Frequenz multipliziert, bei mir: Seed := (Seed shl 11) xor Seed;

Warum ich einen anderen Generator verwende? Weil ich nicht zuviel von anderen klauen wollte ;)
Soweit ich das sehe spuckt dein Generator einen Wertebereich -1 bis 1, während bei mir 0 bis 1 generiert wird. daher wird der mit deinem Generator dunkel

Die Frequenz ist bei mir auf 2 festgelegt, da ich im 2er Potenzen haben wollte und da noch keinen Nutzen für andere Frequenzen gesehn hatte.
Bei meiner neueren Variante wird das wohl anders, wenn ich die mal fertigschreibe.

naja, komplex isses nicht wirklich, es sind nur halt noch nen paar altlasten drin und die ansteuerung mit sehr vielen Parametern is auch nich optimal

mit dem Tempo:
naja, Erfahrung, probieren, Internetlektüre ;)

@AL:
naja, soweit ich das sehe ist der dort beschriebene Perlin Noise im wesentlichen das gleiche, nur, dass dort splines benutzt werden. oder übersehe ich da was?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 21:29 
Offline
DGL Member

Registriert: Sa Jan 22, 2005 21:10
Beiträge: 225
Naja, die ganzen Splines werden durch eine 1-dimensionale Gradientenliste und eine 1-dimensionale Permutationsliste repräsentiert. Das verbraucht erheblich weniger Speicher, und es ist einfacher nur kleinere Ausschnitte, oder Teile mit unterschiedlichen Auflösungen zu berechnen. Dafür war es aber bei mir (hab beides mal getestet) langsamer. Muss aber nichts bedeuten, hab beides nicht optimiert...

_________________
[18:30] tomok: so wie ich das sehe : alles. was nich was anderes ist als nen Essay ist nen Essay

hi, i'm a signature viruz, plz set me as your signature and help me spread :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 21:38 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1944
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Ich mein' nicht den Frequenzfaktor, sondern die Frequenz, die normalerweise mit 0,01 anfängt (siehe Wiki).

@AL: Du haust da mit Begriffen um dich... Permutationsliste... ;)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 22:19 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 13, 2004 11:00
Beiträge: 229
Wohnort: Steinhude
im Wiki wird als Frequenz soweit ich dass sehe doch quasi beschrieben, wie groß das orginal einer Oktave (also vor dem resize is).
Da stelle ich ein, bei welcher Oktave angefangen wird und bei welcher aufgehört (Größe je 2^Nummer).
Oder was meinst du?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 12, 2005 23:48 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1944
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Mit Frequenz meine ich die Startfrequenz. Beim Durchlaufen der Oktaven wird ja die Frequenz der aktuellen Oktave mit Dem Frequenzfaktor (2) multipliziert, um die Frequenz der nächsten Oktave zu erhalten.

Im Wiki ist die (Start)Frequenz 0,01.

Man kann die Frequenz prima verwenden, um quasi zu zoomen. So zoomt eine niedrigere Frequenz hinein, eine höhere Frequenz jedoch raus. Eine kleine Frequenz vergrößert also quasi das Perlin Noise.

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Nov 13, 2005 12:28 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 13, 2004 11:00
Beiträge: 229
Wohnort: Steinhude
Damit ist das Quasi das Verhältnis Anfangsgröße zu Engröße.
Soetwas wird bei mir nicht direkt festgelegt, die Zählweise fängt bei 1x1 and und hört entsprechend bei einer 2er Potenz auf. Ich sah da nicht so die veranlassung mehr als notwendig rumzuresizen, das können andere Programme eh besser. Wofür brauch ich also noch einen derartigen Wert?
Nebenbei gesagt hab ich den Wiki artikel vorher nicht gelesen, sondern mich hier dran orientiert, daher die anderen Begrifflichkeiten und auch einige abweichungen in der Implementation


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Nov 13, 2005 13:05 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1944
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
An dem Artikel von Hugo Elias hab' ich mich anfangs auch orientiert, bevor das im Wiki überarbeitet wurde.

Wie gesagt, durch Veränderung der (Start)frequenz (Wiki) von 0,01 auf etwas anderes, kann man wunderbar das Perlin Noise vergrößern oder verkleinern. Falls man z.B. eine Landschaft haben möchte mit einigen wenigen großen Hügeln z.B..

Zitat:
Ich sah da nicht so die veranlassung mehr als notwendig rumzuresizen, das können andere Programme eh besser.

Weil andere Programme bei weitem nicht so schnell sind, wie deine Implementation vom Perlin Noise ;)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 50 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4  Nächste
Foren-Übersicht » Sonstiges » Community-Projekte


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 14 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.098s | 19 Queries | GZIP : On ]