2

我正在尝试实现 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. 高光添加到环境和漫反射

    在此处输入图像描述

  • 选项 2. 单独添加高光。

    在此处输入图像描述

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

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

4

2 回答 2

3

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

这是黑暗时代的历史产物,当时照明方程仍然硬连线在 GPU 中,而Gouraud 着色是标准。光照模型仅在顶点处进行评估,并在整个图元中插值生成的光照值。由于纹理通常用于模拟材料的表面特性,因此通常在每个片段处对纹理进行采样(以便我们可以为我们的图元提供超出几何体指定级别的结构)。但是由于 gouraud 着色,我们需要使用每个片段的纹理数据来调制已经计算的光照值。最简单的方法是将两者相乘。

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

通过纹理颜色调制整个光照会为许多材质提供不切实际的结果。为了解决这些问题,有时会分离镜面反射部分。我们现在计算每个顶点的环境+漫反射部分和镜面反射部分,对它们进行插值,使用纹理调制环境+漫反射部分,然后在每个片段中添加镜面反射部分。

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

于 2018-01-09T20:23:16.443 回答
2

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

一般来说,BRDF 模型可以分为以下一类或两类:

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

进一步看:


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

于 2018-01-09T06:15:30.420 回答