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

Aktuelle Zeit: Fr Jul 18, 2025 07:27

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



Ein neues Thema erstellen Auf das Thema antworten  [ 29 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Mo Jul 05, 2010 16:43 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Also ich verstehe nicht was du da machst. Z.B. was enthält dieses 2D-Array normal.

Nimm doch einfach mal diesen Terrain-Shader aus der Shadersammlung als Beispiel:
  • coords ist ein 2D-Integer-Vektor (ivec2) und entspricht deinem x bzw. z.
  • "texelFetch2DOffset(heightmap, coords, 0, ivec2(i,j)).a" entspricht "heightmap[x+i][z+j]"
  • terrainscale ist ein Skalierungsfaktor für die Terrainhöhe, weil ich diese als 16bit Integer speichere.
Alles andere sollte klar sein.

Code:
   if (coords.x < tmin || coords.y < tmin || coords.x > tmax || coords.y > tmax) {
      // clamping borders
      height = 0.0;
      normal = vec3(0,-1,0);
   }
   else {
      //retrieve height
      height = terrainscale * texelFetch2DOffset(heightmap, coords, 0, ivec2(0,0)).a;
 
      //compute normal
      vec3 vector[6];
      vector[0] = vec3( 0.0, texelFetch2DOffset(heightmap, coords, 0, ivec2( 0, -1)).a, -1.0);
      vector[1] = vec3(-1.0, texelFetch2DOffset(heightmap, coords, 0, ivec2(-1, -1)).a, -1.0);
      vector[2] = vec3(-1.0, texelFetch2DOffset(heightmap, coords, 0, ivec2(-1,  0)).a,  0.0);
      vector[3] = vec3( 0.0, texelFetch2DOffset(heightmap, coords, 0, ivec2( 0,  1)).a,  1.0);
      vector[4] = vec3( 1.0, texelFetch2DOffset(heightmap, coords, 0, ivec2( 1,  1)).a,  1.0);
      vector[5] = vec3( 1.0, texelFetch2DOffset(heightmap, coords, 0, ivec2( 1,  0)).a,  0.0);
      for (int i=0; i<6; ++i) {
         vector[i].y = terrainscale * vector[i].y - height;
      }
      normal = cross(vector[5], vector[0]);
      for (int i=1; i<6; ++i) {
         normal += cross(vector[i-1], vector[i]);
      }
      normal = normalize(normal);
   }

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Mo Jul 05, 2010 18:36 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
Jo thx, werde ich bei Gelegenheit auch mal ausprobieren :).
Hab das Problem jetzt fast geloest, sind noch leicht sichtbare Streifen aber
die werd ich schon noch irgentwie wegbekommen:

Code:
            for(z = 0; z < length-1; z++) {
                glBegin(GL_TRIANGLE_STRIP);
                for(x = 0; x < width-1; x++) {
                    Vector.Conv(&norm[0], 0, 0, 0);
                    Vector.Conv(&norm[1], 0, 0, 0);

                    for(j = 0; j < 7; j++) {
                        if(x+j+1 >= length || z+j+1 >= width) break;
                       
                        for(i = 0; i < 7; i++) {
                            if(x+i+1 >= length || z+j+1 >= width) break;

                            Vector.Conv(&vec1, x+i, heightmap[x+i][z+j], z+j);
                            Vector.Conv(&vec2, x+1+i, heightmap[x+1+i][z+j], z+j);
                            Vector.Conv(&vec3, x+i, heightmap[x+i][z+1+j], z+1+j);
                            Vector.Conv(&vec4, x+1+i, heightmap[x+1+i][z+1+j], z+1+j);

                            Vector.Normal(&vec1, &vec2, &vec3, &normal[0][0]);
                            Vector.Normal(&vec1, &vec4, &vec3, &normal[0][1]);

                            norm[0].X += normal[0][0].X;
                            norm[0].Y += normal[0][0].Y;
                            norm[0].Z += normal[0][0].Z;

                            norm[1].X += normal[0][1].X;
                            norm[1].Y += normal[0][1].Y;
                            norm[1].Z += normal[0][1].Z;
                        }
                    }
                   
                    norm[0].X /= 7*7;
                    norm[0].Y /= 7*7;
                    norm[0].Z /= 7*7;
                    norm[1].X /= 7*7;
                    norm[1].Y /= 7*7;
                    norm[1].Z /= 7*7;

                    glNormal3f(norm[0].X, norm[0].Y, norm[0].Z);
                    glTexCoord2f((float)x/TERRAIN_TEXTURE_RES_X, (float)z/TERRAIN_TEXTURE_RES_Y);
                    glVertex3f(x, heightmap[x][z], z);

                    glNormal3f(norm[1].X, norm[1].Y, norm[1].Z);
                    glTexCoord2f((float)(x+1)/TERRAIN_TEXTURE_RES_X, (float)(z+1)/TERRAIN_TEXTURE_RES_Y);
                    glVertex3f(x+1, heightmap[x+1][z+1], z+1);
                }
                glEnd();
            }


