Erfassen, welche Dreiecke gesehen werden



  • Hallo,

    Ich hab eine 3D-Szene, welche mit OpenGL gerendert wird. Nun moechte ich von jedem einzelnen Dreieck erfassen, ob es sich im Blickfeld des Betrachters befindet (oder ueberhaupt je befand).

    Ob sich das Dreieck "im sichtbaren Bereich" befindet, wird ja im Verlauf des Renderns auf der GraKa berechnet. Aber kann ich die Info auch irgendwie rausholen?



  • Hi!

    Den Vorgang nennt man "Frustum Culling". Du Überprüfst ob ein Dreieck zwischen deinen Frustum Planes (Ebenen welche dein Blickfeld eingrenzen) liegen oder eine Ebene schneiden.
    Dazu musst du die Ebenen aus der View/Projection Matrix extrahieren und jedes Dreieck auf eine Kollision testen (Dreieck-Ebenen kollision in Google suchen).

    grüße



  • Danke fuer den Hint!
    Mit Frustum Culling bliebe noch das Problem, dass ein Dreieck wohl im Sichtbereich liegen kann, aber verdeckt ist (depth, stencil...). Bin aber auf "GL_NV_occlusion_query" gestossen, scheint die Loesung zu allen Problemen zu sein 😉


  • Mod

    durito schrieb:

    Danke fuer den Hint!
    Mit Frustum Culling bliebe noch das Problem, dass ein Dreieck wohl im Sichtbereich liegen kann, aber verdeckt ist (depth, stencil...). Bin aber auf "GL_NV_occlusion_query" gestossen, scheint die Loesung zu allen Problemen zu sein 😉

    da mußt du aufpassen, weil selbst wieder verdeckte dreiecke, erstmal sichtbar sein könnten. du müßtest die scene also erstmal zumindestens in den zbuffer rendern und danach dann mit occlusionquery normal rendern.

    eine alternative möglichkeit ist jedem dreieck eine farbe zu geben und es mit dieser zu rendern (ohne beleuchtung usw) und dann den framebuffer auslesen, dort stehen dann die colors/IDs aller dreiecke die zu sehen sind.

    rapso->greets();



  • rapso schrieb:

    durito schrieb:

    Danke fuer den Hint!
    Mit Frustum Culling bliebe noch das Problem, dass ein Dreieck wohl im Sichtbereich liegen kann, aber verdeckt ist (depth, stencil...). Bin aber auf "GL_NV_occlusion_query" gestossen, scheint die Loesung zu allen Problemen zu sein 😉

    da mußt du aufpassen, weil selbst wieder verdeckte dreiecke, erstmal sichtbar sein könnten. du müßtest die scene also erstmal zumindestens in den zbuffer rendern und danach dann mit occlusionquery normal rendern.

    eine alternative möglichkeit ist jedem dreieck eine farbe zu geben und es mit dieser zu rendern (ohne beleuchtung usw) und dann den framebuffer auslesen, dort stehen dann die colors/IDs aller dreiecke die zu sehen sind.

    rapso->greets();

    Danke fuer den Hinweis. Ja, ist klar, ich wollte so nen ersten Pass eh schon lang mal implementieren, um den Z-Buffer zu setzen. Funktioniert nun prima mit der Extension... thx



  • in doom BSP haben sies doch auch mit 2d maps gemacht, also^^ visibly-map oder so änlich heist des



  • deine kommentare sind sehr unqualifiziert. manchmal landest du nen glückstreffer und man könnte teile als konstruktive antwort werten, aber meist ist es einfach totaler bullshit.

    die bekanntesten verfahren sind frustrum culling und backface culling. backface culling guckt sich einfach die normale eines dreiecks an. wenn sie vom betrachter wegzeigt, dann wird das dreieck vom betrachter nicht gesehen. das kann man als gl funktion aktivieren. was dafür schlicht gemacht wird ist zu überprüfen, ob die dreiecke im uhrzeigersinn (sichtbar) oder gegen den uhrzeigersinn (nicht sichtbar) angegeben wurden.



  • Nicht die Dreiecke sondern die Dreieckspunkte der Dreiecke (Vertizes). 💡 😉



  • thordk schrieb:

    deine kommentare sind sehr unqualifiziert. manchmal landest du nen glückstreffer und man könnte teile als konstruktive antwort werten, aber meist ist es einfach totaler bullshit.

    die bekanntesten verfahren sind frustrum culling und backface culling. backface culling guckt sich einfach die normale eines dreiecks an. wenn sie vom betrachter wegzeigt, dann wird das dreieck vom betrachter nicht gesehen. das kann man als gl funktion aktivieren. was dafür schlicht gemacht wird ist zu überprüfen, ob die dreiecke im uhrzeigersinn (sichtbar) oder gegen den uhrzeigersinn (nicht sichtbar) angegeben wurden.

    Mittels BFC kann man allerdings nicht ermitteln, ob ein Dreieck im View Volume liegt.
    Nur als Anmerkung:
    Wenn man Testen will ob ein Vertex im View Volume liegt, so kann man entweder die Position des Vertex mit den Lagen der 6 Ebenen des View Frustums vergleichen oder den Vertex in das Canonical View Volume transformieren und dann einfach prüfen, ob die 3 Koordinaten in den Intervallen [0,1] bzw. [-1,1] liegen.



  • Sgt. Nukem schrieb:

    Nicht die Dreiecke sondern die Dreieckspunkte der Dreiecke (Vertizes). 💡 😉

    stimmt, punkte. ich schiebs auf den rotwein 😉

    zu interpreter: das kann man mit backface culling nicht, aber die frage war, ob sich ein dreieck im sichtbereich befand. ich interpretiere (oO) das so, dass es nur um die frage geht, ob es jemals sichtbar war.

    für den vergleich mit dem sichtpolyeder (ist das frustrum nicht nur eine ebene des polyeders?) würd ich einfach jede seite als separierende ebene auffassen und testen, auf welcher seite dieser ebene ein punkt liegt. ist meiner meinung nach performanter, als ein direkter check, ob ein punkt innerhalb des polyeders liegt.


  • Mod

    wenn durito sagen würde, wofür er es braucht, wäre es eventuell leichter ihm etwas optimales vorzuschlagen, ich gehe mal von einem preprozess ab für PVS 🙂



  • ach das brauch er ja doch nicht ist sicher nur so ein projekt das nie fertig wird^^
    aber ich sarg immer hauptsache man hat was gelernt dabei^^


  • Mod

    strummelbunzi schrieb:

    ach das brauch er ja doch nicht ist sicher nur so ein projekt das nie fertig wird^^
    aber ich sarg immer hauptsache man hat was gelernt dabei^^

    void?



  • ????????



  • Nur mal so: wenn du jedes Dreieck testen willst, dann kannst das eh sein lassen, das macht OpenGL eh selber.
    Sinn macht das ganze nur, wenn du deine Daten entsprechend anordnest, um durch wenige Tests viele Dreiecke auszuschließen, das macht OpenGL nicht(z.B. mit nem Octree).


  • Mod

    bei displaylists kann oGL das durchaus machen... machen einige treiber auch 😉



  • rapso schrieb:

    bei displaylists kann oGL das durchaus machen... machen einige treiber auch 😉

    Hm das interessiert mich, is mir neu. 🙂
    Kann man denn davon ausgehen, wenn die Treiber halbwegs aktuell sind, dass dieses Verhalten immer da ist?


  • Mod

    Pellaeon schrieb:

    rapso schrieb:

    bei displaylists kann oGL das durchaus machen... machen einige treiber auch 😉

    Hm das interessiert mich, is mir neu. 🙂
    Kann man denn davon ausgehen, wenn die Treiber halbwegs aktuell sind, dass dieses Verhalten immer da ist?

    nein, grundsätzlich ist das nicht möglich, z.b. bei verwendung von vertexshadern.
    ich glaube das stand mal in nem kleinen satz im ogl form, als ich jemand wunderte dass displaylists schneller waren als alle methoden die er versucht hatte, "cass" als nv-guy hat das rausgeplappert.

    kannst ja einfach mal ne displaylist machen die du mit einer suppe aus winzigen triangles füllst, und dann davon weggucken... wobei die art des cullings nicht rausgerückt wurde, vermutzlich boundingspheres oder AABB.



  • Oh, hey, da lief ja einiges in dem Thread...

    Dochdoch, rapso & strummelbunzi (was fuer'n nick...) ich brauch das schon 😉

    Pellaeon & thordk, es geht mir nicht um Performance. Ich weiss, dass die GraKa das Dreieck testet, ich will diese Information aber nicht nur fuer die grafische Ausgabe, sondern auch in meinem RAM zwecks spaeteren Auswertung in einem Simulator. Da wird ne Szene gerendert und das Opfer (der User ;)) bewegt sich in der Szene. Fuer die Auswertung brauch ich anschliessend eine Markierung des Bereiches, welcher auch wirklich gesehen wurde.

    Ich hab das jetzt mal so implentiert:
    - buffer loeschen
    - rendern
    - buffer swappen
    - nochmals einfaches rendern mit GL_NV_occlusion_query
    -->Anhand von erfassten Pixeln und Flaeche des Dreiecks wird festgelegt, wie stark das Dreieck gesehen wurde 😉

    rapso schrieb:

    bei displaylists kann oGL das durchaus machen... machen einige treiber auch 😉

    jep, nvidia's Linux-Treiber machen das 🙂



  • rapso was genau studierst du/hast du studiert?? lernt man das alles im normalen Informatik studium oder muss man da was spezielles Wählen??


Anmelden zum Antworten