【问题标题】:Phong lighting: add specular lighting separately or with ambient and diffuse?Phong 光照:单独添加镜面光照还是与环境和漫反射一起添加?
【发布时间】:2018-06-18 00:20:49
【问题描述】:

我正在尝试实现 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。

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

【问题讨论】:

    标签: opengl glsl phong specular


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      进一步了解:


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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-24
        • 2021-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-05
        • 2021-12-25
        • 2012-10-28
        相关资源
        最近更新 更多