Was ist Scene Graph Management und was ist es nicht?



  • Hi,

    ich versuch mich gerade an einem eigenen Scene Graph Manager und bin am grübeln, welche Aufgaben er erfüllen muss.

    Die Frage, die sich mir stellt ist:
    Was ist Scene Graph Management und was ist es nicht?

    Ich dachte zuvor, dass der Scene Graph sowohl für die Transformation der Szene als auch fürs Culling verwendet wird (hab mir das so gedacht, dass bestimmte "Area-Nodes" beim durchlaufen des Graphen zum rendern einfach auf Sichtbarkeit geprüft werden um sie von vorn herein auszuschließen). Nun hab ich mich etwas umgeschaut und festgestellt, dass ich das mit dem Culling mal besser bleiben lass und dafür lieber einen extra Graphen mach.

    Gibts hier jemanden, der schon einige Erfahrung mit dem Thema gemacht hat und mich über die Aufgaben und Arbeitsschritte eines SGM aufklären kann?

    Also ich weiß bereits, dass ein Scene Graph verdammt nützlich is um Objekte aus dem Modell-Koordinatensystem in die reale Welt zu holen und zu komplexeren Konstrukten zusammenzusetzen und dass sich damit sowohl lokal als auch global leicht Effekte einsetzen lassen, die auch tun, was sie sollen. Aber ist die "Erstellung" der Spielewelt anhand kleiner Einzelteile alles, was der Scene Graph Manager können muss?

    Und noch was:
    Ist es sinnvoll, die Objekte einer Szene in einem extra Manager zu verwalten und dem Scene Graph nur Zeiger zu übergeben oder sollte der Scene Graph die Daten selbst halten?

    lg, WirrWar2850.


  • Mod

    eingentlich hat man erst ein problem das man loesen will und sucht sich dann den passenden weg. "ich will einen scenegraph, was mach ich damit und wie?" ist entsprechend schwer zu beantworten. sie koennen fuers culling usw. benutzt werden, die koennen auch nur eine hierarchy von IDs sein oder garnicht verwendet werden. entsprechend ist ein scenegraph bei manchen engine das kernstueck, bei manchen ein hilfsobjekt beim managen von scenen und bei manchen garnicht noetig.

    scene graphs haben den vorteil das du viele dinge auf sehr einheitliche art verwalten kannst, das kann dann aber auch gleich ein nachteil sein, wenn du z.b. terrain in ein scenegraph aufnehmen willst, koennte die 'logisch' beste anordnung der nodes nicht die beste fuers rendern sein. ein weiteres problem ist oft das update der nodes, das benoetigt selbst mit optimierungen oft sehr lange, weil es eben die logische anordnung enthaellt.

    deswegen, wenn du einen scenegraph haben willst, implementier ihn (eventuell an beispiel von anderen scenegraphs). mach ruhig erstmal die 'naive' implementierung.
    wenn du dann merkst dass deine anforderungen an einer stelle von dem was der scenegraph liefert sehr auseinander laufen, dann kann man versuchen das problem zu loesen.

    eine allgemeingueltige scenegraphloesung gibt es nicht 😉

    reference:
    http://developer.nvidia.com/object/nvsg_home.html
    http://www.openscenegraph.org/



  • Danke für die rasche Antwort 🙂 !

    Also ist wie so oft die wichtigste Frage erstmal ob ich ihn überhaupt brauche und nicht, wofür ich ihn brauche!?

    Allerdings stell ich mir die Szenenverwaltung ohne Scene Graph recht schwer vor^^!

    Ich schätz mal, dass die Vorteile klar überwiegen und wenn man an der Performance noch ein wenig was dreht, dann kann der auch recht schnell werden!

    Zum Update hab ich mir überlegt, wäre es sinnvoll, allen Objekten, die ein Update nötig haben eine Art "sleep" Variable zuzuweisen um so etwas wie ein Update "Culling" zu bewerkstelligen und nur das up-zu-daten, was auch wirklich gebraucht wird.

    Ob der Scene Graph jetzt das Kernstück meiner Engine wird oder nicht, sei dahingestellt... ich sehe ihn einfach als eine Art Landkarte für meine Szenen mit nützlichen Zusatzdiensten 🙂 .

    Was das Rendern betrifft:
    Meint ihr, es wäre sinnvoll, beim Rendern der Szene eine Art "Einkaufszettel" anhand des Scene Graphs zu erstellen und dann nur diese Liste an den Renderer zu übergeben? Diese Liste könnte dann anhand von Sortieralgos auch in eine fürs Rendern effiziente Reihenfolge gebracht werden, womit die Logik-Renderer-Gegensätze recht einfach umgangen wären.
    Nur inwieweit frisst das Erstellen einer solchen Liste die gewonnene Performance wieder auf?

    Ich bedank mich für die Antworten!

    lg, WirrWar2850.


  • Mod

    WirrWar2850 schrieb:

    Allerdings stell ich mir die Szenenverwaltung ohne Scene Graph recht schwer vor^^!

    echt? also wenn ich mir z.b. Quake anschaue, hab ich da keinen scenengraphen, 99% sind brushes in einem cullingtree und dazu ein paar wenige actors die in einem array sein koennten.

    Ich schätz mal, dass die Vorteile klar überwiegen und wenn man an der Performance noch ein wenig was dreht, dann kann der auch recht schnell werden!

    und ich schaetze dass diese aussage void ist, wenn man sich nicht auf ein konkretes beispiel bezieht ;), ansonsten sage ich "ich schaetze die vorteil von raytracing ueberwiegen klar" 😛

    Zum Update hab ich mir überlegt, wäre es sinnvoll, allen Objekten, die ein Update nötig haben eine Art "sleep" Variable zuzuweisen um so etwas wie ein Update "Culling" zu bewerkstelligen und nur das up-zu-daten, was auch wirklich gebraucht wird.

    premature optimization == root of evil.
    richtig waere:
    profilen
    grund fuer das profiling ergebnis rausfinden
    optimierung dafuer vornehmen.
    wenn ich 2mio baelle in einem raum haette und in deinen scenegraph reinstecke, dann alle durch die gegen fliegen lasse, ist deine sleep optimierung nur overhead;)

    Ob der Scene Graph jetzt das Kernstück meiner Engine wird oder nicht, sei dahingestellt... ich sehe ihn einfach als eine Art Landkarte für meine Szenen mit nützlichen Zusatzdiensten 🙂 .

    also das was ich hilfsobjekt nannte :). dann hast du sicher ein anderes kernstueck zur verwaltung der game daten. ich verwalte meistens auch auf andere weisen, ist bei grossen szenen oft praktischer. meist verwende ich zonen um objekte als gruppe darin zu verwalten, so sind sie auch einfach als gruppe, zwar nicht logisch, aber geographisch zu sehen und das muss man bei spielen oft.

    Was das Rendern betrifft:
    Meint ihr, es wäre sinnvoll, beim Rendern der Szene eine Art "Einkaufszettel" anhand des Scene Graphs zu erstellen und dann nur diese Liste an den Renderer zu übergeben? Diese Liste könnte dann anhand von Sortieralgos auch in eine fürs Rendern effiziente Reihenfolge gebracht werden, womit die Logik-Renderer-Gegensätze recht einfach umgangen wären.

    das nennt man dann frustum culling, ist sehr gaengig, dabei evaluiert man aus allen vorhandenen objekten die sichtbaren und dann arbeitet man sie im renderer ab.

    Nur inwieweit frisst das Erstellen einer solchen Liste die gewonnene Performance wieder auf?

    meist siehst du nur einen bruchteil der scene, ohne culling bist du meist auf verlorener seite, deswegen generiert "jeder" diese liste von potenziel sichtbaren objekten. (jeder in anfuehrungszeichen, weil es gerade am anfang vom schreiben einer engine oder wenn man das gerade erst lernt oft einen naiven ansatz nimmt und alles 'immediate' rendert was man gerade als renderbar findet.)



  • rapso schrieb:

    echt? also wenn ich mir z.b. Quake anschaue, hab ich da keinen scenengraphen, 99% sind brushes in einem cullingtree und dazu ein paar wenige actors die in einem array sein koennten.

    Nun gut, aber funktioniert das auch noch so gut, wenn man außer den Spielern auch noch andere Entities auf der Map hat? Dann werden die Arrays wahrscheinlich recht groß und unhandlich werden 😕 .

    rapso schrieb:

    und ich schaetze dass diese aussage void ist, wenn man sich nicht auf ein konkretes beispiel bezieht ;), ansonsten sage ich "ich schaetze die vorteil von raytracing ueberwiegen klar" 😛

    Ich wollte damit eigentlich nur sagen, dass die Szene über einen Scene Graph wahrscheinlich deutlich einfacher zu verwalten ist (klar mein ich keine Szenen, in denen bis auf den Spieler alles statisch is!) und dass die Performance eines der wenigen Mankos ist, die man ausmerzen muss.

    Was die Bälle betrifft:
    Wenn ich die Bälle alle in einem Raum hab und weiß, dass alle auf einmal rumfliegen, würd ich sie mit einem Group Node gruppieren und allen die gleichen Render-Settings zuweisen (Rendern? Updaten? Schlafen?).

    Aber ich schätze mit dem Profiling hast schon recht... ich mach mir wahrscheinlich viel zu viele Gedanken die ich nachher sowieso net alle berücksichtigen kann 🙄 .

    rapso schrieb:

    ich verwalte meistens auch auf andere weisen, ist bei grossen szenen oft praktischer. meist verwende ich zonen um objekte als gruppe darin zu verwalten, so sind sie auch einfach als gruppe, zwar nicht logisch, aber geographisch zu sehen und das muss man bei spielen oft.

    Absolut! Mein erster Gedanke war eigentlich z.b. die Karte in verschiedene Zonen einzuteilen und diese als extra Nodes in den Scene Graph einzufügen, welchen dann der Inhalt angehängt wird. Dann hab ich bspw. einen Node "Zone1" dem alle Objekte unterliegen, die sich in Zone1 befinden, und wenn Zone1 den/das(?) View Frustum nich kratzt, muss gar nich weiter in die Tiefe gegangen werden, was das Durchlaufen meines Graphen deutlich verschnellern würde. Wenn solche Nodes dann nach ihrer World Matrix gefragt werden, geben sie einfach die ihres Parents zurück und schon machen sie keine Faxen mehr. Dass könnten dann zum Beispiel die ersten 2 oder 3 Ebenen des Scene Graph sein.

    Kurz: Ich wollte meinen Scene Graph sowohl räumlich als auch logisch als Karte benutzen!

    rapso schrieb:

    das nennt man dann frustum culling, ist sehr gaengig, dabei evaluiert man aus allen vorhandenen objekten die sichtbaren und dann arbeitet man sie im renderer ab.

    Das is mir auch klar 😃 . Es geht eher um das WIE statt um das WAS 🙂 . Ich könnte auch bei meinem ganzen SG die Draw() Funktion aufrufen und innerhalb der Funktion entscheiden, ob der Node gezeichnet wird oder nicht, was eben eine recht lange Beschäftigung mit dem Renderer mit sich brächte. Was ich aber will, is eine Funktion im SG Manager, die mir eine Liste mit allen Objekten erstellt, die gezeichnet werden KÖNNEN oder die eben noch einer genaueren Kontrolle bedürfen. Sodass der Renderer nur noch die Nodes bekommt, die auch wirklich was zu zeichnen beinhalten. Blah blah -.- ... ich red mich hier nur um Kopf und Kragen ^^ aber ich weiß was ich mein, also lass mers mal lieber 😃 .

    lg, WirrWar2850.


  • Mod

    WirrWar2850 schrieb:

    rapso schrieb:

    echt? also wenn ich mir z.b. Quake anschaue, hab ich da keinen scenengraphen, 99% sind brushes in einem cullingtree und dazu ein paar wenige actors die in einem array sein koennten.

    Nun gut, aber funktioniert das auch noch so gut, wenn man außer den Spielern auch noch andere Entities auf der Map hat? Dann werden die Arrays wahrscheinlich recht groß und unhandlich werden 😕 .

    was waere bei einem scenegraph anders? du hast ne root node und darunter dann die entities alle auf einer ebene. ein scenegraph hilft dir erst weiter wenn du wirklich eine hierarchy hast, doch das kann jedes entity fuer sich auch haben, bzw. sagen wir den worstcase, ein rts.
    1000 einheiten, die haben geschuetztuerme und 10 andere kleine attachments pro einheit. da diese dinge spielrelevant sind, haellt der gamecode eh eine representation davon. der scenegraph kann in diesem fall das medium sein um daten zwischen gamecode und enginecode zu transferieren, aber welchen vorteil hat das dass die engine die hierarchy kennt? genau so gut koennten alle objekte nur in einem cullinggraphen liegen, ohne logische hierarchy.

    Sinn mach der scenegraph dann erst wenn du nicht fuer die logik relevante, aber fuer die engine wichtige dinge hast. wenn in deinem strategiespiel eine windmuehle ist deren windrad sich dreht, dann will das spiel eventuell garnicht wissen ob es ein windrad etc. gibt. es ist da und dreht sich.
    ein kraftwerk stoesst rauchpartikel am schornstein aus, das muss das spiel nicht wissen, aber die engine muss irgendwo einen emitter fuer den rauch haben.
    in dem fall macht ein scenegraph eventuell sinn. vielleicht aber auch kein globaler, sondern hilfs scenegraphs pro objekt.
    sagen wir, du machst ein sims spiel, du kannst ein frosch in den mixer legen, du kannst den mixer auf ein tisch legen, du kannst den tisch auf ein schlauchbot und das wiederrum in den pool legen. in diesem fall wuerde ich sehr auf scenegraphen legen.

    rapso schrieb:

    und ich schaetze dass diese aussage void ist, wenn man sich nicht auf ein konkretes beispiel bezieht ;), ansonsten sage ich "ich schaetze die vorteil von raytracing ueberwiegen klar" 😛

    Ich wollte damit eigentlich nur sagen, dass die Szene über einen Scene Graph wahrscheinlich deutlich einfacher zu verwalten ist (klar mein ich keine Szenen, in denen bis auf den Spieler alles statisch is!) und dass die Performance eines der wenigen Mankos ist, die man ausmerzen muss.

    und ich wollte sagen, dass das so nicht grundsaetzlich gesagt werden kann. in einem spiel wie quake wuerde ein scenegraph nichts einfacher machen, es waere nur ein overhead der alles aufwendiger macht. was zwar nicht sonderlich schlimm ist, aber auch nichts nuetzt.

    Was die Bälle betrifft:
    Wenn ich die Bälle alle in einem Raum hab und weiß, dass alle auf einmal rumfliegen, würd ich sie mit einem Group Node gruppieren und allen die gleichen Render-Settings zuweisen (Rendern? Updaten? Schlafen?).

    du hast also eine root node, darunter die groupnode und dann darunter in einer ebene die baelle die alle durch die gegend flitzen. ich sehe nicht was die groupnode da bringt, ich sehe auch nicht dass sleep irgendwas optimieren wuerde.
    andererseits, stell dir vor du hast nen scenegraph in dem zu 99.9% statische objekte sind, dann waere dein sleep auch suboptimal, weil du bei unmengen von objekten immer nur sehen wuerdest dass der sleep auf unendlich steht. in dem fall koennte eine liste mit nodes wo wirklich was passiert sehr viel effizienter sein.
    deswegen ist optimieren bevor ein problem ueberhaupt besteht nicht das sinnvollste;)

    Aber ich schätze mit dem Profiling hast schon recht... ich mach mir wahrscheinlich viel zu viele Gedanken die ich nachher sowieso net alle berücksichtigen kann 🙄 .

    ja, das wollte ich auch damit sagen. implementier es erstmal, wenn es dann an einer stelle nicht so ist wie du es willst, kannst du es optimieren. wer weiss, vielleicht zieht dein ganzes update nur 1%, klar ist das gut wenn du es auf 0.01% optimieren kannst, aber es wuerde mehr bringen wenn du das rendering das 99% zieht optimiert haettest in der zeit.
    also erstmal implementieren, dann weiterschauen 😉

    Absolut! Mein erster Gedanke war eigentlich z.b. die Karte in verschiedene Zonen einzuteilen und diese als extra Nodes in den Scene Graph einzufügen, welchen dann der Inhalt angehängt wird. Dann hab ich bspw. einen Node "Zone1" dem alle Objekte unterliegen, die sich in Zone1 befinden, und wenn Zone1 den/das(?) View Frustum nich kratzt, muss gar nich weiter in die Tiefe gegangen werden, was das Durchlaufen meines Graphen deutlich verschnellern würde. Wenn solche Nodes dann nach ihrer World Matrix gefragt werden, geben sie einfach die ihres Parents zurück und schon machen sie keine Faxen mehr. Dass könnten dann zum Beispiel die ersten 2 oder 3 Ebenen des Scene Graph sein.

    ist ne moeglichkeit. alternativen zu zones im scenegraph sind zones die z.b. durch portale verbunden sind, oder die in einem grid liegen. wer will schon 1024*1024 zone nodes in ein scenegraph stecken, wenn zur selben zeit vielleicht nur 9 aktiv sind.

    rapso schrieb:

    das nennt man dann frustum culling, ist sehr gaengig, dabei evaluiert man aus allen vorhandenen objekten die sichtbaren und dann arbeitet man sie im renderer ab.

    Das is mir auch klar 😃 . Es geht eher um das WIE statt um das WAS 🙂 . Ich könnte auch bei meinem ganzen SG die Draw() Funktion aufrufen und innerhalb der Funktion entscheiden, ob der Node gezeichnet wird oder nicht, was eben eine recht lange Beschäftigung mit dem Renderer mit sich brächte. Was ich aber will, is eine Funktion im SG Manager, die mir eine Liste mit allen Objekten erstellt, die gezeichnet werden KÖNNEN oder die eben noch einer genaueren Kontrolle bedürfen. Sodass der Renderer nur noch die Nodes bekommt, die auch wirklich was zu zeichnen beinhalten. Blah blah -.- ... ich red mich hier nur um Kopf und Kragen ^^ aber ich weiß was ich mein, also lass mers mal lieber 😃 .

    gibt noch viele andere wege das problem zu loesen, wenn es mal auftaucht 😉

    du kannst auch noch alles multithreaded machen, damit es schnell ist, und du koenntest streaming integrieren, synchronisation uebers netzwerk und... 😉

    aber wenn du erstmal einen basic SG machst der sauber funzt, waere es gut 👍


Log in to reply