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

Aktuelle Zeit: Do Mär 28, 2024 15:57

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Perspektive Matrix
BeitragVerfasst: Di Mai 10, 2016 14:53 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 12, 2013 07:45
Beiträge: 61
Programmiersprache: Turbo Delphi 2006
Hallo,
ich habe mal wieder ein Problem.
Ich versuche mich in Richtung Ogl 3.3 zu bewegen. Dabei nutze ich learnopengl.com als grobe Richtung.
Die dort verwendete glm library ist in Pascal nicht nutzbar also muss ich die benötigte Funktionalität nachbauen.
Die Perspektive Matrix bringt mich da doch etwas zum grübeln. Ersteinmal findet man viele verschiedene Berechnungen dafür
und muss sich für eine entscheiden.
Als Szene nutze ich 5 sich drehende Würfel. Berechne ich die Szene mit zNear=1.0 und zFar=100.0 sieht alles super aus (1.Bild).
http://www.bilder-upload.eu/show.php?file=b33485-1462887532.jpg
Ändere ich ZNear auf 5.0 sieht es aus, als ob die Würfel sehr weit weg sind (2.Bild). Ich hätte erwartet, daß der ersten Würfel weggeschnitten wird da er näher als 5.0 ist.
Ist das so normal oder habe ich etwas übersehen?
Dann habe ich mal die Fenstergröße geändert. Breitgezogen (3.Bild) sieht gut aus aber beim einem hohen Fenster werden die Seiten der Szene beschnitten (4. Bild).
Das dürfte doch auch nicht passieren oder?


Hier Ausschnitte aus dem Programm:

Code:
  1. function CreatePerspektiveMatrix(const FOV,NPlane,FPlane :Single ; Width, Heigth :integer) : ToGLmatrix;
  2. var
  3.      cos, sin, CosSin, aspect1 : extended;
  4. begin
  5.      SinCos((FOV/2.0), sin, cos);
  6.      CosSin:=cos/sin;
  7.      aspect1:=(Heigth/Width);
  8.  
  9.      Result[0]  := aspect1*CosSin;
  10.      Result[1]  := 0;
  11.      Result[2]  := 0;
  12.      Result[3]  := 0;
  13.      Result[4]  := 0;
  14.      Result[5]  := CosSin;
  15.      Result[6]  := 0;
  16.      Result[7]  := 0;
  17.      Result[8]  := 0;
  18.      Result[9]  := 0;
  19.      Result[10] := (FPlane+NPlane)/(NPlane-FPlane);
  20.      Result[11] := -1;
  21.      Result[12] := 0;
  22.      Result[13] := 0;
  23.      Result[14] := ((2*FPlane*NPlane)/(NPlane-FPlane));
  24.      Result[15] := 0;
  25. end;
  26.  
  27. procedure SetViewport_OpenGL(w, h: Integer);
  28. begin
  29.   glViewport( 0, 0, w, h );
  30.   PerspekMatrix:=CreatePerspektiveMatrix((PI/4), 1.0, 100.0, w, h) ;
  31. end;
  32.  
  33. //   Übergabe an Shader   //
  34. glUniformMatrix4fv(glGetUniformLocation(MyShader, 'perspektive' ),1,GL_FALSE,PerspekMatrix);
  35.  



Und der VertexShader

Code:
  1. #version 330 core
  2.  
  3. layout (location = 10) in vec3 inPosition;
  4. layout (location = 11) in vec2 texCoord;
  5.  
  6. out vec2 TexCoord;
  7.  
  8. uniform mat4 transform;
  9. uniform mat4 perspektive;
  10.  
  11. void main()
  12. {
  13.     gl_Position =  vec4(inPosition, 1.0) * transform * perspektive;
  14.     TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
  15. }


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Di Mai 10, 2016 17:36 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Dass die Szene seitlich beschnitten wird, ist das zu erwartende Ergebnis. Den vertikalen Kamerawinkel gibst du ja mit PI/4 vor, der horizontale Winkel berechnet sich aus dem Seitenverhältnis des Fensters und wird dementsprechend klein, wenn das Fenster Hochkantformat hat.

CreatePerspektiveMatrix sieht gut aus, wobei mich eins irritiert (wohl aufgrund meiner mangelhaften Pascalkenntnisse):
Code:
  1. SinCos((FOV/2.0), sin, cos);
  • Sind die Bezeichner sin und cos nicht schon für Mathefunktionen reserviert? Das Syntaxhighlighting deutet darauf hin.
  • Tut SinCos das richtige und ist es richtig, die letzten beiden Parameter nicht als Referenz zu übergeben?
