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

Aktuelle Zeit: Fr Jul 04, 2025 18:49

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



Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Backface Culling
BeitragVerfasst: Sa Feb 07, 2009 21:58 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Hi,

ich habe mir einen Software Rasterizer geschrieben und dabei mehr oder weniger die OpenGL Pipeline übernommen, sprich für jedes Vertex wird zuerst ein VertexShader aufgerufen, dann wird der Frustum-Culling test gemacht, dann der Backface-Culling test.. dann wird gerastert, der DepthTest und final der PixelShader ausgeführt.

Soweit klappt das alles ganz gut, nur... beim Backface-Culling hab ich ein kleines problem.

Im prinzip macht man für den test ja einfach nur das punktprodukt zwischen der normalen und dem vektor von der kamera zum vertex.

Die normale transformiere ich mit der NormalMatrix (Transponierte, Invertierte Modelview), das Vertex mit der ModelviewProjectionMatrix.. im grunde sollte doch jetzt das Vertex (wenn man den vektor invertiert) der vektor Kamera->Vertex sein..

aber der Normal-Test klappt nicht... hab ich da nen denk fehler evtl?

Aya


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 07, 2009 22:12 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Mhh.. es scheint zu funktionieren wenn ich den vertex nur mit der ModelviewMatrix transformiere, nicht mit der ModelviewProjection Matrix..

aber das wäre doch eher unpraktisch, weil dann müßte ich es ja einmal mit der modelviewProjectionMatrix und dann nochmal separat mit der modelviewMatrix transformieren... wo ist da mein fehler? :/

Aya


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 07, 2009 22:36 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Im prinzip macht man für den test ja einfach nur das punktprodukt zwischen der normalen und dem vektor von der kamera zum vertex.

Wieso von der Kamera zum Vertex? Ein Face besteht aus 3 Vertices. Rechnest du da etwa mit interpolierten Vertexnormalen oder so?

Ich würde die Face-Normale nach der Transformation, also im Cliping-Space berechnen. Dann brauchst du auch nur die Z-Koordinate mit 0 vergleichen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 07, 2009 22:42 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Coolcat hat geschrieben:
Zitat:
Im prinzip macht man für den test ja einfach nur das punktprodukt zwischen der normalen und dem vektor von der kamera zum vertex.

Wieso von der Kamera zum Vertex? Ein Face besteht aus 3 Vertices. Rechnest du da etwa mit interpolierten Vertexnormalen oder so?

Ich würde die Face-Normale nach der Transformation, also im Cliping-Space berechnen. Dann brauchst du auch nur die Z-Koordinate mit 0 vergleichen.


Ich überprüfe jede vertex-normale vom dreieck, und sobald eine richtung kamera zeigt wird das dreieck gerastert.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 07, 2009 22:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ich würde mich an Face-Normalen halten. Geht ja auch schnell zu testen:

Code:
  1. drei Punkte: A,B,C
  2.  
  3. if ((Bx-Ax)*(Cy-Ay)-(By-Ay)*(Cx-Ax) <= 0) then ....

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 07, 2009 23:22 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Ne ich will schon die vertex-Normal nehmen, denn die vertices müßen nicht zwingend in der richtigen reihenfolge sein.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 07, 2009 23:58 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Wie willst du dann wissen was innen und was außen ist? Setzt du für jedes Vertex manuell die Normale?

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 00:00 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Flash hat geschrieben:
Wie willst du dann wissen was innen und was außen ist? Setzt du für jedes Vertex manuell die Normale?

Ja, tue ich :)
Jedes Vertex hat eine normale.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 02:46 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Ich dachte die Normalmatrix ist einfach nur die Modelviewmatrix ohne Translation, also einfach die 4te Spalte und/oder Zeile wie in der Einheitsmatrix.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 11:26 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
@Schläfer: Nein, die Matrix muss zuerst invertiert werden und dann nochmal transponiert werden. Allerdings gibt es einen (häufigen) Spezialfall, wo sich beide Operationen genau wegheben: Wenn es sich um eine orthonormal Basis handelt, also die drei Spaltenvektoren zueinander senkrecht stehen und zudem noch normalisiert sind, dann ist die transponierte Matrix gleich der Inversen: M * M^T = Id Kann man sich auch leicht überlegen, das Skalarprodukt der Spalten/Zeilen ist dann nämlich entweder 0 oder 1. Dieser Fall tritt z.B. dann auf wenn man nur Rotationsmatrizen verwendet. Sobald man aber skaliert oder gar eine Scherung macht funktioniert das nicht mehr.

