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

Aktuelle Zeit: Do Jul 10, 2025 08:25

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



Ein neues Thema erstellen Auf das Thema antworten  [ 24 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Normalen auf TriangleFan
BeitragVerfasst: Di Jun 16, 2009 11:11 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Hi,
wie kann ich einem Trianglefan sinnvoll Normalen verpassen?
Also im Grunde fällt mir grad nur die Lösung ein, dass man allen einzlnen Flächen, aus denen sich der Fan zusammensetz, seperate Normalen verpasst, die man aus den Eckpunkten des jeweiligen Fanausschnitts berechnet.
Ich hab aber auch schoneinmal was gelesen, dass man die Normalen nicht pro Fläche sondern pro Vertex also praktisch pro Punkt berechent. Geht das bei einem Trianglefan? Dass ich pro Eckpunkt eine Normale berechne? Wenn ja aus, welchen Punkten berechne ich dann die Normale eines Eckpunktes?

Mein momentanes Problem ist eine Map, deren Felder allesamt aus seperaten Trianglefans je aus auch 8 Triangles bestehend aufgebaut sind. Jeder Fan bildet dabei ein Quadrat und wird von anderen Quadraten umgeben. Wahrscheinlich ist es noch am einfachsten, die Normale in der Mitte des Fans zu berechnen, weil die ja eine Kombination aus den Eckpunkten seien müsste. Aber wie berechne ich die Normalen an den Eckpunkten? Aus dem Mittelpunkt und den Mittelpunkten angerenzender Fans?

Hat da jemand schon mal was in der Richtung gemacht? Wäre für einige Denkanstöße sehr dankbar.
Danke


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 11:47 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Der übliche Ansatz zur Berechnung der Normale ist der folgende:

Hier wird einfach der Mittelwert der Normalen aller beteiligten Dreiecke berechnet.
Code:
  1. // (Pseudocode)
  2. forall (Vertex V : alle Vertices) begin
  3.     V.normal = (0,0,0);
  4. end;
  5. forall (Dreieck ABC : alle Dreiecke) begin
  6.     normal = Normalisieren(Kreuzprodukt(B-A, C-A));
  7.     A.normal += normal;
  8.     B.normal += normal;
  9.     C.normal += normal;
  10. end;
  11. forall (Vertex V : alle Vertices) begin
  12.     V.normal = Normalisieren(V.normal);
  13. end;


Das ist der einfache Ansatz. Es gibt auch einen Ansatz wo die Normalen gewichtet werden. Der Kreuzprodukt von zwei Vektoren ist um so größer, je größer der Winkel zwischen den beiden Vektoren ist. Das macht man sich hier zu nutze:

Code:
  1. // (Pseudocode)
  2. forall (Vertex V : alle Vertices) begin
  3.     V.normal = (0,0,0);
  4. end;
  5. forall (Dreieck ABC : alle Dreiecke) begin
  6.     A.normal += Kreuzprodukt(B-A, C-A);
  7.     B.normal += Kreuzprodukt(C-B, A-B);
  8.     C.normal += Kreuzprodukt(A-C, B-C);
  9. end;
  10. forall (Vertex V : alle Vertices) begin
  11.     V.normal = Normalisieren(V.normal);
  12. end;


Beide Ansätze funktionieren mit beliebigen Meshes, also nicht nur mit TriangleFans.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 12:42 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Ich hab das mal bei mir implementiert und was raus kommt, kann ich gar nicht richtig beschreiben, es sieht auf jedenfall sehr obskur und definitiv falsch aus:

Code:
  1.  
  2.         for (int i = 1; i < fieldCount; i++)
  3.             for (int j = 1; j < fieldCount; j++)
  4.             {
  5.                 gridData[i][j][NORMAL] = new Vector3f(0,0,0);
  6.                 gridData[i][j][NORMAL].AddVector(
  7.                         Vector3f.CrossProductVector(
  8.                                 Vector3f.SubtractVector(gridData[i-1][j-1][VECTOR], gridData[i][j][VECTOR]),
  9.                                 Vector3f.SubtractVector(gridData[i-1][j][VECTOR], gridData[i][j][VECTOR])));
  10.                 gridData[i][j][NORMAL].AddVector(
  11.                         Vector3f.CrossProductVector(
  12.                                 Vector3f.SubtractVector(gridData[i-1][j][VECTOR], gridData[i][j][VECTOR]),
  13.                                 Vector3f.SubtractVector(gridData[i-1][j+1][VECTOR], gridData[i][j][VECTOR])));
  14.                 gridData[i][j][NORMAL].AddVector(
  15.                         Vector3f.CrossProductVector(
  16.                                 Vector3f.SubtractVector(gridData[i-1][j+1][VECTOR], gridData[i][j][VECTOR]),
  17.                                 Vector3f.SubtractVector(gridData[i][j+1][VECTOR], gridData[i][j][VECTOR])));
  18.                 gridData[i][j][NORMAL].AddVector(
  19.                         Vector3f.CrossProductVector(
  20.                                 Vector3f.SubtractVector(gridData[i][j+1][VECTOR], gridData[i][j][VECTOR]),
  21.                                 Vector3f.SubtractVector(gridData[i+1][j+1][VECTOR], gridData[i][j][VECTOR])));
  22.                 gridData[i][j][NORMAL].AddVector(
  23.                         Vector3f.CrossProductVector(
  24.                                 Vector3f.SubtractVector(gridData[i+1][j+1][VECTOR], gridData[i][j][VECTOR]),
  25.                                 Vector3f.SubtractVector(gridData[i+1][j][VECTOR], gridData[i][j][VECTOR])));
  26.                 gridData[i][j][NORMAL].AddVector(
  27.                         Vector3f.CrossProductVector(
  28.                                 Vector3f.SubtractVector(gridData[i+1][j][VECTOR], gridData[i][j][VECTOR]),
  29.                                 Vector3f.SubtractVector(gridData[i+1][j-1][VECTOR], gridData[i][j][VECTOR])));
  30.                 gridData[i][j][NORMAL].AddVector(
  31.                         Vector3f.CrossProductVector(
  32.                                 Vector3f.SubtractVector(gridData[i+1][j-1][VECTOR], gridData[i][j][VECTOR]),
  33.                                 Vector3f.SubtractVector(gridData[i][j-1][VECTOR], gridData[i][j][VECTOR])));
  34.                 gridData[i][j][NORMAL].AddVector(
  35.                         Vector3f.CrossProductVector(
  36.                                 Vector3f.SubtractVector(gridData[i][j-1][VECTOR], gridData[i][j][VECTOR]),
  37.                                 Vector3f.SubtractVector(gridData[i-1][j-1][VECTOR], gridData[i][j][VECTOR])));
  38.                 gridData[i][j][NORMAL].Normalize();
  39.             }


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 13:53 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Hm, vielleicht irgendwo die Normale falschrum berechnet?

Screenshot wäre nicht schlecht. Du solltest wissen das diese Methode die Oberfläche rund aussehen lässt. Bei einem Würfel würde das dementsprechend grauenhaft aussehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 17:50 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Rund
Genau das wollte ich eigentlich haben. Ich dachte dabei aber eher an eine Abrundung der Scharfen Ecken der Dreiecksformationen wie zb im Octreetutorial.
Bei mir allerdings wirkt sich das irgendwie etwas anders aus:
Klick mich

Dieser Kreis ist tatsächlich ein Kreis, der sich auch irgendwie mitbewegt, wenn ich mich durch die Szene bewege. Die LightSource ist fix, aber je nach betrachtungswinkel ändert sich ja da auch die Beleuchtung. Also irgendetwas läuft da ziemlich schief ^^


Vielleicht mal etwas mehr Quellcode:
Ich lege die Basisdaten meiner Map fest (also die Vectoren jedes Punktes + Normale):
Code:
  1.  
  2.         gridData = new Vector3f[fieldCount+1][fieldCount+1][2];
  3.         fields = new GLField[fieldCount][fieldCount];
  4.    
  5.         Random random = new Random();
  6.        
  7.         for (int i = 0; i <= fieldCount; i++)
  8.             for (int j = 0; j <= fieldCount; j++)
  9.                 if (randomized)
  10.                     gridData[i][j][VECTOR] = new Vector3f(i*fieldSize,(float)random.nextInt(Math.round(height*variety))/100,j*fieldSize);
  11.                 else
  12.                     gridData[i][j][VECTOR] = new Vector3f(j,1,i+6);
  13.  
  14.  

Hier direkt schliesst sich dann die normalenberechnung an (siehe Quellcode oben)

Dann erzeuge ich logische Felder, die sich je aus 9 Punkten eben erzeugter Daten zusammensetzen und die Basis für einen Trianglefan darstellen:
Code:
  1.  
  2.         for (int i = 0; i < fieldCount; i=i+2)
  3.             for (int j = 0; j < fieldCount; j=j+2)
  4.             {                          
  5.                 fields[i][j] = new GLField(gridData[i][j], gridData[i][j+1], gridData[i][j+2],
  6.                         gridData[i+1][j], gridData[i+1][j+1], gridData[i+1][j+2],
  7.                         gridData[i+2][j], gridData[i+2][j+1],gridData[i+2][j+2],defaultTextureName);
  8.             }
  9.         }


