Soar ja siehe Topic.
Momentan mach ich das so, dass ich zuerst alle undurchsichtigen Objekte zeichne und dann in beliebiger Reihenfolge alle Transparenten(mit ausgeschaltetem z-Buffer-Schreiben)
Jetzt habe ich aber auch Objekte, die fast nur oder wirklich nur aus transparenten Flächen bestehen. Das führt bei geringer Transparenz zu einem optisch sehr fragwürdigen und komischen Ergebnis. Daher will ich das verbessern.
Erster Ansatz: ich muss bei jedem Rendern die transparenten Objekte tiefensortieren. Wie mach ich das am besten? Welcher Ansatz liefert da brauchbare Ergebnisse? Wer da Infos hat, ich wäre dankbar.
Meine erste Idee wäre, einfach den Abstand zum geometrischen Schwerpunk des grafischen Objektes zu nehmen. Aber ich stelle mir da grad eine ganz lange Fläche die bis zum Betrachter geht und eine kleine, welche weit hinten aber vor der Langen ist. Da würde der Abstand zur hinteren, aber vorderen evtl. größer sein und ich hätte hier die falsche Reihenfolge oder?
Also wie gesagt, wer was weis, bitte helfen.
Zweiter Ansatz: ich hab hier grad "Spieleprogrammierung Gems 1" vor mir liegen und da behandeln die auch das Problem. Da steht als 3. Lösung folgendes:
Gems 1 hat geschrieben:
1. Lösche Z-Buffer
2. Lösche Alpha-Buffer mit Wert 0(transparent)
3. Setze Z-Funktion auf "größer als"(zeichne hinter), verwende Blend-Formel A(glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);) und zeichne die erste transparente Primitive bei ausgeschaltetem Z-Überschreiben. Zusätzlich schreibe den Alphawert der Primitiven in den Framebuffer, sodass nachfolgender Pixel dahinter korrekt geblendet werden.
4. Setze Z-Funktion auf "kleiner oder gleich"(zeichne davor), verwende Blend-Formel A und zeichne diese Primitive noch einmal mit eingeschaltetem Z-Überschreiben. Schreibe den Alpha-Wert der Primitiven in den Framebuffer, sodass nachfolgender Pixel dahinter korrekt geblendet werden.
5. Wiederhole die letzten beiden Schritte für alle transparenten Objekte
6. Setze Z-Funktion auf "größer als"(zeichne hinter), verwende Blendformel B (glBlendFunc(GL_ONE_MINUS_DST_ALPHA,GL_DST_ALPHA);). und zeichne alle opaken Primitive mit ausgeschaltetem Z-Überschreiben. Der Alpha-Wert, um in den Framebuffer zu schreiben, ist 1.0 (bzw. der maximale Integerwert).
7. Setze Z-Funktion auf "kleiner oder gleich" (zeichne davor) und zeichne alle opaken Primitive mit eingeschaltetem Z-Überschreiben und ausgeschaltetem Blending
So die Methode habe ich bisher nur so halb verstanden, voll blick ich da noch nicht durch.
Meine Fragen dazu: Muss man den Alpha-Buffer der hier erwähnt wird in OpenGL irgendwie extra anlegen und dann leeren? Wenn ja wie?
Dann dieses Schreiben des Alphawertes, das geht doch sicher standardmäßig von allein? Habe dazu bisher noch nix gelesen, wäre über Aufklärung dankbar.
Das Ein/-Ausschalten des Tiefenpuffers usw. kenn ich.
Also wenn mir da wer noch etwas Licht ins dunkel bringen kann zu den erwähnten Alpha-Werten oder die Methode kennt und generell das vielleicht verständlicher erklären kann ... .
MfG Pellaeon
_________________ __________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup
Zunächst einmal, sind die transparenten Faces statisch oder dynamisch? Weil wenn sie statisch sind, kann man ne Menge vorberechnen.
Zitat:
Meine erste Idee wäre, einfach den Abstand zum geometrischen Schwerpunk des grafischen Objektes zu nehmen. Aber ich stelle mir da grad eine ganz lange Fläche die bis zum Betrachter geht und eine kleine, welche weit hinten aber vor der Langen ist. Da würde der Abstand zur hinteren, aber vorderen evtl. größer sein und ich hätte hier die falsche Reihenfolge oder?
Du hast recht, bei langen Faces klappt das nicht. Da muss man dann überprüfen, ob sich die AABBs der Faces überlappen, und wenn sies tun, dann guckst du auf die Ebenen der beiden Faces. Wenn eines der Faces komplett auf einer Seite der Ebene des anderen liegt, dann kannst dus danach sortieren. Wenn nicht, dann schneiden sich beide Faces, und dann must du clippen - oder es einfach ignorieren, weils sehr selten ist.
Zitat:
ich hab hier grad "Spieleprogrammierung Gems 1" vor mir liegen
Öhm, hast du "Spieleprogrammierung Gems 1" oder "Game Programming Gems 1" vor dir liegen? Wenns letzteres ist, dann poste doch lieber den englischen Originaltext, das ist einfacher zu lesen, als wenn alle Begriffe eingedeutscht sind...
Zitat:
Meine Fragen dazu: Muss man den Alpha-Buffer der hier erwähnt wird in OpenGL irgendwie extra anlegen und dann leeren? Wenn ja wie?
Beim Initialisieren von OGL sagt man OGL, ob man ihn haben will oder nicht. Is aber im allgemeinen immer dabei.
Löschen:
Code:
glColorMask(FALSE, FALSE, FALSE, TRUE);
glClear(GL_COLOR_BUFFER_BIT);
glColorMask(TRUE, TRUE, TRUE, TRUE);
wenn ich mich nicht irre.
Zitat:
Dann dieses Schreiben des Alphawertes, das geht doch sicher standardmäßig von allein? Habe dazu bisher noch nix gelesen, wäre über Aufklärung dankbar.
Is normalerweise eingeschaltet.
Ein und Abschalten läuft wie oben beim Löschen beschrieben mit glColorMask.
_________________ [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
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Wenn die Flächen in der Szene statisch sind, dann könnte ein BSP-Baum das richtige für dich sein. Ist aber nicht ganz trivial.
Wegen GL_COLOR_BUFFER_BIT : Der Framebuffer besteht aus so ziemlich allen Puffern (soweit ich das verstanden habe). U.A. auch aus dem Farbpuffer. Der ist wiederum 4 geteilt, in die jeweiligen Farben. Der Alphapuffer ist also nur ein Teil eines Teiles des Framebuffers.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Wie kann ich denn jetzt den Alphawert im Framebuffer mit 0 "löschen" ? Mit dem Code von AL?
Weil dann würde ich einfach mal den Algorithmus aus Gems testen, schließlich geht Probieren über Studieren. Falls es klappt, kann ich das ja posten.
MfG Pellaeon.
_________________ __________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup
Mit statisch meinte ich, dass sich die transparenten Faces nicht bewegen. Dann könnte man vorher nen BSP-Tree erstellen, wie Flash bereits beschrieben hat. Wenn der schön balanced ist, dann kannste mit n paar Node-Tests alle Faces sehr schnell sortieren.
Zitat:
Habe die deutsche Ausgabe, Text ist 1 zu 1 abgetippt.
Das ist ja grausig
Zitat:
zeichne die erste transparente Primitive bei ausgeschaltetem Z-Überschreiben.
Ohje pass bloß auf, dass dein grafisches Verarbeitungs-Aggregat kein Abfülltempo-Problem bekommt, denn das geht bei eingeschaltetem Verschmelzen und vielen betroffenen Abbildungszellen sehr schnell
_________________ [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
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Al: Ich sage nur. Beitrag wegen seelischer Grausamkeit und Vergewaltätigung der deutschen Sprache gelöscht. Das ist ja echt bitter.
Denke aber ähnlich wie Al und Flash. Je nachdem wie viel Transparente Objekte du Renderst kann sich die obere Methode schon recht negativ auswirken. Wenn ich das richtig verstanden werden dabei alle Objekte 3 Mal gezeichnet. Von den ganzen State Changes mal abgesehen.
*hehe Jo due Übersetzung ist teilweise etwas lustig/komisch, aber was er will habsch verstanden, es war eher das Prinzip an sich wo es klemmte. Nuja ich teste das einfach mal.
@lossy: jedes Objekt wird 2 mal gerendert. Es wird auch im Buch drauf hingewiesen, dass bei vielen Objekten die Performance drunter leidet, obwohl bei dieser Methode eine Sortierung der transparenten Objekte entfällt. Mal soll gegebenenfalls optimieren, leider steht nicht drinnen wie
_________________ __________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup
Habe mal meinen Codeausschnitt gepostet.
Meine grafischen Objekte sind in den beiden Listen gespeichert.
Das Zeichnen habe ich mal nur als "Zeichne Objekt i" umschrieben.
Hat auf Anhieb geklappt, Ergebniss sieht wunderbar aus. Da ich keine riesige Anzahl an Objekten habe, scheint es auch kein Performance-Problem zu geben und meine alte draw-Methode habe ich ja auch noch, kann also zwischen den beiden Methoden zum Rendern der Objekte von außen wählen, OOP sei dank^^
Also falls es wem hilft, hier der Code:
Code:
backGround.alpha:= 0;
setBackground(backGround);
//transparente Objekte
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
i:= 0;
while (i <> m_transpObjects.count) do
begin
glDepthFunc(GL_GREATER);
glDepthMask(GL_FALSE);
//
Zeichne Objekt i
//
glDepthFunc(GL_LEQUAL);
glDepthMask(true);
//
Zeichne Objekt i
//
inc(i);
end;
//solide Objekte
i:= 0;
glBlendFunc(GL_ONE_MINUS_DST_ALPHA,GL_DST_ALPHA);
while (i <> m_solidObjects.count) do
begin
glDepthFunc(GL_GREATER);
glDepthMask(GL_FALSE);
//
Zeichne Objekt i
//
glDepthFunc(GL_LEQUAL);
glDepthMask(true);
//
Zeichne Objekt i
//
inc(i);
end;
edit: backGround ist eine Struktur die die RGBA-Anteile der Farbe enthält, in setbackGround wird der Framebuffer gelöscht
_________________ __________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup
Ich habs auch mal nachvollzogen....
Die Anzeigeresultate sind wirklich etwas besser, aber die Performance geht ca. auf die Hälfte zurück, da ja alle Objekte 2 mal gerendert werden.
Dann sind auch noch ein paar korrekturen im Code nötig:
Insbesondere bei dem Zeichnen der nicht transparenten Objekte. Hier sind in Schritt 6 und 7 jeweils alle nicht transparenten Objekte hinterenander zu zeichnen und dann das ganze ein 2. Mal. Außerdem ist noch glBlend auszuschalten.
Ich verstehe noch nicht, warum das funktionieren soll.
Wenn in der Liste der transparenten Faces am Ende eins ist, dass weiter von der Camera entfernt ist, als andere, dann wird es doch trotzdem mit GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA geblendet und die Fragements erhalten die gleiche Farbportion von dem Face, als wenn keine anderen Faces davor wären. Wenn das Face z.B. ein Alpha von 0.1 hat, dann würden die betroffenen Pixel auch auf jeden Fall 10% ihrer Farbe von diesem Face bekommen, unabhängig davon, ob noch ein anderes Face mit nem Alpha von 0.75 davor ist, so dass der richtige Faktor 2.5% wäre.
_________________ [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
Ok ich habe das im Wiki mal noch abngepasst.
Das Setzen der Zustände bei den soliden Objekten kann man noch aus der Schleife rausziehen, da sich das ja in der Schleife nicht ändert.
_________________ __________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup
Ein ziemlich verzwicktes Problem ist es, wenn sich transparente Objekte überlappen. Es ist nicht möglich diese Situation durch einmaliges Zeichnen zu behandeln (Es sei den man kann die Polygone in sich nicht überlappende Teile zerlegen. Dies ist aber eher eine akademische Lösung, und in der Praxis nicht umsetzbar.).
Ich glaube ihr meint, dass sie sich nicht schneiden dürfen. Überlappen ist ok, und kann durch normales Sortieren behoben werden. Clippen würde ich auch nicht als akademische Lösung betrachten, weils doch recht gängig ist.
Trotzdem verstehe ich den Code noch nicht. Für mich sieht das so aus, als hätte es den gleichen Effekt, wie wenn man die Faces unsortiert und ohne Depth-Test rendert. Und die statische Geometrie 2x rendern ist definitv keine gute Idee. Die wird durch die normalen Shader schon so oft gerendert, das würde sich dann ja alles verdoppeln.
_________________ [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
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.