OpenGL是否需要法线来制作阴影?

时间:2016-04-29 21:25:15

标签: opengl

有人可以解释我为什么添加以下行

glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, 0);

代码

    glewInit();
    glEnable ( GL_LIGHTING ) ;
    glEnable ( GL_COLOR_MATERIAL ) ;
    glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_GREATER);

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    glClearDepth(0);


    GLuint vertexbuffer;

    glGenBuffers(1, &vertexbuffer);

    glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER,sizeof(float)*Loader.verticesFixed.size(),&Loader.verticesFixed[0],GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
    glVertexAttribPointer(
            0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  // size
            GL_FLOAT,           // type
            GL_FALSE,           // normalized?
            12,                  // stride
            (void*)(0)            // array buffer offset
        );
 glDrawArrays(GL_TRIANGLES,0,Loader.verticesFixed.size()/3);

改变这个模型: enter image description here

进入带阴影的模型:

enter image description here

我没有提供任何正常数据,我被告知OpenGL不能计算法线数据。但是,我是如何在模特身上获得适当的灯光效果?我错误地认为阴影需要法线,或者OpenGL会计算法线吗?

2 个答案:

答案 0 :(得分:3)

对我而言,看起来它只是在没有法线的情况下应用的正常衰减公式。光强度会随着距离的增加而减小,因此模型中更远的部分会变暗。

现在,如果你 使用法线,你会看到正确的阴影,即只有指向光源的面会被点亮,光线方向垂直于正常,照明越强。没有法线,我认为它完全忽略了法线。

顺便提一下,您可以将这个添加到非常非常长的列表中,列出为什么您应该使用可编程管道来渲染对象,就好像您必须实现(非常简单;通常是对我来说约5-15行代码)自己的照明算法,你就能马上知道。 Tutorial

答案 1 :(得分:1)

在过时/兼容性OpenGL提供的固定功能管道中,您需要使用glNormal*系列函数手动指定顶点法线。如果您没有指定法线,OpenGL将使用一些默认值。

在由现代OpenGL核心提供的可编程管道中,您可以在着色器中实现所需的任何照明模型。如果要使用法线,则必须将它们指定为通用顶点属性。

OpenGL计算法线的唯一因素是背面剔除,由glCullFace控制。