Registriert: Do Mär 05, 2009 20:17 Beiträge: 284 Wohnort: Kaiserslautern
Hallo,
ich hatte das Tutorial 8 (http://wiki.delphigl.com/index.php/Tutorial_Lektion_8) und dort ist kurz vor dem Ende die rede davon die Normalen zu glätten und es sind zwei Bilder eingefügt, ungeglättet und geglättet.
Da meine Daten so aussehen wie im oberen Bild (ungeglättet) habe ich mich nun daran gemacht zu versuchen, die normalen zu glätten:
dabei habe ich folgenden Ansatz versucht:
- die normalen der identischen vertices aufsteigend sortiert. - dann n0 mit n1 verglichen, ist der winkel zwischen den beiden < X dann werden beide in einen 0 vektor addiert. - danach wird n1 mit n2 verglichen, ist auch dieser winkel kleiner X wird n2 ebenfalls zum vektor addiert
bis der fall eintritt das der winkel größer ist oder das ende der normalenliste erreicht ist.
- in dem fall wird dann der aufaddierte vektor normalisiert und allen betroffenen vertices zugewiesen.
leider sieht mein ergebnis bei weitem nicht so schön aus wie im unteren beispielbild, nun frage ich mich ob die Qualität des unteren Bildes tatsächlich erreichbar ist und wenn ja, wie man da herangehen muß um das zu erzielen.
ich vermute ich habe einen denkfehler dahingehend, das ich am ende auch normalen hinzuaddiere die zu einem früheren knoten einen winkel > x haben.
also beispiel: x sei 2 grad, dann wäre mit einem winkel zwischen n0 und n1 von 1.5 der erste fall erfüllt. ist nun zwischen n1 und n2 der winkel auch 1.5 grad zähle ich diese zwar hinzu und damit wirkt sich das glätten auf den vertice von n0 aus, aber der winkel zwischen n0 und n2 kann 3° sein und würde eigentlich rausfallen.
ich hab nur keinen ansatz wie ich das abprüfen soll.
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Du solltest nie versuchen Vektoren in Winkel oder sowas zu berechnen! Lineare Algebra bietet meistens einfachere Methoden um sich sowas zu sparen.
Zum Normalenglätten gibt es eine einfache Lösung. Aktuell hast du eine Normale pro Fläche. Möchtest du diese glätten, brauchst du eine Normale pro Vertex, damit diese von Fläche zu Fläche übergehend interpoliert werden. Diese Vertexnormalen ergeben sich aus dem Mittelwert der Normalen der Flächen zu denen das Vertex gehört. Man Addiert also einfach die benötigten Flächennormalen zusammen und normalisiert das Ergebnis anschließend wieder. Und schon haste deine geglätteten Normalen.
Man muss also nichts bei den Winkeln beachten oder so. Das ist vollkommen irrelevant. Hoffe dir hats geholfen!
Registriert: Do Mär 05, 2009 20:17 Beiträge: 284 Wohnort: Kaiserslautern
Sellmann hat geschrieben:
Du solltest nie versuchen Vektoren in Winkel oder sowas zu berechnen! Lineare Algebra bietet meistens einfachere Methoden um sich sowas zu sparen.
Zum Normalenglätten gibt es eine einfache Lösung. Aktuell hast du eine Normale pro Fläche.
nein, ich habe eine normale pro vertex, die sind aber alle 3 pro fläche gleich im ausgangszustand. aber egal, vom prinzip läuft es auf das gleiche raus.
Sellmann hat geschrieben:
Möchtest du diese glätten, brauchst du eine Normale pro Vertex, damit diese von Fläche zu Fläche übergehend interpoliert werden. Diese Vertexnormalen ergeben sich aus dem Mittelwert der Normalen der Flächen zu denen das Vertex gehört. Man Addiert also einfach die benötigten Flächennormalen zusammen und normalisiert das Ergebnis anschließend wieder. Und schon haste deine geglätteten Normalen.Man muss also nichts bei den Winkeln beachten oder so. Das ist vollkommen irrelevant.
ok, wie schliesse ich bei dieser Methode das glätten von echten kanten aus? ich muß doch erstmal prüfen ob da nicht vielleicht ein 90° winkel gewollt ist, also muß ich doch auch schauen wie sich die winkel ändern.
ok, wie schliesse ich bei dieser Methode das glätten von echten kanten aus? ich muß doch erstmal prüfen ob da nicht vielleicht ein 90° winkel gewollt ist, also muß ich doch auch schauen wie sich die winkel ändern.
Bei komplexeren Objekten glättet man die Normalen bereits beim erstellen des Meshes im Modelingprogramm deiner Wahl. Üblicherweise kann man dort einfach Gruppen von Faces (Smoothing Groups) erstellen die geglättet werden. Ein weiterer Vorteil ist das auch gleich das Mesh mit Indices herauskommt. Also wenn sich mehrere Dreiecke einen Vertex teilen und sie zur selben Gruppe gehören muss der Vertex nur einmal gespeichert werden.
Eine andere Möglichkeit die auch mit Programmen funktioniert die keine Smoothing Groups unterstützen, bzw. dein Dateiformat das nicht kann, dann kannst du auch Einzel-Meshes benutzen. Also z.B. 3DS unterstützt ja mehrere Meshes in einer Datei. Jedes Mesh in dieser Datei ist einfach eine Gruppe. Alles wird zusammen in einen VBO gepackt und kann normal wie ein großes Mesh gerendert werden.
Registriert: Do Mär 05, 2009 20:17 Beiträge: 284 Wohnort: Kaiserslautern
Coolcat hat geschrieben:
Eine andere Möglichkeit die auch mit Programmen funktioniert die keine Smoothing Groups unterstützen, bzw. dein Dateiformat das nicht kann, dann kannst du auch Einzel-Meshes benutzen. Also z.B. 3DS unterstützt ja mehrere Meshes in einer Datei. Jedes Mesh in dieser Datei ist einfach eine Gruppe. Alles wird zusammen in einen VBO gepackt und kann normal wie ein großes Mesh gerendert werden.
dieser Fall liegt vor. Die Daten vorher besser zu designen liegt nicht in meiner Hand, da ich die Daten nicht erstelle sondern nur visualisiere.
im grunde habe ich ganz einfache dreiecksdaten, die nichtmal kanten als linien darstellen können - ich prüfe bereits alle nachbarkanten aller dreiecke auf winkligkeit und wenn der winkel >X ist, zeichne ich eine Kante, das funktioniert wunderbar.
nur beim Glätten habe ich irgendwie einen Knoten im Gehirn.
nur beim Glätten habe ich irgendwie einen Knoten im Gehirn.
Naja, du musst dir irgendwie diese Gruppen erstellen. Hier mal auf die schnelle etwas Code zum finden der Gruppen:
Die Idee ist halt jede Normale zu jeder Normale zu vergleichen. Ist der Winkel kleiner X werden die bestehenden Gruppen der beiden Dreiecke zusammengefasst. Dadurch bekommst du Transitivität. Also angenommen du betrachtest die Spitze eines Kegelstumpfs, dann werden die gegenüberliegende Dreiecke zusammengefasst, weil es dazwischen genug Verbindungsdreiecke gibt die unter dem Winkel X liegen.
Ich habe das gerade nur so runter geschrieben, also gut möglich, dass das nicht funzt. Und optimieren kann man sicher auch noch.
Code:
int group[N]; // die Gruppen ID für jedes Dreieck Vector3f normal[N]; Vector3f smoothnormal[N]; for (int i=0; i<N; ++i) { normal[i] = ...Normale von Dreieck i... }
// Gruppen suchen for (int i=0; i<N; ++i) { group[i] = i; for (int j=0; j<i; ++j) { if (dot(normal[i], normal[j]) < X) { for (int k=0; k<i; ++k) { if (group[k] == group[j]) { group[k] = i; } } } } }
// geglättete Normalen berechnen for (int i=0; i<N; ++i) { int grp = group[i]; smoothnormal[i] = Vector3f(0,0,0); for (int j=0; j<N; ++j) { if (grp == group[j]) { smoothnormal[i] += normal[j]; } } smoothnormal[i] = normalize(smoothnormal[i]); }
Mitglieder in diesem Forum: 0 Mitglieder und 8 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.