Im Anschluss zeichne ich im Grunde nur noch die Trianglefans mit den zugehörigen Texturkoordinaten und Normalen

Also.. wo ist der Fehler^^


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 18:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Also dein Dreiecks-Netz sieht so aus wie auf dem Bild?

Wenn ja dann berechnest du die Normalen falsch. Du behandelst nämlich alle Vertices wie den grünen Vertex. Aber es gibt auch andere Vertices, nämlich solche die nur zu 4 Dreiecken gehören, siehe roter Punkt. Dort wären dann auch nur 4 Normalen auf zu summieren.
Andererseits sollte dieser Fehler nicht zu dem Bild führen welches du da bekommst.

Zitat:
Die LightSource ist fix, aber je nach betrachtungswinkel ändert sich ja da auch die Beleuchtung.

Dann ist der Fehler wahrscheinlich da irgendwo. Setze mal testweise alle normalen so, dass sie alle nach oben zeigen. Also wenn bei dir Y oben ist überall (0,1,0). Dann müsste alles die gleiche Helligkeit haben.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 10:10 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Okay es lag alles an fehlerhaftem C&P meines eigeen Quellcodes ^^ Deine Anmerkung bezüglich Roter Punkt ist gut und hab ich direkt mit übernommen
Danke


Zuletzt geändert von Shaddow am Mi Jun 17, 2009 10:25, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 10:20 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Sieht für mich so aus als hätten alle Vertices eines TriangleFans jeweils immer die gleiche Normale? Du musst die Normale wirklich für JEDEN Vertex einzelnen berechnen und dabei ALLE Dreiecke berücksichtigen die an diesen Vertex grenzen. Also auch die Dreiecke benachbarter TriangleFans.

