Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Jul 12, 2025 18:52

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Vertexnormalen der Heightmap
BeitragVerfasst: Mi Okt 24, 2007 21:29 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
hi,
ich nutze eine leicht abgewandelte Version des Heightmap Codes aus dem wiki, welchen ich als Klasse aufgearbeitet habe.
Nun möchte ich diesen Code so abwandeln, dass die Normale für jedes Vertex berechnet wird, da es bei der Beleuchtung recht schlimm aussieht ;) Außerdem denke ich, so ein paar Polygone einsparen zu können. Allerdings habe ich noch so meine Probleme damit, wie ich das anstellen soll. Am Ende der Heightmap-Erstellung habe ich ja alle Flächennormalen berechnet. jetzt könnte ich daraus natürlich die Vertex-Koordinaten berechnen, allerdings weiß ich nicht so recht, welche Flächen an mein Vertex angrenzen. Ich hab da zwar einige Ideen, die scheinen mir aber ein wenig zu kompliziert, am liebsten wäre es mir natürlich, wenn ich diese gleich im ersten Durchgang berechnen könnte.

Hier ist mein Code:
Code:
  1.  
  2. procedure THeightmap.GenerateHeightmap;
  3. const
  4.   VertPos: array[0..3] of array[0..1] of Byte = ((0,0),(0,1),(1,1),(1,0));
  5. var
  6.   Map: array of array of byte;
  7.   Vertices : Array[0..3] of TVector3f;
  8.   x, z, i: integer;
  9.  
  10.   procedure DrawTriangle(V1, V2, V3: Integer);
  11.   var
  12.     Normal: TVector3f;
  13.   begin
  14.     Normal := v3f_normalize(v3f_CrossProduct(v3f_sub(Vertices[V1], Vertices[V2]), v3f_sub(Vertices[V2], Vertices[V3])));
  15.     glNormal3f(Normal.x, Normal.y, Normal.z);
  16.     glBegin(GL_TRIANGLES);
  17.       glTexCoord2f(Vertices[V1].x / FSize.x, Vertices[V1].z / FSize.z); glVertex3f(Vertices[V1].x, Vertices[V1].y, Vertices[V1].z);
  18.       glTexCoord2f(Vertices[V2].x / FSize.x, Vertices[V2].z / FSize.z); glVertex3f(Vertices[V2].x, Vertices[V2].y, Vertices[V2].z);
  19.       glTexCoord2f(Vertices[V3].x / FSize.x, Vertices[V3].z / FSize.z); glVertex3f(Vertices[V3].x, Vertices[V3].y, Vertices[V3].z);
  20.     glEnd;
  21.   end;
  22. begin
  23.   FDisplayList := glGenLists(1);
  24.   glNewList(FDisplayList, GL_COMPILE);
  25.   FTexture.Bind();
  26.   setlength(Map, FMapResolution + 1, FMapResolution + 1);
  27.   for X := 0 to FMapResolution do
  28.     for Z := 0 to FMapResolution do
  29.       Map[X, Z] := Trunc(FHeightmap.Canvas.Pixels[Trunc(X / FMapResolution * FHeightmap.Width),
  30.                                                   Trunc(Z / FMapResolution * FHeightmap.Height)] / clWhite * 255);
  31.   for X := 0 to FMapResolution - 1 do
  32.     for Z := 0 to FMapResolution - 1 do
  33.     begin
  34.       for i := 0 to 3 do
  35.       begin
  36.         Vertices[i].x := (X + VertPos[i][0]) / FMapResolution * FSize.x;
  37.         Vertices[i].z := (Z + VertPos[i][1]) / FMapResolution * FSize.z;
  38.         Vertices[i].y := Map[X + VertPos[i][0], Z + VertPos[i][1]] / 255 * FSize.y;
  39.       end;
  40.       DrawTriangle(0, 1, 3);
  41.       DrawTriangle(1, 2, 3)
  42.     end;
  43.   glEndList;
  44. end;
  45.  

in dem lässt sich auch noch einiges Optimieren, aber ich wollte zunächst einmal die Normalen einbauen.

vielen dank schonmal

mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Okt 25, 2007 17:40 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Genau das wartet bei mir auch noch auf eine Implementation...

