Ich habe ein Raster, ein array der größe n*n, sprich: 0..n-1, 0..n-1
Diese beinhaltet Vertexkoordinaten, diese werden als einzelne Dreiecke gezeichnet. (Hier wäre zum Beispiel schon eine Optimierung mit LineStrip möglich)
Jetzt möchte ich die Normalen pro Vertex statt pro Fläche berechnen. Ich habe es versucht, in dem ich die benachbarten Dreiecke auf gemeinsame Punkte untersuche.
Das hat soweit auch funktioniert, nur passiert dies durch die Doppelbelegung bis zu 6 mal pro Vertex. Außerdem finde ich diese Bruteforce Variante nicht gerade elegant.
bei n=50, sprich 50*50*2 = 5000 dreiecken also 3*5000 = 15000 vertices braucht das Teil ganz schon lange Deshalb möchte ich nun zunächst einmal auf LINE_STRIP umsteigen und brauche dann gleich eine Funktion dir mir möglichst schnell die anliegenden Flächennormalen liefert. (diese müssen dann halt vorher gescheit berechnet und gespeichert werden)
Momentan ist das ganze sehr unschön (noch ohne Glättung)
Code:
for i :=0to n-2do
for j :=0to n-2do
begin
triangle[0]:= particles[i, j+1].new;
triangle[1]:= particles[i+1, j].new;
triangle[2]:= particles[i,j].new;
normal := v3f_normalize(v3f_crossproduct(v3f_sub(triangle[1], triangle[0]), v3f_sub(triangle[2], triangle[0])));
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
IMHO kannst du schonmal glBegin und glEnd ausserhalb der Schleife platzieren. Sind schonmal 2397 Aufrufe weniger (bei n=50).
ich tippe mal darauf, dass du eine landschaft zeichnen willst? bzw: wozu vertexnormalen wenn du Linien zeichnest?
hast du mal ein bild davon?
[edit]wieso suchst du den nachbarn? liegen die koordinaten nicht nebeneinander? dann wird auch das zeichnen als STRIP nicht so richtig funktionieren. IMHO[/edit]
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
hi, mir ist leider ein Schreibfehler passiert, ich meinte TRIANGLE_STRIP Ich kann ja erstmal den Code auf TRIANGLE_STRIP umschreiben, beim letzten Versuch sah das allerdings nicht so ganz richtig aus.
EDIT:
das wäre die TRIANGLE_STRIP Variante:
Code:
for i :=0to n-2do
begin
glBegin(GL_TRIANGLE_STRIP);
for j :=0to n-2do
begin
triangle[0]:= particles[i, j+1].new;
triangle[1]:= particles[i+1, j].new;
triangle[2]:= particles[i,j].new;
normal := v3f_normalize(v3f_crossproduct(v3f_sub(triangle[1], triangle[0]), v3f_sub(triangle[2], triangle[0])));
Die sieht allerdings leicht anders aus, liegt wahrscheinlich daran, dass immer 2 Vertices eine Normale zugewiesen bekommen.
Die einzelnen Reihen wirken dadurch ja schon recht geglättet.
mfg
Zuletzt geändert von Seth am Do Mär 20, 2008 12:46, insgesamt 1-mal geändert.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
ich würde wohl die normalen in einem vorbereitenden schritt berechnen und gleich in einem array ablegen, dass man auch ohne weiteres für vertexarrays benutzen könnte.
die normale dabei aus dem normalisierten durchschnitt zwischen den flächennormalen der 4 anliegenden dreiecke bilden (a-d) und in o.g. array speichern.
aus deiner skizze wird allerdings schon deutlich dass die 4 anliegenden nicht den 4 vorher berechneten entsprechen.
Man könnte auch mehr nehmen, aber das sieht vielleicht nicht unbedingt gut aus.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
abgeleitet habe ich das von einem normalgenerator, der aus einer heightmap eine normalmap macht.
da gibt es noch andere methoden um den durchschnitt zu berechnen. 3x3, 5x5, gauss, etc.
4 berechnete?
aus den 4 blauen und der roten vertexkoordinaten wird die normale für die rote koordinate berechnet.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
function CalculateNormal(i0, j0:integer): TVector3f;
var
i, j:integer;
tr:array[0..4]of TVector3f;
begin
tr[0]:= particles[i0, j0].new;
// unten
tr[1]:= particles[i0, j0+1].new;
// rechts
tr[2]:= particles[i0+1, j0].new;
// oben
tr[3]:= particles[i0, j0-1].new;
//links
tr[4]:= particles[i0-1, j0].new;
result := to_v3f(0,0,0);
for i :=0to3do
begin
j := i+1;
if j > 3then
j :=0;
result := v3f_add(result, v3f_crossproduct(v3f_sub(tr[i+1], tr[0]), v3f_sub(tr[j+1], tr[0])));
end;
result := v3f_normalize(v3f_scale(result,1/4));
end;
Allerdings gibt es am Rand weiße Stellen, ich denke mal weil auf Array Elemente zugegriffen wird, die nicht existieren (komisch, dass keine AV kommt), wie vermeide ich das am besten ?
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
evtl liest er ja irgendeinen müll aus dem speicher. das sollte dann durch einen vector ala (0,1,0) ersetzt werden. also für die betroffenen flächennormalen.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.