Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL漫反射照明问题_C++_Opengl_Glsl_Glfw_Lighting - Fatal编程技术网

C++ OpenGL漫反射照明问题

C++ OpenGL漫反射照明问题,c++,opengl,glsl,glfw,lighting,C++,Opengl,Glsl,Glfw,Lighting,我的漫反射照明似乎工作不正常 片段着色器: #version 330 core out vec4 gl_FragColor; in vec4 vertexColor; in vec2 texelCoord; in vec3 Normal; struct DirectionalLight { vec3 color; float ambientIntensity; vec3 direction; float diffuseIntensity; }; unifo

我的漫反射照明似乎工作不正常

片段着色器:

#version 330 core

out vec4 gl_FragColor;

in vec4 vertexColor;
in vec2 texelCoord;
in vec3 Normal;

struct DirectionalLight
{
    vec3 color;
    float ambientIntensity;
    vec3 direction;
    float diffuseIntensity;
};

uniform sampler2D textureSampler;
uniform DirectionalLight directionalLight;

void main()
{
    vec4 ambientColor = vec4(directionalLight.color, 1.0f) * directionalLight.ambientIntensity;
    
    float diffuseFactor = max(dot(normalize(Normal), normalize(directionalLight.direction)), 0.0f);
    vec4 diffuseColor = vec4(directionalLight.color, 1.0f) * directionalLight.diffuseIntensity * diffuseFactor;
    
    gl_FragColor = texture(textureSampler, texelCoord) * (ambientColor + diffuseColor);
}
顶点着色器:

#version 330 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in vec3 normal;

out vec4 vertexColor;
out vec2 texelCoord;
out vec3 Normal;

uniform mat4 transformation;
uniform mat4 projection;
uniform mat4 view;

void main()
{
    gl_Position = projection * view * transformation * vec4( position, 1.0f );
    vertexColor = vec4(clamp(position, 0.0f, 1.0f), 1.0f);
    
    texelCoord = texCoord;
    Normal = mat3(transpose(inverse(transformation))) * normal;
}
如何创建网格:

void CalcAverageNormals( unsigned int* indices , unsigned int indicesCount , float* vertices , unsigned int verticesCount , unsigned int vertexLength , unsigned int normalOffset )
{
    for ( int i = 0; i < indicesCount; i += 3 )
    {
        unsigned int v1 = indices[i] * vertexLength;
        unsigned int v2 = indices[ i + 1 ] * vertexLength;
        unsigned int v3 = indices[ i + 2 ] * vertexLength;

        glm::vec3 line1( vertices[ v2 ] - vertices[ v1 ] , vertices[ v2 + 1 ] - vertices[ v1 + 1 ] , vertices[ v2 + 2 ] - vertices[ v1 + 2 ] );
        glm::vec3 line2( vertices[ v3 ] - vertices[ v1 ] , vertices[ v3 + 1 ] - vertices[ v1 + 1 ] , vertices[ v3 + 2 ] - vertices[ v1 + 2 ] );
        glm::vec3 normal = glm::normalize( glm::cross( line1 , line2 ) );

        v1 += normalOffset;
        v2 += normalOffset;
        v3 += normalOffset;

        vertices[ v1 ] += normal.x; vertices[ v1 + 1 ] += normal.y; vertices[ v1 + 2 ] += normal.z;
        vertices[ v2 ] += normal.x; vertices[ v2 + 1 ] += normal.y; vertices[ v2 + 2 ] += normal.z;
        vertices[ v3 ] += normal.x; vertices[ v3 + 1 ] += normal.y; vertices[ v3 + 2 ] += normal.z;
    }

    for ( int j = 0; j < verticesCount / vertexLength; j++ )
    {
        unsigned int offset = j * vertexLength + normalOffset;
        glm::vec3 normalVertex( vertices[ offset ] , vertices[ offset + 1 ] , vertices[ offset + 2 ] );
        normalVertex = glm::normalize( normalVertex );

        vertices[ offset ] = normalVertex.x;
        vertices[ offset + 1 ] = normalVertex.y;
        vertices[ offset + 2 ] = normalVertex.z;
    }
}

void CreateTriangle() {

    float vertices[] {
       -0.5f,-0.5f, 0.0f,  0.0f, 0.0f,  0.0f, 0.0f, 0.0f, // Left
        0.5f,-0.5f, 0.0f,  1.0f, 0.0f,  0.0f, 0.0f, 0.0f, // Right
        0.0f, 0.5f, 0.0f,  0.5f, 1.0f,  0.0f, 0.0f, 0.0f, // Top
        0.0f,-0.5f, 0.5f,  0.5f, 0.0f,  0.0f, 0.0f, 0.0f  // Back Z
    };

    unsigned int indices[]{
        0, 1, 2, // Front
        3, 2, 1, // Right
        3, 2, 0, // Left
        3, 0, 1  // Bottom
    };

    CalcAverageNormals( indices , 12 , vertices , 32 , 8 , 5 );

    for ( int i = 0; i < 1; i++ )
    {
        Mesh* obj = new Mesh();

        obj->CreateMesh( vertices , 32 , indices , 12 );
        meshlist.push_back( obj );
    }

}
如果旋转网格,我只能获得某种照明:

