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

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

11

26.09.2011, 13:22

Warum dividierst du an einer Stelle durch 40?

Fnord42

Frischling

  • »Fnord42« ist der Autor dieses Themas

Beiträge: 18

Beruf: Student

  • Private Nachricht senden

12

26.09.2011, 13:29

Warum dividierst du an einer Stelle durch 40?
Da dies die maximale Entfernung vom Licht zu einer Vertexposition ist.
Beim Erstellen der Cubemap verwende ich eine Projektionsmatrix mit einem Far-Plane bei 40 um das Fragment auf eine Cubemapfläche zu projizieren.
Ich versuche damit die Entfernung vom Licht zur Vertexposition auf [0, 1] zu normieren.

Fnord42

Frischling

  • »Fnord42« ist der Autor dieses Themas

Beiträge: 18

Beruf: Student

  • Private Nachricht senden

13

26.09.2011, 14:44

Nochmal zussammenfassend, vielleicht wird es dadurch jemandem klarer wo das Problem genau liegt:

Beim Shadow-Map berechnen mach ich effektive folgendes: (sowohl (var_)vertex_pos als auch light_pos sind hierbei in Worldspace)

C-/C++-Quelltext

1
2
gl_Position = light_viewprojection_matrix * vertex_pos; // Für die viewprojection-matrix siehe letztes Codesnippet.
 gl_FragDepth = length(var_vertex_pos - light_pos) / max_distance;

max_distance ist hier die maximal mögliche Entfernung zwischen Lichtposition und Vertexposition in Worldspace und somit das Farplane das ich für die Projektion verwende (siehe unten für die Projektionsmatrizen).

Beim berechnen des Lichts mach ich dann effektiv folgendes: (auch hier sowohl (var_)vertex_pos als auch light_pos in Worldspace)

C-/C++-Quelltext

1
2
3
4
gl_Position = camera_mvp_matrix * vertex_pos;
 frag_depth = length(var_vertex_pos - light_pos) / max_distance;
 shadow_map_depth = texture(shadow_map, (var_vertex_pos - light_pos)).x;
 if (shadow_map_depth > frag_depth + 0.0005) is_in_light = 1.0;


Die Shadowmap initialisiere ich folgendermaßen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
glGenTextures(1, &m_shadow_depth_cubemap_id);
 glBindTexture(GL_TEXTURE_CUBE_MAP, m_shadow_depth_cubemap_id);
 glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
 for (char face = 0; face < 6; face++)
 {
   glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT32,
    1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
 }



Das sind die Projektionsmatrizen die ich verwende um auf die verschiedenen Flächen der Shadowcubemap zu projizieren:

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
//  Create Projection Matrix for the light, 90degrees, ratio 1:1, nearplane  0.1, farplane: 40.0 (this is the max_distance I use in my shaders).
 Mat4f light_proj_matrix;
 light_proj_matrix.set_projection(90.0, 1.0, 0.1, 40.0);
 
 // Create ViewProjection- and View-Matrices which are facing the cubemap-face from the lightpositions point of view.
 Mat4f light_vp_matrices[6];
 Mat4f light_v_matrices[6];
 for (size_t i = 0; i < 6; i++)
 {
   Vec3f cube_normal, cube_up;
   switch (i)
   {
    case 0: cube_normal.set( 1.0,  0.0,  0.0); cube_up.set( 0.0, -1.0,  0.0); break;
    case 1: cube_normal.set(-1.0,  0.0,  0.0); cube_up.set( 0.0, -1.0,  0.0); break;
    case 2: cube_normal.set( 0.0,  1.0,  0.0); cube_up.set( 0.0,  0.0,  1.0); break;
    case 3: cube_normal.set( 0.0, -1.0,  0.0); cube_up.set( 0.0,  0.0, -1.0); break;
    case 4: cube_normal.set( 0.0,  0.0,  1.0); cube_up.set( 0.0, -1.0,  0.0); break;
    case 5: cube_normal.set( 0.0,  0.0, -1.0); cube_up.set( 0.0, -1.0,  0.0); break;
   }
   // set_view(position, look_at_position, up_dir), just like gluLookAt
   light_v_matrices[i].set_view(light_position, light_position + cube_normal, cube_up);
   light_vp_matrices[i] = light_proj_matrix * light_v_matrices[i];
 }


