Registriert: Do Jun 22, 2006 19:13 Beiträge: 52 Wohnort: Lübeck
Hallo zusammen,
ich habe da ein 3D Model welches aus ganz vielen Polygonen besteht. Nehmen wir mal als Beispiel, das dieses Model ein Osterei ist. (passt ja gerade ganz gut)
Ich möchte nun "nur" eine Kontur von dem Ei darstellen. Nehmen wir an, dass das Ei senkrecht auf dem Boden steht. In der Senkrechten ist die Y in der Waagerechten die X und in der Tiefe die Z Achse.
Nun erstelle ich mir die Kontur, in dem ich zwei Clippingplanes so auf der Z Achse verschiebe, dass nur noch ein schmaler Ring zurückbleibt.
Nun mein Problem: Dieser Ring ist nun sehr fein gezeichnet (hat nur die Stärke 1. Die Dicke eines Polygons). Was habe ich nun für Möglichkeiten diesen ovalen Verlauf "dicker" aussehen zu lassen?
Meines Wissens nach hat man zwar die Möglichkeit Points und Lines jeweils mit einer Linen- oder Punktbreite "dicker" werden zu lassen, aber wie soll das mit Polygonen gehen? Geht meiner Meinung nach nicht, oder?
Eine Idee ist mir allerdings gekommen: Wenn ich quasi vom Ei Mittelpunkt mich um die Z Achse drehe und mir nun z.B. 360 mal per Selektion alle Positionen merke die durch den "Selektionsstrahl" getroffen wurden und an jeden der gemerkten Positionen einen dicken Punkt render, müsste ich eigentlich genau das erreicht haben was ich mir wünsche.
Aber ich bin davon überzeugt, dass das noch viel eleganter zu bewerkstelligen ist.
In zwei Schritten rendern: Das Objekt zuerst im Wireframemodus rendern und dann nochmal normal:
Code:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDepthRange(factor, 1.0); glLineWidth(3.0); // Objekt rendern glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDepthRange(0.0, 1.0); // Objekt nochmal rendern
Die Variable factor musst du ggf. etwas tunen, anfangen kannst du z.B. mit 0.01. glDepthRange verschiebt das gerenderte ein kleines Stückchen nach hinten damit der Z-Buffer keine Probleme macht. Wenn du Linien siehst wo keine sein sollen musst du factor größer machen.
Wireframe passt glaub ich nicht, da auch die "Wires" zwischen den Flächen gezeichnet werden. Nur die Silhouette zu rendern ist etwas schwerer.
Darum ja zweimal rendern und die Verwendung von glDepthRange. Die "Wires" werden ein kleines bisschen nach hinten verschoben, so dass die im nächsten Pass trotz Z-Buffer von der normalen Geometrie überzeichnet werden. Zurück bleibt nur die Silhouette.
Im ersten Pass werden die Kanten aller Polygone mit 3px dicken Linien gezeichnet. Nennt sich auch Wireframe-Modus. Durch das glDepthRange wird die Z-Achse vom Bereich 0...1 in den Bereich factor...1 gemappt, das Wireframe-Modell also ganz leicht von der Kamera weg geschoben. Im nächsten Pass wird dann das Objekt ganz normal drüber gezeichnet. Das funktioniert problemlos, da die Linien wie erwähnt jeweils ein kleines Stück zurückgesetzt wurden, also einen leicht größeren Z-Wert haben. Da die Linien 3px dick waren bleibt eine 1px dicke Silhouette zurück. Der innere Pixel und der Pixel in der Mitte wird übermalt. Ohne das glDepthRange würde es in den meisten Fällen ebenfalls funktionieren, allerdings können dann kleine Rundungsfehler (Z-Fighting) dazuführen, dass die Linien nicht vollständig übermalt werden und hässliche Artefakte zurückbleiben.
Das erwähnte Cell-Shading ist so was ähnliches wie das von mir vorgeschlagene Toon-Shading. Ich kenne mich damit aber nicht sonderlich aus, es wäre möglich das es einfach nur eine andere Bezeichnung für das gleiche ist.
Registriert: So Jun 23, 2002 12:37 Beiträge: 144
Programmiersprache: C/C++, Delphi
Wäre es nicht eine ganz einfache Lösung einfach auf den Tiefenpuffer einen Kantenfilter (Sobel-Faltungskern o.ä. ohne Edge-Thinning) anzuwenden und bei Bedarf über einen Grenzwert festzulegen ob feine Konturen im Anschluss rausgefiltert werden sollen? Anschließend natürlich nocheinmal das ganz Bildschirmfüllen über die Szene zeichnen, et voilà...
Bei den Normalen sehe ich irgendwie keine vernünftige Möglichkeit die Kantendicke festzulegen.
Registriert: So Jun 23, 2002 12:37 Beiträge: 144
Programmiersprache: C/C++, Delphi
"Einfach" würde heißen, ein zusätzliches Offscreen-Rendering und ich behaupte, dass der zuzätzliche Aufwand für die Grafikkarte mit einem zusätzlichen Pixelshader minimal ist
Im Grunde liefe das ganze so ab: 1. Tiefenpuffer in eine Textur kopieren. 2. Textur Bildschirmfüllend auf ein Quad mappen. 3. Mit aktiviertem Sobel Faltungspixelshader rendern. (In dem Shader Programm kann dann ja alles wichtige ablaufen: Faltung, Filtern v. Rauschen/feiner Konturen, Alphablending)
Damit hätte man auch direkt die Konturen wirklich aller Objekte durch einen Postprocessing-Effekt und müsste nicht den Code in soweit anpassen, als das u.U. alle Rendermethoden angepasst werden müssten um die Objekte doppelt zu zeichnen.
@EnORItZ: Deine Variante setzt voraus das alle Objekte eine Silhouette bekommen sollen. Die Frage ist ob das überhaupt gewünscht ist. Vielleicht will Coolman1974 ja nur ein gerade selektiertes Objekt hervorheben? Wenn man aber wirklich alles mit einer Silhouette umfassen möchte ist ein Postprocessing-Effekt natürlich eine gute Idee, sofern den Shader eine Option sind.
Registriert: Di Sep 06, 2005 18:34 Beiträge: 362 Wohnort: Hamburg
hab da auch noch meinen senf dazu zu geben Ich hab bis jetzt 3 Möglichkeiten genutzt Silhouetten zu zeichnen. schaust du hier Die 1. Methode ist die von Coolcat beschriebene, wobei man sie auch mit einem pixeloffset realisieren kann glaube ich (ich mag die funktion aber nicht). Die 2. Methode funktioniert mit dem Stencilbuffer. Diese finde ich für die meisten Sachen am besten. Die 3. Methode ist dann auch für Cellshading zu gebrauchen. Hier wird praktisch jede Linie selber berechnet, wodurch nicht nur eine reine Silhouette gezeichnet werden kann.
_________________ Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Würdest du das fürs Wiki Spnsorn? Die Bilder sind schön, und die Erklärung auch. Und ein Beispiel hast du auch. Ist quasi perfekt. Darfst da ruhig auch DICK deinen Namen drunter schreiben.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Mitglieder in diesem Forum: 0 Mitglieder und 4 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.