Wahrscheinlich hat beides seine Richtigkeit, aber nur um sicher zu gehen.

Im Shader fällt mir was anderes auf:
Code:
  1.     gl_Position =  vec4(inPosition, 1.0) * transform * perspektive;
Normalerweise multipliziert man im Shader keine Transformationsmatrizen miteinander. Stattdessen würde man transform und perspektive auf der CPU zu einer Matrix zusammenfassen und nur die als Uniform übergeben. Wenn du noch keine Matrixmultiplikation in Pascal implementiert hast, ist es aber ok (und eine gute Möglichkeit, zukünftig deine eigene Implementation durch Ergebnisvergleich auf Korrektheit zu testen).
In dieser Zeile würde ich auch den Fehler vermuten. Üblicherweise schreibt man etwas wie
Code:
  1. gl_Position =  zusammengefassteMatrix * vec4(inPosition, 1.0);
Also erst die Matrix, dann der Vektor. Wenn du die Reihenfolge vertauschst, hat das den selben Effekt als hättest du die Matrix vorher transponiert. Dies würde erklären, warum sich deine Würfel weiter weg bewegen statt näher zu kommen.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Di Mai 10, 2016 20:39 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Sind die Bezeichner sin und cos nicht schon für Mathefunktionen reserviert? Das Syntaxhighlighting deutet darauf hin.

Sie sind schon in der Unit System vorhanden, aber sie werden in der Function neu deklariert, somit ist dies keine Fehler.

Aber ich würde dies trotzdem nicht machen, wegen so etwas kann man Fehlersuchen bis zur Weissglut. :wink:

Was ich noch staune, die CreatePerspektiveMatrix hat sehr viele Result[?]:=0;

Ich habe auch mal eine Function dafür geschrieben, diese sieht aber einiges komplizierter aus.

Code:
  1. procedure SetFrustum(left, right, bottom, top, znear, zfar: glFloat);
  2. begin
  3.   FrustumMatrix := EinheitsMatrix;
  4.   FrustumMatrix[0, 0] := 2 * znear / (right - left);
  5.   FrustumMatrix[1, 1] := 2 * znear / (top - bottom);
  6.   FrustumMatrix[2, 0] := (right + left) / (right - left);
  7.   FrustumMatrix[2, 1] := (top + bottom) / (top - bottom);
  8.   FrustumMatrix[2, 2] := -(zfar + znear) / (zfar - znear);
  9.   FrustumMatrix[2, 3] := -1;
  10.   FrustumMatrix[3, 2] := -2 * zfar * znear / (zfar - znear);
  11.   FrustumMatrix[3, 3] := 0;
  12. end;  

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Di Mai 10, 2016 21:38 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
@mathias: Habe mir schon gedacht, dass man die Deklaration in einem eigenen Scope überschreiben kann. Das mit SinCos kommt mir trotzdem noch komisch vor - naja ich bin ja auch kein Pascaler.
Deine Prozedur SetFrustum macht etwas anderes. Twist reimplementiert gluPerspective, während deine Funktion glOrtho entspricht* (von der Matrixmultiplikation abgesehen).

*Edit: Nee, dein SetFrustum macht noch was anderes (siehe Matrixdarstellung im Wiki). Was machst du da eigentlich genau?

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Mi Mai 11, 2016 06:48 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 12, 2013 07:45
Beiträge: 61
Programmiersprache: Turbo Delphi 2006
Danke für die Antwort.

Zitat:
Den vertikalen Kamerawinkel gibst du ja mit PI/4 vor

Das war mir auch nicht so recht klar, in manchen Beschreibungen ist FOV der vertikale Winkel und in manchen der horizontale. Aber so kann man es austesten.

sincos berechnet gleichzeitig den sin und cos. Die Bezeichnungen sind unschön gewählt das stimmt.

Zitat:
Normalerweise multipliziert man im Shader keine Transformationsmatrizen miteinander.

In den Anleitungen basteln sie später einen Parallax-Mapping Shader und da benutzen sie alle Matrizen extra. Ich habe es mit meiner CPU-Matrixmultiplikation versucht - genau das gleiche.

Zitat:
Also erst die Matrix, dann der Vektor. Wenn du die Reihenfolge vertauschst, hat das den selben Effekt als hättest du die Matrix vorher transponiert.