Hatte mir überlegt aus der Heightmap eine Normalmap zu generieren und die auch an den Shader zu binden, da meine landschaft sowieso im shader entsteht.
Bzgl. des Algorythmus zur berechnung hatte ich mit überlegt:
(fast) jeder Pixel hat vier Nachbarn.
mit jeweils zweien lässt sich ein Dreieck bilden und die Normale berechnen.
alle normalen zusammen rechnen durch 4 teilen und normalisieren.
dann sollte das doch die normale des vertex ergeben oder?

keine ahnung obs geht, fiel mir gestern aufm klo ein :D

_________________
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"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Okt 25, 2007 18:29 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Meine Idee war folgende:

Alle Vertices mit den zugehörigen Flächennormalen in ein Array speichern und bei jedem hinzuprüfen testen ob das Vertex schon im Array ist. bei diesem Fall wird die Flächennormale aufaddiert und durch zwei geteilt.
Beim zeichnen müsste man dann wieder das jeweilge Vertex suchen, da sich das sonst so nicht ohne weiteres zeichnen lässt, es sei denn man schreibt die vertices doppelt und kopiert die normalen von deren ersten instanzen aus dem array an die jeweilige stelle.

Ich habe auch das Problem, dass wenn ich die Kamera bewege einige Vertices fast komplett schwarz werden, die es vorher nicht waren. Ein ähnliches Problem hatte ich schonmal, ist das opengl licht wirklich so mies ?

mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 26, 2007 15:22 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
So ich habs jetzt...sieht zumindest so aus wie im Nvidia Photoshop Plugin :D

teilweise noch etwas dirty...

Code:
  1.  
  2. type
  3.   TVector : array[0..2] of single;
  4.   TTriangle = array[0..2] of TVector;
  5.  
  6. function GetNeighbor(x,y:integer):TVector;
  7. const
  8.   VertPos: array[0..3] of array[0..2] of array[0..1] of smallint =
  9.     (
  10.      ((0,0), (1, 0), (0, 1)),
  11.      ((0,0), (0,-1), (1, 0)),
  12.      ((0,0), (-1,0), (0,-1)),
  13.      ((0,0), (0, 1), (-1,0))
  14.     );
  15.   Scale: single = 5;
  16. var
  17.   Face, Vertex : integer;
  18.   xx,yy : integer;
  19.   n : array[0..3] of TVector;
  20.   t : TTriangle;
  21.   tmp : TVector;
  22. begin
  23.   tmp := MakeVector(0,0,0);
  24.   for Face := 0 to 3 do begin
  25.     for Vertex := 0 to 2 do begin
  26.       xx := x + VertPos[Face][Vertex][0];
  27.       yy := y + VertPos[Face][Vertex][1];
  28.       if (xx < 0) then xx := 0;
  29.       if (yy < 0) then yy := 0;
  30.       if (xx > 255) then xx := 255;
  31.       if (yy > 255) then yy := 255;
  32.       t[Vertex][0] := xx;
  33.       t[Vertex][1] := yy;
  34.       t[Vertex][2] := GetHeight(xx, yy) * Scale / 256;
  35.     end;
  36.     n[Face] := GetNormal(t);
  37.     //Normale addieren
  38.     tmp := AddVectors(tmp, n[Face]);
  39.   end;
  40.   Normalize(tmp);
  41.   //von Interval -1..0..1 auf 0..255 umrechnen
  42.   tmp := AddVectors(tmp, MakeVector(1, 1, 1));
  43.   tmp := ScaleVector(tmp, 128);
  44.   //Clamp
  45.   if (tmp[0] > 255) then tmp[0] := 255;
  46.   if (tmp[1] > 255) then tmp[1] := 255;
  47.   if (tmp[2] > 255) then tmp[2] := 255;
  48.   result := tmp;
  49. end;
  50.  


man könnte jetzt noch verschiedene filter (3x3, 5x5, 7x7, etc) einbauen

_________________
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"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Okt 29, 2007 20:55 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
x und y sind die koordinaten auf der heightmap, oder die des vertex ? und das ergebnis ist der durchschnittsvektor aller umgebenden flächennormalen ? also praktisch die vertexnormale von x y ?


mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 30, 2007 12:56 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Ja hast recht. Ist etwas verwirrend. Man sollte eigentlich x und z nehmen... :lol:

Das ist jetzt nur ein einfacher Abgleich mit den direkten Nachbarn (Links, Rechts, Oben, Unten).

Btw: habe jetzt meine Landschaft auch um die Normalmap erweitert. Sieht wirklich schick aus mittlerweile. Fehlt nur noch ne Shadowmap. Und der Shader wird auch langsam richtig voll.

_________________
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"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 5 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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]