代码之家  ›  专栏  ›  技术社区  ›  DavidG

opengl中的光照问题

  •  2
  • DavidG  · 技术社区  · 17 年前

    我有一个没有纹理的三角形网格,但是有一个固定的颜色(蓝色)和alpha(0.7f)。此网格是运行时生成的,并且法线是正确的。我发现当灯光打开时,我的对象的颜色会随着它在水平面上的移动而改变。而且,灯光看起来也不对。当我绘制这个对象时,这是代码:

    glEnable( GL_COLOR_MATERIAL );
    float matColor[] = { cur->GetRed(), cur->GetGreen(), cur->GetBlue(), cur->GetAlpha() };
    float white[] = { 0.3f, 0.3f, 0.3f, 1.0f };
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matColor);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
    

    我注意到的另一件奇怪的事情是,当我禁用gl_front_和_back并且只使用gl_front或gl_back时,照明失败。 这是我的灯光设置(在渲染器开始时完成一次):

    m_lightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
    m_lightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    m_lightPosition[] = { 0.0f, 1200.0f, 0.0f, 1.0f };
    
    glLightfv(GL_LIGHT0, GL_AMBIENT, m_lightAmbient);
    glLightfv(GL_LIGHT0, GL_SPECULAR, m_lightSpecular);
    glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition);
    

    编辑:我已经做了很多工作使法线“更正确”(因为我自己生成了曲面),但对象的颜色仍然会根据它的位置而改变。这是为什么?opengl是否有一些我不知道的特殊环境混合? 编辑:原来颜色变化是因为以前的纹理是在纹理堆栈上的,即使它没有被绘制,GrOrthAlFFV也与它混合。

    6 回复  |  直到 17 年前
        1
  •  1
  •   mwahab    17 年前

    如果禁用gl_front_和_back时照明失败,则可能会翻转法线。

        2
  •  1
  •   Sebastian    17 年前

    你能发布初始化opengl的代码吗?你是说其他的网格都画得很完美?你在同时渲染它们吗?

        3
  •  1
  •   korona    17 年前

    @对斯图史密斯的回应:

    z-testing不会帮助您处理透明三角形,您还需要对每个三角形进行alpha排序。如果对象在任何时候都可能有重叠的三角形面对摄影机(凹面对象),则必须首先绘制最远的三角形,以确保正确执行混合,因为Z测试不考虑透明度。 考虑这两个重叠的(透明的)三角形,并考虑在绘制这个小的重叠区域时会发生什么,有没有z-测试。你可能会得出这样的结论:事实上,画图的顺序确实很重要。透明度差:p

        /\    /\
       /  \  /  \
      /    \/    \
     /     /\     \
    /_____/__\_____\
    

    我不认为这是你的问题,但在处理部分透明对象时,需要考虑alpha排序。

        4
  •  0
  •   stusmith    17 年前

    如果你的三角形是alpha混合的,你不需要从相机中按z顺序对你的脸进行排序吗?否则,可以在对象的后面渲染一个面,在前面渲染一个面。

        5
  •  0
  •   DavidG    17 年前

    塞巴斯蒂安: 多个draw调用,每个对象都得到一个gldrawArrays。有些是有纹理的,有些是彩色的,都是正常的。gl init代码是: glmatrixmode(总帐模型视图);

    // Vertices!
    glEnableClientState(GL_VERTEX_ARRAY);
    
    // Depth func
    glEnable(GL_DEPTH_TEST);
    glDepthFunc( GL_LESS );
    
    // Enable alpha blending
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    // Lighting
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_AMBIENT, m_lightAmbient);
    glLightfv(GL_LIGHT0, GL_SPECULAR, m_lightSpecular);
    glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition);
    
    // Culling
    glDisable( GL_CULL_FACE );
    // Smooth Shading
    glShadeModel(GL_SMOOTH);
    
    m_glSetupDone = true;
    

    在这之后,我有一些相机设置,但这是完全标准的,投影模式,截锥,模型视图,看,翻译。

        6
  •  0
  •   Manuel    17 年前

    你确定你的常态是 归一化 ? 如果没有,并且您通过GLRADION调用指定法线,您可以尝试让OpenGL为您做正常化,记住应该避免这一点,但是您可以测试它:

    glEnable(GL_NORMALIZE);
    

    这样,您就可以告诉opengl重新缩放通过glnormal提供的所有法向量。

    推荐文章