Scharfe Kanten unter DirectX V9.0
-
Ich möchte ein Gelände in Form eines Dreiecksnetzes unter DirectX V9.0 ausgeben. Nun habe ich ein Problem mit dem Shader, wenn eine scharfe Bruchkante im Gelände ist.
Beispielsweise kann ein Gelände eine Klippe oder ein Loch enthalten. Der Rand der Klippe bzw. des Lochs wird von dem Shader grau schattiert obwohl er dies nicht sollte. Hintergrund ist dass der Grad des Schattens von dem Normalenvektor der Punkte abhängt. Der Normalenvektor für einen gemeinsamen Punkt zweier Dreiecke berechnet sich aus den gemittelten Flächennormalen der beiden Dreiecke und dadurch kommt es zu dem Problem.Wenn also ein senkrechtes Dreieck und ein waagrechtes Dreieck eine gemeinsame Linie haben, wird das senkrechte Dreieck auch zum Teil mit einem Schatten überzogen was falsch ist.
Mircosoft empfiehlt daher für alle Punkte aller Dreiecke die Normalenvektoren anzugeben. Bedeutet dies nun dass ich im Endeffekt alle Punkte aller Dreiecke seperat speichern muss, damit ich zu jedem Eckpunkt eines Dreieck den Normalenvektor angeben kann ? Momentan habe ich das so realisiert dass wenn zwei Dreiecke einen gemeinsamen Punkt haben, sie auch auf den gleichen Punkt in dem Punktpool des LPD3DXMESH Objektes zeigen. Wenn ich ich nun alle Punkte aller Dreiecke seperat speichern müsste, weil ich zu jedem Punkt jedes Dreiecks ein Normalenvektor angeben müsste, wäre dies ein kleine Verschwendung von Speichernplatz da ein Eckpunkt von mehreren Dreiecken geteilt werden kann. Weiterhin benötige ich im Endeffekt zu jedem Dreieck nur einen Normalenvektor. Das alles würde bedeuten dass im schlimmsten Fall mein Netz doppelt zu groß werden könnte.
Oder kann man DirectX nicht sagen dass er fürs Shading die Flächennormalen eines Dreiecks benutzen soll ?
Danke
-
wenn jedes polygon eine farbe haben soll hilft dir SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
wenn nur an scharfen kanten nicht interpoliert werden soll, musst du deine eckpunkte da doppeln, sodass fuer beide polygone unterschiedliche normalen gespeichert werden koennen.
-
Gerade bei dem Flat Shading ist das Problem ja schlimm. Ich habe ein einfarbiges, grünes, horizontales Gelände mit einer Vertiefung drin. Alle Dreiecke am Rand werden dunkel gezeichnet, ob sie nun Teil der Vertiefung sind oder nicht. Das sieht dann lustig aus wenn ein Dreieck welches nicht in der Vertiefung liegt, aber mit einem Punkt auf dem Rand liegt, dunkelgrün gefärbt wird, obwohl alle seine Nachbarn hellgrün sind.
Naja, wann ich keine Lösung finde verdoppele ich halt die Punktanzahl.
Aber danke für deine Antwort
-
wann ich keine Lösung finde verdoppele ich halt die Punktanzahl.
es ist ein bischen schlimmer als du vermutest.
ein gleichmaessiges triangle-mesh hat rund doppelt so viele polygone wie eckpunkte.
im schlimmsten fall hat jedes polygon 3 unabhaengige eckpunkte, also summa summarum 6x soviele eckpunkte wie vorher.
man sollte sich also schon ueberlegen wo man eckpunkte doppeln muss.
-
Wow, das wusste ich gar nicht das ein triangle-mesh Objekt bis zu 6 Polygone hat.
So ganz verstehe ich aber deine Aussage nicht, dass man nur gewisse Eckpunkte verdoppeln sollte.
Denn ich benutze das FVF Format zur Speicherung der Eckpunkte. Und in dieses Format wollte ich auch dann die Normalenvektoren speichern. Also wenn ich die Eckpunkte eines Dreiecks verdoppele, muss ich zwangsläufig alle Eckpunkte aller Dreiecke verdoppeln. Das heißt entweder haben alle Eckpunkte einen Normalenvektor oder keiner.
-
1--2--3 |\B|\D| |A\|C\| 4--5--6 |\F|\H| |E\|G\| 7--8--9Die 6 Polygone A,B,C,F,G,H verweisen alle auf den Eckpunkt '5' - es koennten auch beliebig mehr sein.
Sollen die Polygone an diesem Eckpunkt unterschiedliche Normalenvektoren haben, musst Du entsprechend viele neue Eckpunkte erzeugen.
-
Das ist mir klar.
Und ich glaube ich habe mich versprochen als ich meinte die Punkte verdoppeln zu müssen. Ich meinte das ich zu jedem Dreieck seperat die Eckpunkte speichern muss. Das bedeutet dass die Anzahl der Punkte für ein Netz die Anzahl der Dreiecke mal Drei ist. Das ich diese Lösung nicht gut ist, dürfte klar sein.
Das mit dem Verdoppeln kam aus der DirextX Hilfe. Dort wurde das Ganze an einer Kante erklärt. Und in diesem Fall müssen die Anzahl der Punkte verdoppelt werden.