Habe ich ausprobiert und ich musste alle Matrizen Transponieren um überhaupt etwas zu sehen. Das Ergebnis ist aber dann das Gleiche.

Ich brauche als zNear keine 5.0 oder so, es ist nur die Frage warum geht das nicht.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Mi Mai 11, 2016 16:32 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
In den Anleitungen basteln sie später einen Parallax-Mapping Shader und da benutzen sie alle Matrizen extra. Ich habe es mit meiner CPU-Matrixmultiplikation versucht - genau das gleiche.

Wen alles richtig ist, müsste das gleicher Ergebnis kommen, egal ob CPU oder GPU.
Das man die mit der CPU machen sollte hat einen anderen Grund, der Performance.
Wen man zB. eine Mesh mit 100 Dreiecken hat, wir dir Matrix mit der CPU 1x gerechnet, mit der GPU aber 300x.
Ich hoffe du verstehst was ich meine.


Zitat:
@mathias: Habe mir schon gedacht, dass man die Deklaration in einem eigenen Scope überschreiben kann. Das mit SinCos kommt mir trotzdem noch komisch vor - naja ich bin ja auch kein Pascaler.
Deine Prozedur SetFrustum macht etwas anderes. Twist reimplementiert gluPerspective, während deine Funktion glOrtho entspricht* (von der Matrixmultiplikation abgesehen).

*Edit: Nee, dein SetFrustum macht noch was anderes (siehe Matrixdarstellung im Wiki). Was machst du da eigentlich genau?


Die Ortho und Frustum - Berechnung siet ähnlich aus.
Vom Frustum habe ich eine Perspektive abgeleitet, in welcher das sin und cos vorkommt. Man könnte dies auch mit tan lösen, aber dann muss man die Unit Math einbinden.

Übrigens habe ich die Functionen aus dem Wiki geholt.

Code:
  1. procedure TMatrix.Ortho(left, right, bottom, top, znear, zfar: single);
  2. begin
  3.   Identity;
  4.   FMatrix[0, 0] := 2 / (right - left);
  5.   FMatrix[1, 1] := 2 / (top - bottom);
  6.   FMatrix[2, 2] := -2 / (zfar - znear);
  7.   FMatrix[3, 0] := -(right + left) / (right - left);
  8.   FMatrix[3, 1] := -(top + bottom) / (top - bottom);
  9.   FMatrix[3, 2] := -(zfar + znear) / (zfar - znear);
  10. end;
  11.  
  12. procedure TMatrix.Frustum(left, right, bottom, top, znear, zfar: single);
  13. begin
  14.   Identity;
  15.   FMatrix[0, 0] := 2 * znear / (right - left);
  16.   FMatrix[1, 1] := 2 * znear / (top - bottom);
  17.   FMatrix[2, 0] := (right + left) / (right - left);
  18.   FMatrix[2, 1] := (top + bottom) / (top - bottom);
  19.   FMatrix[2, 2] := -(zfar + znear) / (zfar - znear);
  20.   FMatrix[2, 3] := -1;
  21.   FMatrix[3, 2] := -2 * zfar * znear / (zfar - znear);
  22.   FMatrix[3, 3] := 0;
  23. end;
  24.  
  25. procedure TMatrix.Perspective(fovy, aspect, near, far: single);
  26. var
  27.   p, right, top: single;
  28. begin
  29.   p := fovy * Pi / 360;
  30.   top := near * (sin(p) / cos(p));
  31.   //  top := near * tan(p);
  32.   right := top * aspect;
  33.   Frustum(-right, right, -top, top, near, far);
  34. end;

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Di Jun 28, 2016 15:14 
Offline
DGL Member

Registriert: So Jun 12, 2016 13:05
Beiträge: 9
Programmiersprache: Lazarus 1.6.
Ich bin scheinbar am selben Punkt...die Transformationen des Objektes funktionieren, als nächstes wollt ich die Perspektive setzen..

ich hab mich daran gehalten http://www.mathematik.uni-marburg.de/~thormae/lectures/graphics1/graphics_6_1_ger_web.html#1

