Éclairage Phong - il y a quelque chose de très étrange avec l'éclairage spéculaire

17

J'ai implémenté l'éclairage Phong. Tout semble fonctionner - le tore et les sphères sont éclairés comme prévu, etc. Mais je remarque quelque chose d'étrange concernant l'éclairage spéculaire de la lumière directionnelle.

Voici deux captures d'écran.

Premier:

entrez la description de l'image ici

Seconde:

entrez la description de l'image ici

Comme vous pouvez le voir, plus de zone a un éclairage spéculaire lorsque la caméra est loin d'un objet.

Voici un vertex shader simplifié:

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

... et fragment shader:

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

Le code source complet sans aucune simplification peut être trouvé dans ce référentiel .

Je voulais savoir si j'avais implémenté quelque chose de mal. Ou est-ce correct pour l'éclairage Phong?

Aleksander Alekseev
la source
2
Il y a une pile d'infographie que vous pourriez trouver de meilleures réponses à cette question.
Andrew Wilson

Réponses:

34

éclairage spéculaire de la lumière directionnelle

plus de zone a un éclairage spéculaire lorsque la caméra est loin d'un objet

Oui, ça me regarde bien.

La zone spéculaire des lumières directionnelles est censée être plus ou moins constante par rapport à la caméra, étant donné la même surface de réflexion. Pour comparer, nous pouvons examiner le phénomène connu sous le nom de glissement solaire , qui est essentiellement une réflexion spéculaire du Soleil sur l'eau, et puisque le Soleil est approximativement une source de lumière directionnelle à des fins terrestres, et que la surface de réflexion est la Terre qui est approximativement plate, c'est un bon analogue de votre éclairage Phong.

Exemple 1: surface de glande solaire à peu près la même chose qu'un lot résidentiel

Soleil sur le lac

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

Exemple 2: zone de glissement solaire proche des Grands Lacs

Soleil sur les Grands Lacs

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

En fait, la zone des reflets solaires continuera de s'agrandir jusqu'à ce que vous soyez suffisamment éloigné de la Terre pour qu'elle soit plus ronde que plate, de votre point de vue.

En termes de modèle de réflexion Phong, le spéculaire dépend de trois directions: l'œil, la lumière et la surface. Puisque votre appareil photo regarde la même surface, s'éloignant, l'œil reste le même; la surface reste la même en raison d'être plate, et la lumière reste la même par définition (c'est une lumière directionnelle), donc la réflexion spéculaire sera la même - du point de vue de la caméra / de l'écran, bien sûr.

congusbongus
la source
1
Love the real-life examples réponse à une question de programmation
defhlt
bon sang, tu m'as fait créer un compte juste pour voter.
Spongman