Probleme beim Verstehen von Ambient Occlusion



  • Hallo,

    ich habe diesen netten Artikel gefunden und versucht diese HBAO Methode selber mit OpenGL/GLSL zu implementieren. Ganz am Ende vom Artikel findet man Beispiel HLSL-Shader an denen ich mich orientiert habe. In dem Fragment-Shader findet man dann folgende Zeilen:

    // scale the sample radius perspectively according to the given view depth (becomes ellipse)
    float w = centerViewPos.z * projectionMatrix[2][3] + projectionMatrix[3][3];
    float2 projectedRadii = halfSampleRadius * float2(projectionMatrix[1][1], projectionMatrix[2][2]) / w;	// half radius because projection ([-1, 1]) -> uv ([0, 1])
    float screenRadius = projectedRadii.x * renderTargetResolution.x;
    

    In GLSL übersetzt sollte das ganze dann so Aussehen:

    float w = centerViewPos.z * gl_ProjectionMatrix[2][3] + gl_ProjectionMatrix[3][3];
    vec2 projectedRadii = halfSampleRadius * vec2(gl_ProjectionMatrix[1][1], gl_ProjectionMatrix[2][2]) / w;
    float screenRadius = projectedRadii.x * renderTargetResolution.x;
    

    Allerdings verstehe ich hier zwei Dinge nicht.
    In der ersten Zeile wird nach meinem Verständnis einfach nur die w-Koordinate anhand der aktuellen View-Space-Position errechnet. Aber was soll das

    + projectionMatrix[3][3]
    

    Ist dieser Wert nicht immer 0?

    In der zweiten Zeile soll dann nach meinem Verständnis der Sample-Radius in Screen-Space-Koordinaten transformiert werden. Aber müsste es dann nicht

    float2 projectedRadii = halfSampleRadius * float2(projectionMatrix[0][0], projectionMatrix[1][1]) / w;
    

    heißen? Alles andere ergibt in meinem Kopf keinen Sinn 😕

    Wenn ich jedoch die von mir erdachten Korrekturen andwende ist mein Ergebnis immer noch fehlerhaft. Hier mal ein Beispiel wie mein HBAO mit diesen Korrekturen aussieht im vergleich zum normalen SSAO:
    SSAO
    HBAO

    Kann mir jemand genauer erklären es mit diesen Zeilen auf sich hat und ob ich richtig oder falsch liege? 🙂

    Vielen Dank schonmal im Voraus


  • Mod

    scheinbar hat hier keiner spass hbao zu reviewen.

    also, ich wuerde deinen beiden annahmen zustimmen, [3][3] sollte 0 sein, projectedradii scheint x|y sein zu sollen, wird jedenfalls zum screenspace interpolieren der frustum richtungen verwendet.

    was genau gefaellt dir an deinem hbao-bildchen nicht? schaut doch recht nah an ssao an (ich meine was dithering quality etc. angeht).



  • Hätte nicht gedacht, dass sich doch noch jemand meldet. Es stimmt, dass das so alles funktioniert. Der Grund, dass das HBAO so dunkel aussah lag an folgendem Umstand

    One thing I forgot to mention that needs to be taken into account is the case when the angle extends 90 degrees:
    ...
    In this case, the occlusion should be total, but the dot product with the normal would result in the wrong angle. This is actually a limitation of working in screen-space, where marching in 2D does not match a marching in 3D due to overlap. What we need to do is test the angle with the tangent: if t \cdot h < 0, we simply do not have proper data in the direction we’re interested in: it could be completely occluded, or not at all. Personally, I find picking “half-occluded” works best in this case.

    Wie ich finde ist das eine total dämliche Abschätzung. Ich habe diese Abfrage einfach komplett entfernt, dass Ergebnis sieht dadurch deutlich besser aus 🙂
    Hier mal ein Vergleich wie mein Ergebnis jetzt aussieht (mit angewandten Blur Filter):
    SSAO
    HBAO


Anmelden zum Antworten