Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[OpenGL GLFW GLM] Generowanie normalnych

Ostatnio zmodyfikowano 2025-02-26 19:14
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
[OpenGL GLFW GLM] Generowanie normalnych
» 2025-02-26 18:33:10
Witam.
Próbuję wygenerować normalne sześcianu w taki sposób by każda ściana będąca trójkątem zawierała po trzy normalne dla trójkąta.
Może obrazek lepiej to zobrazuje tzn to co chcę osiagnać:

W ogóle to lecę z przykładem z książki "OpenGL Programowanie Gier" Kevin Hawkins, Dave Astle strona 149 "obliczanie normalnych", ale algorytm jakoś nie działa.


std::vector<float> cube() {

    std::vector<float> vertices = {
        // x, y, z, tu, tv
        // Front face
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

        // Back face
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

        // Left face
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

        // Right face
         0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

         // Bottom face
         -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
          0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
          0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
          0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

         // Top face
         -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
         -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
          0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
          0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
          0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };

    return vertices;
}


C/C++
void generateNormals() {
   
_normals.clear();
   
_normals.resize( _vertices.size() / 5 * 3, 0.0f ); // Każdy wierzchołek ma tylko 3 wartości (x, y, z)
   
    // Sprawdzanie poprawności danych
   
if( _vertices.size() % 15 != 0 ) { // 3 wierzchołki * 5 wartości
       
std::cerr << "Błąd: Liczba danych wierzchołków nie jest podzielna przez 15!" << std::endl;
       
return;
   
}
   
   
for( short i = 0; i < _vertices.size() / 15; i += 15 ) {
       
       
glm::vec3 p1 = glm::vec3( _vertices[ i * 15 ], _vertices[ i * 15 + 1 ], _vertices[ i * 15 + 2 ] );
       
glm::vec3 p2 = glm::vec3( _vertices[ i * 15 + 5 ], _vertices[ i * 15 + 6 ], _vertices[ i * 15 + 7 ] );
       
glm::vec3 p3 = glm::vec3( _vertices[ i * 15 + 10 ], _vertices[ i * 15 + 11 ], _vertices[ i * 15 + 12 ] );
       
       
glm::vec3 v1 = p1 - p2;
       
glm::vec3 v2 = p2 - p3;
       
       
// tu generuje tylko dla środka ściany ?
       
_normals.push_back( v1.y * v2.z - v1.z * v2.y );
       
_normals.push_back( v1.z * v2.x - v1.x * v2.z );
       
_normals.push_back( v1.x * v2.y - v1.y * v2.x );
       
   
}
}
P-182138
tBane
Temat założony przez niniejszego użytkownika
» 2025-02-26 19:14:08
Oto kod na normalizację. Ważne, by ściany były w formacie CCW (counter clock wise-opisane przeciwnie do ruchu wskazówek zegara)


C/C++
void generateNormals() {
   
   
_normals.clear();
   
_normals.resize( _vertices.size() / 5 * 3 );
   
for( int i = 0; i < _vertices.size() /( 5 * 3 ); ++i ) {
       
int index = i * 15; // początek danych trójkąta i w tablicy _vertices
       
        // Pobierz pozycje trzech wierzchołków trójkąta
       
glm::vec3 p1( _vertices[ index ], _vertices[ index + 1 ], _vertices[ index + 2 ] );
       
glm::vec3 p2( _vertices[ index + 5 ], _vertices[ index + 6 ], _vertices[ index + 7 ] );
       
glm::vec3 p3( _vertices[ index + 10 ], _vertices[ index + 11 ], _vertices[ index + 12 ] );
       
       
// Oblicz wektor normalny ściany (cross product dwóch krawędzi) i znormalizuj go
       
glm::vec3 v1 = p2 - p1;
       
glm::vec3 v2 = p3 - p1;
       
glm::vec3 faceNormal = glm::normalize( glm::cross( v1, v2 ) );
       
       
// Dodaj tę normalną do każdego z trzech wierzchołków trójkąta
       
int vIndex1 = index / 5;
       
_normals[ vIndex1 * 3 + 0 ] += faceNormal.x;
       
_normals[ vIndex1 * 3 + 1 ] += faceNormal.y;
       
_normals[ vIndex1 * 3 + 2 ] += faceNormal.z;
       
       
int vIndex2 =( index + 5 ) / 5;
       
_normals[ vIndex2 * 3 + 0 ] += faceNormal.x;
       
_normals[ vIndex2 * 3 + 1 ] += faceNormal.y;
       
_normals[ vIndex2 * 3 + 2 ] += faceNormal.z;
       
       
int vIndex3 =( index + 10 ) / 5;
       
_normals[ vIndex3 * 3 + 0 ] += faceNormal.x;
       
_normals[ vIndex3 * 3 + 1 ] += faceNormal.y;
       
_normals[ vIndex3 * 3 + 2 ] += faceNormal.z;
   
}
   
}
P-182139
« 1 »
  Strona 1 z 1