Screenshot:
http://xyross.de/file.php?id=55


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Mo Jul 05, 2010 18:53 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Warum mittelst du da die Normalen von 7*7 Feldern? Du solltest nur die Dreiecke beachten die auch wirklich zum jeweiligen Vertex gehören.

Die Streifen könnten daher rühren das du die Durchschnitts-Normale nicht erneut normalisierst. Schau was passiert wenn du den Durchschnitt von zwei Normalen berechnest:
Dateianhang:
normale.png

Wenn eine Normale zu kurz (oder zu lang) ist, ist das Licht entsprechend dunkler (bzw. heller).
Edit: Ich sehe gerade, du normalisierst im Shader, daher sollte das kein Problem sein.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Di Jul 06, 2010 07:59 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Mal ne blöde Frage zwischen durch: Wenn du doch schon mit Shadern dran bist....warum benutzt du dann kein VertexbufferObject mit Indices um das Terrain zu rendern? Wenn du Shader verstanden hast sollte ein VBO kein Problem darstellen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Di Jul 06, 2010 12:53 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
Zitat:
Warum mittelst du da die Normalen von 7*7 Feldern? Du solltest nur die Dreiecke beachten die auch wirklich zum jeweiligen Vertex gehören.

Es werden ja auch nur die Dreiecke beachtet, die drum herum liegen, weil von dem jeweiligen Vertex immer bis zu 7 Felder in der X- und Z-Achse
berechnet werden (siehe for(j = 0; j < 7; j++) - Schleife).

Zitat:
Edit: Ich sehe gerade, du normalisierst im Shader, daher sollte das kein Problem sein.

Bringt es vielleicht doch was wenn ich erst nach dem Durchschnitt berechnen die Normale dafür ermittle?

Ich verwende Display-Listen :wink:.

Edit: Die Streifen gehen nur in eine Richtung.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Di Jul 06, 2010 13:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Bringt es vielleicht doch was wenn ich erst nach dem Durchschnitt berechnen die Normale dafür ermittle?

Du meinst den Durchschnitt der Position und dann davon die Normale? Ähm, nein....

Zitat:
Es werden ja auch nur die Dreiecke beachtet, die drum herum liegen,

Jetzt mal vom Rand des Terrains abgesehen, da werden zweimal 49 Normalen gemittelt. Ich hatte dir auf der ersten Seite eine Grafik angehängt mit den Dreiecken die für die Durchschnitts-Normale in Betracht gezogen werden sollten. Um die Normale für den rot markierten Vertex zu berechnen musst du die Normalen der 6 dick gemalten Dreiecke verwenden. Genau das macht auch der Shader-Code den ich später gepostet hatte.

Bitte berechne die Normalen doch mal so, ich denke dann erledigt sich auch das Problem mit den Streifen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Di Jul 06, 2010 17:33 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
Jo, habs jetzt genau so gemacht wie in deinem Vertex-Shader:

Code:
for(z = 0; z < length-1; z++) {
    glBegin(GL_TRIANGLE_STRIP);
    for(x = 0; x < width-1; x++) {

        Vector.Conv(&vertex[0], x, heightmap[x][z-1], z-1);
        Vector.Conv(&vertex[1], x-1, heightmap[x-1][z-1], z-1);
        Vector.Conv(&vertex[2], x-1, heightmap[x-1][z], z);

        Vector.Conv(&vertex[3], x, heightmap[x][z+1], z+1);
        Vector.Conv(&vertex[4], x+1, heightmap[x+1][z+1], z+1);
        Vector.Conv(&vertex[5], x+1, heightmap[x+1][z], z);

        Vector.Cross(&cross, &vertex[5], &vertex[0]);
        for(i = 1; i < 6; ++i) {
            Vector.Cross(&vec, &vertex[i-1], &vertex[i]);
            cross.X += vec.X;
            cross.Y += vec.Y;
            cross.Z += vec.Z;
        }

        Vector.Normalize(&normal, &cross);

        glNormal3f(normal.X, normal.Y, normal.Z);
        glTexCoord2f((float)x/TERRAIN_TEXTURE_RES_X, (float)z/TERRAIN_TEXTURE_RES_Y);
        glVertex3f(x, heightmap[x][z], z);

        glTexCoord2f((float)(x+1)/TERRAIN_TEXTURE_RES_X, (float)(z+1)/TERRAIN_TEXTURE_RES_Y);
        glVertex3f(x+1, heightmap[x+1][z+1], z+1);
    }


Die Normalize- und Cross - Funktion

Code:
void clVector::Normalize(stVec3 *result, stVec3 *vec) {
    GLfloat l;
    l = (GLfloat)sqrt( ((*vec).X * (*vec).X) + ((*vec).Y * (*vec).Y) + ((*vec).Z * (*vec).Z) );
    if(l == 0.0f) l = 1.0f;
    (*result).X = (*vec).X / l;
    (*result).Y = (*vec).Y / l;
    (*result).Z = (*vec).Z / l;
}

void clVector::Cross(stVec3 *result, stVec3 *vec1, stVec3 *vec2) {
    (*result).X = (*vec1).Y * (*vec2).Z - (*vec1).Z * (*vec2).Y;
    (*result).Y = (*vec1).Z * (*vec2).X - (*vec1).X * (*vec2).Z;
    (*result).Z = (*vec1).X * (*vec2).Y - (*vec1).Y * (*vec2).X;
}


Das Terrain ist jetzt komplett schwarz. Es muss irgentwas an den beiden Vektor - Funktionen falsch sein...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Di Jul 06, 2010 17:49 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Da fehlt eine wichtige Schleife:
Code:
height = heightmap[x][z];
for (int i=0; i<6; ++i) {
    vertex[i].y = vertex[i].y - height;
}


Das Array in meinem Shader heißt nicht grundlos "vector", es handelt sich nämlich um die Vektoren die vom zentralen Vertex auf den jeweiligen Nachbarvektor zeigen.

Ganz am Rande:
Was spricht eigentlich gegen A->x statt (*A).x ? Konstante Referenzen sollen in vielen Fällen auch ganz hilfreich sein ;)
Werf doch mal einen Blick auf CoolMath. Das wird dir das Leben wesentlich leichter machen. :)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Di Jul 06, 2010 17:56 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
Oh stimmt, thx, hab die Schleife noch reingemacht. Leider ist das Terrain immernoch komplett schwarz :/

