OpenGL:不带着色器的照明

时间:2020-08-03 14:05:11

标签: c++ opengl glm-math lighting phong

如何在不使用着色器(大学任务)的情况下进行灯光照明。 我可以手动计算环境,漫反射,镜面反射并将它们的总和传输到glColor吗?

UPD: 我很好地展示了环境和漫反射的总和。但是镜面反射无法正确渲染,变得非常分散。

我的图片问题:

我的代码:

void GLRenderSystem::renderTriangleSoup(const std::vector<Vertex>& vertices)
{
    glBegin(GL_TRIANGLES);
    for (const auto& vertex : vertices)
    {
        
        glm::vec3 norm = glm::normalize(glm::vec3(glm::mat3(glm::transpose(inverse(model))) * vertex.normal));
        glm::vec3 FragPos = view * model * glm::vec4(vertex.position, 1.0f); 
        glm::vec3 viewDir = glm::normalize(viewPos - FragPos); 
        glm::vec3 result = glm::vec3(0.0f);
    
        for (const auto& light : lightList)
        {
            if (light.isEnable)
            {
                // ambient
                glm::vec3 ambient = (Ka * light.Ia) * vertex.color;
    
                //diffuse
                glm::vec3 lightDir = glm::normalize(light.position - FragPos);      
                float dist = glm::length(light.position - FragPos);                 
                float diff = glm::max(glm::dot(norm, lightDir), 0.0f);              
                float Att = 1.0f / (1.0f + (0.01 * pow(dist, 2)));                  
                glm::vec3 diffuse = (Kd * light.Id) * (diff * vertex.color); 
    
                //reflect
                glm::vec3 reflectDir = glm::reflect(-lightDir, norm);                     
                float spec = glm::pow(glm::max(glm::dot(viewDir, reflectDir), 0.0f), Se); 
                glm::vec3 specular = (Ks * light.Is) * (spec * vertex.color);         
    
                // result color
                result += (ambient + diffuse + specular);
            }
        }
    
        glColor3fv((GLfloat*)&result);
    
        glm::vec4 vr = proj * view * model * glm::vec4(vertex.position, 1.0f);
        glVertex3fv((GLfloat*)&glm::vec3(vr.x / vr.w, vr.y / vr.w, vr.z / vr.w));
        glNormal3fv((GLfloat*)&vertex.normal);
    }
    glEnd();
}

1 个答案:

答案 0 :(得分:4)

(最初的问题是:我可以在不使用glMaterial或着色器的情况下生成镜面高光)

否。

以一个大三角形为例,其中的角仅由漫反射光照明,并且您希望在中间使用镜面高光。 拐角处的光照方程式没有(明显)镜面反射贡献,因此您只能将漫反射颜色作为glColor传递。

OpenGL将在三个角之间简单地线性插值颜色;除非您a)使用glMaterial告诉它片段如何与照明设置相互作用,或者b)编写片段着色器以评估每个片段的照明方程,否则它不会在中间神奇地生成镜面反射高光。

在2020年,只需使用着色器即可。

相关问题