Scenegraph & Frustum Culling



  • Hi! Ich bin gerade dabei mir einen einfachen SceneGraphen zu basteln. Er funktioniert auch einigermaßen soweit er bisher vorangekommen ist.

    Konzept bisher:
    Knoten mit Unterknoten-Liste
    jeder KnotenTyp hat seine virtuelle Renderfunktion. In der erledigt er die D3DDevice-Status-Änderungen für die er vorgesehen ist und ruft dann RenderChildren auf
    Am untersten Ende der Hierarchie stehen immer die Knoten fürs Mesh rendern.

    /** für jede Art von D3DDevice-Status-Änderung gibts nen eigenen Knoten der abgeleitet ist von... */
    class sgn0
    {
    
    public:		sgn0 (sgn0* parent, sgRessource0* pRes, eNodeType type);
    public:		~sgn0 ();
    public:		bool AddChild (sgn0* );
    protected:      /// wird von AddChild aufgerufen
                    virtual bool Check (sgRessource0* res) const = 0;
    
    public:         virtual void Render (LPD3DDEVICE9 pDevice) = 0;
    protected:      void RenderChildren (LPD3DDEVICE9 pDevice);
    
    public:         const eNodeType m_Type;
    
    private:        sgn0* m_pParent;
    private:        Minimalist<sgn0*> m_lstChildren;
    
    public:         const sgRessource0* m_pRessource;
    protected:      BBox m_BBox;
    
    };
    
    /// Knoten für die Aufgabe "Textur setzten"
    class sgn_Texture : public sgn0
    {
    //ctor
    //virtual void Check (...);
    
    virtual void Render (LPD3DDEVICE9 pDevice)
    {
    	pDevice->SetTexture (m_pRessource->m_dwTexSampler,m_pRessource->m_pTexture);
    	sgn0::RenderChildren (pDevice);
    }
    
    };
    

    Wie gesagt bisher gehts ganz gut. Macht das eurer Meinung nach überhaupt Sinn?
    Nu wollt ich das ganze FrustumCulling-fähig machen.
    Dazu wollt ich jedem Knoten eine BoundingBox verpassen, die alle BB's aller ChildNodes umschließt.
    Wenn sich die Position eines Mesh's ändert, müssten dann die BBs aller Parent-Knoten aktualisiert und evtl. erweitert werden.
    Die Render-Methode jedes Knotens würde als erstes prüfen ob m_BBox innerhalb des Frustums liegt.

    Hört sich in meinen Ohren nach einem guten Plan an. Seht ihr das auch so?



  • Hm, also wenn ich mir vorstelle, einen SceneGraph selber zu basteln, würde ich es ziemlich genau so machen wie du. Hau rinne! 🙂



  • Ich würde eher Bounding-Spheres verwenden.
    Und das Updaten der Bounding-Spheres sollte auf jeden Fall verzögert werden. Dazu wirst du "dirty" Markierungen in den Knoten brauchen.

    Und natürlich ist deine Benamsung schrecklich - ich vermute aber dass das Absicht ist.

    Und das

    für jede Art von D3DDevice-Status-Änderung gibts nen eigenen Knoten der abgeleitet ist von

    halte ich für nicht sehr effizient.



  • Benamsung? 😕 Weiß nich. Sieht doch hübsch aus? 😋

    Ne nicht für *jeden einzelnen* Renderstate. SetTransform und RenderMesh hatte ich auch ursprünglich separat, habs dann aber erstmal zusammengelegt.

    Mir ist noch was eingefallen:
    Zwischen Wurzel und erster Ebene eine Sichtbar-Unsichtbar-Ebene. Jede Entity und die Kamera müsste per Signal verbunden sein. Bei Bewegung wird Bescheid geben.

    eine

    sgn0::OnObjMove
    

    rechnet die BoundingBox mit dem Frustum gegen und sortiert den Pfad um.
    Dann müssten beim Rendern nicht haufenweise BBs verwurstet werden...



  • rob_s schrieb:

    Benamsung? 😕 Weiß nich. Sieht doch hübsch aus? 😋

    Jo, Benamsung.
    sgn0. sgn_Texture. *schauder*
    Namespaces?
    Aber mach wie du es für gut hältst, das hier jetzt lange zu diskutieren führt zu nix (ausser dass die Sachen um die es dir eigentlich geht in den Hintergrund gedrückt werden).

    Mir ist noch was eingefallen:
    Zwischen Wurzel und erster Ebene eine Sichtbar-Unsichtbar-Ebene. Jede Entity und die Kamera müsste per Signal verbunden sein. Bei Bewegung wird Bescheid geben.

    Verstehe ich nicht. Klingt aber nicht effizient.

    Das Updaten von unsichtbaren (=fix auf visible=false gesetzten) Teilen kann man dadurch verhindern, indem man die unsichtbaren Nodes einfach "dirty" lässt, bis sie irgendwann mal wieder visible werden. Für Nodes die nur ausserhalb des Frustrums liegen funktioniert das natürlich nicht. Kann aber auch gar nicht, weil die ja durch Änderung der Position (bzw. allgemein Transformation) wieder in den sichtbaren Bereich kommen würden.

    Und bei Kameraänderung würde ich genau gar nix machen, ausser die Camera-Nodes (+ alle Parents) "dirty" zu setzen. Das Zusammenbasteln der Camera-Transform und World-Transform kann man während des Culling/Rendering machen - eine zusätzliche Matrix-Multiplikation pro potentiell sichtbarem Knoten sollte nicht sehr schlimm sein.

    Ausserdem ... wie verträgt sich deine Variante denn damit dass es mal mehr als eine Kamera geben könnte?

    eine

    sgn0::OnObjMove
    

    rechnet die BoundingBox mit dem Frustum gegen und sortiert den Pfad um.
    Dann müssten beim Rendern nicht haufenweise BBs verwurstet werden...

    Welcher Pfad? 😕

    Üblicherweise hat man hierarchische BBs, d.h. jede Node hat eine BB für "ihren eigenen" Inhalt, und eine die die BBs aller Kinder mit einschliesst.
    Dann kann beim Cullen schön ganze Teilbäume weg-cullen ohne sich die ganzen Child-Nodes anzusehen.

    ----

    Wobei ich noch anmerken möchte dass ich KEIN Experte bin was Grafik-Engines angeht -- gibt Leute hier im Forum die davon wesentlich mehr Ahnung haben. 🙂


Anmelden zum Antworten