Registriert: Do Mär 06, 2003 15:27 Beiträge: 281 Wohnort: Bochum
wie der titel schon sagt: wie kann ich die partiekl in einem Partikel-system so sortieren, dass wirklich erst die gerendert werden, die ganz hinten sind und auch keinen partiekl vor sich überschneiden, so das ich den zbuffer beim rendern der partikel anlassen kann...
wie man sortiert ist mir klar nur wenn ich einfach die normale distance zwischen viewer und partikel-MITTELPUNKT nehme, kann es trotzdem zu überschneidungen wegen der erst später erfolgenden billboarding-rotation kommen...
weiß jemand wie man das lösen kann?
Registriert: Mo Mai 06, 2002 20:27 Beiträge: 479 Wohnort: Bremen
Hi!
Das Billboarding macht hier eigentlich keine Probleme. Ein klassisches Billboard steht ja rechtwinklig auf der gedachten Linie zwischen dir und dem Partikelmittelpunkt. Trotzdem kannst du natürlich nicht einfach die Z-Komponente deiner Partikel als Tiefe verwenden, da deren endgültige Tiefe ja erst durch die Multiplikation mit der Modelviewmatrix bestimmt wird.
Was du also tun musst ist die Transformation, die deine Grafikkarte machen wird noch einmal händisch vor dem Rendern durchzuführen. Dabei reicht es vollkommen aus, wenn du dich auf die Tiefe beschränkst also X u. Y weglässt. Faktisch mutiplizierst du also die 3. Zeile der Modelviewmatrix mit der Z-Komponente deiner Partikel und erhälst so die Tiefe von der Kamera aus gesehen.
Falls das noch nicht weiterhilft, hier etwas Pseudo-Code:
Code:
glGetFloatv(GL_MODELVIEW_MATRIX, @Matrix);
for i := 0 to ParticleCount-1 do
with Particle[i].Position do
Depth := x * Matrix[2] + y * Matrix[6] + z * Matrix[10] + Matrix[14];
Jetzt kannst du deine Partikel nach diesem Wert sortieren und in der richtigen Reihenfolge zum Rendern geben. Das sortieren kann je nach Anzahl der Partikel richtig lang dauern! Deshalb würde ich Algorithmen mit O(n^2) vermeiden... (d.h. Bubblesort u.ä.) und stattdessen lieber einen Algorithmus mit O(n log n) verwenden. Ich habe mit Mergesort gute Erfahrungen gemacht...
Registriert: Do Mär 06, 2003 15:27 Beiträge: 281 Wohnort: Bochum
Hey DANKE!
es klappt perfekt!
aber trotzdem, verstehe ich net ganz wie man darauf kommt welcher werte man aus der modelmatrix nehmen muss!
und warum ist das was anderes als wenn man die normale entfernung zwischen cam-point und partikel-mitte nimmt und sortiert, das habe ich nämlich vorher ausprobiert und es hat halt net geklappt!!
und nochwas: was ist mergesort und meinst du qsort bringt es auch, wie funtkioniert merge-sort(vielleicht n tut? ) ?
Registriert: Mo Mai 06, 2002 20:27 Beiträge: 479 Wohnort: Bremen
Hola!
Extrawurst hat geschrieben:
und warum ist das was anderes als wenn man die normale entfernung zwischen cam-point und partikel-mitte nimmt
Ich weiß nicht genau was dein CamPoint ist, aber der Grund warum man's so macht wie ich das gemacht habe ist der: Die Koordinaten deiner Partikel liegen in Worldspace vor, das heißt ihre Position wird relativ zum Koordinatensystem der Welt angegeben. Um nicht ständig Geometriedaten verändern zu müssen wenn man die Welt aus einem anderen Blickwinkel als dem Ursprung zeigen will, gibt es in OpenGL noch den Camera-Space. Durch die ModelviewMatrix werden alle Objekte in den Camera-Space transformiert, also in ein Koordinatensystem, dass die virtuelle Kamera als Basis hat und wo die negative Z-Achse die Blickrichtung ist! (Dann braucht man sie nur noch zum rendern auf den Viewport zu projezieren und bekommt das gewünschte Bild) Du brauchst für die Tiefensortierung nicht die Entfernung von der Kamera sonden nur die Tiefe d.h. die Z-Komponente deines Partikels in Camera-Space berechenen...
Extrawurst hat geschrieben:
aber trotzdem, verstehe ich net ganz wie man darauf kommt welcher werte man aus der modelmatrix nehmen muss!
... und genau das mache ich hier! Was x und y im Cameraspace ist, ist uns vollkommen egal! Wir brauchen nur die Z-Komponente. Wenn du dir die Rechenvorschriften für die Multiplikation von Vektoren mit Matritzen anguckst (Delphic's Tut!) dann wirst du feststellen, dass sich die Z-Komponente (die 3.) durch Multiplikation der 3. Spalte der Matrix mit dem zu transformierenden Vektor ergibt. Und genau das macht der Source!
Zitat:
und nochwas: was ist mergesort und meinst du qsort bringt es auch, wie funtkioniert merge-sort(vielleicht n tut? ) ?
Ich bin kein Sortieralgorithmen-Experte also am besten probierst du einfach verschiedene Algo's aus. Aber Quicksort hat ne schlechte Worst-Case-Performance O(n^2) außerdem basiert er auf Rekursion, braucht also noch recht viel Platz auf dem Stack.
Mergesort basiert zwar auch auf Rekursion aber hat eine bessere WorstCase Performance O(n log n) und arbeitet sequentiel... was aus Cache-Gesichtspunkten nicht Schaden kann!
Na, wie ich schon sagte: bin kein Experte aber hab gute Erfahrungen mit Mergesort gemacht!
-lith
P.S.: Sind die Rolle der Modelviewmatrix und allgemein alles was OpenGL intern mathematisch gesehen macht um eine Scene auf den Viewport zu rendern eigentlich allen klar? Oder besteht (ich frage mal ganz unverbindlich!) hier noch Klärungsbedarf?
Registriert: Do Okt 09, 2003 15:28 Beiträge: 14 Wohnort: Bochum
Der Depth_Test ist in sofern unverzichtbar, weil man so verhindert, dass er die Partikel hinter Wände zeichnet. Dummerweise kann man nur halt (meines Wissens) keinen Depth_Test machen, ohne automatisch den ZBuffer mit zu beschreiben [=Depth_Test mit ReadOnly geht nicht]...
Registriert: Mo Mai 06, 2002 20:27 Beiträge: 479 Wohnort: Bremen
LarsMiddendorf hat geschrieben:
Warum soll der Z-Buffer für die Partikel denn beschrieben werden? Mich würde mal interessieren für welchen Effekt man das genau braucht.
Nö... da fällt mir jetzt auch keiner ein! Aber so wie ich Extrawurst verstanden habe will er dafür sorgen, dass die Partikel in der richtigen Reihenfolge von vorne nach hinten gezeichnet werden sollen. Und das ist zum Beispiel wichtig, wenn du die transparente Partikel hast wo es schon ne Rolle spielt, wie sie sich gegenseitig verdecken. (Bei additivem Bleinding für z.B. Feuer ist das natürlich wurscht - für halbtransparente Seifenblasen oder Rosenblätter allerdings nicht!)
@Escudo: Depth-Buffer read only geht allerdings schon. Einfach die DepthMask auf false setzen!
Mitglieder in diesem Forum: 0 Mitglieder und 5 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.