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

Aktuelle Zeit: Di Mai 14, 2024 09:35

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Do Sep 05, 2013 15:51 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Hallo,

ich bastele ja gerade an einem kleinen Entwicklungstool und mich beschäftigt schon seit Tagen eine entscheidende Frage:

Wie rendere ich am günstigsten Objekte, die sowohl kurvenreiche als auch Flache Oberflächen besitzen. Als gutes Beispielobjekt bietet sich hier der im Titel genannte Zylinder an.

Um besagten Zylinder zu rendern, der auch in der Nahaufnahme keine deutlich erkennbaren Polygonecken aufweist, würden mir spontan 2 Möglichkeiten einfallen:

- Über den Fragmentshader die Pixel entsprechend an die Stellen verrücken, die sie auf einen perfekten Zylinder hätten

- Über Tesselation und Kameraentfernung die Polygonanzahl anpassen.

Ersterer Ansatz hätte den Nachteil, dass es mitunter sehr Transformations-lastig wird und das auch noch auf Pixelebene, weshalb ich eher zur Tesselation-Variante tendieren würde. Hierbei entstehen jedoch folgende "Probleme":

Die ebene und die gerundete Fläche müssen unterschiedlich behandelt werden. Die Seitenfläche würde ich beispielsweise statt aus Dreiecken eher aus rechteckigen Polygonen gestalten, da so weniger Vertices durch den TCS erzeugt werden müssen und die "Knickkanten" garantiert parallel bleiben. Die Flächen hingegen würde ich als TriangleFan aufbauen und nur die zum Rand hin gelegene Seite aufspalten lassen. Letztendlich sind die Unterschiede zwischen beiden Segmenten schon so groß, dass mir kein vernünftiger Weg einfällt, das Ganze in einem Draw-Call unterzubringen.

Es stellt sich halt für mich nun die Frage ob es da auch einen günstigeren Weg gibt. Das Verwenden unterschiedlicher Polygontypen (Rechtecke und Dreiecke) sowie die mehreren Draw-Calls pro Objekt sind ja tendentiell eher nicht so günstig. :/ Wie macht ihr das denn beispielsweise?


Eine andere Frage wäre noch: Es gibt ja die Möglichkeit Shader ohne Programm in die Pipeline zu laden. Ginge es beispielsweise auch ein festes Programm zu verwenden und dann je nach Bedarf Tesselation-Shader und Geometrieshader in die Pipeline zu schieben, solange die in's und out's entsprechend passen?

Sorry fürs nerven.

MfG Der Tr0ll


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Sep 06, 2013 09:27 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich würde auf Tesselation setzen.

Für gut tesselierende Rundungen solltest du eher auf Bildungsvorschriften und Texturen setzen, statt auf einfaches tesselieren und zwischen normals oder Hull interpolieren.

Um ein Zylinder korrekt rund zu bekommen muss nach dem tesselieren eine positionskorrektur geschehen und da die Normals nicht sauber interpoliert werden können und bei komplexeren Oberflächen zu wenig Informationen liefert, sind Texturen da besser.
Was du dafür bräuchtest wäre ein displacement map und normal map.
Die displacement map gibt die Distanz und die normalmap die Richtung an, in die die vertices verschoben werden sollen.
Tesselierung muss man nicht unbeding mit einem Geometry Shader machen, sondern kann auch per Instancing Patches bauen. OC2k1 hatte das mal vor langer Zeit gemacht und hat den Vorteil, dass es auch älterer Hardware läuft(DX9 Shader Model 2b).

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Sep 06, 2013 13:08 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Ich nutze einen OGL 4+-Kontext und greife da auf die Tesseltion-Shader zurück. Generelle Rundungen von Kurven würde ich ja per Bezier-Patches formen. Im Falle des Zylinders hat man, wie du erwähntest, eine Bildungsvorschrift, die man nutzen kann, was auch der Plan ist. Jedoch gibt es bei der ganzen Sache halt 2 kleinere Probleme. Zum Einen sind die Herangehensweisen für Seiten-Oberfläche und die beiden Deckel unterschiedlich. So macht es sich zum Beispiel schwer mit den GL-Tesselation-Routinen und Dreiecks-Polygonen eine vernünftige Tesselierung der Seitenfläche hinzukriegen, weshalb ich auf Quad-Patches zurückgreifen müsste. Das Problem ist einfach, dass die ausgespuckten Vertices nicht mehr in parallelen Linie liegen, weshalb die Seitenkontur des Zylinders auf einmal hügelig erscheint. Die Deckel hingegen machen nur mit Dreiecken wirklich Sinn.
Das andere Problem ist, dass die Seitenflächen in Normalenrichtung zur Zentralachse verschoben werden. Bei den Deckeln ist es in Flächenrichtung.

