Phong照明:单独添加镜面光源还是环境光和漫反射光?

时间:2018-01-09 01:06:43

标签: opengl glsl phong specular

我正在尝试实施Phong照明。在一些教程中,镜面光照被添加到环境光和漫反射光,然后总光照乘以纹理颜色。我还看到了一个教程,其中在添加环境光和漫反射光与纹理颜色相乘后单独添加了镜面光照。

这是一个片段着色器,同时显示两个选项和屏幕截图。

#version 330 core
out vec4 FragColor;

in vec2 TexCoord;
in vec3 normals;
in vec3 fragPosition;


//texture samplers
uniform sampler2D texture1;
uniform vec3 ambientLight;
uniform vec3 lightPosition;
uniform vec3 lightColor;
uniform vec3 viewPosition;
uniform float specularStrength;
uniform float shineDamp;

void main()
{
    vec3 norm = normalize(normals);
    vec3 lightDir = normalize(lightPosition - fragPosition); 

    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    vec3 viewDir = normalize(viewPosition - fragPosition);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), shineDamp);
    vec3 specular = specularStrength * spec * lightColor;  

    // 1. Specular is added to ambient and diffuse lights and this result is multiplied with texture
    //FragColor = vec4((ambientLight + diffuse + specular), 1.0f) * texture(texture1, TexCoord);

    // 2. Specular is added separately to result of multiplication of ambient + diffuse and texture
    //FragColor = vec4((ambientLight + diffuse), 1.0f) * texture(texture1, TexCoord) + vec4(specular, 1.0);
}
  • 选项1.将镜面反射添加到环境和漫反射

    enter image description here

  • 选项2.单独添加镜面反射。

    enter image description here

在这些截图中,shineDump值为32.0f,specularStrength为0.5f。

哪一个看起来正确?在我看来,与第一个选项相比,第二个选项看起来是正确的,但很多教程使用第一个选项中的公式。

2 个答案:

答案 0 :(得分:3)

  

我正在尝试实施Phong照明。在一些教程中,镜面光照添加到环境光和漫反射光照,然后总光照乘以纹理颜色。

这是一个来自黑暗时代的历史人工制品,当时照明方程仍然在GPU中硬连线,而Gouraud shading是标准。仅在顶点处评估光模型,并且在整个基元上插值得到的光值。由于纹理通常用于模拟材质的表面属性,因此纹理通常在每个片段处进行采样(这样我们就可以为超出几何图形中指定的级别的基元提供结构)。但是由于gouraud阴影,我们需要用每个片段的纹理数据调制已经计算的光值。最简单的方法是将两者相乘。

  

我还看到了一个教程,其中在添加环境光和漫反射光与纹理颜色相乘后单独添加了高光照明。

通过纹理颜色调整整个光照,为许多材料带来不切实际的效果。为了解决这些问题,镜面部分有时会分开。我们现在计算一个amibient + diffuse部分和每个顶点的镜面部分,插入它们,用纹理调制环境+漫反射,然后在每个片段后添加镜面部分。

然而,现在没有人会使用Gouraud阴影,而是计算每个片段的光照。我们没有不同的频率来评估光模型和纹理的采样,因此这些问题变得毫无意义。由于某些表面反射的实际光线取决于材质,我们使用纹理来模拟该材质,我们可以直接使用纹理作为光照计算的输入,即漫反射光谱或镜面反射, 管他呢。这也允许我们在基元上改变任意材料属性,而不仅仅是"颜色",光泽度/粗糙度也可以来自纹理作为法线方向以及您的照明模型的任何参数可能会用。

答案 1 :(得分:2)

通常在计算机图形学中,光通过双向反射分布函数(BRDF)建模。 BRDF是一种功能,它给出了沿出射方向反射的光与从入射方向入射的光之间的关系。

一般而言,BRDF模型可分为以下一类或两类:

  • 实证: 他们的主要目的是提供一种专门设计用于模仿一种反射的简单配方。因此,我们得到一个可通过参数调整的快速计算模型,但不考虑它背后的物理学。
  • 理论:这些模型尝试使用物理定律精确模拟光散射。它们通常会导致复杂的表达和高计算量,因此它们通常不用于渲染系统。
  • 实验性:可以使用机械改变光源和传感器位置的Gonioreflectometer获取BRDF。其他技术使用数码相机通过一张照片获取许多BRDF样本。

再见:


Phong model是经验各向同性模型。由于经验和理论获得的BRDF模型都只是真实材料的反射特性的近似值,因此完全取决于您的场景和表面外观的BRDF。