Normalenberechnung



  • Mein Mesh-Objekt wird mit folgenden structs erstellt:

    struct SVertex
    {
    	SVertex() {};
    	SVertex( D3DXVECTOR3 position )
    	{
    		_position = position;
    	};
    	D3DXVECTOR3 _position;
    	D3DXVECTOR3 _normal;	// not used yet
    
    	// Set the flexible vertex format
    	static const DWORD FVF = D3DFVF_XYZ | D3DFVF_NORMAL;
    };
    
    struct SFace
    {
    	SFace() {};
    	SFace(WORD ind1, WORD ind2, WORD ind3)
    	{
    		_ind1 = ind1;
    		_ind2 = ind2;
    		_ind3 = ind3;
    	};
    	WORD _ind1, _ind2, _ind3;
    };
    

    , wird durch Vertex und Indexbuffer gesetzt und ist daher vom Typ ID3DXMesh.
    Mesh ist vernünfig geladen. Nur um ordentliche Lichtdarstellung zu erhalten
    und nicht nur im Drahtgittermodus etwas zu erkennen, sind Normalen nötig,
    damit das Licht berechnet werden kann. Die Normalen sollen in SVertex::_normal
    gespeichert werden. Ich muss also nun für jedes Element vertices[i] mit i <
    MyMesh->GetVertexCount() die zugehörigen Normalen berechnen und hab nur meine
    Vertex- und Indexlisten und weiß nicht wie ich das machen muss. Es muss doch
    eine Möglichkeit geben, die berechnen zu lassen (D3DXComputeNormals() klappt
    nicht..). Im Moment seh ich nur einen grau gefüllten Kreis anstelle einer
    Kugel. Hab in der ganzen Zeit die ich in der Suche verbracht hab irgendwie nix
    ordentliches gefunden, oder bin zu müde und hab es übersehn. Wär nett wenn mir
    jemand helfen würde..
    Norman.



  • Dann hast du vermutlich nicht gut genug gesucht. Trotzdem nochmal zum Mitmeisseln.

    a) Normale jedes Dreiecks berechnen
    b) Normalen normalisieren
    c) Für jeden Vertex den Durchschnitt der angrenzenden Dreiecke berechnen.

    Bye, TGGC (Pipe my World.)



  • Hi,

    Deine Indexliste liefert dir die Dreiecke die du benötigst um die Normalen zu berechnen. Wie genau das läuft hängt davon ab, wie du deine Dreiecke renderst. (TriangleStrip, TriangleList, ...).
    Der einfachste Fall ist natürlich TriangleList. in dem Fall gehe folgendermaßen vor:
    (v1, v2, vNorm sind Vektoren)

    //Alle Normalen 0 setzen (später wichtig bei Addition der Normalen)

    for(i = 0; i < NumVertices; ++i)
        VrtList[i].vNormal = 0; //(NullVektor)
    
    //Hauptschleife
    for(i = 0; i < NumIndices; i+=3)
    {
      v1 = VrtList[IndList[i+1]].P - VrtList[IndList[i]].P;
      v2 = VrtList[IndList[i+2]].P - VrtList[IndList[i]].P;
      D3DXVec3Cross(&vNorm, &v1, &v2);
      for(i2 = 0; i2 < 3; ++i2)
        VrtList[IndList[i+i2]].vNormal += vNorm;
    }
    

    Hier sind wir durch alle Dreiecke gegangen und haben den Vertices die in den Dreiecken enthalten sind die Normalen zugewiesen. Indem wir die Normalen addieren stellen wir sicher, dass die Normale eines Vertex, welches in mehreren Dreiecken enthalten ist, von allen Dreiecken beeinflußt wird (a.) und c.) von TGGC).
    Jetzt noch normieren (auf länge 1 bringen) (wäre dann wohl b.)):

    for(i = 0; i < NumVertices; ++i)
        D3DXVec3Normalize(&VrtList[i].vNormal, &VrtList[i].vNormal);
    

    Den Code hier kannst du vielleicht nicht 1:1 übernehmen!
    D.h gegebenenfalls +, -, +=, =0 durch entsprechende Funktionen ersetzen.

    Sollte kein TriangleList bei dir vorliegen mußt du die Art wie du durch die Indices in der Hauptschleife gehst ändern.

    Viel Spaß!


Anmelden zum Antworten