Iluminação Phong - há algo muito estranho na iluminação especular

17

Eu implementei a iluminação Phong. Tudo parece funcionar - o toro e as esferas são iluminados conforme o esperado, etc. Mas percebo algo estranho em relação à iluminação especular da luz direcional.

Aqui estão duas capturas de tela.

Primeiro:

insira a descrição da imagem aqui

Segundo:

insira a descrição da imagem aqui

Como você pode ver, mais área possui iluminação especular quando a câmera está longe de um objeto.

Aqui estão os shaders de vértices simplificados:

#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);
}

... e sombreador de fragmento:

#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);
}

O código fonte completo, sem qualquer simplificação, pode ser encontrado neste repositório .

Eu queria saber se implementei algo errado. Ou está tudo bem com a iluminação Phong?

Aleksander Alekseev
fonte
2
Há uma pilha de gráficos de computador que você pode encontrar melhores respostas para esta pergunta.
Andrew Wilson

Respostas:

34

iluminação especular da luz direcional

mais área possui iluminação especular quando a câmera está longe de um objeto

Sim, parece certo para mim.

A área especular para luzes direcionais deve ser mais ou menos constante em relação à câmera, dada a mesma superfície de reflexão. Para comparar, podemos olhar para o fenômeno conhecido como sunglint , que é basicamente reflexo especular do Sol na água, e como o Sol é aproximadamente uma fonte de luz direcional para fins terrestres, e a superfície de reflexão é a Terra aproximadamente plana, Este é um bom análogo da sua iluminação Phong.

Exemplo 1: área de proteção solar aproximadamente a mesma de um lote residencial

Sunglint sobre o lago

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

Exemplo 2: área de proteção solar aproximada aos Grandes Lagos

Sunglint sobre Grandes Lagos

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

De fato, a área de raios solares continuará aumentando até que você esteja longe o suficiente da Terra para que seja mais redonda do que plana, da sua perspectiva.

Em termos do modelo de reflexão de Phong, o especular depende de três direções: o olho, a luz e a superfície. Como sua câmera está olhando para a mesma superfície, apenas se afastando, o olho permanece o mesmo; a superfície permanece a mesma em virtude de ser plana, e a luz permanece a mesma por definição (é uma luz direcional); portanto, a reflexão especular será a mesma - do ponto de vista da câmera / tela, é claro.

congusbongus
fonte
1
Adoro os exemplos da vida real que respondem a uma pergunta de programação
defhlt
caramba, você me fez criar uma conta apenas para votar.
Spongman