2013-12-03 2 views
1

Мне нужно прочитать 3D-объект из файла ASE. Этот объект становится слишком большим для мира, который я должен создать, поэтому я должен его масштабировать.OpenGL Lighting Fail when Scaling

С его первоначальным размером он должным образом освещен.

Teapor properly lighted up

Однако после того, как я масштабировать его вниз, становится перенасыщенным.

enter image description here

Мир вокруг (0, 0, 0) и 100 метров длинных (у оси) и 50 метров ширина (х оси), мой upVector есть (0, 0, 1). Есть два огня, light0 in (20, 35, 750) и light1 in (-20, -35, 750).

Соответствующие части кода:

void init(void){ 
    glClearColor(0.827, 0.925, 0.949, 0.0); 
    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_COLOR_MATERIAL); 
    glColorMaterial(GL_FRONT, GL_DIFFUSE); 

    glEnable(GL_LIGHT0); 
    glEnable(GL_LIGHT1); 
    glEnable(GL_LIGHTING); 
    glShadeModel(GL_SMOOTH); 

    GLfloat difusa[] = { 1.0f, 1.0f, 1.0f, 1.0f}; // white light 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, difusa); 
    glLightfv(GL_LIGHT1, GL_DIFFUSE, difusa); 

    loadObjectFromFile("objeto.ASE"); 
} 

void display (void) { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    gluLookAt(eyeX, eyeY, eyeZ, atX, atY, atZ, 0.0, 0.0, 1.0); 

    GLfloat posicion0[] = { 20.0f, 35.0f, 750.0f, 1.0f}; 
    glLightfv(GL_LIGHT0, GL_POSITION, posicion0); 

    GLfloat posicion1[] = { -20.0f, -35.0f, 750.0f, 1.0f}; 
    glLightfv(GL_LIGHT1, GL_POSITION, posicion1); 

    glColor3f(0.749, 0.918, 0.278); 

    glPushMatrix(); 
     glTranslatef(0.0, 0.0, 1.5); 
       //Here comes the problem 
       glScalef(0.08, 0.08, 0.08); 
       glBegin(GL_TRIANGLES); 
        for(int i = 0; i < numFaces; i++){ 
         glNormal3d(faces3D[i].n.nx, faces3D[i].n.ny, faces3D[i].n.nz); 
         glVertex3d(vertex[faces3D[i].s.A].x, vertex[faces3D[i].s.A].y, vertex[faces3D[i].s.A].z); 
         glVertex3d(vertex[faces3D[i].s.B].x, vertex[faces3D[i].s.B].y, vertex[faces3D[i].s.B].z); 
         glVertex3d(vertex[faces3D[i].s.C].x, vertex[faces3D[i].s.C].y, vertex[faces3D[i].s.C].z); 
        } 
       glEnd(); 
      glPopMatrix(); 

    glutSwapBuffers(); 
} 

Почему освещение терпят неудачу, когда объект масштабируется вниз?

ответ

5

Проблемы вы бежите в том, что масштабирование видовой матрицы также влияет на «нормальные» матричные нормалей трансформируются с. «Нормальная матрица» на самом деле является транспонированием обратной матрицы модели. Таким образом, уменьшая матрицу просмотра модели, вы увеличиваете нормальную матрицу (из-за шага инверсии модели, используемого для ее получения).

Из-за этого преобразованные нормали должны быть перемасштабированы или нормализованы, если шкала матрицы просмотра модели не является унитарной. В фиксированной функции OpenGL есть два способа сделать это: нормальная нормализация (звучит смешно, я знаю) и нормальное масштабирование. Вы можете включить либо с

  • glEnable(GL_NORMALIZE);
  • glEnable(GL_RESCALE_NORMALS);

В шейдера вы просто нормализовать преобразованный нормальный

#version ... 

uniform mat3 mat_normal; 

in vec3 vertex_normal; 

void main() 
{ 
    ... 
    vec3 view_normal = normalize(mat_normal * vertex_normal); 
    ... 
} 
3

В зависимости от настроек GL_NORMALIZE и GL_RESCALE_NORMALS, ваши нормали могут быть преобразованы OpenGL-конвейером.

Начать с glEnable(GL_NORMALIZE) и посмотреть, если это решит вашу проблему