Я реализовал освещение 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);
}
Полный исходный код без каких-либо упрощений можно найти в этом хранилище .
Я хотел знать, реализовал ли я что-то не так. Или это нормально для освещения Фонг?
Ответы:
Да, смотрит прямо на меня.
Предполагается, что зеркальная область для направленных источников света будет более или менее постоянной относительно камеры, учитывая ту же отражающую поверхность. Чтобы сравнить, мы можем взглянуть на явление, известное как sunglint , которое в основном является зеркальным отражением Солнца на воде, и поскольку Солнце является приблизительно направленным источником света для земных целей, а отражающей поверхностью является Земля, которая является приблизительно плоской, Это хороший аналог освещения Phong.
Пример 1: площадь сунлинта примерно такая же, как у жилого участка
Пример 2: район Сунлинт, приближенный к Великим озерам
Фактически, область сунлинта будет только увеличиваться, пока вы не окажетесь достаточно далеко от Земли, чтобы она была более круглой, чем плоской, с вашей точки зрения.
С точки зрения модели отражения Фонга, зеркальное отражение зависит от трех направлений: глаз, свет и поверхность. Так как ваша камера смотрит на ту же поверхность, просто удаляясь, глаз остается тем же самым; поверхность остается неизменной благодаря тому, что она плоская, а свет остается неизменным по определению (это направленный свет), поэтому зеркальное отражение будет таким же - конечно, с точки зрения камеры / экрана.
источник