0

如何在不使用着色器的情况下制作 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();
}
4

1 回答 1

4

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

不。

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

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

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

于 2020-08-03T14:13:45.340 回答