Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

12.12.2011, 19:19

Shadow Mapping #2

Hi, ich bräuchte mal wieder Hilfe mein shadow mapping einzubinden. Allerdings habe ich es "damals" mit dem OpenGL Matrix Stack implementiert.
Jetzt wollte ich das ganze in meine Engine einbauen, erstmal für directional lights, aber scheinbar ist das:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
    glPushMatrix();         
                        glTranslatef(object->getX(), object->getY(), object->getZ());
                        glScalef(object->getScale().x, object->getScale().y, object->getScale().z);
                        glRotatef(object->getXRotation(), 1, 0, 0);
                        glRotatef(object->getYRotation(), 0, 1, 0);
                        glRotatef(object->getZRotation(), 0, 0, 1);

                        mat4 m;
                        glGetFloatv(GL_MODELVIEW_MATRIX, m.getArray());
                    glPopMatrix();


Nicht gleich das:

C-/C++-Quelltext

1
2
3
4
5
6
     mat4 mod;
                    mod.translate(object->getX(), object->getY(), object->getZ());
                    mod.scale(object->getScale().x, object->getScale().y, object->getScale().z);
                    mod.rotate(object->getXRotation(), 1, 0, 0);
                    mod.rotate(object->getYRotation(), 0, 1, 0);
                    mod.rotate(object->getZRotation(), 0, 0, 1);


Und das meine Matrix implementation richtig rechnet habt ihr ja schon mehrfach gesehen. Vorher bekomme ich übrigens alle Matrizen genauso hin wie OpenGL sie liefern würde, nur hier nicht. Warum?
Die Shadow Matrix berechne ich so:

C-/C++-Quelltext

1
2
3
4
5
6
    mat4 bias = mat4(0.5, 0.0, 0.0, 0.0, // Shadowmapping bias-Matrix
                     0.0, 0.5, 0.0, 0.0,
                     0.0, 0.0, 0.5, 0.0,
                     0.5, 0.5, 0.5, 1.0);

mat4 shadowMatrix = bias*lightsource->getProjection()*lightsource->getModelview()*modelview.inverse();


Die modelview ist die transformierte Modelview Matrix der Kamera (welche als Ausgangsmatrix genommen wird).

Die Shader sehen so aus wie vorher und müssen funktionieren:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// VERTEX

// [...]
shadowCoord0 = shadow_matrix0*object_modelview*vec4(a_Vertex, 1.0); // vec4 an fragment shader
// [...]

// FRAGMENT

float shadowmapping(vec2 offset){
    return textureProj(shadowMap0,
                       shadowCoord0+vec4(offset.x*xPixelOffset*shadowCoord0.w, 
                                         offset.y*yPixelOffset*shadowCoord0.w,
                                         -0.005,
                                         0.0));
}

void main(void){    
    color = texture(texture0, texCoord0.st); // color = Ausgabe Pixel
    
    float shadow = 1.0;

    if(shadowCoord0.w > 0.0){
        float x, y;
        
        for(y = -1.5; y <= 1.5; y += 1.0){
            for(x = -1.5; x <= 1.5; x += 1.0){
                shadow += shadowmapping(vec2(x, y));
            }
        }

        shadow /= 16.0;
    }

    color *= shadow;
}


Die depth-Map wird auch richtig gerendert, ich hab sie mal Testweise auf das "Schachbrett" gerendert.
Das scheinbar einzige Problem ist die Matrix Berechnung von oben.

Bisheriges Ergebnis:


(Link)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

12.12.2011, 19:52

Stimmt denn die Multiplikationsreihenfolge dieser mod.Rotate(), Scale() etc. Methoden?
Was genau macht eine ModelView Matrix bei einer Lichtquelle, wie genau wird sie berechnet?
Wieso die inverse ModelView Matrix vom Objekt draufmultiplizieren, wenn du sie im Shader dann erst wieder wegrechnest?

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

3

12.12.2011, 19:53

Zitat