Mir fällt beim besten Willen kein Fehler auf :(

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Fnord42« (26.09.2011, 15:00)


Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

14

26.09.2011, 14:48

Das sieht für mich auch aus, als ob es funktionieren müsste. Außer vielleicht, dass Deinem Schatten-Tiefenvergleich der else-Zweig fehlt, aber das ist sicher nur eine Kürzung für den Thread. Schnapp Dir mal ein Tool wie den gDebugger oder sowas und steppe mal durch eine Ausführung des finalen FragmentShaders. Vielleicht wird es dann klarer.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Fnord42

Frischling

  • »Fnord42« ist der Autor dieses Themas

Beiträge: 18

Beruf: Student

  • Private Nachricht senden

15

26.09.2011, 20:05

So, ich habe nun mein Testszenario etwas vereinfacht, so dass man das ganze optisch besser analysieren kann. Den gDebugger muss ich mir bei Zeiten auch mal anschauen aber ich glaub dafür brauch ich noch etwas Zeit.

(Link)


Eine Lichtquelle die sich im Moment in der Mitte der Debug-Skybox befindet und sich hin und her entlang der Achse bewegt in der sich die beiden großen Ebenen schneiden.
Dann zwei kleine Ebenen die Schatten auf die großen Ebenen werfen sollen.
Der Farbwert der Ebene entspricht dem Tiefenwert, den ich aus der Shadowmap erhalte.

Interessant dabei ist, dass meine Cubemap scheinbar doch falsche Tiefenwerte liefert.
Diese zwei Bilder zeigen die Lichtquelle an verschiedenen Positionen:

(Link)



(Link)


Eigentlich sollte wenn ich mich jetzt nicht verdenke, der nahste Punkt der auf der hinteren Ebene zu sehen ist (Mittelpunkt der Tiefenkreise) direkt unter der Lichtquelle liegen und nicht invariant zur Veränderung der Kameraposition sein.

Bei diesem Bild entspricht die Farbe nicht dem Wert aus der Shadowmap, sondern dem Vergleichswert den ich live im Beleuchtungsshader errechne.
Das vorherige Bild sollte eigentlich genau aussehen wie dieses, nur zusätzlich die Abbildungen der kleinen Ebenen auf den großen Ebenen enthalten.


(Link)


Sehr, sehr merkwürdig das Ganze ?(
Hat jemand eine Idee woran das liegen könnte?

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Fnord42« (26.09.2011, 20:14)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

16

26.09.2011, 22:14

Kannst du uns nicht eine Minimalversion zusammenstellen, die wir selber kompilieren können? ;)
Dann wäre es wesentlich einfacher zu helfen. So ist das ja nur ein Rumgestochere im Dunkeln.

Fnord42

Frischling

  • »Fnord42« ist der Autor dieses Themas

Beiträge: 18

Beruf: Student

  • Private Nachricht senden

17

26.09.2011, 23:13

kann ich machen, allerdings kann ich nur ein Projekt mit Unix-Makefiles zur Verfügung stellen, da ich bisher nur auf Linux programmiert habe.
Die libs die ich verwende sind allerdings alle Crossplatform-tauglich,
Abhängigkeiten würden wenn ich boost.serialization aus meinen Matheklassen entferne, dann eigentlich nur SDL sein.

Fnord42

Frischling

  • »Fnord42« ist der Autor dieses Themas

Beiträge: 18

Beruf: Student

  • Private Nachricht senden

18

27.09.2011, 01:28

Hier die Standalone-Version des Tests: http://dl.dropbox.com/u/12845003/ShadowTest.zip
Sieht auf den ersten Blick etwas durcheinander aus, da ich 2 eigene Libraries + die verschiedenen Module meiner Engine zerstückeln und zusammenschmeißen musste ;)
Einzige Abhängigkeiten sind GLEW und SDL (core-libs sollten ausreichen).

Sourcen:
ClientMain.cpp enthält die main()-Funktion.
Client.cpp/h initialisiert SDL, managed Keyboard/Mouse-Input und beinhaltet den SDL-Mainloop der die Engine clockt.
Engine.cpp/h enthält den gesamten OpenGL-spezifischen code, also das was in diesem Falle im Mittelpunkt steht.
*.cpx/*.hpx Dateien sind Teile meine Mathelib und werden alle in Math3D.h zusammengekleistert.
Math3DGlTypes.h enthält typedefs wie bspws Vec3f für Vec3<GLfloat>
Image.cpp/.h ist ein wrapper um stb_image.c/h, eine tolle unabängige, crossplattform C-Lib die verschiedene Bild-Formate laden kann, in nur eine Datei passt und unter CC steht.
Texture2D.cpp/.h kann Image's in/aus dem Hauptspeicher und dem Grakaspeicher laden.
ShaderProgram.cpp/.h ist mein Wrapper um die OpenGL-Shaderfunktionalitäten, der vorallem das Shader-Kompilieren schöner gestaltet
*.vs/*.fs sind meine Vertex- und Fragment-Shader, TextureLightning.fs beleuchtet stand4rtmäßig die Textur der Ebenen mit Hilfe der Shadowmap, am ende des Fragmentshaders sind noch 2 auskommentierte Zeilen mit denen man sich die Tiefenwerte rendern lassen (Graustufen-Bilder die ich bereits geposted habe).

Keys:
[ F11 ] Fullscreen
[ ESC ] Exit
[ W ], [ S ] vorwärts und rückwärts bewegen (meine Kameraansteuerung musste ich leider etwas verkrüppeln, aber die Funktionalität sollte ausreichen um sich alles anzusehen).
[ L ] toggelt die automatische Lichtbewegung
[ V ] toggelt zwischen Sicht aus Kamera- und Licht-Perspektive in Richtung unterhalb des Lichtes.

Ich hoffe das Kompilieren klappt :)

btw: ihr habt seltsame Zensurregeln: Ich durfte gerade nicht posten da ich "stand4rtmäßig" schreiben wollte ^^ hab ich mich nicht gepflegt genug ausgedrückt? :D

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »Fnord42« (27.09.2011, 01:40)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

19

27.09.2011, 01:33

Das liegt daran, dass es "standard" heißt ;)

Fnord42

Frischling

  • »Fnord42« ist der Autor dieses Themas

Beiträge: 18

Beruf: Student

  • Private Nachricht senden

20

27.09.2011, 01:39

Das liegt daran, dass es "standard" heißt ;)

lulz I haz failed ^^

Werbeanzeige