Edit:
Ggf. ist es hilfreich sich die Normalen einfach mal zeichnen zu lassen. Einfach immer eine GL_LINE vom Vertex zu Vertex + Normale.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 10:41 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Also es ist doch noch nicht alles behoben ^^ Es sieht schon viel besser aus, aber an manchen Stellen treten Flecken auf
Ich habe daher mal die Normalen einzeichnen lassen.
Im ersten Bild sieht man die Dunklen Flecken ziemlich gut, die dort eigentlich rein Lichttechnisch nicht seien sollten
im zweiten Bild dazu die normalen:

Bild1
Bild1


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 10:58 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Sieht aus als würdest du jede zweite Normale falsch berechnen. Jedenfalls stehen die scheinbar alle senkrecht obwohl die umliegenden Normalen alle in eine Richtung geneigt sind. Vermutlich sind das entweder die Normalen mit 4 Dreiecken oder die mit 8 Dreiecken.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 11:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Tipp: Rendere doch mal dein Terrain als Wireframe, sinnvoller weise in einer anderen Farbe als die Normalen. Dann siehst du welche Normalen falsch sind.

Code:
  1. glColor3f(1,0,0);
  2. glLineWidth(1);
  3. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 13:57 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Jap ich habs grad nachgeschaut ;)

Es sind die 4er Normalen:
Code:
  1.  
  2.             gridData[i][j][NORMAL].AddVector(Vector3f.getNormal(gridData[i][j][VECTOR],
  3.                                                                 gridData[i-1][j  ][VECTOR],
  4.                                                                 gridData[i  ][j-1][VECTOR]));
  5.             gridData[i][j][NORMAL].AddVector(Vector3f.getNormal(gridData[i][j][VECTOR],
  6.                                                                 gridData[i  ][j-1][VECTOR],
  7.                                                                 gridData[i+1][j  ][VECTOR]));
  8.             gridData[i][j][NORMAL].AddVector(Vector3f.getNormal(gridData[i][j][VECTOR],
  9.                                                                 gridData[i+1][j  ][VECTOR],
  10.                                                                 gridData[i  ][j+1][VECTOR]));
  11.             gridData[i][j][NORMAL].AddVector(Vector3f.getNormal(gridData[i][j][VECTOR],
  12.                                                                 gridData[i  ][j+1][VECTOR],
  13.                                                                 gridData[i-1][j  ][VECTOR]));
  14.         //  gridData[i][j][NORMAL] = new Vector3f(0,1,0);
  15.  


Die auskommentierte Zeile hatte ich noch drin und sie war der grund für die gleichen Normalen. Ohne sie, bleibt die 4er Normale aber schwarz und wird auch nicht gezeichnet, also scheinbar null. Aber ich hätte angenommen, dass die berechnung so stimmt.

i ist die Reihe
j ist die Spalte

also ist i,j das mittelfeld
i-1,j das feld obenMitte
i,j-1 das feld mitteLinks
i+1,j das feld untenMitte
i,j+1 das feld mitteRechts

Im grunde genommen sollten die dreiecke sich doch so berechnen lassen..


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 14:07 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Sicher das die Normale immer 0 ist? Vielleicht ist sie einfach nur falsch rum und zeigt nach unten. Also testweise einfach mal
Code:
  1. gridData[i][j][NORMAL] = -gridData[i][j][NORMAL];

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 14:12 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Okay sie war tatsächlich negativ ;)

Wenn ich sie mit -1 skalieren, kommt das hier raus:Klick

Die Normalen sind da, die dunklen Flecken bleiben...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 14:19 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Die Normalen sehen merkwürdig flach aus. Oder ist diese Ansicht von oben? Könnte es sein das du vergessen hast zu normalisieren? (würde erklären warum die so flach aussehen...)

Kannst du mal Wireframe an machen? Auf dem Bild kann man nämlich absolut nicht erkennen wie das Terrain aussieht, man könnte es nur wenn die Beleuchtung funktioniert. ;)

Es wäre außerdem hilfreich zu sehen von wo das Licht kommt. Da am besten auch mal ein paar parallele Linien einzeichnen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 24 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 14 Queries | GZIP : On ]