Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Ich implementiere gerade einige generierte Körper. Kugel, Kegel, Cylinder, etc. Da es eigentlich nichts mit OpenGL zu tuen hat, hab ichs mal ins Mathe-Forum gepackt.
Beim Kegel bin ich nun über ein Beleuchtungsproblem gestolpert. In der Skizze (Kegel im Profil) kann man auf der linken Seite, die eigentlich richtigen Normalen sehen. Dies führt allerdings dazu, dass beim Beleuchten hässliche Kanten entstehen. (siehe kegel.jpg) Wenn ich die Normalen so setze wie auf der rechten Seite der Skizze, dann funktioniert die Beleuchtung zwar, aber sie ist eigentlich nicht korrekt, da der Kegel nicht bis zur Spitze beleuchtet wird. Die Licht-Richtung ist übrigens (1,0,0).
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Das müsste eigentlich ganz leicht gehen. Wenn du n Dreiecke für den Mantel hast, brauchst du an der Spitze auch n verschiedene Normalenvektoren, die in jeweils unterschiedliche Richtungen zeigen, damit die Spitze auch wie ein solche aussieht.
Auf der Kreisseite hingegen solltest du für benachbarte Dreiecke jeweils gemeinsame (interpolierte) Normalenvektoren verwenden, damit der Kegel rund aussieht.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
glAwesome hat geschrieben:
Wenn du n Dreiecke für den Mantel hast, brauchst du an der Spitze auch n verschiedene Normalenvektoren, die in jeweils unterschiedliche Richtungen zeigen, damit die Spitze auch wie ein solche aussieht.
Ja. Genau das mache ich ja auf der linken Seite. Das Problem ist das Interpolieren, da die Spitze zwar mehrere Normalen hat aber kein benachbarter Vertex mit dem interpoliert werden kann. Daher ja auch die Kanten.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Wen du Zylinder, Kegel etc. zeichnen willst, neheme ich an, das du eine Kreistabelle verwendest, dieser Wert der Tabelle ist gleich der Normale.
Genau dies will ich als nächstes in mein Programm einbauen, aus diesem Grund habe ich mir heute Gedanken darüber gemacht, nur leider komme ich heute nicht mehr dazu.
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Deine Frage ist viel schwieriger, als sie zunächst scheint.
Nach einiger Überlegung bin ich zu dem Schluss gekommen, dass die Ursache des Problems in der Art der Vertex-Interpolation von OpenGL liegt. Eigentlich will man über die gesamte Fläche eines Dreiecks nur die beiden Normalen des unteren Randes interpolieren. Leider hat aber auch der Vertex an der Spitze Einfluss bei der Interpolation, was zu den von dir beschriebenen Effekten führt.
Dies könnte man beheben, wenn man statt Dreiecken Quads nähme, bei denen je zwei Ecken in der Spitze liegen. Dabei müssten die beiden Ecken in der Spitze verschiedene Normalenvektoren haben. Quads sind aber deprecated. Es bleiben also nur noch die Holzhammer-Methode (mehr Vertices) oder die Berechnung der Normalen im Fragmentshader (damit umgeht man die Interpolation), was aber weniger universell einsetzbar ist.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Zitat:
Deine Frage ist viel schwieriger, als sie zunächst scheint.
Habe auch schon ein paar extra Runden unter der Dusche gestanden. Da hab ich immer die Besten Ideen.
Zitat:
Dies könnte man beheben, wenn man statt Dreiecken Quads nähme, bei denen je zwei Ecken in der Spitze liegen.
Das habe ich schon versucht. Quads sind ja eigentlich 2 Dreiecke. Wenn man also 2 Dreiecke zeichnet, wird das eine an der Stelle des ursprünglichen Dreiecks gezeichnet und das andere wird zu einer Linie. Bringt also effektiv nichts. Außer, dass das VBO größer ist.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
on error goto next
Zuletzt geändert von damadmax am Sa Feb 01, 2014 17:10, insgesamt 1-mal geändert.
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Dass dies so ist, wenn man GL_QUADS mit GL_TRIANGLES emuliert, ist mir klar. Gilt das auch, wenn man wirklich GL_QUADS nimmt?
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Soweit ich weiss werden die doch intern sowieso in Triangles umgewandelt?
[edit]Ich habs gerade mal ausprobiert. Bei einem Quad wird zwischen den Vertices 1 und 3 unterteilt. Sprich: 1,2,3 und 1,3,4 bilden die neuen Dreiecke. Man sieht das ganz gut wenn man das Quad z.b. in der XZ Ebene zeichnet und bei einem Vertex die Y-Komponente variiert.[/edit]
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
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.