C-/C++-Quelltext

1
2
3
4
5
mod.translate(object->getX(), object->getY(), object->getZ());
                    mod.scale(object->getScale().x, object->getScale().y, object->getScale().z);
                    mod.rotate(object->getXRotation(), 1, 0, 0);
                    mod.rotate(object->getYRotation(), 0, 1, 0);
                    mod.rotate(object->getZRotation(), 0, 0, 1);


Vermutlich weisst du die Matrix bei jedem Methodenaufruf neu zu? OpenGL multipliziert die Matrix intern mit jedem Aufruf.
@D13_Dreinig

4

12.12.2011, 19:53

In OpenGL ist die Reihenfolge der Matrizenoperationen umgekehrt, als man es intuitiv erwarten würde (bzw. je nach dem, was man für eine Intuition hat). Stichwort "Matrizen rechts bzw. links dran multiplizieren".
Gut möglich also, dass du einfach nur die Reihenfolge deiner Matrizenmultiplikationen ändern musst.

[edit]Wow, das waren viele Antworten innerhalb einer Minute :D[/edit]
Lieber dumm fragen, als dumm bleiben!

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

5

13.12.2011, 16:00

Zitat

Stimmt denn die Multiplikationsreihenfolge dieser mod.Rotate(), Scale() etc. Methoden?


Immer mod*transformation also in rotate wird am Ende der Funktion dann this *= m; gerechnet, wobei in m die Rotationsmatrix steht. Das gleiche bei scale, translate, ...

Zitat

Was genau macht eine ModelView Matrix bei einer Lichtquelle, wie genau wird sie berechnet?


Das ist einfach die Modelview aus "Sicht" der Lichtquelle, also mit ihr werden die Objekte in den Kameraspace transformiert. Damit wird außerdem die Shadowmap gerendert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
mat4 bbLight::getModelview(){
    mat4 modelview = mat4();
    modelview.setIdentity();
    modelview.lookAt(m_information.position.x, m_information.position.y, m_information.position.z,
                     m_information.direction.x, m_information.direction.y, m_information.direction.z,
                     m_up.x, m_up.y, m_up.z);

    return modelview;
}


Zitat

Wieso die inverse ModelView Matrix vom Objekt draufmultiplizieren, wenn du sie im Shader dann erst wieder wegrechnest?


Das weiß ich auch nicht mehr, müsste ich jetzt nochmal im Tutorial nachschauen.

Zitat

Vermutlich weisst du die Matrix bei jedem Methodenaufruf neu zu?


Natürlich. Deswegen das mat4 mod;
Sie wird also neu erstellt, und nicht neu zugewiesen. Allerdings ist dies nur die "Vergleichsmatrix" um zu testen ob das gleich wie bei der OpenGL Version rauskommt.

Zitat

OpenGL multipliziert die Matrix intern mit jedem Aufruf.


Warum wird sie dann nicht immer größer und ich bekomme in meinem alten Programm das richtige Ergebnis?

Zitat

In OpenGL ist die Reihenfolge der Matrizenoperationen umgekehrt, als man es intuitiv erwarten würde (bzw. je nach dem, was man für eine Intuition hat). Stichwort "Matrizen rechts bzw. links dran multiplizieren".


Row oder Column Major ^^ das habe ich mit dot lang und breit durchgekaut. Daran wird es zumindest bei meinem mat4-struct sicher nicht liegen.

Zitat

Gut möglich also, dass du einfach nur die Reihenfolge deiner Matrizenmultiplikationen ändern musst.


Meinst du damit die "mat4 shadowMatrix = bias*lights..." Reihenfolge? Wenn ich das mache, also:

C-/C++-Quelltext

1
mat4 shadowMatrix = modelview.inverse()*lightsource->getModelview()*lightsource->getProjection()*bias;


Ist alles schwarz (da durch währe die Lichtquelle ja auch "unten").

-----------------------------