正常(无照明):

几天来我一直在想这个问题,但我不确定我做错了什么。如果你能帮助我,那就太好了。

这个:

Normal = mat3(transpose(inverse(transformation))) * normal;
看起来,法线本身应转换为与灯光方向向量所处的坐标系相同的坐标系。因为法线是一个向量,
w
应该是零,所以我希望

Normal = view * transformation * vec4( normal, 0.0f );
如果灯光方向在摄影机坐标中,或:

Normal = transformation * vec4( normal, 0.0f );
如果灯光方向在全局世界坐标中(更可能是这种情况)

另外,设置着色器输出变量(如
gl_Position
)应该是着色器的最后一行,否则您可能会在某些实现上对gl实现后的其余代码进行优化

顺便说一句,IIRC
mat3(转置(逆(变换))
mat3(变换)
变换
的情况下是相同的,但正如拉比76所指出的,它有其目的

我能想到的最后一件事是错误的法线方向(相反或不一致),在这种情况下,我会尝试交换:

max(dot(normalize(Normal), normalize(directionalLight.direction)), 0.0f);
与:

如果它能帮助你检查法线或只是否定点的结果

有关更多信息,请参阅:

  • 。。。然而,在这里我使用
    w=1
    ,因为所使用的矩阵没有偏移,所以它并不重要
    • 这是:

      看起来,法线本身应转换为与灯光方向向量所处的坐标系相同的坐标系。因为法线是一个向量,
      w
      应该是零,所以我希望

      Normal = view * transformation * vec4( normal, 0.0f );
      
      如果灯光方向在摄影机坐标中,或:

      Normal = transformation * vec4( normal, 0.0f );
      
      如果灯光方向在全局世界坐标中(更可能是这种情况)

      另外,设置着色器输出变量(如
      gl_Position
      )应该是着色器的最后一行,否则您可能会在某些实现上对gl实现后的其余代码进行优化

      顺便说一句,IIRC
      mat3(转置(逆(变换))
      mat3(变换)
      变换
      的情况下是相同的,但正如拉比76所指出的,它有其目的

      我能想到的最后一件事是错误的法线方向(相反或不一致),在这种情况下,我会尝试交换:

      max(dot(normalize(Normal), normalize(directionalLight.direction)), 0.0f);
      
      与:

      如果它能帮助你检查法线或只是否定点的结果

      有关更多信息,请参阅:

      • 。。。然而,在这里我使用
        w=1
        ,因为所使用的矩阵没有偏移,所以它并不重要

      原来是我的指数顺序出现了三角形绕组的问题。由于漫反射因子是如何计算的,我通过逆时针顺序绘制索引来修复这个问题

      unsigned int indices[]{
          0, 1, 2, // Front
          3, 1, 2, // Right
          3, 0, 2, // Left
          3, 1, 0  // Bottom
      };
      

      转置和逆运算是为了纠正非均匀比例矩阵。

      结果是,我的指数顺序存在三角形缠绕问题。由于漫反射因子是如何计算的,我通过逆时针顺序绘制索引来修复这个问题

      unsigned int indices[]{
          0, 1, 2, // Front
          3, 1, 2, // Right
          3, 0, 2, // Left
          3, 1, 0  // Bottom
      };
      

      转置和逆运算是为了校正非均匀尺度矩阵。

      如果
      变换
      包含非对称尺度,则需要使用
      mat3(转置(逆(变换))
      @rabbi76嗯,很好的一点,我总是使用对称的和单位的,所以我没有想到…所以它会做某种纵横比反向校正?但是在这种情况下,代码应该首先工作…所以肯定还有其他可疑的地方。当然,我不是有意责备它,这只是一个注释。@rabbi76不工作我认为这是一个很好的例子,我理解它的正确功能…也许你可以在答案中编辑它…有两个很好的问题来解释“反转/转置”:如果
      转换
      包含一个不对称的比例,你需要使用
      mat3(转置(反转(转换))
      @rabbi76嗯,很好的一点,我总是使用对称的和单位的,所以我没有想到…所以它会做某种纵横比反向校正?但是在这种情况下,代码应该首先工作…所以肯定还有其他可疑的地方。当然,我不是有意责备它,这只是一个注释。@rabbi76不工作我认为这是一个很好的例子,我理解它的正确功能…也许你可以在答案中编辑它…有两个很好的问题来解释“反转/转置”:你正在操作顶点(
      vertices[v1]+=normal.x;
      …),同时迭代面并计算面法向量。这会影响由操纵顶点定义的所有后续面的法向量。您正在操纵顶点(
      顶点[v1]+=normal.x;
      …),同时迭代面并计算面法向量。这会影响由操纵顶点定义的所有后续面的法向量。