Das alles ließe sich halt durch 2 separate Draw-Calls relativ simpel lösen, allerdings müsste ich auch noch die Programme oder ggf. Subroutinen Switchen.

Möglicherweise gäbe es auch die Möglichkeit in den Shadern per Uniform eine Selektion zu treffen, ob ich nun die Seitenroutine fahre oder die Deckelroutine. Vielleicht geht das auch ganz ohne Uniform, aber ich denke das würde schon ziemlich aufwendig werden.

Die Frage ist halt, wie "teuer" kommt mich ein zusätzlicher Draw-Call zu stehen und wie "teuer" ein Programm und Subroutinen Wechsel. Auch wenn die jetzige Anwendung vermutlich niemals in den Bereich kommt, dass die Grafikkarte davon irgendwie beeindruckt wäre, will ich es doch möglichst effektiv programmieren um zumindest in der Zukunft zu wissen wie es am besten ist.

Falls meine Ausführungen zum Zylinderproblem nicht gut genug sind, kann ich auch ein paar Grafiken zur Veranschaulichung erstellen.

MfG DerTr0ll


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Sep 06, 2013 13:33 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Das ist jetzt mal alles Theoretisch, weil ich das nicht wirklich in der Praxis getestet habe aber folgende Lösungen fallen mir noch für die Deckel ein.

Du kannst 1. eine quadsphere halbkugel generieren und dabei noch die Höhenachse flatten, damit ist das resultat bündig mit dem Cylinder und kann sauber über die Tesselierung gemacht werden(Hast dann quasi auch gleich die Capsule Primitive).

Die 2. Lösung wäre ein Imposter per Bildungsvorschrift.
Man baut ein Quad als Deckel und im Fragmentshader wird dann einfach sinus/cosinus benutzt um alles im Kreis zu füllen und ausserhalb zu überspringen. Man kann das noch nen smoothstep auf der Kante benutzten um es saubere Kanten zu geben.
Dies bzgl. könntest du unter Raycasted Sphere Imposter googeln. Um recht performanten Shader Code zu finden.

Die 2. Lösung wäre die einfachere aber die 1. ist die Konsistente, wenn es um die Darstellung geht.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Sep 06, 2013 14:39 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Also die Idee mit der Sphere sollte theoretisch klappen, indem man einfach die "Höhe" der Vertices abfragt und je nach Ergebnis die unterschiedlichen Routinen für Seitenwand und Deckel fährt. Sprich Höhe für Deckel clampen und Radius für Seitenflächen. Jedoch müsste ich dafür wieder auf Triangles zurückgreifen und da gibt sich bei der Tesselierung halt das Problem der nicht parallel verlaufenden Primitive-Ränder. Das würde sich dann durch einen Zacken nach innen in der Silhouette äußern. Ist natürlich die Frage wie stark das überhaupt auffällt. Davon abgesehen würde man bei Dreiecken im Falle der Zylinder-Aussenkante auch eine Menge unnötiger Unterteilungen vornehmen im Gegensatz zu den Quads. Da ist dann halt die Frage wie stark die Performanceeinbuße oder der Performancegewinn gegenüber 2 Draw-Calls ausfällt. :/

MfG Der Tr0ll


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.033s | 17 Queries | GZIP : On ]