如何在不使用着色器(大学任务)的情况下进行灯光照明。 我可以手动计算环境,漫反射,镜面反射并将它们的总和传输到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();
}
答案 0 :(得分:4)
(最初的问题是:我可以在不使用glMaterial或着色器的情况下生成镜面高光)
否。
以一个大三角形为例,其中的角仅由漫反射光照明,并且您希望在中间使用镜面高光。 拐角处的光照方程式没有(明显)镜面反射贡献,因此您只能将漫反射颜色作为glColor传递。
OpenGL将在三个角之间简单地线性插值颜色;除非您a)使用glMaterial告诉它片段如何与照明设置相互作用,或者b)编写片段着色器以评估每个片段的照明方程,否则它不会在中间神奇地生成镜面反射高光。
在2020年,只需使用着色器即可。