Showroom - Aktuelle Arbeiten und Projekte
Forumsregeln
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.
Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.
This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.
Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.
This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
Re: Showroom - Aktuelle Arbeiten und Projekte
schaut stabil aus :D
(und schick)
(und schick)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: Showroom - Aktuelle Arbeiten und Projekte
Maze-Generator revisited.
Arbeitsweise: Binäres splitten von Rechteckzellen, einen zufälligen Durchgang in die Trennwand setzen, eine Mindest-Raumgröße anhand der Durchgangspositionen ermitteln, zwischen aktueller Zellen- und Mindestgröße interpolieren, wahlweise den Raum so vergrößern dass Eingänge nicht mit Wänden plan liegen (corners).
Jetzt muss ich wieder das Konzept "mehrere Durchgänge pro Trennwand" einführen, variable Wand- und Korridorbreiten, lokale statt globale Einflusswerte usw.
Wie zuvor ohne konkretes Projekt, nur Proof-of-Concept.
Arbeitsweise: Binäres splitten von Rechteckzellen, einen zufälligen Durchgang in die Trennwand setzen, eine Mindest-Raumgröße anhand der Durchgangspositionen ermitteln, zwischen aktueller Zellen- und Mindestgröße interpolieren, wahlweise den Raum so vergrößern dass Eingänge nicht mit Wänden plan liegen (corners).
Jetzt muss ich wieder das Konzept "mehrere Durchgänge pro Trennwand" einführen, variable Wand- und Korridorbreiten, lokale statt globale Einflusswerte usw.
Wie zuvor ohne konkretes Projekt, nur Proof-of-Concept.
Re: Showroom - Aktuelle Arbeiten und Projekte
Sehr cool, ich überlege auch gerade, wie ich einen Map-Editor für Rayworld am Geschicktesten anstelle, prozedural ist immer nett. :-)
Re: Showroom - Aktuelle Arbeiten und Projekte
Für dich könnte auch ein zellulärer Automat passen, zumindest für ausgiebigere Tests mit variantenreicheren, zufälligeren Geometrien. Genau für solche Zwecke hatte ich mir mal sowas gebaut: https://zfx.info/viewtopic.php?p=54715#p54715
Den Algo kann man aus den Screenshots direkt nachvollziehen. z.B. https://zfx.info/download/file.php?id=3962&mode=view
Unten im Screenshot steht z.B. "5IIIJFA" für das angezeigte Endmuster. Die 5 am Anfang bedeutet: Fläche mit 50% zufälligen Pixeln füllen.
Dann 3x Regel I anwenden, dann je einmal J, F und A. Die einzelnen Regeln stehen rechts, z.B. I = S0128/B0128
Die Regeln werden so gelesen, beispielhaft für B=B3/S23: "a cell is born if it has 3 neighbors and survives if it has 2 or 3 neighbors."
Also wenn eine Zelle 0, greift die B-Regel ob sie auf 1 gesetzt wird. Wenn 1, greift die S-Regel, ob sie so bleibt oder auf 0 gesetzt wird.
(B3/S23 ist glaube ich die Original-Conway-Regel)
Re: Showroom - Aktuelle Arbeiten und Projekte
Danke für den Hinweis, das kommt mir tatsächlich noch ein wenig bekannt vor, auch wenn es schon wieder sechs Jahre her ist...
-
- Establishment
- Beiträge: 266
- Registriert: 25.08.2019, 05:00
- Alter Benutzername: gdsWizard
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Ich habe mich in letzter Zeit mit Computer Vision beschäftigt. Hier ein Beispiel für eine berechnete DisparityMap:
Hat den StormWizard 1.0 und 2.0 verbrochen. http://www.mirrorcad.com
Re: Showroom - Aktuelle Arbeiten und Projekte
Meine letzte eigene Disparitätskarte liegt wahrscheinlich schon 20 Jahre zurück, aber das Tsukuba-Referenzbild erkennt man sofort, insofern schonmal ein schönes Ergebnis :-). Was für ein Verfahren hast Du verwendet? Der Lampenarm wird spannend, ich denke da ist derzeit noch das meiste Potential. Es scheint auch so, dass recht viel Kontext im Ortsbereich verwendet wurde, was das Rauschen unterdrückt und ein konsistentes Bild gibt, aber eben mit kleineren Disparitätssprüngen wie am Lampenarm dann Schwierigkeiten hat.
-
- Establishment
- Beiträge: 266
- Registriert: 25.08.2019, 05:00
- Alter Benutzername: gdsWizard
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Ich verwende ein Verfahren das als Belief-Propagation bezeichnet wird.
Hat den StormWizard 1.0 und 2.0 verbrochen. http://www.mirrorcad.com
Re: Showroom - Aktuelle Arbeiten und Projekte
![Bild](https://www.phoximages.de/uploads/2023/04/i71213bneb8x.png)
Nochmal Maze-Generator, leicht angepasstes Verfahren, neuer Graph, zufällige Wanddicken, maximale Durchgangsbreiten.
Ich werde ihn wohl "Mondrian" nennen ;)
Weiß: "Räume".
Rot: "Wände", welche min. 1 Durchgang haben müssen, um lösbar zu sein.
Also man geht hier immer von Weiß über Rot nach Weiß.
Grau: Alternativ zusätzliche Durchgangswände, können Ringwege ermöglichen, oder nicht begehbare Fenster in andere Räume sein, oder massiv sein.
Dunkelgrau: Nicht beghehbar.
Man sieht hier sozusagen die maximal nutzbare Fläche; Räume und die Durchgänge selbst können jeweils deutlich kleiner sein. Jetzt muss ich noch einen Levelbuilder machen, der entsprechende Wände und Durchgänge zusammenstückelt.
- Schrompf
- Moderator
- Beiträge: 4867
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas Ziegenhagen
- Wohnort: Dresden
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Cool, das hat Potential. Da seh ich irgendne Raumstation drin
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Re: Showroom - Aktuelle Arbeiten und Projekte
![Bild](https://www.phoximages.de/uploads/2023/04/i71214be6i0v.png)
Mal die Boxen mit einfachen 3D-Formen gefüllt, welche die jeweils entsprechenden Box-Bedingungen erfüllen.
Für die Durchgangswände (im letzten Post rot) gibt es hier 4 Variationen: Wand mit Tür, Durchgang mit Deckenbalken auf Säulen, nur Deckenbalken, nichts. Für die soliden Wände gibts hier nur solide Quader ohne weitere Variationen.
Re: Showroom - Aktuelle Arbeiten und Projekte
Prinzipiell ist der Algo cool, aber die generierten Räume und Durchgänge empfinde ich aktuell noch als wenig "spannend". Hoffe Du verzeihst es mir, Joey!
EDIT: Ich denke das größte Problem ist die Anzahl der generierten Räume. Glaube ist Dir selber auch bewusst, stellt sich die Frage wie man das auf "sinnvolle" Räume reduzieren kann.
EDIT: Ich denke das größte Problem ist die Anzahl der generierten Räume. Glaube ist Dir selber auch bewusst, stellt sich die Frage wie man das auf "sinnvolle" Räume reduzieren kann.
Re: Showroom - Aktuelle Arbeiten und Projekte
Es ist ein Labyrinth-Algo. Also er macht exakt das wofür er designt ist ;)
Die gezeigte 3D-Interpretation verteilt lediglich zufällig irgendwelche Standard-Wandtypen, ohne bestimmten Use-Case. Es könnte auch ein Waldgebiet sein. Oder schwebende Felseninseln, welche mit Stegen verbunden sind. Dass das dann jeweils "sinnvoll" oder "spannend" wird, ist nicht Aufgabe des Basisalgos.
Problem des Algos ist vielmehr, dass im ersten Schritt immer sehr lange gerade Wände durch den ganzen Level generiert werden. Hier muss ich noch schauen, wie ich das besser aufbrechen kann. Aber erstmal noch ein paar andere Dinge aufräumen.
Die gezeigte 3D-Interpretation verteilt lediglich zufällig irgendwelche Standard-Wandtypen, ohne bestimmten Use-Case. Es könnte auch ein Waldgebiet sein. Oder schwebende Felseninseln, welche mit Stegen verbunden sind. Dass das dann jeweils "sinnvoll" oder "spannend" wird, ist nicht Aufgabe des Basisalgos.
Problem des Algos ist vielmehr, dass im ersten Schritt immer sehr lange gerade Wände durch den ganzen Level generiert werden. Hier muss ich noch schauen, wie ich das besser aufbrechen kann. Aber erstmal noch ein paar andere Dinge aufräumen.
Re: Showroom - Aktuelle Arbeiten und Projekte
Habe die letzten beiden Tage Kollisionserkennung auf ein 2D multiresolution spatial hash grid umgeschrieben.
Jedes Objekt wird immer nur in genau eine Zelle geschrieben, unabhängig von seiner Größe. Abhängig von seiner Größe aber in jeweils ein passendes Grid (Layer). D.h. die Zellen sind keine Bounding-Boxen, sieht man im ersten Screen unten. Updates für dynamische Objekte sind daher wenig Aufwand.
Prüft man mit maximal dem Radius des kleinsten Grids (idealerweise legt man die Grids so an, dass der Player in Layer 1 reinpasst), muss man in jedem Layer lediglich 4 Zellen testen. Also auch nicht viel Aufwand.
"Nachteil": Der Objektradius in einem Grid muss kleiner sein als 1/4 Gridgröße; bei Rays sogar nur Sqrt(2)/8. Die Boundingspheres der Objekte im Screen1 sind daher nur etwa 1/3 der Gridgröße im Durchmesser; alles was größer ist muss ins nächstgrößere Layer wandern.
Bedientechnisch werden einfach Objekte mit add(obj) in die Struktur geworfen (dynamische wie statische, ohne Unterschied), ein weiterer Hash hilft beim Wiederfinden für update(obj) und kill(obj). Was dynamisch ist wird also lediglich von außen bestimmt, in der Struktur sind alle gleich.
Die Layergröße und -Anzahl bestimme ich derzeit hardcoded nach Anwendung. Auto-Detection gibts dafür nicht, wäre was stochastisches. Man könnte auch einfach immer Gridsize automatisch stur verdoppeln bis es passt, Das Raster sähe dann ähnlich aus wie ein Quadtree, technisch aber nur von unten nach oben aufgebaut, und ohne den schweren Tree-Firlefanz.
Umgebungssuche mit größerem Radius (mehr als 4 Zellen) wird spiralig aus dem Suchzentrum aufgebaut (statt Doppelloop von -r bis r), um die innersten Objekte möglichst früh in der Liste zu haben.
Strahlsuche/Spheresweep wird wie bei einem Raycaster gemacht (horizontale/vertikale Abschnitte aufaddieren), standardmäßig ist der Strahl dann mindestens so "breit" wie die Objektobergrenze im kleinsten Grid. Im ersten Screen unten so ein Broadphase-1-Strahl der Stärke "null". Broadphase 2 wäre dann die Prüfung Abstand Linie-Boundingsphere der einzelnen Items in den betroffenen Containern, also diejenigen nicht in die Liste aufnehmen, deren Kreise den grünen Sweep nicht berühren, dann erst der genaue Raycast mit der Liste (Phase 3). Auch hier liegen dann die nächsten Objekte früh in der Liste.
Ray/Spheresweep (Phase1) durch ein einzelnes Grid.
![Bild](https://www.phoximages.de/uploads/2023/04/i71236badwu4.jpg)
Same, Objekte im Raum, einsortiert in ein 2D Multires-Grid (3 Layer).
![Bild](https://www.phoximages.de/uploads/2023/04/i71237bfy3qj.jpg)
Und in Aktion.
Im Video sieht man 12.000 statische und 150 kreisende dynamische Objekte. Ohne weitere Aufteilung (Chunks oder so), ich habe nur alle dynamischen möglichst in der Mitte versammelt für mehr Kollision und Dichte.
Alles was aufblinkt, ist geade in eine Kollision verwickelt. Dynamische Objekte werden dabei generell nur als Sphere getestet.
Universell jeder mit jedem, alle mit dem "Level", groß mit klein und klein mit groß.
Jedes Objekt wird immer nur in genau eine Zelle geschrieben, unabhängig von seiner Größe. Abhängig von seiner Größe aber in jeweils ein passendes Grid (Layer). D.h. die Zellen sind keine Bounding-Boxen, sieht man im ersten Screen unten. Updates für dynamische Objekte sind daher wenig Aufwand.
Prüft man mit maximal dem Radius des kleinsten Grids (idealerweise legt man die Grids so an, dass der Player in Layer 1 reinpasst), muss man in jedem Layer lediglich 4 Zellen testen. Also auch nicht viel Aufwand.
"Nachteil": Der Objektradius in einem Grid muss kleiner sein als 1/4 Gridgröße; bei Rays sogar nur Sqrt(2)/8. Die Boundingspheres der Objekte im Screen1 sind daher nur etwa 1/3 der Gridgröße im Durchmesser; alles was größer ist muss ins nächstgrößere Layer wandern.
Bedientechnisch werden einfach Objekte mit add(obj) in die Struktur geworfen (dynamische wie statische, ohne Unterschied), ein weiterer Hash hilft beim Wiederfinden für update(obj) und kill(obj). Was dynamisch ist wird also lediglich von außen bestimmt, in der Struktur sind alle gleich.
Die Layergröße und -Anzahl bestimme ich derzeit hardcoded nach Anwendung. Auto-Detection gibts dafür nicht, wäre was stochastisches. Man könnte auch einfach immer Gridsize automatisch stur verdoppeln bis es passt, Das Raster sähe dann ähnlich aus wie ein Quadtree, technisch aber nur von unten nach oben aufgebaut, und ohne den schweren Tree-Firlefanz.
Umgebungssuche mit größerem Radius (mehr als 4 Zellen) wird spiralig aus dem Suchzentrum aufgebaut (statt Doppelloop von -r bis r), um die innersten Objekte möglichst früh in der Liste zu haben.
Strahlsuche/Spheresweep wird wie bei einem Raycaster gemacht (horizontale/vertikale Abschnitte aufaddieren), standardmäßig ist der Strahl dann mindestens so "breit" wie die Objektobergrenze im kleinsten Grid. Im ersten Screen unten so ein Broadphase-1-Strahl der Stärke "null". Broadphase 2 wäre dann die Prüfung Abstand Linie-Boundingsphere der einzelnen Items in den betroffenen Containern, also diejenigen nicht in die Liste aufnehmen, deren Kreise den grünen Sweep nicht berühren, dann erst der genaue Raycast mit der Liste (Phase 3). Auch hier liegen dann die nächsten Objekte früh in der Liste.
Ray/Spheresweep (Phase1) durch ein einzelnes Grid.
![Bild](https://www.phoximages.de/uploads/2023/04/i71236badwu4.jpg)
Same, Objekte im Raum, einsortiert in ein 2D Multires-Grid (3 Layer).
![Bild](https://www.phoximages.de/uploads/2023/04/i71237bfy3qj.jpg)
Und in Aktion.
Im Video sieht man 12.000 statische und 150 kreisende dynamische Objekte. Ohne weitere Aufteilung (Chunks oder so), ich habe nur alle dynamischen möglichst in der Mitte versammelt für mehr Kollision und Dichte.
Alles was aufblinkt, ist geade in eine Kollision verwickelt. Dynamische Objekte werden dabei generell nur als Sphere getestet.
Universell jeder mit jedem, alle mit dem "Level", groß mit klein und klein mit groß.
Re: Showroom - Aktuelle Arbeiten und Projekte
Sieht cool aus :)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- starcow
- Establishment
- Beiträge: 533
- Registriert: 23.04.2003, 17:42
- Echter Name: Mischa Schaub
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
@joeydee
Sehr eindrücklich!
Ich erinnere mich noch wage, als ich damals versucht hatte einen Quad-Tree zu implementieren. Ich bin dabei auf das Problem gestossen, dass ich nicht wusste, wie ich mit Objekten verfahren sollte, die mehr als nur eine Zelle belegen. Die Tutorials, die ich dazu finden konnte, behandelten nur Punkte, die sich immer nur genau in einer Zelle befanden.
Ich bin dann auf ein simples, statisches Grid gewechselt (Spatial Hashing).
Wirklich interessant zu sehen, wie du das jetzt gelöst hast.
Sehr eindrücklich!
Ich erinnere mich noch wage, als ich damals versucht hatte einen Quad-Tree zu implementieren. Ich bin dabei auf das Problem gestossen, dass ich nicht wusste, wie ich mit Objekten verfahren sollte, die mehr als nur eine Zelle belegen. Die Tutorials, die ich dazu finden konnte, behandelten nur Punkte, die sich immer nur genau in einer Zelle befanden.
Ich bin dann auf ein simples, statisches Grid gewechselt (Spatial Hashing).
Wirklich interessant zu sehen, wie du das jetzt gelöst hast.
Re: Showroom - Aktuelle Arbeiten und Projekte
SDF und Minkowskisumme und kommutativ und so:
Capsule1 vs. Capsule2 //wtf?
== (Sphere1 + Line1) vs. (Sphere2 + Line2)
== (Sphere1 + Sphere2) vs. (Line1 + Line2)
== Sphere vs. Parallelogram //yay!
In Worten und Bewegung:
Die beiden Kapseln berühren sich genau dann, wenn der graue Kreis das graue Parallelogramm berührt.
Das Problem reduziert sich damit auf "Abstand Punkt zu Parallelogramm", bzw. "Punkt zu elongated Line", eine gut lösbare SDF-Funktion.
Also, es hat bis gestern gedauert, bis es da bei mir Klick gemacht hat dass man das ja auch auf diese Art betrachten und ausdrücken kann. Obwohl ich mich mit SDF ja schon eine ganze Weile beschäftige, und auch Minkowskisummen zumindest vom geometrischen Prinzip her kenne, und auch den Zusammenhang Minkowskisumme mit mancher SDF-Funktion sowie mit Kollisionen. Aber nicht, wie man das praktisch einsetzt.
Das nächste für mich wäre, den allgemeinen Fall zu testen, und dann bitte auch gleich in 3D, also Capsule vs. World == Sphere vs. (World + Line).
"+ Line" wäre dann lediglich ein Term vor der eigentlichen Distanzabfrage (Elongate-Modifier). Ähnlich dem "Trick" wie man gegen ein Ellipsoid testet, indem man die Welt so skaliert, dass man gegen eine Kugel testen kann. Wobei ich den Elongate-Modifier noch für beliebige Richtungen anpassen müsste. Irgendwann, wenn ich mal groß bin ... ;) Skizze (2D-Fall) dazu:
![Bild](https://www.phoximages.de/uploads/2023/05/i71299bvaq3e.png)
Capsule1 vs. Capsule2 //wtf?
== (Sphere1 + Line1) vs. (Sphere2 + Line2)
== (Sphere1 + Sphere2) vs. (Line1 + Line2)
== Sphere vs. Parallelogram //yay!
In Worten und Bewegung:
Die beiden Kapseln berühren sich genau dann, wenn der graue Kreis das graue Parallelogramm berührt.
Das Problem reduziert sich damit auf "Abstand Punkt zu Parallelogramm", bzw. "Punkt zu elongated Line", eine gut lösbare SDF-Funktion.
Also, es hat bis gestern gedauert, bis es da bei mir Klick gemacht hat dass man das ja auch auf diese Art betrachten und ausdrücken kann. Obwohl ich mich mit SDF ja schon eine ganze Weile beschäftige, und auch Minkowskisummen zumindest vom geometrischen Prinzip her kenne, und auch den Zusammenhang Minkowskisumme mit mancher SDF-Funktion sowie mit Kollisionen. Aber nicht, wie man das praktisch einsetzt.
Das nächste für mich wäre, den allgemeinen Fall zu testen, und dann bitte auch gleich in 3D, also Capsule vs. World == Sphere vs. (World + Line).
"+ Line" wäre dann lediglich ein Term vor der eigentlichen Distanzabfrage (Elongate-Modifier). Ähnlich dem "Trick" wie man gegen ein Ellipsoid testet, indem man die Welt so skaliert, dass man gegen eine Kugel testen kann. Wobei ich den Elongate-Modifier noch für beliebige Richtungen anpassen müsste. Irgendwann, wenn ich mal groß bin ... ;) Skizze (2D-Fall) dazu:
![Bild](https://www.phoximages.de/uploads/2023/05/i71299bvaq3e.png)
- Krishty
- Establishment
- Beiträge: 8262
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Ist vielleicht eine gute Gelegenheit um zu sagen, wie gern ich hier mitlese – auch wenn ich nicht unbedingt was beitragen kann :)
- Lord Delvin
- Establishment
- Beiträge: 580
- Registriert: 05.07.2003, 11:17
Re: Showroom - Aktuelle Arbeiten und Projekte
Ja geht mir auch so :)
Re: Showroom - Aktuelle Arbeiten und Projekte
Das Problem kommt mir ziemlich bekannt vor, aber ich habe es nie auf Punkt Parallelogramm reduzieren können. Habe es auch nie so schön visualisiert. Ich habe sowas für Kollisionserkennung in Devader benötigt, wenn sich Elemente schnell bewegen. Ist das bei dir auch der Fall?joeydee hat geschrieben: ↑17.05.2023, 12:46 SDF und Minkowskisumme und kommutativ und so:
Capsule1 vs. Capsule2 //wtf?
== (Sphere1 + Line1) vs. (Sphere2 + Line2)
== (Sphere1 + Sphere2) vs. (Line1 + Line2)
== Sphere vs. Parallelogram //yay!
In Worten und Bewegung:
Die beiden Kapseln berühren sich genau dann, wenn der graue Kreis das graue Parallelogramm berührt.
Das Problem reduziert sich damit auf "Abstand Punkt zu Parallelogramm", bzw. "Punkt zu elongated Line", eine gut lösbare SDF-Funktion.
Discord: https://discord.gg/AWhsvN3 für Devader: http://devader.space
- Schrompf
- Moderator
- Beiträge: 4867
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas Ziegenhagen
- Wohnort: Dresden
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Ob Du's glaubst oder nicht, exakt das habe ich letztens versucht, auszuformeln. Und ich war irgendwo auf dem Weg des Abstands zweier Punkte auf jeweils einer Gerade abgestorben, also die Formeln aufm Papier dreizeilig wurden. Uff. Das hier ist primitiv und fix gemacht, wow.
Edit: die gängige Implementation mit Early Out bei nahezu Parallelität beißt einen hier übrigens. Dank des Radius können sich auch zwei parallele Linien berühren.
Edit2: ich lese gerade im IRC-Log, dass mein Versuch der Auslöser für diese Idee war. Danke!
Edit: die gängige Implementation mit Early Out bei nahezu Parallelität beißt einen hier übrigens. Dank des Radius können sich auch zwei parallele Linien berühren.
Edit2: ich lese gerade im IRC-Log, dass mein Versuch der Auslöser für diese Idee war. Danke!
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Re: Showroom - Aktuelle Arbeiten und Projekte
Nein, dafür nahm ich bisher Raycasting, d.h. am Strahlbeginn den Abstand zur Szene messen, auf dem Strahl genau so weit gehen, und dort erneut messen.
Ich werfe hier einfach mal ein wenig Code rein von meinen Tests.
Für den Parallelogramm-Test habe ich eine allgemeine Polygon-Abstandsmessung benutzt, welcher ich dann als verts[] die 4 Parallelogramecken übergebe die sich aus den Kapsel-Endpunkten ergben. Im Wesentlichen von Quilez, nur dass sie sich noch die Kanten-ID und die Normale merkt.
Wegen Parallelität-Sonderfall kann man wahrscheinlich noch irgendwie optimieren und auch ohne Schleife aufbauen.
Code: Alles auswählen
public float distPolygon(Vector2 p, Vector2[]verts, out Vector2 dir, out int id)
{
dir = new Vector2();
id = -1;
if (verts.Length == 0) return float.MaxValue;
float dq = Vector2.Dot(p - verts[0], p - verts[0]);
float s = 1.0f;
for (int i = 0, j = verts.Length - 1; i < verts.Length; j = i, i++)
{
Vector2 e = verts[j] - verts[i];
Vector2 w = p - verts[i];
float cl = clamp(Vector2.Dot(w, e) / Vector2.Dot(e, e), 0.0f, 1.0f);
float bx = w.X - e.X * cl;
float by = w.Y - e.Y * cl;
Vector2 b = new Vector2(bx, by);
float bq = Vector2.Dot(b, b);
if (i == 0) dir = b;
if (bq < dq) { dq = bq; dir = b; id = i; }
bool c0 = p.Y >= verts[i].Y;
bool c1 = p.Y < verts[j].Y;
bool c2 = e.X * w.Y > e.Y * w.X;
if ((c0 && c1 && c2) || (!c0 && !c1 && !c2)) s *= -1.0f;
}
return s * (float)Math.Sqrt(dq);
}
In der Praxis löse ich das Normalenproblem daher allgemeiner, d.h. gültig für beliebige SDF in allen Dimensionen und an beliebiger Position: ein getGradient(pos), welches um die pos herum 4 (in 3D: 6) Distanzmessungen macht und daraus den Gradienten bestimmt. Mehr Messungen, dafür keine Sonderfälle.
Fehlt noch der Kontaktpunkt, bzw. Ort der kürzesten Entfernung zwischen den Kapseln selbst, es kommt ja nur Info über das Parallelogramm zurück. Habe ich mit einer weiteren Fallunterscheidung gelöst. Man kann das auch sicher gleich in die Polygonschleife einbauen und so eine komplett integrierte Funktion für Kapseltests bauen. Und auch die Redundanz von dist in dir ist eigentlich unnötig. Ich habe einfach nur schnell die einzelnen Werkzeuge genommen, die ich eh rumliegen hatte. Also seht den ganzen Code unbedingt nur als Bastelkram an.
Der gesamte Aufruf und Auswertung für 2 Kapseln c0(a,b,rad) vs. c1(a,b,rad) sah dann ungefär so aus:
Code: Alles auswählen
Vector2 d = c0.a - c0.b;
Vector2[] quad = new Vector2[] { c1.a, c1.b, c1.b + d, c1.a + d };//Polygon == Minkowski Line+Line
float dist = distPolygon(c0.a, quad, out Vector2 dir, out int id) - (c0.rad + c1.rad);//Last term == Minkowski Sphere+Sphere
Vector2 nextP;
switch (id)
{
case 1: nextP = c0.a; break;
case 2: nextP = c1.b + dir; break;
case 3: nextP = c0.b; break;
default: nextP = c1.a + dir; break;
}
Bei Parallelität kann nextP zwischen 2 möglichen Endpunkten "flackern"; tatsächlich gäbe es in diesem Fall unendlich viele Kontaktpunkte zwischen diesen beiden.
Noch ein Ansatz, das war mein erster Gedanke: Alle Endpunkte auf die jeweils andere Linie testen (Abstand Punkt-Linie), und der kürzeste Abstand gewinnt. Was im Prinzip auch dem Parallelogramm-Test entspricht, allerdings nur als Linienzug betrachtet, nicht gefüllt. Man muss daher noch testen, ob die Linien sich kreuzen. Was bei der SDF-Lösung durch "Punkt is im Inneren des Parallelogramms" automatisch abgefangen wird.
Hier nochmal der Pseudocode dazu, ohne Linienschnitt, falls das jemand besser gebrauchen kann:
Code: Alles auswählen
//distance point [p] vs. line segment [ab]
public Vector2 dSegment(Vector2 p)
{
Vector2 pa = p - a, ba = b - a;
float h = clamp(Vector2.Dot(pa, ba) / Vector2.Dot(ba, ba), 0.0f, 1.0f);
return ba * h - pa;
}
//a0 vs capsule 1
p = c0.a;
dir = c1.dSegment(p);
d = dir.Length;
min = d; m0 = p; md = dir;
//b0 vs capsule 1
p = c0.b;
dir = c1.dSegment(p);
d = dir.Length;
if (d < min) { min = d; m0 = p; md = dir; }
//a1 vs capsule 0
p = c1.a;
dir = c0.dSegment(p);
d = dir.Length;
if (d < min) { min = d; m0 = p; md = dir; }
//b1 vs capsule 0
p = c1.b;
dir = c0.dSegment(p);
d = dir.Length;
if (d < min) { min = d; m0 = p; md = dir; }
//TODO: also test intersecting lines
if (min < c0.r + c1.r) [...]
Re: Showroom - Aktuelle Arbeiten und Projekte
Habe mal Joeys Tipp bzgl. Fogrendering ausprobiert. Das hatte er beim letzte ZFX-Stammtisch erklärt.
Kurz gesagt: Helle Bereiche werden weniger vom Nebel beeinflusst. Damit verschwindet nicht einfach alles nur in einer Suppe und man hat noch eine schöne Zeichnung bis zum Horizont.
Standard: Joeys Fog: Benutzt habe ich:
defaultFogFactor = Default Fog Anteil des Pixels
pixBrightness = Grauwert des Pixels
_FogWhiteAmount = Im Shader einstellbarer Faktor
Gefällt mir persönlich sehr gut!
Nochmals Danke für den Tipp, Joey.
Kurz gesagt: Helle Bereiche werden weniger vom Nebel beeinflusst. Damit verschwindet nicht einfach alles nur in einer Suppe und man hat noch eine schöne Zeichnung bis zum Horizont.
Standard: Joeys Fog: Benutzt habe ich:
Code: Alles auswählen
float joeyFogFactor = defaultFogFactor - pixBrightness * pixBrightness * pixBrightness * _FogWhiteAmount;
pixBrightness = Grauwert des Pixels
_FogWhiteAmount = Im Shader einstellbarer Faktor
Gefällt mir persönlich sehr gut!
Nochmals Danke für den Tipp, Joey.
- Krishty
- Establishment
- Beiträge: 8262
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Kurze Info, wie das im RL ist (beim Stammtisch war ich leider krank): Nebel besteht aus einer multiplikativen Komponente und einer additiven Komponente.
Die multiplikative Komponente verdunkelt entfernte Bereiche. Bspw. erreichen uns nach 30 km Luft noch 50 % des ursprünglichen Objektlichts. Diese Komponente ist stark abhängig von der Wellenlänge, also Farbe – rotes Licht kommt besser durch als blaues Licht. Allgemein folgt die Abschwächung ungefähr (1 / distance).
Die additive Komponente ist Streulicht. Jeder Kubikmeter Luft streut eine gewisse Menge Licht z.B. der Sonne. Blau wird besser gestreut als rot, und dadurch scheint der Himmel blau (und ebenso entfernte Berge). Diese additive Komponente nimmt allgemein linear mit dem durchquerten Luftvolumen zu – deshalb ist der Horizont viel heller als der Zenith – gleichzeitig unterliegt das Streulicht aber auch wieder der multiplikativen Komponente, so dass man in der Berechnung eine Endlosschleife bekommt und wir nur den Grenzwert sehen.
Es gibt also eine 1/d-Funktion, mit der entfernte Landschaft multipliziert wird; und eine lineare Funktion, die auf entfernte Landschaft addiert wird. Beides findet zudem im linearen Farbraum statt, nicht in sRGB.
Lustigerweise füttert eine Funktion die andere, so dass die Gesamtenergie gleich bleibt. Die optische Tiefe stammt komplett aus der Addition der beiden unterschiedlichen Funktionsformen.
Joeys Fog ist eine tolle Annäherung daran, aber ich würde definitiv RGB statt eines Skalars draus machen und in der Distanz blaue Features der Landschaft stärker abschwächen, dafür mit Distanz den blauen Fog verstärken!
Die multiplikative Komponente verdunkelt entfernte Bereiche. Bspw. erreichen uns nach 30 km Luft noch 50 % des ursprünglichen Objektlichts. Diese Komponente ist stark abhängig von der Wellenlänge, also Farbe – rotes Licht kommt besser durch als blaues Licht. Allgemein folgt die Abschwächung ungefähr (1 / distance).
Die additive Komponente ist Streulicht. Jeder Kubikmeter Luft streut eine gewisse Menge Licht z.B. der Sonne. Blau wird besser gestreut als rot, und dadurch scheint der Himmel blau (und ebenso entfernte Berge). Diese additive Komponente nimmt allgemein linear mit dem durchquerten Luftvolumen zu – deshalb ist der Horizont viel heller als der Zenith – gleichzeitig unterliegt das Streulicht aber auch wieder der multiplikativen Komponente, so dass man in der Berechnung eine Endlosschleife bekommt und wir nur den Grenzwert sehen.
Es gibt also eine 1/d-Funktion, mit der entfernte Landschaft multipliziert wird; und eine lineare Funktion, die auf entfernte Landschaft addiert wird. Beides findet zudem im linearen Farbraum statt, nicht in sRGB.
Lustigerweise füttert eine Funktion die andere, so dass die Gesamtenergie gleich bleibt. Die optische Tiefe stammt komplett aus der Addition der beiden unterschiedlichen Funktionsformen.
Joeys Fog ist eine tolle Annäherung daran, aber ich würde definitiv RGB statt eines Skalars draus machen und in der Distanz blaue Features der Landschaft stärker abschwächen, dafür mit Distanz den blauen Fog verstärken!
Re: Showroom - Aktuelle Arbeiten und Projekte
Ah super. Dein Atmosphärenrendering sieht ja sowieso extrem glaubhaft aus. Auch Dir nochmal ein Dank für die Erklärung.
Müsste ich mal ausprobieren, wie das Verfahren in meinen Projekten ausschaut, da ich den Nebel bisher eher "künstlerisch" einsetze. Könnte aber zu interessanten Ergebnissen führen.
Müsste ich mal ausprobieren, wie das Verfahren in meinen Projekten ausschaut, da ich den Nebel bisher eher "künstlerisch" einsetze. Könnte aber zu interessanten Ergebnissen führen.
Re: Showroom - Aktuelle Arbeiten und Projekte
Ja, da steckt physikalisch natürlich noch viel mehr dahinter, cooles Bild Krishty!
Zur näheren Info: wir hatten es beim Stammtisch davon, wie man mit kleinen simplen Hacks ein etwas besseres Bild als Standard-NdotL hinbekommt, es ging auch um Lesbarkeit, ohne Anspruch auf Realismus. Darunter zählte auch z.B. senkrechte Wände nach unten etwas dunkler verlaufen zu lassen, wenn man so möchte, ein AO-Hack. Kleine Sachen, die man ohne große Renderengine und Hirnschmalz machen kann bei Prototypen oder einfachen Games. Gibt noch mehr, das nächste wäre z.B., konvexe Kanten mit einer helleren Linie zu betonen, konkave mit einer dunkleren.
Und noch ergänzend: Der o.g. Nebel-"Hack" simuliert eigentlich nur eine HDR-Komponente von z.B. reflektierendem Schnee. Je nachdem kann das sogar fast 111-Weiß bleiben.
Was die RGB-Skalierung angeht, auch dafür habe ich einen simplen "Hack", der aber noch weniger mit Physik zu tun hat, kommt alles mehr aus der Digitalküstlerküche. Man mappt einfach die Helligkeit nochmal auf einen anderen Farbverlauf (z.B. Violett über Blau und Cyan auf Weiß statt nur Dunkel- auf Hellblau) und mixt das Ergebnis nochmal rein. Eine Art Hollywood-Remapping, Amber/Teal & Co. lassen grüßen.
Zur näheren Info: wir hatten es beim Stammtisch davon, wie man mit kleinen simplen Hacks ein etwas besseres Bild als Standard-NdotL hinbekommt, es ging auch um Lesbarkeit, ohne Anspruch auf Realismus. Darunter zählte auch z.B. senkrechte Wände nach unten etwas dunkler verlaufen zu lassen, wenn man so möchte, ein AO-Hack. Kleine Sachen, die man ohne große Renderengine und Hirnschmalz machen kann bei Prototypen oder einfachen Games. Gibt noch mehr, das nächste wäre z.B., konvexe Kanten mit einer helleren Linie zu betonen, konkave mit einer dunkleren.
Und noch ergänzend: Der o.g. Nebel-"Hack" simuliert eigentlich nur eine HDR-Komponente von z.B. reflektierendem Schnee. Je nachdem kann das sogar fast 111-Weiß bleiben.
Was die RGB-Skalierung angeht, auch dafür habe ich einen simplen "Hack", der aber noch weniger mit Physik zu tun hat, kommt alles mehr aus der Digitalküstlerküche. Man mappt einfach die Helligkeit nochmal auf einen anderen Farbverlauf (z.B. Violett über Blau und Cyan auf Weiß statt nur Dunkel- auf Hellblau) und mixt das Ergebnis nochmal rein. Eine Art Hollywood-Remapping, Amber/Teal & Co. lassen grüßen.
- Schrompf
- Moderator
- Beiträge: 4867
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas Ziegenhagen
- Wohnort: Dresden
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- Schrompf
- Moderator
- Beiträge: 4867
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas Ziegenhagen
- Wohnort: Dresden
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Hab mich jetzt echt zwei Wochen mit Kollisionstest beschäftigt. Hab viel dabei gelernt, auch dass ich früher mal klüger war und mein Kreis vs. Strahl-Test schon echt gut optimiert war, was ich zuerst für nen Fehler hielt.
Jetzt aber geht endlich: Circle Sweep vs. Ray. Also Strahl mit Radius gegen Strahl. Damit rutschen die Character Controller in meinem Spiel über die bodenbasierten Dreiecke, und jetzt stoppen sie exakt an Wänden und gleiten daran entlang. Hab ein fixes Debug-Sweep rund um die Mauspos eingebaut, und das ergibt folgende Hits:
Man sieht, wie da von außen zur Maus gesweept wird, und wo die Kollisionen festgestellt werden. Die Kreise liegen reihum exakt am Dreieck an <3
Die Idee, nach vielen verworfenen, ist jetzt Folgende: der Teststrahl wird ins Koordinatensystem des Zweitstrahls transformiert. X ist dann "entlang StrahlB" und Y ist "senkrecht zu StrahlB". Damit hab ich automatisch immer den Abstand zum Strahl und auch immer die Position auf dem Strahl für jeden beliebigen POI. Und es fallen ein paar Sonderfälle raus, die anders unangenehm zu händeln sind. Iquilez hat das natürlich auch schon gelöst, aber ich habe den Verdacht, der er für parallele Strahlen zu früh early-outet. Guck ich mir ein ander mal an. Code gern auf Wunsch, aber jetzt muss ich erstmal los.
Jetzt aber geht endlich: Circle Sweep vs. Ray. Also Strahl mit Radius gegen Strahl. Damit rutschen die Character Controller in meinem Spiel über die bodenbasierten Dreiecke, und jetzt stoppen sie exakt an Wänden und gleiten daran entlang. Hab ein fixes Debug-Sweep rund um die Mauspos eingebaut, und das ergibt folgende Hits:
Man sieht, wie da von außen zur Maus gesweept wird, und wo die Kollisionen festgestellt werden. Die Kreise liegen reihum exakt am Dreieck an <3
Die Idee, nach vielen verworfenen, ist jetzt Folgende: der Teststrahl wird ins Koordinatensystem des Zweitstrahls transformiert. X ist dann "entlang StrahlB" und Y ist "senkrecht zu StrahlB". Damit hab ich automatisch immer den Abstand zum Strahl und auch immer die Position auf dem Strahl für jeden beliebigen POI. Und es fallen ein paar Sonderfälle raus, die anders unangenehm zu händeln sind. Iquilez hat das natürlich auch schon gelöst, aber ich habe den Verdacht, der er für parallele Strahlen zu früh early-outet. Guck ich mir ein ander mal an. Code gern auf Wunsch, aber jetzt muss ich erstmal los.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Re: Showroom - Aktuelle Arbeiten und Projekte
Smoooth. Sieht so aus als ob du KI-Rennfahrer trainieren willst?
Discord: https://discord.gg/AWhsvN3 für Devader: http://devader.space
- Lord Delvin
- Establishment
- Beiträge: 580
- Registriert: 05.07.2003, 11:17
Re: Showroom - Aktuelle Arbeiten und Projekte
Faszinierend; zumal ich in dem Bereich auch immer wieder so getestet habe und es auch weitgehend weiter so machen würde anstatt irgendwie Tests zu definieren und darüber die Funktionalität zu zementieren.