当前位置: 首页 > 知识库问答 >
问题:

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

单于季
2023-03-14

我正在尝试实现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,镜面强度为0.5f。

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

  • 共有2个答案

    谷梁弘深
    2023-03-14

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

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

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

    见更多:

    • 双向反射分布函数


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

    强安和
    2023-03-14

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

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

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

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

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

     类似资料:
    • 在我的照明场景中,由于某种原因,环境照明根本不起作用。无论朝哪个方向,整个模型都是相同的亮度。我试图消除衰减,但仍然有相同的结果。除此之外,无论相机位于何处,镜面照明都会一直闪烁。它应该根据球员的位置而发光。以下是环境问题的截图:Imgur。通用域名格式 如您所见,球体背向光线的部分(位于[0.0,4.0,0.0])与面向光线的部分颜色相同。环境因子应该是片段颜色的0.2。 顶点着色器源: 片段着

    • 本章介绍如何使用JOGL将光照效果应用于对象。 要设置光照,最初使用glEnable()方法启用光照。 然后使用GLLightingFunc接口的GLLightingFunc glLightfv(int light, int pname, float[] params, int params_offset)方法为GLLightingFunc 。 该方法有四个参数。 下表描述了gllightfv()

    • 基于图像的光照(Image based lighting, IBL)是一类光照技术的集合。其光源不是如前一节教程中描述的可分解的直接光源,而是将周围环境整体视为一个大光源。IBL 通常使用(取自现实世界或从3D场景生成的)环境立方体贴图 (Cubemap) ,我们可以将立方体贴图的每个像素视为光源,在渲染方程中直接使用它。这种方式可以有效地捕捉环境的全局光照和氛围,使物体更好地融入其环境。 由于基

    • 我正在为体素游戏开发一个3通道延迟照明系统,但是我在像素化照明和环境遮挡方面有问题。 第一阶段将屏幕上每个像素的颜色、位置和法线渲染成单独的纹理。这部分工作正常: 第二个着色器为屏幕上的每个像素计算环境光遮挡值,并将其渲染为纹理。此部分工作不正常,已像素化: 原始遮挡数据: 第三个着色器使用颜色、位置、法线和遮挡纹理将游戏场景渲染到屏幕上。这一阶段的照明也是像素化的: SSAO(第二遍)片段着色器

    • 传递给Illumate\Auth\SessionGuard::登录()的参数1必须是Illumate\合同\Auth\身份验证的实例,Illumate\Http\重定向响应的实例 我有我的注册控制器,它在创建用户之前检查成员身份是否存在于单独的成员表中。对于现有成员Id,它可以正常工作,但是当用户输入一个不存在的Id时,我需要它重定向到带有错误消息的同一注册页面。但我得到的只是上面的错误。请注意,

    • 我是Laravel的新手,正在查看一些示例代码。 在控制器中,我看到了这个: 为什么我必须使用“use Illumbite\Support\Facades\Input;”? 我不能只使用eg Input::get();就像我在路线文件中做的那样?