Phong照明-镜面照明有些奇怪


17

我实施了Phong照明。一切似乎都可以正常工作-圆环和球体都按预期方式进行了照明,等等。但是我注意到定向光的镜面照明有些奇怪。

这是两个屏幕截图。

第一:

在此处输入图片说明

第二:

在此处输入图片说明

如您所见,当相机远离物体时,更多区域具有镜面照明。

以下是简化的顶点着色器:

#version 330 core

layout(location = 0) in vec3 vertexPos;
layout(location = 1) in vec3 vertexNorm;
layout(location = 2) in vec2 vertexUV;

uniform mat4 MVP;
uniform mat4 M;

out vec2 fragmentUV;
out vec3 fragmentNormal;
out vec3 fragmentPos;

void main() {
  fragmentUV = vertexUV;
  fragmentNormal = (M * vec4(vertexNorm, 0)).xyz;
  fragmentPos = (M * vec4(vertexPos, 1)).xyz;

  gl_Position = MVP * vec4(vertexPos, 1);
}

...和片段着色器:

#version 330 core

in vec2 fragmentUV;
in vec3 fragmentNormal;
in vec3 fragmentPos;

struct DirectionalLight {
  vec3 Color;
  vec3 Direction;
  float AmbientIntensity;
  float DiffuseIntensity;
};

uniform sampler2D textureSampler;
uniform vec3 cameraPos;
uniform float materialSpecularFactor;
uniform float materialSpecularIntensity;
uniform DirectionalLight directionalLight;

out vec4 color;

void main() {
  vec3 normal = normalize(fragmentNormal); // should be normalized after interpolation

  vec4 ambientColor = vec4(directionalLight.Color, 1) * directionalLight.AmbientIntensity;

  float diffuseFactor = clamp(dot(normal, -directionalLight.Direction), 0, 1);
  vec4 diffuseColor = vec4(directionalLight.Color, 1) * directionalLight.DiffuseIntensity * diffuseFactor;

  vec3 vertexToCamera = normalize(cameraPos - fragmentPos);
  vec3 lightReflect = normalize(reflect(directionalLight.Direction, normal));
  float specularFactor = pow(clamp(dot(vertexToCamera, lightReflect), 0, 1), materialSpecularFactor);
  vec4 specularColor = vec4(directionalLight.Color, 1) * materialSpecularIntensity * specularFactor;

  color = texture(textureSampler, fragmentUV) * (ambientColor + diffuseColor + specularColor);
}

在此存储库中可以找到完整的源代码,没有任何简化。

我想知道我是否实施了错误的操作。还是Phong照明可以吗?


2
有一个计算机图形堆栈,您可能会对此问题找到更好的答案。
安德鲁·威尔逊

Answers:


34

定向光的镜面照明

当相机远离物体时,更多区域具有镜面照明

是的,对我来说看起来不错。

在给定相同的反射面的情况下,定向光的镜面区域应该在摄像机中或多或少是恒定的。比较一下,我们可以看一下被称为sunglint的现象基本上是太阳在水上的镜面反射,并且由于太阳大约是用于陆地目的的定向光源,并且反射表面是大约平坦的地球,这是您的Phong照明的一个很好的类似物。

示例1:阳光照射的面积与住宅区大致相同

湖上的阳光

http://academic.emporia.edu/aberjame/remote/lec10/lec10.htm

示例2:接近大湖的日照面积

大湖上的阳光

http://earthobservatory.nasa.gov/IOTD/view.php?id=78617

实际上,从您的角度来看,阳光直射区域只会不断扩大,直到您离地球足够远为止为止,才能使它比圆形更圆。

根据Phong反射模型,镜面反射取决于三个方向:眼睛,光线和表面。由于您的相机注视着同一表面,所以只要移开,眼睛就保持不变。表面由于平坦而保持不变,并且光在定义上保持不变(它是定向光),因此镜面反射将是相同的-当然,从相机/屏幕的角度来看。


1
喜欢现实生活中的示例,可以回答编程问题
defhlt

该死,您让我创建了一个仅用于投票的帐户。
Spongman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.