每个模型上的 opengl 照明都是相反的

opengl lighting is reversed on each model

我有一个问题,我的模型中的光照看起来好像在渲染的每个模型上都反转了。我正在照亮一块瓷砖,每个瓷砖封装了一个 8x8 的较小瓷砖子集,因此每个较大的瓷砖包含 4*8*8 个顶点。

我在 Y 方向上将法线设置为 1 - 尝试将其反转,但当然这会使照明点相反,所以场景变暗了。还尝试反转所有三角形的绕组,但这只会产生完全乱码。我确实将法线和光线位置传递给着色器,但我在那里看不到任何会产生这种效果的东西。我已经查看了着色器,改变了各种标志等,但没有解决它。
有没有人见过这个?我要找什么来修复它?

这个项目涉及大量代码,所以我只post我认为相关的代码。

为 VBO 数据初始化数组:

public void initVBOData(int _worldID, int SIZE, ArrayList<Cube> c){
    int i = 0;

    cubes = c;

    worldID = _worldID;
    QUAD_SIZE = SIZE;

    //the vertices for each tile
    vertBuffer[0] = 1;
    vertBuffer[1] = 1;
    vertBuffer[2] = 1;

    vertBuffer[3] = -1;
    vertBuffer[4] = 1;
    vertBuffer[5] = 1;

    vertBuffer[6] = -1;
    vertBuffer[7] = 1;
    vertBuffer[8] = -1;

    vertBuffer[9] = 1;
    vertBuffer[10] = 1;
    vertBuffer[11] = -1;

    for (int x = 0; x < QUAD_SIZE;x+=1 ){
        for (int z = 0; z < QUAD_SIZE;z+=1 ){

            vertBuffer[i + 0] = vertBuffer[0] + (2 * x);
            vertBuffer[i + 1] = vertBuffer[1];
            vertBuffer[i + 2] = vertBuffer[2] + (2 * z);
            vertBuffer[i + 3] = vertBuffer[3] + (2 * x);
            vertBuffer[i + 4] = vertBuffer[4];
            vertBuffer[i + 5] = vertBuffer[5] + (2 * z);
            vertBuffer[i + 6] = vertBuffer[6] + (2 * x);
            vertBuffer[i + 7] = vertBuffer[7];
            vertBuffer[i + 8] = vertBuffer[8] + (2 * z);
            vertBuffer[i + 9] = vertBuffer[9] + (2 * x);
            vertBuffer[i + 10] = vertBuffer[10];
            vertBuffer[i + 11] = vertBuffer[11] + (2 * z);  
            i+=12;
        }
    }

    //the IBO index values
    i = 0;
    idxBuffer[0] = 1;
    idxBuffer[1] = 0;
    idxBuffer[2] = 3;
    idxBuffer[3] = 3;
    idxBuffer[4] = 2;
    idxBuffer[5] = 1;
    for (int x = 1; x < 64; x++){
        i+=6;
        idxBuffer[0 + i] = (4 * x) + 1;
        idxBuffer[1 + i] = (4 * x) + 0;
        idxBuffer[2 + i] = (4 * x) + 3;
        idxBuffer[3 + i] = (4 * x) + 3;
        idxBuffer[4 + i] = (4 * x) + 2;
        idxBuffer[5 + i] = (4 * x) + 1;
    }

    //the normals for each vertex.
    for (i = 0; i<vertBuffer.length;i+=3){
        normals[0 + i] = 0;
        normals[1 + i] = 1;
        normals[2 + i] = 0;
    }

    //the uvs for texture
    for (i = 0; i < UVs.length; i+=32){
        System.arraycopy(yellow, 0, UVs, i, 8);
        System.arraycopy(red, 0, UVs, i + 8, 8);
        System.arraycopy(green, 0, UVs, i + 16, 8);
        System.arraycopy(blue, 0, UVs, i + 24, 8);
    }
}

光照位置和方向(在draw()方法中设置):

    glfwSwapBuffers(window); // swap the color buffers

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer

    //calc rotate camera
    if (updatecamera == true){
        updateCamera();
    }

    glUseProgram(shader.iProgram);

    Vector4f lp = new Vector4f(lightX, lightY, lightZ,1.0f);

    //camera is the 4x matrix representing 'lookAt'
    shader.setUniform(iLightCam, camera);
    shader.setUniform(iLightVec, lp);

片段着色器

#version 430

in vec3 Position;
in vec3 Normal;
in vec2 TexCoord;

//uniform sampler2D Tex1;
layout(binding=0) uniform sampler2D Tex1;

struct LightPos {
    vec4 LightVector;
    mat4 CameraPos;
};
uniform LightPos SetLight;

struct LightInfo {
    vec4 Position; //light pos in eye coords
    vec3 Intensity; //ads light intensity 
};
uniform LightInfo Light;

struct MaterialInfo {
    vec3 Ka; //ambient reflectivity
    vec3 Kd; //diffuse reflectivity
    vec3 Ks; //specular reflectivity
    float Shininess; //specular shininess factor
};
uniform MaterialInfo Material;

layout ( location = 0 ) out vec4 FragColor;

void phongModel (vec3 position, vec3 norm, out vec3 ambanddiff, out vec3 spec)
{

    vec4 LightPosition = SetLight.LightVector * SetLight.CameraPos;

    vec3 s = normalize( vec3(LightPosition) - position);
    vec3 v = normalize( -position.xyz );
    vec3 r = reflect( -s, norm );
    vec3 ambient = Light.Intensity * Material.Ka;
    float sDotN = max( dot( s, norm ), 0.0);
    vec3 diffuse = Light.Intensity * Material.Kd * sDotN;
    spec = vec3(0.0);

    if ( sDotN > 0.0 ) 
        spec = Light.Intensity * Material.Ks * pow(max( dot(r,v), 0.0), Material.Shininess);

    ambanddiff = ambient + diffuse;
}

void main(void) 
{
    vec3 ambanddiff, spec;
    vec4 texColor = texture( Tex1, TexCoord );

    phongModel (Position, Normal, ambanddiff, spec);
    FragColor = vec4(ambanddiff, 1.0) * texColor + vec4(spec, 1.0); 
}

顶点着色器

#version 430

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexCoord;

out vec3 Position;
out vec3 Normal;
out vec2 TexCoord;

out vec4 MVPPos;

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;

void main()
{
    TexCoord = VertexTexCoord;
    Normal = normalize( NormalMatrix * VertexNormal );
    Position = vec3( ModelViewMatrix * vec4(VertexPosition,1.0) );
    //gl_Position = MVP * vec4(VertexPosition,1.0);
    MVPPos = MVP * vec4(VertexPosition,1.0);
    gl_Position = MVPPos;
}

三天后我终于弄明白了。我唯一的线索是照明不知何故 'reversed' 所以我花了很多时间将 - 的符号更改为 +,反之亦然,并更改各种乘法顺序。最后错误不在我的着色器中。我在顶点着色器中传递给 "ModelViewMatrix" 的值计算顺序错误。

        Matrix4f.mul(model, camera, modelview); 
        shader.setUniform(iModelView, modelview);

应该是:

        Matrix4f.mul(camera, model, modelview); 
        shader.setUniform(iModelView, modelview);