Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
OpenglerF hat geschrieben:
Ich habe gerade so im Kopf, dass man Normalen mit der transponierten inversen Matrix multiplizieren muss.
Wenn die Matrix nur Rotation enthält, ist das Inverse = die transponierte Matrix. Bei Translation gilt das für den 3x3-Teil afaik immer noch. Insofern sollte das klappen (ich mach's in meinen Programmen genau so).
Edit: Ich habe mal von WolframAlpha eine Matrix mit Translation und Rotation invertieren lassen: [url]https://www.wolframalpha.com/input/?i=inverse+{{x1%2Cx2%2Cx3%2Ca}%2C{y1%2Cy2%2Cy3%2Cb}%2C{z1%2Cz2%2Cz3%2Cc}%2C{0%2C0%2C0%2C1}}[/url] Wie man sieht, steckt im 3x3-Teil nichts von der Translation drin.
mathias hat geschrieben:
Was kommt in inNormal?
Ein Normalenvektor (auch Normale) ist ein Vektor der Länge 1, welcher Senkrecht auf der Oberfläche steht, die du beschreiben willst. Zur Bestimmung der Normale n eines Dreiecks (A,B,C) gibt es folgende Formel: n = normalize(cross(B-A, C-A));
Du benötigst die Normalen aber nicht pro Dreieck, sondern pro Vertex. Du kannst natürlich jedem Vertex eines Dreiecks den gleichen Normalenvektor geben. Dann sehen die Kanten hart aus (wie echte Kanten eben). Bei einem Würfel wäre das erwünscht. Bei runden Körpern dagegen i.d.R. nicht. Hier sollte man die Normalen aller an den Vertex grenzenden Dreiecke interpolieren (und anschließend normalisieren!), damit es "smooth" aussieht.
Diese Berechnungen führst du einmal auf der CPU aus und lädst sie dann in den VBO. Oder du lädst deine Modelle direkt aus Dateien, in denen schon Normalenvektoren gespeichert sind. Das war übrigens alles auch schon vor OpenGL3 nötig (nur um OGL3 jetzt nicht in unnötig schlechtes Licht zu stellen).
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Kann man die Normale so berechnen, ich hab dies aus einem alten OpenGlProgramm kopiert. Es gibt eine Farbänderung auf dem Würfel, aber so nach richtigem Licht sieht dies nicht aus.
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Die Funktion NormalCut tut nichts weiter, als einen Vektor zu normalisieren (auf Länge 1 kürzen). Die andere Funktion sieht nicht so geeignet aus. Sie erzeugt Normalenvektoren, die nicht senkrecht auf den Flächen stehen, sondern diagonal von den Ecken weg (unter der Voraussetzung, dass es sich um einen Würfel mit (0,0,0) als Mittelpunkt handelt). Auf diesem Weg würde man Normalenvektoren einer Kugel erzeugen, da sie keine harten Kanten bringt.
Die Normalen eines an den Achsen ausgerichteten Würfels sind so einfach, dass du sie im Prinzip per Hand eintragen kannst. Die "rechte" Seite bekommt (1,0,0), die "linke" entsprechend (-1,0,0). Für oben/unten machst du das gleiche mit der Y-Achse und für vorne/hinten hast setzt du die Z-Achse analog.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Ja, eine Normale pro Vertex.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Sieht auf den ersten Blick ganz gut aus. Nicht benutzte Variablen optimiert der Treiber einfach weg. Wenn du LightColor nicht reinmultiplizierst, wird das Licht halt weiß.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Stimmt schon: Das Indices bei 0 anfangen, sollte man sich möglichst früh angewöhnen. Alles Verbreitete was nicht aus der VB Welt stammt, arbeitet mit dem Basisindex 0. OpenGL zum Beispiel aber auch alle anderen Programmbibliotheken. Außerdem ist ab 0 vom Code her meist eleganter/kürzer und entspricht der Abbildung in Maschninencode. Es ist halt einfach unkonsistent mal gezwungener Maßen mit 0 zu rechnen und dann wieder mit 1. Und dann manchmal umzurechnen. Wenn es am Shader scheitert, mein schon genannter Geheimtipp: Einfach die zwischen Ergebnisse ausgeben lassen und schauen ob sie mit den Erwarteten übereinstimmen. Debugger gibt es für GLSL im Gegensatz zu HLSL in DirectX leider praktisch keinen Brauchbaren, deshalb muss man sich so behelfen.
Zuletzt geändert von OpenglerF am Di Dez 17, 2013 20:25, insgesamt 1-mal geändert.
Da war der Fehler begraben. Da der Compiler bei der ersten Zeile eine Fehlermeldung gab, habe ich folgendes geschrieben:
Code:
Position =vec3(meinMatrix)* inPos;
Normal =mat3(meinMatrix)* inNormal;
anstelle
Code:
Position =mat3(meinMatrix)* inPos;
Normal =mat3(meinMatrix)* inNormal;
Die rechte Seite des Würfels hat eine falsche Farbe. Soviel ich weis kann man dies verbessern, in dem man beim Zeichen eines Dreiecks auf die Drehrichtung der Eckpunkte achtet.
Zitat:
und lass deine Arrays mal bei 0 anfangen, das ist üblich in c/c++/pascal/delphi/asm/c#/d .... 1 ist eher vba/vb6...
Ne, das kann irgendwie nicht sein. Die Inverse errechnet sich relativ kompliziert, wie es auch auf Wikipedia steht. Das hat nichts mit dem transponieren zu tun. Auf Wolframalpha komme ich übrigens zu dem Ergebnis im Anhang. Wenn das überall steht wird das schon seinen Sinn haben.
Ob das mit Translation für den 3x3-Teil immer noch gilt, da bin ich mir nicht 100%ig sicher. Jedoch hatte ich damit bisher noch keine Probleme. Wolframalpha zeigt außerdem, dass die Translation auf den 3x3-Teil keinen Einfluss hat - oder siehst du dort irgendein a, b oder c?
Bei Skalierung funktioniert das natürlich so nicht mehr.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Achso, reine Rotation, dass kann sein. Normalerweise ist halt noch mindestens Skalierung darauf. Und in eher seltenen Fällen auch manchmal noch Scherung. Translation ist bei Normalvektoren ohnehin nicht angebracht. Das macht nur bei Positionsvektoren Sinn.
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Weil meinMatrix eine 4x4-Matrix ist. Damit kannst du nur 4-komponentige Vektoren transformieren. Also musst du erst inPos in einen vec4 umwandeln. Bei der Matrixtransformation kommt wieder ein vec4 raus. Dich interessieren aber nur die ersten 3 Komponenten. Deshalb die erneute Umwandlung nach vec3.
Wie die Multiplikation im Detail funktioniert, wird hier recht anschaulich gezeigt und mit etwas Überlegung kannst du dir daraus erschließen, warum man mit einer 4x4-Matrix nur einen vec4 mutliplizieren kann.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Mitglieder in diesem Forum: 0 Mitglieder und 40 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.