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

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

11

15.02.2013, 11:53

Ich habe gestern Nacht noch schnell mit folgendem Ansatz angefangen:

Die Portale bestehen aus vier, beliebig platzierbaren, 3D Punkten. Momentan baue ich das transformierte Frustum so auf: Near- und Far Clipping Plane bleiben unverändert. Die anderen vier Ebenen werden durch die Position der Kamera und die vier Punkte des Portals aufgespannt.
Eigentlich ganz einfach. Allerdings fehlt da noch etwas, was ich dieses WE weiter machen will:
Es muss geprüft werden, welche Punkte des Portals außerhalb des vorherigen Frustums liegen. Sonst wäre das neue Frustum immer 'so groß' wie das Portal, auch wenn die Kamera nur einen Teil des Portals sieht. D.h. es muss ermittelt werden, ob und welche Ebenen - außer der Near- und Far Plane - noch unverändert bleiben müssen.
Außerdem müssen nach der Transformation die Normalen-Vektoren der Ebenen immer von dem Frustum weg zeigen - zumindest brauchen das die Frustum-Culling tests in meiner Engine so.

Folgende weitere Überlegungen habe ich mir gemacht:
was passiert, wenn ein großes Objekt durch zwei oder mehrere Portale gleichzeitig sichtbar ist?
Dann würde das Objekt mehrfach gerendert. Wenn dieses Objekt auch noch einen Shader mit Tessellation oder Relief-Mapping hat, wäre das höchst unpraktisch.

Eine Lösung wäre eine Hash-Map (bzw. std::map) zu verwenden, in der für jedes Objekt gespeichert wird, ob es bereits im aktuellen Frame gerendert wurde.
Nur ob das so viel bringt ist fraglich, denn es muss dann in jedem Frame eine Hash-Map angelegt und wieder gelöscht werden.
Auch nicht gerade toll.

Eine Andere Lösung hatte ich mir schon früher mal überlegt, aber noch nie ausprobeirt:
Für jedes Objekt wird ein Frame-Index gespeichert (unsigned int sollte reichen). Dieser wird immer auf den aktuellen Frame-Index gesetzt, wenn es gerendert wird. Der globale Frame-Index wird logischer Weise in jedem Frame um eins erhöht. Dadurch kann geprüft werden, ob ein Objekt, im aktuellen Frame, schon mal gerendert wurde.

Theoretisches Problem bei der Sache: sobald es einen Überlauf gibt, funktioniert der 'Algorithmus' nicht mehr zuverlässig. Ist also nur eine Heuristik.
Aber das ist vernachlässigbar ^^ denn: selbst bei einem 32-bit unsigned integer sieht das folgender Maßen aus:
Angenommen das Spiel läuft mit 500 FPS - was schon viel ist - dann gibt es einen Überlauf nach:
(2^32)/500 Sekunden = (2^32)/500/60 Minuten = (2^32)/500/60/60 Stunden ~ 2386 Stunden ~ 99 Tage.
Ich denke das kann man vernachlässigen :)

Was meint ihr dazu?

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »LukasBanana« (15.02.2013, 12:03)


Ähnliche Themen