Сбой освещения OpenGL при масштабировании

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

При своем исходном размере он правильно освещен.

Teapor правильно освещен

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

введите здесь описание изображения

Мир сосредоточен вокруг (0, 0, 0) и имеет длину 100 метров (ось y) и ширину 50 метров (x), мой upVector равен (0, 0, 1). Есть два источника света: light0 в (20, 35, 750) и light1 в (-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();
}

Почему освещение не работает при уменьшении масштаба объекта?


person eversor    schedule 03.12.2013    source источник


Ответы (2)


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

Из-за этого преобразованные нормали должны быть перемасштабированы или нормализованы, если масштаб матрицы представления модели не является унитарным. В фиксированной функции 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 );
     ...
}
person datenwolf    schedule 03.12.2013

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

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

person user1781290    schedule 03.12.2013