C++ 镜面反射高光故障OpenGL

C++ 镜面反射高光故障OpenGL,c++,opengl,rendering,glsl,C++,Opengl,Rendering,Glsl,当我渲染Phong或其他镜面反射BRDF时,我有这个 我从搅拌机中导入OBJ。只有顶点。在我像这样重新计算法线之后: Vertex& v1 = _vertices[id1]; Vertex& v2 = _vertices[id2]; Vertex& v3 = _vertices[id3]; glm::vec3 edge1 = v2.position - v1.position; glm::normalize(edge1);

当我渲染Phong或其他镜面反射BRDF时,我有这个

我从搅拌机中导入OBJ。只有顶点。在我像这样重新计算法线之后:

    Vertex& v1 = _vertices[id1];
    Vertex& v2 = _vertices[id2];
    Vertex& v3 = _vertices[id3];

    glm::vec3 edge1 = v2.position - v1.position;
    glm::normalize(edge1);
    glm::vec3 edge2 = v3.position - v1.position;
    glm::normalize(edge2);

    glm::vec3 normal = glm::cross(edge1, edge2);
    if (normal != glm::vec3(0.0))
        glm::normalize(normal);
            
            TrianglePtr triangle(new Triangle);
    triangle->normal = normal;
之后,我对顶点三角形中的所有法线求和。当我显示法线时,它们看起来很正常

我在这个阶段计算一切

VS:

一般事务:

有什么想法吗


小故障是由于我的正常计算造成的。我只从OBJ导入顶点。我用叉积来计算三角形法线的权重,但这还不够。所以我改进了微积分,在公式中加入了角权重。 对于基本形状,我在程序中创建它,而不是导入它们。所以我可以直接计算给定形状的法线

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec3 tangent;
layout (location = 4) in vec2 uv;

layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec3 outTangent;
layout (location = 2) out vec3 outBitangent;
layout (location = 3) out vec3 outColor;
layout (location = 4) out vec2 outUV;

out gl_PerVertex
{
    vec4 gl_Position;
    float gl_PointSize;
    float gl_ClipDistance[];
};

void main()
{   
    outNormal = normalize(normal);
    outTangent = normalize(tangent);
    outBitangent = normalize(cross(normal, tangent));
    outColor = color;
    outUV = uv;
    gl_Position =  vec4(position, 1.0);
}
#version 430 core

layout(triangles, invocations = 1) in;
layout (triangle_strip, max_vertices = 3) out;

layout (location = 0) in vec3 normal[];
layout (location = 1) in vec3 tangent[];
layout (location = 2) in vec3 bitangent[];
layout (location = 3) in vec3 color[];
layout (location = 4) in vec2 uv[];

layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec3 outTangent;
layout (location = 2) out vec3 outBitangent;
layout (location = 3) out vec3 outColor;
layout (location = 4) out vec2 outUv;
layout (location = 5) out vec3 lightDir;
layout (location = 6) out vec3 viewDir;

layout (std140, binding = 0) uniform WorldDataBlock
{
    mat4 modelMatrix;
    mat4 viewMatrix;
    mat4 projectionMatrix;
    mat4 normalMatrix;
}worldData;

uniform vec3 lightPosition = vec3(100.0, 100.0, 100.0);

in gl_PerVertex
{
    vec4 gl_Position;
    float gl_PointSize;
    float gl_ClipDistance[];
}gl_in[];

out gl_PerVertex
{
    vec4 gl_Position;
    float gl_PointSize;
    float gl_ClipDistance[];
};

void main()
{
    mat4 MV = worldData.viewMatrix * worldData.modelMatrix;
    mat4 MVP =  worldData.projectionMatrix * MV;

    for(int idx = 0; idx < gl_in.length(); ++idx)
    {       
        outNormal = normalize(worldData.normalMatrix * vec4(normal[idx], 0.0)).xyz;
        outTangent = normalize(mat3(worldData.normalMatrix) * tangent[idx]);
        outBitangent = normalize(mat3(worldData.normalMatrix) * bitangent[idx]);
        
        vec3 pos = (MV * gl_in[idx].gl_Position).xyz;
        vec3 lightPos = (worldData.viewMatrix * vec4(lightPosition, 1.0)).xyz;
        
        lightDir = normalize(lightPos - pos);       
        viewDir = normalize(-pos);

        gl_Position = MVP *  gl_in[idx].gl_Position;
        EmitVertex();
    }

    EndPrimitive();
}
    float roughness = clamp(materialData.roughness, 0.0, 1.0);
float alpha = roughness * roughness;
float k = pow((roughness + 1.0), 2) / 8.0;
vec3 H = normalize(lightDir + viewDir);

float NdotV = max(dot(normal, viewDir), 0.0);
float NdotL = max(dot(normal, lightDir), 0.0);
float NdotH = max(dot(normal, H), 0.0);
float VdotH = max(dot(viewDir, H), 0.0);
float LdotH = max(dot(lightDir, H), 0.0);

float D = alpha * alpha / ( PI * pow((pow(NdotH, 2) * ( alpha * alpha - 1.0) + 1), 2));

float Gv = NdotV / (NdotV * (1.0 - k) + k);
float Gl = NdotL / (NdotL * (1.0 - k) + k);
float G = Gv * Gl;

float F0 = 0.5 + 2 * VdotH * VdotH * roughness;
float exponent = -5.55473 * VdotH - 6.98316 * VdotH;
float F = F0 + (1.0 - F0) * pow(2.0, exponent);

float denum = clamp(4.0 * NdotL * NdotV, EPSILON, 1.0);

return max(D * G * F / denum, 0.0);