Code:
  1. function SetPerspektivMatrix(fovy, Width, Heigth, NPlane, FPlane: glFloat;
  2.   Perspektivmatrix: tMat44): tMat44;
  3. var
  4.    aspect : glFloat;
  5.    f : glFloat;
  6. begin
  7.    aspect:=Heigth/Width;
  8.    f:=cot(0.5*DegToRad(fovy));
  9.    PerspektivMatrix[0,0]:=f/aspect;PerspektivMatrix[1,0]:=0; PerspektivMatrix[2,0]:=0;                                               PerspektivMatrix[3,0]:=0;
  10.    PerspektivMatrix[0,1]:=0;         PerspektivMatrix[1,1]:=f;  PerspektivMatrix[2,1]:=0;                                               PerspektivMatrix[3,1]:=0;
  11.    PerspektivMatrix[0,2]:=0;         PerspektivMatrix[1,2]:=0;  PerspektivMatrix[2,2]:=((FPlane+NPlane)/(NPlane-FPlane));  PerspektivMatrix[3,2]:=((2*FPlane*NPlane)/(NPlane-FPlane));
  12.    PerspektivMatrix[0,3]:=0;         PerspektivMatrix[1,3]:=0;  PerspektivMatrix[2,3]:=-1;                                             PerspektivMatrix[3,3]:=0;
  13. result:=PerspektivMatrix;
  14. end;    


Code:
  1. //Perspektive setzen
  2.   PerspektivMatrix:=SetPerspektivMatrix(45,OpenGlControl1.Width,OpenGlControl1.Height,1,100,PerspektivMatrix);  


hier werden die Multiplikatonen durchgeführt

Code:
  1. function Solve_MV_Matrix(RotxMat, RotyMat, RotzMat, TransMat, Perspektive: tMat44): tMat44;
  2. var
  3.    temp: tMat44;
  4.    temp2 : tMat44;
  5.    temp3 : tMat44;
  6.    temp4 : tMat44;
  7. begin
  8.    temp:=MatrixMulti(RotXMat,RotYMat);
  9.    temp2:=MatrixMulti(Temp,RotZMat);
  10.    temp3:=MatrixMulti(temp2,TransMat);
  11.     temp4:=MatrixMulti(temp3,Perspektive);
  12. result:=temp4;
  13. end;    


und dann hier an den Shader übergeben
Zitat:
MatrixID := glGetUniformLocation(programID, 'MVP'); //ID der Uniform prüfen
glUniformMatrix4fv(MatrixID,1,false,@ModelViewMatrix); //matrix übergeben


wenn ich die Perspektivmatrix weglasse, seh ich was...ansonsten lediglich die Hintergrundfarbe :?:
Ich habs sowohl per Berechnung durch die CPU als auch im Shader probiert.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Di Jun 28, 2016 17:34 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
wenn ich die Perspektivmatrix weglasse, seh ich was...ansonsten lediglich die Hintergrundfarbe


Ich denke, du hast diesen beiden Parametern NPlane, FPlane zB. 1, 1000 übergeben.

Hast du deine Mesh mit Translate in den Bereich zwischen 1, 1000 verschoben ?
ZB auf -8.
Wen man dies nicht macht, wird auf Z 0 gerendert, also ausserhalb deines definierten Bereiches.

Dies ist ein Fehler den man gerne macht. :wink:

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Di Jun 28, 2016 18:14 
Offline
DGL Member

Registriert: So Jun 12, 2016 13:05
Beiträge: 9
Programmiersprache: Lazarus 1.6.
Code:
  1. Quad: array[0..1] of TFace =
  2.     (((-0.2, -0.6, -1.0), (-0.2, -0.1, -1.0), (0.2, -0.1, -1.0)),
  3.     ((-0.2, -0.6, -1.0), (0.2, -0.1, -1.0), (0.2, -0.6, -1.0)));  


Das ist der Testwürfel..also eine Seite davon :o
ich habe jetzt mal von Haus aus Z auf -1.0 gesetzt, da seh ich dann was..
im unten angehangen Bild probiere ich mich gerade, die Nummer mit den Matrizen zu verstehen..

wenn ich auf Translation Z Achse rummache, seh ich lediglich wenn ich bei 0 und 1 bin, alles andere macht das Bild leer....
Des Weiteren hab ich das Gefühl, dass vom "Gesamtbild" her irgendwie was nicht stimmt... :shock: :shock:


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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Perspektive Matrix
BeitragVerfasst: Di Jun 28, 2016 18:51 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Du muss nicht an deiner Mesh rumpasteln, sondern du muss die mit eine Matrix verschieben.

Im Anhang sieht man, das ich dies mit der Camera-Matrix gemacht habe.


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

_________________
OpenGL


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 13 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.087s | 17 Queries | GZIP : On ]