Hier nochmal das mat4 struct, bzw. die relevanten Funktionen daraus: http://cnp.marvinblum.de/index.php?id=49

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

6

13.12.2011, 18:01

Haha, ich liebe es wenn ihr ratlos seit :D
Nee Spaß. Warum steht in der OpenGL Matrix nach glPushMatrix() ... auslesen ... glPopMatrix() eigentlich etwas (also keine 0en)?
"Schiebe" ich dann nicht die aktuelle zurück und bekomme eine leere (vorausgesetzt es wurde noch nicht in diese geschrieben)?

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

7

13.12.2011, 18:18

Haha, ich liebe es wenn ihr ratlos seit :D


Vielleicht liegt es aber auch einfach an den Informationen die du lieferst...

Nee Spaß. Warum steht in der OpenGL Matrix nach glPushMatrix() ... auslesen ... glPopMatrix() eigentlich etwas (also keine 0en)?
"Schiebe" ich dann nicht die aktuelle zurück und bekomme eine leere (vorausgesetzt es wurde noch nicht in diese geschrieben)?


Nachdem du die aktuelle Matrix vom Stack geschoben hast, hat die neue (aktive) Matrix natürlich die Werte der Matrix die als nächste auf dem Stack liegt. Initial hat der Matrixstack genau einen Eintrag, nämlich die Identitätsmatrix. Wenn du versuchst diese vom Stack zu entfernen liefert OpenGL den Fehlercode GL_STACK_UNDERFLOW.
@D13_Dreinig

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

8

13.12.2011, 19:12

Zitat

Vielleicht liegt es aber auch einfach an den Informationen die du lieferst...


Ich finde meine Ausführungen genauer als die meisten die ich hier so sehe.

Zitat

Identitätsmatrix


Ist die nicht

1000
0100
0010
0001

? Weil bei mir kommt dann irgendwas mit 4.003219, bla bla wenn ich pushe und dann auslese. Irgendwie verstehe ich nicht wie GL jetzt auf die Matrix kommt mit der mein SM funktioniert hat...

[EDIT]

Mit "hier" oben meinte ich im Forum, nicht ausschließlich in diesem Thema.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

9

13.12.2011, 20:01

Oh, ich war gerade in Gedanken bei einer anderen Matrix, so hab ichs früher gemacht, ich will also nur die Kameramodelview haben:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, 1.0*windowSize[0]/windowSize[1], 0.1, 10000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(view[0], view[1], view[2],
              view[3], view[4], view[5],
              view[6], view[7], view[8]);

    mat4 bias = mat4(0.5, 0.0, 0.0, 0.0,
                     0.0, 0.5, 0.0, 0.0,
                     0.0, 0.0, 0.5, 0.0,
                     0.5, 0.5, 0.5, 1.0);

    mat4 modelview;
    glGetFloatv(GL_MODELVIEW_MATRIX, modelview.getArray());
    modelview.inverse();
    
    shadowMatrix = bias*ligProjection*ligModelview*modelview;


Das ist in der Hauptrenderfunktion von damals. Danach werden die Objekte gerendert und dieses einmal als "shadow_matrix" Uniform übergeben. Ich probier das mal gerade aus...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

10

13.12.2011, 20:06


(Link)


*hust* also gut, dann weiß ich schonmal ungefähr welche Matrix ich nachbilden muss, aber einer ne Idee woher die Streifen kommen? Kann das am Boden liegen der beim Licht mitgerendert wird? Eigentlich ja nicht...

[EDIT]

Es liegt natürlich an der Position der Lichtquelle, aber ein directionaler Schatten ist das sowieso nicht, kann man den überhaupt hinbekommen? Schließlich kann es sein das ich das Objekt mal am rechten/linken Rand der Lichtquellenkamera habe und somit der Schatten in unterschiedliche Richtungen zeigt, was bei einem Spotlight ganz gut ist, aber hier unerwünscht.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (13.12.2011, 20:24)


Werbeanzeige