Oświetlenie Phong - jest coś dziwnego w oświetleniu lustrzanym

17

Wdrożyłem oświetlenie Phong. Wydaje się, że wszystko działa - torus i kule są oświetlone zgodnie z oczekiwaniami itp. Ale zauważam coś dziwnego w odniesieniu do lustrzanego oświetlenia światła kierunkowego.

Oto dwa zrzuty ekranu.

Pierwszy:

wprowadź opis zdjęcia tutaj

Druga:

wprowadź opis zdjęcia tutaj

Jak widać, więcej obszarów ma lustrzane oświetlenie, gdy kamera znajduje się daleko od obiektu.

Oto uproszczony moduł cieniujący wierzchołek:

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

... i shader fragmentów:

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

W tym repozytorium można znaleźć pełny kod źródłowy bez żadnego uproszczenia .

Chciałem wiedzieć, czy coś zaimplementowałem źle. Czy jest to w porządku w przypadku oświetlenia Phong?

Aleksander Alekseev
źródło
2
Istnieje stos grafiki komputerowej, w którym można znaleźć lepsze odpowiedzi na to pytanie.
Andrew Wilson,

Odpowiedzi:

34

specjalne odbicie światła kierunkowego

więcej obszaru ma specjalne oświetlenie, gdy kamera znajduje się daleko od obiektu

Tak, wygląda mi dobrze.

Obszar odbłyskowy dla świateł kierunkowych powinien być mniej więcej stały względem kamery, biorąc pod uwagę tę samą powierzchnię odbicia. Dla porównania możemy przyjrzeć się zjawisku znanemu jako promień słońca , który jest w zasadzie lustrzanym odbiciem Słońca na wodzie, a ponieważ Słońce jest w przybliżeniu kierunkowym źródłem światła do celów naziemnych, a powierzchnią odbicia jest Ziemia, która jest w przybliżeniu płaska, to dobry analog do twojego oświetlenia Phong.

Przykład 1: powierzchnia promienia słonecznego mniej więcej taka sama jak działka mieszkalna

Sunglint nad jeziorem

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

Przykład 2: powierzchnia promienia słońca zbliżona do Wielkich Jezior

Sunglint nad Wielkimi Jeziorami

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

W rzeczywistości obszar promienia słońca będzie się powiększał, dopóki nie będziesz wystarczająco daleko od Ziemi, aby była bardziej okrągła niż płaska z twojej perspektywy.

Jeśli chodzi o model odbicia Phong, zwierciadło zależy od trzech kierunków: oka, światła i powierzchni. Ponieważ kamera patrzy na tę samą powierzchnię, po prostu się odsuwa, oko pozostaje takie samo; powierzchnia pozostaje taka sama, ponieważ jest płaska, a światło pozostaje takie samo z definicji (jest to światło kierunkowe), dlatego odbicie lustrzane będzie takie samo - oczywiście z perspektywy kamery / ekranu.

congusbongus
źródło
1
Uwielbiam przykłady z życia, które odpowiadają na pytanie programistyczne
defhlt
cholera, kazałeś mi założyć konto tylko po to, by głosować.
Spongman