缩放时OpenGL照明失败

 秘密不能说雨 发布于 2023-02-13 11:21

我必须从ASE文件中读取3D对象.对于我必须创建的世界来说,这个对象变得太大了,因此,我必须缩小它.

凭借其原始尺寸,它被正确点亮.

Teapor正常点亮

但是,一旦我缩小它,它就会变得过饱和.

在此输入图像描述

世界以(0,0,0)为中心,长100 (y轴),宽50 (x轴),我的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();
}

为什么在缩小对象时照明会失败?

1 个回答
  • 您遇到的问题是,缩放模型视图矩阵也会影响"正常矩阵"法线的变换."正常矩阵"实际上是模型视图矩阵的逆的转置.因此,通过缩小模型视图矩阵,您可以放大普通矩阵(因为用于获取它的模型视图反转步骤).

    因此,如果模型视图矩阵的比例不是单一的,则必须重新调整转换的法线或进行标准化.在固定功能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 );
         ...
    }
    

    2023-02-13 11:24 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有