DGL
https://delphigl.com/forum/

Nachbildung von ModelView und Projection
https://delphigl.com/forum/viewtopic.php?f=20&t=9003
Seite 1 von 1

Autor:  Shaddow [ So Feb 07, 2010 21:49 ]
Betreff des Beitrags:  Nachbildung von ModelView und Projection

Hallo, mithilfe von Shadern versuche ich gerade die OGL Matrizen nachzubilden, die ja bei WebGL nimmer existieren. Ich dachte eigentlich, ich hätte das schon hinbekommen, bin nun aber auf ein Phänomen gestoßen, dass mich daran heftig zweifeln lässt.

Die WebGL Demo lässt sich hier ansehen: www.stayinaction.de/webGL/WebCore.html

Für die, die es sich aufgrund des fehlenden Browser nicht ansehen können, versuch ichs kurz zu beschreiben. Ein Viereck, das etwas in den Raum gekippt ist, und sich um sich selbst (um die Y-Achse) dreht. Dabei erweckt es bei der Drehung den Eindruck, als wäre es in Richtung des Betrachters und von ihm weg abgeschnitten. Gerade so, als würde Near oder Farclipping sehr niedrig eingestellt sein und das Viereck dadurch abschneiden. Allerdings steht nearclipping auf 0.1 und farclipping auf 1000.

Hier mal der Code für den Shader:
Code:
  1.  
  2. vertex:
  3.     attribute vec3 aPosition;
  4.     attribute vec3 aNormal;
  5.     attribute vec2 aTexCoord;
  6.     varying vec3 vNormal;
  7.     varying vec2 vTexCoord;
  8.     uniform vec4 uMyColor;
  9.     varying vec4 vColor;
  10.     uniform mat4 uModelView;
  11.     uniform mat4 uPerspective;
  12.     void main() {
  13.         gl_Position = uModelView * vec4(aPosition, 1.0);
  14.         vTexCoord = aTexCoord;
  15.         vNormal = aNormal;
  16.        vColor = uMyColor;
  17.     }
  18.    
  19. fragment:
  20.     varying vec3 vNormal;
  21.     varying vec2 vTexCoord;
  22.     uniform sampler2D uTexture;
  23.     uniform vec4 uMyColor;
  24.     void main() {
  25.         gl_FragColor = texture2D(uTexture, vTexCoord);
  26.     }


Ich nehme mal an das meine Modelview stimmt, allerdings weiss ich nicht genau, wie ich nun die Projection mit einrechne. Wird die einfach in der Multiplikation, in der die Modelview stattfindet, mit eingerechnet?
Irgendwie steh cih da etwas auf dem Schlauch
Oder brauch ich überhaupt eine Projectionmatrix?

