Huhu! Kein Problem wenn du fragst, ich versuche es gerne zu erklären!

Ist auch alles nicht so trivial wenn man da nicht so in der Materie ist... und mal abgesehen davon, dass ich sicher auch nicht ganz so optimal erkläre, erschließen sich ja auch manche Zwischenschritte nach außen hin überhaupt nicht, weil ich die eben für mich alleine betrachte.
Also nochmal kurz, worum es beim Occlusion Culling geht:
Am ehesten zu Vergleichen ist das mit dem Frustum Culling. Ganz prinzipiell schickt man Objekte zur Grafikkarte, die dann gerendert werden. Jedes Objekt kostet natürlich Rechenleistung, bestehend aus zumeist tausenden von Dreiecken müssen die alle von 3D nach 2D umgerechnet werden um dann dessen Pixel zu malen. Selbst wenn die dann z.B. hinter der Kamera liegen und gar nicht sichtbar wären. Nun wäre die erste Überlegung zu schauen, ob ein Objekt überhaupt im Viewfrustum der Kamera ist, bevor man die Grafikkarte darauf loslässt. Allerdings ist die Grafikkarte sehr gut in dem, was sie tut, deswegen würde es tausendfach länger dauern, wenn man nun jedes Dreieck vorher per CPU prüft, als wenn man es einfach von der Grafikkarte rendern lässt.
Also wird approximiert. Statt das Objekt wird nur noch dessen Boundingbox betrachtet. Mit relativ weniger Rechenaufwand kann man nun schauen, ist die Objektboundingbox überhaupt im Kamerasichtfeld. Das absurde ist, dass selbst dieser kleine Test oftmals noch langsamer ist, als die Grafikkarte einfach rendern zu lassen... deswegen muss man auf Octrees usw. zurückgreifen. Aber ich möchte es an dieser Stelle dabei belassen, damit das ganze erstmal auf einer einfachen Ebene bleibt.
Das Frustum Culling bedeutet also, dass man das Objekt vorher gegen das Kamerasichtfeld prüft und dann übergeht, wenn es nicht im Sichtfeld ist.
Das Occlusion Culling hingegen soll die Objekte ausschließen, die hinter anderen Objekte liegen. Prinzipiell sieht man sowieso nur das, was am nahesten zur Kamera liegt, das macht der Z-Buffer. Aber der Z-Buffer verarbeitet auf Pixelebene ziemlich am Ende der Renderpipeline, nachdem das Objekt längst von der GPU bearbeitet wurde. Ziel von Occlusion Culling ist, das Objekt noch auszuschließen, bevor es überhaupt zur Grafikkarte geschickt wird.
Das ist allerdings wesentlich schwieriger als beim einfachen Frustum Culling.
Man kann sich die Kamera als Punktlichquelle vorstellen, und jetzt muss man rausfinden, was alles im Schatten liegt.
Ein weg wäre, man rendert das Objekt, zumindest in aproximierter Form und fragt die GPU hinterher, wie viele Pixel davon denn sichtbar waren. Schwierig ist das, weil das ganze nicht sehr zuverlässig funktioniert. Denn das Ergebnis steht erst ein paar Frames später fest. Wenn man sich vorstellt, man straft an einer Tunnelöffnung entlang, wo man dann mit einmal einen langen Gang zu Gesicht bekommt, dann weiß die Engine erst ein paar Frames später, dass dieser Gang auch gerendert werden muss. Das ganz verschlimmert sich dann auch noch, wenn man eben hierarchisch prüft, weil ein solche Occlusion Querrie Test für jede Würfelfläche einzeln wäre eben wieder auch ne Menge overhead.
Eigentlich ist es besser, wenn man schon auf der CPU Seite berechnen könnte, ob etwas sichtbar ist oder nicht.
Mein erster Ansatz war nun, Occluder für einen Chunk zu erzeugen. Da kann man ähnlich wie beim Frustum Culling dann einfach prüfen, ob das aufgespannte Occlusion Frustum eine Box dahinter umschließt. Also zu jeder Würfelfläche wird dann auch eine Bounding Box erstellt und mit dem Occlusion Frustum geprüft.
Problematisch ist, dass man das Objekt nur verwerfen darf, wenn es vollkommen von dem Occluder verdeckt wird. Wenn man nun zwei Occluder nebeneinander hat, die sich nicht überlagern, dann könnte es sein, dass die Würfelfläche von dem einen Occluder teilweise und von dem anderen Occluder auch teilweise verdeckt wird. Insgesamt wäre die Würfelfläche vielleicht komplett verdeckt, aber es wird ja immer nur jeder Occluder einzeln getestet.
Wenn man nun 4000 Würfelflächen prüfen muss, und das mit 100 Occludern resultiert das in 400.000 solche Occlusion Frustum Tests. Das heißt, Würfelfläche (W) wird mit Occluderanzahl (O) multipliziert. Besser wäre es, wenn man erstmal alle Occluder sammeln könnte und dann alle Würfelflächen mit dem Sammelsurrium testen könnte. Aus (W) * (O) würde dadurch (W) + (O).
Nun bedeutet dieses Sammeln eigentlich nichts anderes, als alle Occluder in einen Tiefenbuffer zu rendern. Am trivialsten wäre der Test nun, wenn man nun die Würfelfläche auch in diesen Buffer rendert und schaut, wie viele Pixel davon den Tiefentest bestehen würden. (Man überschreibt die Tiefenwerte im Buffer natürlich nicht mehr, die sind nur noch zum testen da dann)
Was nun auf den letzten Bildern zu sehen ist, ist der Versuch, selbst per Hand Boxen in ein Bild zu zeichnen über CPU.