Я пытаюсь реализовать модель затенения Фонга, но сталкиваюсь с чем-то довольно странным. Когда я меняю положение просмотра, кажется, что свет ведет себя по-другому, как если бы он зависел от вида. Например, если я нахожусь близко к объекту, я вижу только эффекты окружающего света, а если я ухожу далеко от него, я начинаю видеть вклад рассеянного света.
Это мои шейдеры:
//Vertex Shader
attribute vec4 vPosition;
attribute vec4 vNormal;
varying vec3 N, L, E;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec4 lightPosition;
void main()
{
vec3 pos = -(modelViewMatrix * vPosition).xyz;
vec3 light = lightPosition.xyz;
L = normalize(light - pos);
E = -pos;
N = normalize((modelViewMatrix * vNormal).xyz);
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
//Fragment Shader
uniform vec4 ambientProduct;
uniform vec4 diffuseProduct;
uniform vec4 specularProduct;
uniform float shininess;
varying vec3 N, L, E;
void main()
{
vec4 fColor;
vec3 H = normalize(L + E);
vec4 ambient = ambientProduct;
float Kd = max(dot(L, N), 0.0);
vec4 diffuse = Kd * diffuseProduct;
float Ks = pow(max(dot(N, H), 0.0), shininess);
vec4 specular = Ks * specularProduct;
if (dot(L, N) < 0.0) {
specular = vec4(0.0, 0.0, 0.0, 1.0);
}
fColor = ambient + diffuse + specular;
fColor.a = 1.0;
gl_FragColor = fColor;
}
Что я делаю неправильно? Как сделать так, чтобы свет вел себя независимо от положения зрителя?
Обновление 1:
После ответа @Rabbid76 я отредактировал вершинный шейдер, добавив эти строки (а также передав отдельные модели и матрицы представления, но я опущу это для краткости):
vec3 pos = (modelViewMatrix * vPosition).xyz;
vec3 light = (viewMatrix * lightPosition).xyz;
И я также обновил вычисление вектора N, поскольку предыдущий способ сделать это, казалось, фактически не допускал затенения для каждого фрагмента:
N = normalize(mat3(modelViewMatrix) * vNormal.xyz);
Тем не менее, тень, кажется, движется вместе с вращением камеры. Я думаю, это может быть связано с тем, что свет умножается на viewMatrix?