Probleme bei Konvertierung von World zu Screen Koordinaten
-
Hallo,
ich bin gerade dabei simple Screen Space Reflections einer in der Szene befindlichen Ebene zu implementieren. Dazu berechne ich zuerst die Normale der Ebene und den Sichtvektor des aktuellen Fragments, und berechne meinen Sample Strahl durch Reflektion des Sichtvektors an der Normale in World Koordinaten.
Jetzt versuche ich mir aus der World Position des aktuellen Fragments und des Strahlvektors die für 2D Ray Tracing nötigen Informationen in Screen Koordinaten zu berechnen. Mein Ansatz ist folgender:const vec4 RayStartV = gl_ModelViewMatrix * vec4(PositionWorld, 1.0); const vec4 RayDirV = gl_ModelViewMatrix * vec4(RayDirection * SceneDepth, 0.0); const vec4 RayEndV = RayStartV + RayDirV; const vec4 RayStartClip = gl_ProjectionMatrix * RayStartV; const vec4 RayEndClip = gl_ProjectionMatrix * RayEndV; const vec3 RayStartScreen = RayStartClip.xyz / RayStartClip.w; const vec3 RayEndScreen = RayEndClip.xyz / RayEndClip.w;
Die Matrizen, World Position und die Ray Direction (in World Space) sind aufjedenfall korrekt berechnet. Dennoch sieht mein 2D Strahl irgendwie falsch aus. Ich möchte das mal an zwei Bildergalarien demonstrieren:
Die Kamera wird nur in z-Richtung bewegt (oben und unten), an der Reflektion ändert sich rein gar nichts.
Ich translatiere meine Eben mithilfe einer Multiplikation an die ModelView Matrix (das Ergebnis ist zu 99,99% korrekt), die Reflektion sieht vollkommen falsch aus.Hat irgendwer eine Idee wo mein Problem liegen könnte?
-
Das Problem mit der Translation habe ich gelöst bekommen. Meine berechnung von RayDirection war doch nicht ganz korrekt wenn ich in die Ebene eine Translation eingebracht habe
Ich habe den ganzen Shader jetzt nochmal durch Debuggen geprüft und bin jetzt wirklich sicher, dass alle Ausgangswerte für das Ray Tracing korrekt sind. Da ich meine Ebene jetzt translatieren konnte, kann ich mein eigentliches Problem jetzt nochmal besser beschreiben.
Hier zwei Bilder der aktuellen Lage. Wie man sieht, ist an der Stelle wie die Reflektion sein sollte ein "Schatten". In dem anderen Bild sieht man exemplarisch das Ergebnis eines Strahls.
Ich kann mir das Ergebnis nicht wirklich erklären. Wie kommt es dazu?
Hier meine Methode die ich zum Ray Tracen benutze:const vec4 RayStartV = gl_ModelViewMatrix * vec4(vertex, 1.0); const vec4 RayDirV = gl_ModelViewMatrix * vec4(RayDirection, 0.0); const vec4 RayEndV = RayStartV + RayDirV; const vec4 RayStartClip = gl_ProjectionMatrix * RayStartV; const vec4 RayEndClip = gl_ProjectionMatrix * RayEndV; const vec3 RayStartScreen = RayStartClip.xyz / RayStartClip.w; const vec3 RayEndScreen = RayEndClip.xyz / RayEndClip.w; // Normalize 2D length vec3 RayStepScreen = ( RayEndScreen - RayStartScreen ) / length( RayEndScreen.xy - RayStartScreen.xy ); RayStepScreen *= 1.5; vec3 RayStartUVz = vec3(RayStartScreen.xy * vec2(0.5, 0.5) + 0.5, RayStartScreen.z); vec3 RayStepUVz = vec3(RayStepScreen.xy * vec2(0.5, 0.5), RayStepScreen.z); const float Step = 1.0 / float(NumSteps + 1); const float CompareTolerance = abs(RayStepScreen.z) * Step * 1.0; vec4 Result = vec4(0, 0, 0, 1); float MinHitTime = 1; float LastDiff = 0; float SampleTime = StepOffset * Step + Step; for (int i = 0; i < NumSteps; ++i) { vec3 SampleUVz = RayStartUVz + RayStepUVz * SampleTime; float SampleDepth = texture(sceneDepthTex, SampleUVz.xy).r; float DepthDiff = SampleUVz.z - SampleDepth; bool Hit = abs(DepthDiff) < CompareTolerance; float HitTime = Hit ? SampleTime : 1; MinHitTime = min(MinHitTime, HitTime); SampleTime += Step; } vec3 HitUVz = RayStartUVz + RayStepUVz * MinHitTime; Result = vec4(HitUVz, MinHitTime); return Result;
-
Um ehrlich zu sein verstehe ich die Aufgabenstellung hier nicht. Willst du ein Schatten per Ambient Occlusion berechnen und willst nun wissen, warum der Schatten so aussieht wie jetzt oder wie lautet eigentlich die Aufgabe?
-
Wie im ersten Satz erwähnt versuche ich mich an Screen Space Reflections
Und um es kurz auf dem Punkt zu bringen. Ich verstehe nicht warum die Reflektion am falschen Platz erscheinen