Zitat:
Werf doch mal einen Blick auf CoolMath.

Werd ich machen, thx :D.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Di Jul 06, 2010 19:10 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Es wäre möglich das dein Koordinatensystem rechtshändig statt linkshändig ist oder umgekehrt. Das hätte zur folge das die Normalen falsch herum orientiert wären, also nach unten zeigen statt nach oben.

Drehe mal testweise das Kreuzprodukt um, also:
Code:
Vector.Cross(&cross, &vertex[0], &vertex[5]);
...
            Vector.Cross(&vec, &vertex[i], &vertex[i-1]);

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Mi Jul 07, 2010 13:06 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
Ah, daran hats gelegen! Jetzt funktioniert alles :D!
http://xyross.de/file.php?id=56

Vielen Dank für deine Hilfe :wink:!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Mi Jul 07, 2010 13:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Jetzt funktioniert alles :D!

Sorry, aber die Normalen sind immer noch nicht 100%ig richtig.

Du berechnest die Normale korrekt für den Punkt (x, z), verwendest sie dann aber ebenfalls für (x+1, z+1). Dadurch bekommt der eigentlich gleiche Vertex beim benachbarten Triangle-Strip eine andere Normale.
=> Gleiche Berechnung für x+1, z+1 nochmal durchführen. Am besten versuchst du das in eine extra Funktion auszulagern, also irgendwie so:
Code:
computeNormal(&normal0, x, z);
computeNormal(&normal1, x+1, z+1);

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Mi Jul 07, 2010 13:26 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
Ich hab für den 2. Vertex auch die Normale berechnet. Hier der Code:

Code:
for(z = 0; z < length-1; z++) {
    glBegin(GL_TRIANGLE_STRIP);
    for(x = 0; x < width-1; x++) {
        for(j = 0; j < 2; j++) {
            if(x+2>=width || z+2>=length) break;

            if(x == 0 || z == 0) {
                Vector.Conv(&vertex[0], 0.0, heightmap[x][z], -1.0);
                Vector.Conv(&vertex[1], -1.0, heightmap[x][z], -1.0);
                Vector.Conv(&vertex[2], -1.0, heightmap[x][z], 0.0);
            }
            else {
                Vector.Conv(&vertex[0], 0.0, heightmap[x][z-1], -1.0);
                Vector.Conv(&vertex[1], -1.0, heightmap[x-1][z-1], -1.0);
                Vector.Conv(&vertex[2], -1.0, heightmap[x-1][z], 0.0);
            }

            Vector.Conv(&vertex[3], 0.0, heightmap[x][z+1], 1.0);
            Vector.Conv(&vertex[4], 1.0, heightmap[x+1][z+1], 1.0);
            Vector.Conv(&vertex[5], 1.0, heightmap[x+1][z], 0.0);

            for(i=0; i < 6; ++i) {
                vertex[i].Y -= heightmap[x][z];
            }
            Vector.Cross(&cross, &vertex[0], &vertex[5]);
            for(i=1; i < 6; ++i) {
                Vector.Cross(&vec, &vertex[i], &vertex[i-1]);
                cross.X += vec.X;
                cross.Y += vec.Y;
                cross.Z += vec.Z;
            }

            Vector.Normalize(&normal, &cross);

            glNormal3f(normal.X, normal.Y, normal.Z);
            glTexCoord2f((float)x/TERRAIN_TEXTURE_RES_X, (float)z/TERRAIN_TEXTURE_RES_Y);
            glVertex3f(x, heightmap[x][z], z);

            x++;
            z++;
        }
        x-=j;
        z-=j;
    }
    glEnd();
}


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Normalen für TRIANGLE_STRIP
BeitragVerfasst: Mi Jul 07, 2010 13:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Jup, müsste so stimmen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 29 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 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.010s | 15 Queries | GZIP : On ]