Autor:  Coolcat [ Mo Feb 08, 2010 00:20 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Zitat:
Oder brauch ich überhaupt eine Projectionmatrix?

Naja...jein....wie du siehst bekommst du ja ein Bild, allerdings ist das nur eine orthogonale Projektion. D.h. die Szene wird einfach nur so gedreht das du in Richtung der Z-Achse blickst, dann wird die Z-Koordinate einfach weggelassen. Für eine perspektivische Projektion musst du aber durch Z teilen. Das ist es was die Projektionsmatrix macht (*). Near- und FarPlane sind in der Projektionsmatrix, deswegen hat das hier keine Wirkung.

Also vermutlich willst du sowas hier:
Code:
  1. gl_Position = uModelView * uPerspective * vec4(aPosition, 1.0);


Allerdings solltest du die beiden Matrizen vorher selbst multiplizieren, damit das nicht für jeden Vertex neu gemacht werden muss:
Code:
  1. gl_Position = uModelViewProjection * vec4(aPosition, 1.0);



(*) natürlich kann man mit einer Matrix keine Division ausführen, aber dafür gibt es die vierte Koordinate ("w"). Diese Koordinate wird einfach als Nenner genutzt, die Grafikkarte teilt später einfach alle Koordinaten durch w so das man wieder bei (x,y,z,1) landet.

Autor:  Shaddow [ Mo Feb 08, 2010 09:38 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Okay sowas hatte ich mir gedacht. Also dass ich modelview und projection multiplizieren muss. Allerdings gab das kein ergebnis (alles ist schwarz)

Hierzu der Code: (vertex)
Code:
  1.     attribute vec3 aPosition;
  2.     attribute vec3 aNormal;
  3.     attribute vec2 aTexCoord;
  4.     varying vec3 vNormal;
  5.     varying vec2 vTexCoord;
  6.     uniform vec4 uMyColor;
  7.     varying vec4 vColor;
  8.     uniform mat4 uModelView;
  9.     uniform mat4 uProjection;
  10.     uniform mat4 uModelViewProjection;
  11.     void main() {
  12.         gl_Position = uModelViewProjection * vec4(aPosition, 1.0);
  13.         vTexCoord = aTexCoord;
  14.         vNormal = aNormal;
  15.         vColor = uMyColor;
  16.     }


Die uModelViewProjection wird als Multiplikation von uModelView und uModelViewProjection errechnet.
Code:
  1.  
  2.     public Matrix multiply(Matrix m) {
  3.         return new Matrix(
  4.             (_00*m._00 + _01*m._10 + _02*m._20 + _03*m._30),
  5.             (_00*m._01 + _01*m._11 + _02*m._21 + _03*m._31),
  6.             (_00*m._02 + _01*m._12 + _02*m._22 + _03*m._32),
  7.             (_00*m._03 + _01*m._13 + _02*m._23 + _03*m._33),
  8.  
  9.             (_10*m._00 + _11*m._10 + _12*m._20 + _13*m._30),
  10.             (_10*m._01 + _11*m._11 + _12*m._21 + _13*m._31),
  11.             (_10*m._02 + _11*m._12 + _12*m._22 + _13*m._32),
  12.             (_10*m._03 + _11*m._13 + _12*m._23 + _13*m._33),
  13.  
  14.             (_20*m._00 + _21*m._10 + _22*m._20 + _23*m._30),
  15.             (_20*m._01 + _21*m._11 + _22*m._21 + _23*m._31),
  16.             (_20*m._02 + _21*m._12 + _22*m._22 + _23*m._32),
  17.             (_20*m._03 + _21*m._13 + _22*m._23 + _23*m._33),
  18.  
  19.             (_30*m._00 + _31*m._10 + _32*m._20 + _33*m._30),
  20.             (_30*m._01 + _31*m._11 + _32*m._21 + _33*m._31),
  21.             (_30*m._02 + _31*m._12 + _32*m._22 + _33*m._32),
  22.             (_30*m._03 + _31*m._13 + _32*m._23 + _33*m._33)
  23.         );
  24.     }


Die Errechnung der Projection:
Code:
  1.     public static Matrix createPerspectiveMatrix(double fovy, double aspect, double zNear, double zFar)
  2. {
  3.         fovy *= Math.PI / 180.0;
  4.         double f = Math.tan(Math.PI/2.0 - fovy/2.0);
  5.         return new Matrix( f/aspect, 0, 0,  0,
  6.                                   0, f, 0,  0,
  7.                                   0, 0, (zFar+zNear)/(zNear-zFar), -1,
  8.                                   0, 0, (2*zFar*zNear)/(zNear-zFar),  0);
  9.     }


Es bleibt nun leider alles schwarz.

Autor:  Coolcat [ Mo Feb 08, 2010 10:48 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Hm, also das sollte so funktionieren. Multiplizierst du vielleicht falschrum? Deine Multiplikations-Methode sieht zwar korrekt aus, aber vielleicht rechnest du Projection * ModelView statt ModelView * Projection?

Ansonsten kann es natürlich sein das die Uniforms falsch gesetzt sind. Einige Grafiktreiber bekommen Probleme wenn Uniforms nicht genutzt werden. Der Compiler wirft sie nämlich aus dem Code während der Treiber das nicht mitbekommt. Danach stimmten dann die Indices nicht mehr überein.

Autor:  Shaddow [ Mo Feb 08, 2010 11:02 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Dass das folgende nicht sonderlich sinnvoll/performant ist, ist mir bewusst, aber geht ja grad nur um den Test:
Code:
  1.  
  2.         gl.uniformMatrix4fv(gl.getUniformLocation(program, "uModelView"), false, Renderer.getInstance().getCamera().getView());
  3.         gl.uniformMatrix4fv(gl.getUniformLocation(program, "uProjection"), false, Renderer.getInstance().getCamera().getProjection());
  4.         gl.uniformMatrix4fv(gl.getUniformLocation(program, "uModelViewProjection"), false, Renderer.getInstance().getCamera().getView().multiply(Renderer.getInstance().getCamera().getProjection()));
  5.  


So setze ich die drei Matrizen

Autor:  Coolcat [ Mo Feb 08, 2010 11:09 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Die ersten beiden werden vom Shader nicht genutzt und daher vom Compiler entfernt. Daher könnte gl.getUniformLocation(program, "uModelViewProjection") einen falschen Rückgabewert liefern.

Autor:  Shaddow [ Mo Feb 08, 2010 11:15 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Mh okay ich habe die ersten beiden Uniforms escaped und analog auch im Shader die Deklarationen rausgeschmissen. Es gibt jetzt also nur noch uModelViewProjection. Das Resultat bleibt aber weiterhin schwarz

Autor:  TAK2004 [ Mi Feb 10, 2010 09:12 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Code:
  1. #Vertex
  2. #version 130
  3.  
  4. uniform mat4 ProjectionMatrix;
  5. uniform mat4 ModelviewMatrix;
  6.  
  7. in vec4 Vertex;
  8. in vec4 Color;
  9.  
  10. void main(void)
  11. {
  12.   gl_Position=ProjectionMatrix*ModelviewMatrix*Vertex;
  13.   gl_FrontColor=Color;
  14. }
  15.  
  16. #Fragment
  17. #version 130
  18.  
  19. out vec4 gl_FragColor;
  20.  
  21. void main(void)
  22. {
  23.   gl_FragColor=gl_Color;
  24. }


Du berechnestdie position falsch, hab mal ein passenden OpenGL2 und 3 fähigen basis shader mit gepostet.

Code:
  1. void ProjectionMatrix::SetDefaultProjectionMatrix()
  2. {
  3.   for (int i=0;i<16;i++)
  4.     m_ProjectionMatrix[i]=0.0f;
  5.   float f=1.0f/tan(m_FieldOfView/2.0);
  6.   float neg_depth=m_Near-m_Far;
  7.   m_ProjectionMatrix[0]=f/m_AspectRatio;
  8.   m_ProjectionMatrix[5]=f;
  9.   m_ProjectionMatrix[10]=(m_Far+m_Near)/neg_depth;
  10.   m_ProjectionMatrix[11]=-1.0f;
  11.   m_ProjectionMatrix[14]=(2.0*m_Far*m_Near)/neg_depth;
  12. }


Ich empfehle dir eher FieldOfView in Gradmaß zu nutzen statt Bogenmaß, dann kannst du LoadIdentity einer Modelview Matrix mit obiger funktion erreichen und sparst dir das ständige hin und her rechnen.

Autor:  Coolcat [ Mi Feb 10, 2010 11:30 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

@TAK2004:
Warum berechnet er die Position falsch? Projection*Modelview? Es heißt doch nicht grundlos ModelViewProjection und nicht ProjectionModelView.

Übrigens benutzt er WebGL, daher würde ein "#version 130" dazu führen das der Shader nicht funktioniert, da die erst bei 1.0 sind.

@Shaddow:
Wie konvertierst du deine Matrix in WebGLFloatArray? Bei mir sieht das so aus:
Code:
  1.     /** convert matrix row-wise into an native JavaScript array. */
  2.     public native JsArrayNumber toArray() /*-{
  3.         return [
  4.             this.@com.delphigl.wgt.math.Matrix44d::_00,
  5.             this.@com.delphigl.wgt.math.Matrix44d::_01,
  6.             this.@com.delphigl.wgt.math.Matrix44d::_02,
  7.             this.@com.delphigl.wgt.math.Matrix44d::_03,
  8.             this.@com.delphigl.wgt.math.Matrix44d::_10,
  9.             this.@com.delphigl.wgt.math.Matrix44d::_11,
  10.             this.@com.delphigl.wgt.math.Matrix44d::_12,
  11.             this.@com.delphigl.wgt.math.Matrix44d::_13,
  12.             this.@com.delphigl.wgt.math.Matrix44d::_20,
  13.             this.@com.delphigl.wgt.math.Matrix44d::_21,
  14.             this.@com.delphigl.wgt.math.Matrix44d::_22,
  15.             this.@com.delphigl.wgt.math.Matrix44d::_23,
  16.             this.@com.delphigl.wgt.math.Matrix44d::_30,
  17.             this.@com.delphigl.wgt.math.Matrix44d::_31,
  18.             this.@com.delphigl.wgt.math.Matrix44d::_32,
  19.             this.@com.delphigl.wgt.math.Matrix44d::_33
  20.         ];
  21.     }-*/;

Autor:  TAK2004 [ Mi Feb 10, 2010 12:27 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Aus den namen zu schliessen, wie die Multiplikation vor sich geht ist gewagt und auch falsch.

Als erstes wird die ModelviewMatrix mit den Vertex und der daraus resultierende Vektor mit der Projektionsmatrix multipliziert.
2D Pos=(Proj*Model*Vert).xy;
Wenn ich im Shader Model*Proj*Vert umstelle bekomme ich ein schwarzen Bildschirm und die Werte sind völliger murks.
Ein OpenGL ES und OpenGL3 equivalent zu gl_ModelViewProjectionMatrix ist folgender "mat4 mvp_matrix = u_proj_matrix * u_model_matrix;" und ist in recht rar verstreuten Dokus sowie Beispielen zu finden.
Daher funktioniert auch das oben und es steht übrigens auch im wiki http://wiki.delphigl.com/index.php/Tutorial_OpenGL3_Lineare_Algebra#Vom_Vektor_zur_Bildschirmkoordinate.
Dieses Thema(ersetzung der Funktionspipeline) ist recht ätzend, da die Doku zu der Thematik quasi nicht existent ist und man nur durch leute die das bereits gemacht haben(opengl software renderer) an passende Infos kommt.
edit:gl_NormalMatrix nach zu bilden hatte mich auch ein weile beschäftigt, bis ich das funktionstüchtig hatte.

Autor:  Coolcat [ Mi Feb 10, 2010 12:39 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Zitat:
Aus den namen zu schliessen, wie die Multiplikation vor sich geht ist gewagt und auch falsch.

Eigentlich nicht, den bei mir funktioniert das ;) Es liegt daran ob die Matrizen transponiert sind oder nicht, denn es gilt:
Code:
  1. A*B = (B^T * A^T)^T


Deswegen ja auch die Frage an Shaddow wie er die Matrizen übergibt bzw. wie die Matrix aussieht. Bei mir wird die Translation z.B. so gebildet:
Code:
  1.     /** creates a translation matrix. */
  2.     public static Matrix44d translation(double x, double y, double z) {
  3.         return new Matrix44d( 1, 0, 0, 0,
  4.                               0, 1, 0, 0,
  5.                               0, 0, 1, 0,
  6.                               x, y, z, 1  );
  7.     }

Autor:  TAK2004 [ Mi Feb 10, 2010 12:59 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Wenn ich natürlich alle Matrizen Row based rein gebe dann funktioniert das, aufgrund der Eigenschafften mit OpenGL ES und OpenGL3 aber nicht mit OpenGL unter Version 3.(steht auch in der OpenGL.org FAQ). Dies wird ja auch als großes Feature von OpenGL3 genannt, dass man nun die ganze umwandlungsproblematik sparen kann, wenn man Direct3D und OpenGL3 renderer verwendet.

Autor:  Shaddow [ Di Mär 02, 2010 11:22 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Sorry dank Klausurenphase 5. Semester bin ich zum Programmieren gar nicht gekommen. Erstmal danke für die Antworten ^^

Soo nun aber:
Coolcat hat geschrieben:
Wie konvertierst du deine Matrix in WebGLFloatArray? Bei mir sieht das so aus:
Code:
  1.     /** convert matrix row-wise into an native JavaScript array. */
  2.     public native JsArrayNumber toArray() /*-{
  3.         return [
  4.             this.@com.delphigl.wgt.math.Matrix44d::_00,
  5.             this.@com.delphigl.wgt.math.Matrix44d::_01,
  6.             this.@com.delphigl.wgt.math.Matrix44d::_02,
  7.             this.@com.delphigl.wgt.math.Matrix44d::_03,
  8.             this.@com.delphigl.wgt.math.Matrix44d::_10,
  9.             this.@com.delphigl.wgt.math.Matrix44d::_11,
  10.             this.@com.delphigl.wgt.math.Matrix44d::_12,
  11.             this.@com.delphigl.wgt.math.Matrix44d::_13,
  12.             this.@com.delphigl.wgt.math.Matrix44d::_20,
  13.             this.@com.delphigl.wgt.math.Matrix44d::_21,
  14.             this.@com.delphigl.wgt.math.Matrix44d::_22,
  15.             this.@com.delphigl.wgt.math.Matrix44d::_23,
  16.             this.@com.delphigl.wgt.math.Matrix44d::_30,
  17.             this.@com.delphigl.wgt.math.Matrix44d::_31,
  18.             this.@com.delphigl.wgt.math.Matrix44d::_32,
  19.             this.@com.delphigl.wgt.math.Matrix44d::_33
  20.         ];
  21.     }-*/;


Meine Erzeugung sieht ziemlich gleich aus:
Code:
  1.  
  2.     public native JsArrayNumber toArray() /*-{
  3.         return [
  4.         ];
  5.     }-*/;  
  6.    

Autor:  Shaddow [ Mo Mär 08, 2010 14:08 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Habs immernoch nich hinbekommen. Irgendwelche Ideen?

Autor:  Coolcat [ Do Apr 01, 2010 12:54 ]
Betreff des Beitrags:  Re: Nachbildung von ModelView und Projection

Das Problem wurde mittlerweile via PM gelöst. Es lag an einer kaputten Projektionsmatrix.

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/