Da die Herleitung so schnell geht kann man die auch nochmal machen :)

Also, wir haben eine Ebene (geg. durch Normale n) die wir mit einer Matrix M transformieren wollen. Es gilt:
n^T * p = 0 für alle Punkte p auf der Ebene, wir suchen die transformierte Ebene
n'^T * p' = 0
Punkte kann man leicht transformieren, einfach die Matrix M nehmen:
<=> n'^T * Mp = 0
wir suchen nun die Matrix Q für die Normale
<=> (Qn)^T * Mp = 0
<=> n^T * Q^T * M * p = 0
Der Vektor n^T * Q^T * M muss die gleiche Richtung haben wie n, sonst würde die Gleichung nicht stimmen. Also für einen konstanten Skalarierungsfaktor c gilt:
n^T * Q^T * M = n^T * c
Also muss gelten:
Q^T * M = Id * c
wobei Id die Einheitsmatrix ist. Da uns c egal ist, setzen wir das gleich 1 und können wir nun Q berechnen:
Q = ( M^(-1) )^T

Nach der Transformation mit Q sollte man Normalen erneut normalisieren.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 14:00 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Mein problem ist ja nicht wie ich die normal matrix berechne etc, sondern nur generell was zum culling-test benuzt wird.

Wie macht es den OpenGL?
Ein weiteres problem an der vertex-normal ist (ja auch bei OpenGL) das die ja im shader zwar durch die normal matrix transformiert wird, allerdings in der regel nur als varying weitergegeben wird.. entweder muß OpenGL hier nun nochmal selbst die normal transformieren für den normal test, oder es benutzt sie nicht.

Wenn ich die normal vom dreieck aus den drei eckpunkten berechne habe ich immernoch das problem mit dem zweiten vektor, ich habe dann eine normal "n" berechnet, aber wie bekomme ich nun den zweiten vektor für's punktprodukt?


Und wie ist das bei OpenGL, wenn ich ein triangle im uhrzeigersinn zeichne (also im grunde falschrum) wird es ja durch das backface-culling nicht gezeichnet, wenn ich aber jetzt via glNormal die normals der vertices anpasse, dann wird es korrekt.. sprich OpenGL muß auch irgendwie die normal dafür hernehmen.

Aya


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 14:23 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Und wie ist das bei OpenGL, wenn ich ein triangle im uhrzeigersinn zeichne (also im grunde falschrum) wird es ja durch das backface-culling nicht gezeichnet, wenn ich aber jetzt via glNormal die normals der vertices anpasse, dann wird es korrekt.. sprich OpenGL muß auch irgendwie die normal dafür hernehmen.

Du meinst du setzt im Vertexshader gl_Normal = -gl_Normal und das Culling wird umgedreht? Ich bin mir eigentlich ziemlich sicher das OpenGL die Normalen der Faces benutzt. Vertexnormalen sind nur für die Beleuchtung von Bedeutung. Insbesondere sollte gl_Normal im Vertexshader eigentlich read-only sein, zumindest steht das so hier.

Zitat:
aber wie bekomme ich nun den zweiten vektor für's punktprodukt?

Nach der perspektivischen Transformation sollte die Blickrichtung (0,0,-1) sein, ist jedenfalls ne Konvention. Entsprechend brauchst du nur testen ob die z-Koordinate deiner Face-Normale positiv oder negativ ist. Zudem brauchst auch nur die z-Koordinate der Face-Normale ausrechnen.
Ich bin mir gerade allerdings nicht sicher ob du die Face-Normale auch vor der Division durch w berechnen kannst. Da aber auch Cliping in der Pipeline vor dieser Division ist, müsste das eigentlich gehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 14:40 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
OpenGL schaut laut Spezifikation nur die Vertices im Window-Space an. Formel 2.6 auf Seite 63 in der OpenGL 2.0 Spezifikation. Siehe auch ersten Absatz des Abschnitts 3.5.1 auf Seite 108.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


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.009s | 15 Queries | GZIP : On ]