Hi Leute,
also mittlerweile haben sich ein paar offene Fragen angesammelt die ich aber fein dosiert in neue Themen packen will. ^^
Eines meiner Probleme ist, der Zugriff auf Objektdaten in der Objektmatrix. Wenn ich das richtig verstanden habe sind ja
in der Objektmatrix alle meine Objekte gerspeichert. Diese werden dann erst ausgegeben.
Wie kann ich denn die Daten aus einer Matrix auslesen um sie für mich zu nutzen und was steht in der Objektmatrix ?
Mir kommen da verschiedene Ideen zur Nutzung die ich gerne versuchen würde umzusetzen. Meiner Vorstellung nach
könnte man damit berechnen welches Objekt wo, wie im Schatten liegt und den Alphawert der Objekte in diesem Bereich
anpassen oder Wolken die in der Nähe der Sonne sind heller leuchten lassen ...
... aber wie haben all die Daten in einer 4x4 Matrix platz ?!
Da ich so ziemlich im Unklaren darüber bin wie die Matrix nun genau funktioniert konnte ich auch noch kein Frustum
Culling in meinen Projekt nutzen. Ich verstehe von dem Tutorial fast gar nichts. Finde da einige, von Schwierigkeitsgrad
als schwerer makierte Tutorials, viel einfacher. Ich verstehe auch nicht warum man die Matrizen multipliziert (vorallem die Art wie man sie multipliziert und später dann addiert und subtrahiert) und wie man dann darauf kommt das dort die
Objekte innerhalb des Frustums sind.
Frustum Culling Tutorial: http://wiki.delphigl.com/index.php/Tutorial_Frustum_Culling
Verweist mich übrigens bitte nicht auf das DGL Wiki. Ich verstehe die mathematische Erklärung dort ebenfalls nicht.
Mir wird mehr damit geholfen wenn man es versucht möglichst ohne Mathematik zu erklären (na gut, ein bisschen geht
schon ^^) oder an einem kleinen Beispiel den Sinn zu erklären, was nicht copy und paste bedeuten soll.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Zitat:
... aber wie haben all die Daten in einer 4x4 Matrix platz ?!
Haben sie nicht. Du hast da etwas missverstanden. In einer Matrix werden nur ein paar Werte abgespeichert. Und zwar die Rotation, Verschiebung und Skalierung.
Bei der Verarbeitung der neuen Vertexdaten wird jeder übergebene Vertex mit der ModelView Matrix multipliziert. Danach ist die Grafikkarte im Besitz einer absoluten Koordinate. Und diese dient dann dazu um die Dreiecke auf den Schirm zu bringen. Die Vertexdaten die du übergibst sind nur relativ gesehen. Erst mit der Matrix wird daraus eine wirklich absolute Weltkoordinate. Damit es möglich 2 Mal das gleiche Objekt zu zeichnen ohne jedes mal selber die wirklich absoluten Koordinaten errechnen zu müssen. So braucht man vorher nur eine Verschiebung (glTranslate) oder eine Rotation (glRotate) zu setzen und du erhältst 2 unterschiedliche Objekte obwohl du nur ein Mal das Objekt hast. Aber die Positionsbeschreibung ist unterschiedlich.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Das könnte für den ein oder anderen jetzt etwas abwegig werden - aber ich denke das geht in Ordnung.
Kennst du diese Automaten, wo du mit einem Greifarm Plüschtiere rausholen kannst?
Die Modelviewmatrix hab ich mir mal als so ein Greifarm vorgestellt. Allerdings in einem Automaten wo man was reintut, und der Greifarm positioniert meine eingaben (Vertex). Nehmen wir mal an, der Bildschirm (bzw. der Framebuffer) ist eine 2D Fläche in so einem Automaten. Du stehst vor dem Automaten und hast ein Teilchen (Vertex) in der Hand. Du steckst das Teilchen in einen Schlitz und der Greifarm legt es an der Stelle auf der Fläche ab wo es gerade hingehört. Wenn du das Teilchen wo anders haben willst, muss der Greifarm anders justiert werden. Das machst du mit glRotate,Scale,Translate.
Um nicht komplett abwegige Sachen zu erzählen kurz eine Zusammenfassung.
Die Matrizen sind keine Speicher für deine Vertexdaten. Es sind Werkzeuge die deine Daten transformieren (und zwar von deinen Positionsangaben in der GL Welt in Positionsangaben auf dem Bildschirm). Die Zahlen in der Matrix beschreiben nur wie die transformation ausfällt.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Danke für deine kreative Darstellung ^^, aber irgendwo muss das Ganze doch gespeichert werden. Wie funktionieren
denn sonst Shader die Schatten berechnen ? Die müssen doch auch "wissen" wo welches Objekt gezeichnet wird.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Das kommt darauf an, mit welchem Modus Du arbeitest. Wenn Du glBegin/glEnd ("Immediate Mode" = Sofortmodus) benutzt, werden die Daten, die Du an OpenGL schickst (Farben, Vertices, Texturkoordinaten) nur verarbeitet, aber nicht gespeichert. Als Ergebnis dieses Prozesses siehst Du ein Bild auf dem Bildschirm. Beim jedem Zeichenvorgang ("Frame") schickst Du die Daten alle nochmal.
Es gibt dann noch einen anderen Modus, in dem die Daten auf der Grafikkarte gespeichert werden und daher nicht dauernd vom Hauptspeicher in die Grafikkarte geschickt werden müssen. Wenn man nun mit dem immediate Mode arbeitet, hat man auf diese Vertices nur mehr einen begrenzten Einfluß, nämlich über den Matrizen. Begrenzter Einfluss deshalb, weil man damit zwar viel, aber nicht alles machen kann.
Mit den Matrizen werden die vorhandenen Daten nur manipuliert. Eine Matrix hat maximal 16 Gleitkommawerte. Da ließe sich nicht viel unterbringen.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Wo die Daten gespeichert sind spielt für deren Verarbeitung keine Rolle. Ankommende Vertices werden entweder an Shadern oder an eine fixe Funktion übergeben. Diese fixe Funktion wird aber auf neueren Systemen mittlerweile auch mit interenen Shadern gelöst. Die Shader kennen aber auch nur das betreffende Vertex (oder Fragment). Alles andere ist denen unbekannt.
Schatten werden häufig so gelöst, dass verschiedene Informationen aus der Sicht der Kamera gesammelt werden. Ich habe mich damit nie wirklich intensiv beschäftig weswegen ich das nachfolgende nicht zu genau nehmen würde. Gefährliches Halbwissen sozusagen. Bei Stencil Schatten werden diese Informationen glaube ich im Stencil Buffer gesammelt. Anhand der Informationen in diesem Buffer werden dann zusätzliche Flächen in die Szene eingefügt die einen Schatten erstellen.
Sascha Willems hat auf seiner Seite eine Demo mit dem Namen "Projective shadow mapping". In dieser wird aus Sicht der Kamera eine Textur erstellt die Tiefeninformationen enthält. Diese Textur wird dann zum Zeichnen benutzt und OpenGL erzeugt einen halbwegs anständigen Schatten. Sofern das Objekt sinnvoll in die Textur passt. Ob diese Technik allerdings überall gefahrlos eingesetzt werden kann und ob die überhaupt noch Zeitgemäß ist. Das ist eine ganz andere Frage. Denn was Schatten angeht gibt es in etwa jedes Jahr eine neue Technik die noch besser und einfacher ist. *hust*
Allerdings solltest du konkrete Fragen zum Thema Schatten haben, dann solltest du dein Thema entweder umbenennen oder ein neues Thema dazu machen. Denn ob die Schattenexperten ein Thema Verfolgen bei denen es um Matrixfragen geht wage ich mal zu bezweifeln.
Gut, es sollte jetzt eigentlich nicht unbedingt in die Thematik Schatten abweichen, obwohl mich das auch interessiert.
Denke aber, dass ich dafür (noch) zu wenig Grundwissen mitbringe um mit Shadern zu arbeiten. Ich wollte eigentlich
nur genauer wissen wie Frustum Culling funktioniert. Schließlich berechnet man ja dabei ob ein Objekt innerhalb des
sichtbaren Bereiches liegt. Man multipliziert erst die Matrizen, um sie dann zu subtrahieren und zu addieren.
Warum wird in dem Tutorial genau so vor gegangen ?
Also warum wird exakt Wert X mit Y multipliziert danach wieder mit Z und X subtrahiert usw. Ich verstehe halt die
ganze Vorgehensweise nicht. Da müssen doch die Daten irgendwo sein. Sonst würde das Ganze doch nicht funktionieren, oder ?!
Also im Spiel in dem Tutorial sind Projektionsmatrix P und Modelviewmatrix M. M beschreibt für gewöhnlich wie wie die Objekte in der Welt positioniert werden und wie sich die Kamera dazu verhält; die Proketionsmatrix dagegen, wie die charakteristik der kamera ist, etwa ob sie sich eher wie ein teleobketiv oder ein weitwinkel verhält oder eher ein schrägbild zeichnet... Jedenfalls wenn du z.B. ein Dreieck an OpenGl übergibst, dann werden zuerst P und M miteinander verrechnet und zwar so, daß zuerst die Verschiebungen, Skalierungen, etc. von M angewendet werden und dann die Projektion von P - man landet dann in irgendwelchen schönen koordinaten, die die Hardware dann als Pixelkoordinaten zum zeichnen verwendet. Hast Du z.B. ein Dreieck mit den drei vertices v1, v2, v3, dann wird gerechnet:
Code:
T := P*M /*Also erst M dann P anwenden wie beschrieben; heisst mathematisch Matrixmultiplikation */
v1' = T*v1 /*Anwenden der Matrix T auf das vertex */
v2' = T*v2
v3' = T*v3
Die Vertices v1', v2', v3' entsprechen dann schon fast pixelkoordinaten des dreiecks, wie es am bildschirm erscheint (stimmt nicht ganz, aber weit ist der weg nicht mehr). Jedenfalls bekommt die Grafikkarten diese drei Werte, Farbinformationen, etc. und beginnt sofort zu zeichnen; darauf werden v1', v2', v3' nicht mehr benötigt und gehen irgendwo im Bitnirwana des Grafikprozessors unter - sie werden nicht mehr anderswo abgelegt und stehen normalerweise dann auch nicht mehr zur verfügung; stattdessen wartet die grafikkarte auf die nächsten drei punkte um wieder ein dreieck zeichnen zu können. So in etwa läuft das spielchen, etwas vereinfacht ausgedrückt.
Jedenfalls passiert im Tutorial in der Funtktion TFrustum.Calculate erstmal die genannte Matrixmultiplikation (T heisst dort Clip); die schaut halt einfach genau so aus, kann man auch mathematisch begründen, warum sie genau so aussehen muss, führt hier aber zu weit. Jedenfalls stehen in T dann an bestimmten stellen Informationen darüber, wie der "Bildschirm" im Raum steht, wie die kamera vergrössert, etc. und das wird danach in den 6 Ebenen Frustum[...] abgelegt. Um Frustum Culling zu verwenden braucht man die genaue Rechnung nicht zu kennen; hab auch erst viel später en Detail verstanden, warum genau so. Das Frustum jedenfalls ist ein etwas deformierter quader, daher hat das ding 6 Ebenen. Die Ebenen sind so konstruiert, daß jede Mathematisch den Raum in zwei Hälften aufteilt: Eine Inneren und eine Äusseren Halbraum (schau mal "Hesse Normalform" in Wikipedia nach). Der Sichtbare Bereich ist dann genau der, in dem sich alle inneren Halbräume überschneiden; Das sieht man am besten in der Funktion TFrustum.IsPointWithin; die gibt nämlich genau dann false zurück, wenn sich der betrachtete punkt auf der aussenseite befindet (berechneter wert <= 0). Tatsächlich besagt dieser Wert noch mehr, nämlich wie weit der Punkt von der Ebene entfernt ist (Im Wikipediaartikel gibts eine Überschrift "Anwendung zur Abstandsberechnung"). Naja und wenn man den Abstand kennt, dann kann man auch kugeln testen....
Danke für die detaillierte Erklärung. Ich habe es zwar immer noch nicht ganz verstanden wie das Frustum aufgebaut
ist, aber ich denke mal, wenn ich mich länger damit beschäftige kommt mit der Zeit auch das erlösende "ah". ^^
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Falls du mit dem, sehr im Mathematikerslang geschriebenen, ersten Teil des Matrix Artikels probleme hast, hier ein kleiner Tipp: Bei Mathematikern ist der Text meist viel dichter mit Informationen belegt als in anderen Sprachen und außerdem sehr(!) präzise. (Also so, wie es Juristen gern wären )
Wenn man da zu schnell drüber wegließt (wie bei normalen Texten) bleibt am Ende bestenfalls die hälfte im Kopf und ein richtiges Verständnis kommt dabei nicht raus. So gehts jedenfalls mir. Satz für Satz durchdenken - so wird das was.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Mitglieder in diesem Forum: 0 Mitglieder und 8 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.